]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/c/c-parser.cc
9c02141e2c66fdfc2e27db2c3b4f34f074990c79
[thirdparty/gcc.git] / gcc / c / c-parser.cc
1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2022 Free Software Foundation, Inc.
3
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
22
23 /* TODO:
24
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
27 of syntax accepted.
28
29 Add testcases covering every input symbol in every state in old and
30 new parsers.
31
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
34
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
37
38 #include "config.h"
39 #define INCLUDE_MEMORY
40 #include "system.h"
41 #include "coretypes.h"
42 #include "target.h"
43 #include "function.h"
44 #include "c-tree.h"
45 #include "timevar.h"
46 #include "stringpool.h"
47 #include "cgraph.h"
48 #include "attribs.h"
49 #include "stor-layout.h"
50 #include "varasm.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
53 #include "c-lang.h"
54 #include "c-family/c-objc.h"
55 #include "plugin.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
58 #include "builtins.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
62 #include "context.h"
63 #include "gcc-rich-location.h"
64 #include "c-parser.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
68 #include "intl.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
72 #include "memmodel.h"
73 #include "c-family/known-headers.h"
74
75 /* We need to walk over decls with incomplete struct/union/enum types
76 after parsing the whole translation unit.
77 In finish_decl(), if the decl is static, has incomplete
78 struct/union/enum type, it is appended to incomplete_record_decls.
79 In c_parser_translation_unit(), we iterate over incomplete_record_decls
80 and report error if any of the decls are still incomplete. */
81
82 vec<tree> incomplete_record_decls;
83
84 void
85 set_c_expr_source_range (c_expr *expr,
86 location_t start, location_t finish)
87 {
88 expr->src_range.m_start = start;
89 expr->src_range.m_finish = finish;
90 if (expr->value)
91 set_source_range (expr->value, start, finish);
92 }
93
94 void
95 set_c_expr_source_range (c_expr *expr,
96 source_range src_range)
97 {
98 expr->src_range = src_range;
99 if (expr->value)
100 set_source_range (expr->value, src_range);
101 }
102
103 \f
104 /* Initialization routine for this file. */
105
106 void
107 c_parse_init (void)
108 {
109 /* The only initialization required is of the reserved word
110 identifiers. */
111 unsigned int i;
112 tree id;
113 int mask = 0;
114
115 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
116 the c_token structure. */
117 gcc_assert (RID_MAX <= 255);
118
119 mask |= D_CXXONLY;
120 if (!flag_isoc99)
121 mask |= D_C99;
122 if (flag_no_asm)
123 {
124 mask |= D_ASM | D_EXT;
125 if (!flag_isoc99)
126 mask |= D_EXT89;
127 }
128 if (!c_dialect_objc ())
129 mask |= D_OBJC | D_CXX_OBJC;
130
131 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
132 for (i = 0; i < num_c_common_reswords; i++)
133 {
134 /* If a keyword is disabled, do not enter it into the table
135 and so create a canonical spelling that isn't a keyword. */
136 if (c_common_reswords[i].disable & mask)
137 {
138 if (warn_cxx_compat
139 && (c_common_reswords[i].disable & D_CXXWARN))
140 {
141 id = get_identifier (c_common_reswords[i].word);
142 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
143 C_IS_RESERVED_WORD (id) = 1;
144 }
145 continue;
146 }
147
148 id = get_identifier (c_common_reswords[i].word);
149 C_SET_RID_CODE (id, c_common_reswords[i].rid);
150 C_IS_RESERVED_WORD (id) = 1;
151 ridpointers [(int) c_common_reswords[i].rid] = id;
152 }
153
154 for (i = 0; i < NUM_INT_N_ENTS; i++)
155 {
156 /* We always create the symbols but they aren't always supported. */
157 char name[50];
158 sprintf (name, "__int%d", int_n_data[i].bitsize);
159 id = get_identifier (name);
160 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
161 C_IS_RESERVED_WORD (id) = 1;
162
163 sprintf (name, "__int%d__", int_n_data[i].bitsize);
164 id = get_identifier (name);
165 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
166 C_IS_RESERVED_WORD (id) = 1;
167 }
168
169 if (flag_openmp)
170 {
171 id = get_identifier ("omp_all_memory");
172 C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
173 C_IS_RESERVED_WORD (id) = 1;
174 ridpointers [RID_OMP_ALL_MEMORY] = id;
175 }
176 }
177 \f
178 /* A parser structure recording information about the state and
179 context of parsing. Includes lexer information with up to two
180 tokens of look-ahead; more are not needed for C. */
181 struct GTY(()) c_parser {
182 /* The look-ahead tokens. */
183 c_token * GTY((skip)) tokens;
184 /* Buffer for look-ahead tokens. */
185 c_token tokens_buf[4];
186 /* How many look-ahead tokens are available (0 - 4, or
187 more if parsing from pre-lexed tokens). */
188 unsigned int tokens_avail;
189 /* Raw look-ahead tokens, used only for checking in Objective-C
190 whether '[[' starts attributes. */
191 vec<c_token, va_gc> *raw_tokens;
192 /* The number of raw look-ahead tokens that have since been fully
193 lexed. */
194 unsigned int raw_tokens_used;
195 /* True if a syntax error is being recovered from; false otherwise.
196 c_parser_error sets this flag. It should clear this flag when
197 enough tokens have been consumed to recover from the error. */
198 BOOL_BITFIELD error : 1;
199 /* True if we're processing a pragma, and shouldn't automatically
200 consume CPP_PRAGMA_EOL. */
201 BOOL_BITFIELD in_pragma : 1;
202 /* True if we're parsing the outermost block of an if statement. */
203 BOOL_BITFIELD in_if_block : 1;
204 /* True if we want to lex a translated, joined string (for an
205 initial #pragma pch_preprocess). Otherwise the parser is
206 responsible for concatenating strings and translating to the
207 execution character set as needed. */
208 BOOL_BITFIELD lex_joined_string : 1;
209 /* True if, when the parser is concatenating string literals, it
210 should translate them to the execution character set (false
211 inside attributes). */
212 BOOL_BITFIELD translate_strings_p : 1;
213
214 /* Objective-C specific parser/lexer information. */
215
216 /* True if we are in a context where the Objective-C "PQ" keywords
217 are considered keywords. */
218 BOOL_BITFIELD objc_pq_context : 1;
219 /* True if we are parsing a (potential) Objective-C foreach
220 statement. This is set to true after we parsed 'for (' and while
221 we wait for 'in' or ';' to decide if it's a standard C for loop or an
222 Objective-C foreach loop. */
223 BOOL_BITFIELD objc_could_be_foreach_context : 1;
224 /* The following flag is needed to contextualize Objective-C lexical
225 analysis. In some cases (e.g., 'int NSObject;'), it is
226 undesirable to bind an identifier to an Objective-C class, even
227 if a class with that name exists. */
228 BOOL_BITFIELD objc_need_raw_identifier : 1;
229 /* Nonzero if we're processing a __transaction statement. The value
230 is 1 | TM_STMT_ATTR_*. */
231 unsigned int in_transaction : 4;
232 /* True if we are in a context where the Objective-C "Property attribute"
233 keywords are valid. */
234 BOOL_BITFIELD objc_property_attr_context : 1;
235
236 /* Whether we have just seen/constructed a string-literal. Set when
237 returning a string-literal from c_parser_string_literal. Reset
238 in consume_token. Useful when we get a parse error and see an
239 unknown token, which could have been a string-literal constant
240 macro. */
241 BOOL_BITFIELD seen_string_literal : 1;
242
243 /* Location of the last consumed token. */
244 location_t last_token_location;
245 };
246
247 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
248
249 c_token *
250 c_parser_tokens_buf (c_parser *parser, unsigned n)
251 {
252 return &parser->tokens_buf[n];
253 }
254
255 /* Return the error state of PARSER. */
256
257 bool
258 c_parser_error (c_parser *parser)
259 {
260 return parser->error;
261 }
262
263 /* Set the error state of PARSER to ERR. */
264
265 void
266 c_parser_set_error (c_parser *parser, bool err)
267 {
268 parser->error = err;
269 }
270
271
272 /* The actual parser and external interface. ??? Does this need to be
273 garbage-collected? */
274
275 static GTY (()) c_parser *the_parser;
276
277 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
278 context-sensitive postprocessing of the token is not done. */
279
280 static void
281 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
282 {
283 timevar_push (TV_LEX);
284
285 if (raw || vec_safe_length (parser->raw_tokens) == 0)
286 {
287 token->type = c_lex_with_flags (&token->value, &token->location,
288 &token->flags,
289 (parser->lex_joined_string
290 ? 0 : C_LEX_STRING_NO_JOIN));
291 token->id_kind = C_ID_NONE;
292 token->keyword = RID_MAX;
293 token->pragma_kind = PRAGMA_NONE;
294 }
295 else
296 {
297 /* Use a token previously lexed as a raw look-ahead token, and
298 complete the processing on it. */
299 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
300 ++parser->raw_tokens_used;
301 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
302 {
303 vec_free (parser->raw_tokens);
304 parser->raw_tokens_used = 0;
305 }
306 }
307
308 if (raw)
309 goto out;
310
311 switch (token->type)
312 {
313 case CPP_NAME:
314 {
315 tree decl;
316
317 bool objc_force_identifier = parser->objc_need_raw_identifier;
318 if (c_dialect_objc ())
319 parser->objc_need_raw_identifier = false;
320
321 if (C_IS_RESERVED_WORD (token->value))
322 {
323 enum rid rid_code = C_RID_CODE (token->value);
324
325 if (rid_code == RID_CXX_COMPAT_WARN)
326 {
327 warning_at (token->location,
328 OPT_Wc___compat,
329 "identifier %qE conflicts with C++ keyword",
330 token->value);
331 }
332 else if (rid_code >= RID_FIRST_ADDR_SPACE
333 && rid_code <= RID_LAST_ADDR_SPACE)
334 {
335 addr_space_t as;
336 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
337 targetm.addr_space.diagnose_usage (as, token->location);
338 token->id_kind = C_ID_ADDRSPACE;
339 token->keyword = rid_code;
340 break;
341 }
342 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
343 {
344 /* We found an Objective-C "pq" keyword (in, out,
345 inout, bycopy, byref, oneway). They need special
346 care because the interpretation depends on the
347 context. */
348 if (parser->objc_pq_context)
349 {
350 token->type = CPP_KEYWORD;
351 token->keyword = rid_code;
352 break;
353 }
354 else if (parser->objc_could_be_foreach_context
355 && rid_code == RID_IN)
356 {
357 /* We are in Objective-C, inside a (potential)
358 foreach context (which means after having
359 parsed 'for (', but before having parsed ';'),
360 and we found 'in'. We consider it the keyword
361 which terminates the declaration at the
362 beginning of a foreach-statement. Note that
363 this means you can't use 'in' for anything else
364 in that context; in particular, in Objective-C
365 you can't use 'in' as the name of the running
366 variable in a C for loop. We could potentially
367 try to add code here to disambiguate, but it
368 seems a reasonable limitation. */
369 token->type = CPP_KEYWORD;
370 token->keyword = rid_code;
371 break;
372 }
373 /* Else, "pq" keywords outside of the "pq" context are
374 not keywords, and we fall through to the code for
375 normal tokens. */
376 }
377 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
378 {
379 /* We found an Objective-C "property attribute"
380 keyword (getter, setter, readonly, etc). These are
381 only valid in the property context. */
382 if (parser->objc_property_attr_context)
383 {
384 token->type = CPP_KEYWORD;
385 token->keyword = rid_code;
386 break;
387 }
388 /* Else they are not special keywords.
389 */
390 }
391 else if (c_dialect_objc ()
392 && (OBJC_IS_AT_KEYWORD (rid_code)
393 || OBJC_IS_CXX_KEYWORD (rid_code)))
394 {
395 /* We found one of the Objective-C "@" keywords (defs,
396 selector, synchronized, etc) or one of the
397 Objective-C "cxx" keywords (class, private,
398 protected, public, try, catch, throw) without a
399 preceding '@' sign. Do nothing and fall through to
400 the code for normal tokens (in C++ we would still
401 consider the CXX ones keywords, but not in C). */
402 ;
403 }
404 else
405 {
406 token->type = CPP_KEYWORD;
407 token->keyword = rid_code;
408 break;
409 }
410 }
411
412 decl = lookup_name (token->value);
413 if (decl)
414 {
415 if (TREE_CODE (decl) == TYPE_DECL)
416 {
417 token->id_kind = C_ID_TYPENAME;
418 break;
419 }
420 }
421 else if (c_dialect_objc ())
422 {
423 tree objc_interface_decl = objc_is_class_name (token->value);
424 /* Objective-C class names are in the same namespace as
425 variables and typedefs, and hence are shadowed by local
426 declarations. */
427 if (objc_interface_decl
428 && (!objc_force_identifier || global_bindings_p ()))
429 {
430 token->value = objc_interface_decl;
431 token->id_kind = C_ID_CLASSNAME;
432 break;
433 }
434 }
435 token->id_kind = C_ID_ID;
436 }
437 break;
438 case CPP_AT_NAME:
439 /* This only happens in Objective-C; it must be a keyword. */
440 token->type = CPP_KEYWORD;
441 switch (C_RID_CODE (token->value))
442 {
443 /* Replace 'class' with '@class', 'private' with '@private',
444 etc. This prevents confusion with the C++ keyword
445 'class', and makes the tokens consistent with other
446 Objective-C 'AT' keywords. For example '@class' is
447 reported as RID_AT_CLASS which is consistent with
448 '@synchronized', which is reported as
449 RID_AT_SYNCHRONIZED.
450 */
451 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
452 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
453 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
454 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
455 case RID_THROW: token->keyword = RID_AT_THROW; break;
456 case RID_TRY: token->keyword = RID_AT_TRY; break;
457 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
458 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
459 default: token->keyword = C_RID_CODE (token->value);
460 }
461 break;
462 case CPP_COLON:
463 case CPP_COMMA:
464 case CPP_CLOSE_PAREN:
465 case CPP_SEMICOLON:
466 /* These tokens may affect the interpretation of any identifiers
467 following, if doing Objective-C. */
468 if (c_dialect_objc ())
469 parser->objc_need_raw_identifier = false;
470 break;
471 case CPP_PRAGMA:
472 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
473 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
474 token->value = NULL;
475 break;
476 default:
477 break;
478 }
479 out:
480 timevar_pop (TV_LEX);
481 }
482
483 /* Return a pointer to the next token from PARSER, reading it in if
484 necessary. */
485
486 c_token *
487 c_parser_peek_token (c_parser *parser)
488 {
489 if (parser->tokens_avail == 0)
490 {
491 c_lex_one_token (parser, &parser->tokens[0]);
492 parser->tokens_avail = 1;
493 }
494 return &parser->tokens[0];
495 }
496
497 /* Return a pointer to the next-but-one token from PARSER, reading it
498 in if necessary. The next token is already read in. */
499
500 c_token *
501 c_parser_peek_2nd_token (c_parser *parser)
502 {
503 if (parser->tokens_avail >= 2)
504 return &parser->tokens[1];
505 gcc_assert (parser->tokens_avail == 1);
506 gcc_assert (parser->tokens[0].type != CPP_EOF);
507 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
508 c_lex_one_token (parser, &parser->tokens[1]);
509 parser->tokens_avail = 2;
510 return &parser->tokens[1];
511 }
512
513 /* Return a pointer to the Nth token from PARSER, reading it
514 in if necessary. The N-1th token is already read in. */
515
516 c_token *
517 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
518 {
519 /* N is 1-based, not zero-based. */
520 gcc_assert (n > 0);
521
522 if (parser->tokens_avail >= n)
523 return &parser->tokens[n - 1];
524 gcc_assert (parser->tokens_avail == n - 1);
525 c_lex_one_token (parser, &parser->tokens[n - 1]);
526 parser->tokens_avail = n;
527 return &parser->tokens[n - 1];
528 }
529
530 /* Return a pointer to the Nth token from PARSER, reading it in as a
531 raw look-ahead token if necessary. The N-1th token is already read
532 in. Raw look-ahead tokens remain available for when the non-raw
533 functions above are called. */
534
535 c_token *
536 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
537 {
538 /* N is 1-based, not zero-based. */
539 gcc_assert (n > 0);
540
541 if (parser->tokens_avail >= n)
542 return &parser->tokens[n - 1];
543 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
544 unsigned int raw_avail
545 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
546 gcc_assert (raw_avail >= n - 1);
547 if (raw_avail >= n)
548 return &(*parser->raw_tokens)[parser->raw_tokens_used
549 + n - 1 - parser->tokens_avail];
550 vec_safe_reserve (parser->raw_tokens, 1);
551 parser->raw_tokens->quick_grow (raw_len + 1);
552 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
553 return &(*parser->raw_tokens)[raw_len];
554 }
555
556 bool
557 c_keyword_starts_typename (enum rid keyword)
558 {
559 switch (keyword)
560 {
561 case RID_UNSIGNED:
562 case RID_LONG:
563 case RID_SHORT:
564 case RID_SIGNED:
565 case RID_COMPLEX:
566 case RID_INT:
567 case RID_CHAR:
568 case RID_FLOAT:
569 case RID_DOUBLE:
570 case RID_VOID:
571 case RID_DFLOAT32:
572 case RID_DFLOAT64:
573 case RID_DFLOAT128:
574 CASE_RID_FLOATN_NX:
575 case RID_BOOL:
576 case RID_ENUM:
577 case RID_STRUCT:
578 case RID_UNION:
579 case RID_TYPEOF:
580 case RID_CONST:
581 case RID_ATOMIC:
582 case RID_VOLATILE:
583 case RID_RESTRICT:
584 case RID_ATTRIBUTE:
585 case RID_FRACT:
586 case RID_ACCUM:
587 case RID_SAT:
588 case RID_AUTO_TYPE:
589 case RID_ALIGNAS:
590 return true;
591 default:
592 if (keyword >= RID_FIRST_INT_N
593 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
594 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
595 return true;
596 return false;
597 }
598 }
599
600 /* Return true if TOKEN can start a type name,
601 false otherwise. */
602 bool
603 c_token_starts_typename (c_token *token)
604 {
605 switch (token->type)
606 {
607 case CPP_NAME:
608 switch (token->id_kind)
609 {
610 case C_ID_ID:
611 return false;
612 case C_ID_ADDRSPACE:
613 return true;
614 case C_ID_TYPENAME:
615 return true;
616 case C_ID_CLASSNAME:
617 gcc_assert (c_dialect_objc ());
618 return true;
619 default:
620 gcc_unreachable ();
621 }
622 case CPP_KEYWORD:
623 return c_keyword_starts_typename (token->keyword);
624 case CPP_LESS:
625 if (c_dialect_objc ())
626 return true;
627 return false;
628 default:
629 return false;
630 }
631 }
632
633 /* Return true if the next token from PARSER can start a type name,
634 false otherwise. LA specifies how to do lookahead in order to
635 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
636
637 static inline bool
638 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
639 {
640 c_token *token = c_parser_peek_token (parser);
641 if (c_token_starts_typename (token))
642 return true;
643
644 /* Try a bit harder to detect an unknown typename. */
645 if (la != cla_prefer_id
646 && token->type == CPP_NAME
647 && token->id_kind == C_ID_ID
648
649 /* Do not try too hard when we could have "object in array". */
650 && !parser->objc_could_be_foreach_context
651
652 && (la == cla_prefer_type
653 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
654 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
655
656 /* Only unknown identifiers. */
657 && !lookup_name (token->value))
658 return true;
659
660 return false;
661 }
662
663 /* Return true if TOKEN is a type qualifier, false otherwise. */
664 static bool
665 c_token_is_qualifier (c_token *token)
666 {
667 switch (token->type)
668 {
669 case CPP_NAME:
670 switch (token->id_kind)
671 {
672 case C_ID_ADDRSPACE:
673 return true;
674 default:
675 return false;
676 }
677 case CPP_KEYWORD:
678 switch (token->keyword)
679 {
680 case RID_CONST:
681 case RID_VOLATILE:
682 case RID_RESTRICT:
683 case RID_ATTRIBUTE:
684 case RID_ATOMIC:
685 return true;
686 default:
687 return false;
688 }
689 case CPP_LESS:
690 return false;
691 default:
692 gcc_unreachable ();
693 }
694 }
695
696 /* Return true if the next token from PARSER is a type qualifier,
697 false otherwise. */
698 static inline bool
699 c_parser_next_token_is_qualifier (c_parser *parser)
700 {
701 c_token *token = c_parser_peek_token (parser);
702 return c_token_is_qualifier (token);
703 }
704
705 /* Return true if TOKEN can start declaration specifiers (not
706 including standard attributes), false otherwise. */
707 static bool
708 c_token_starts_declspecs (c_token *token)
709 {
710 switch (token->type)
711 {
712 case CPP_NAME:
713 switch (token->id_kind)
714 {
715 case C_ID_ID:
716 return false;
717 case C_ID_ADDRSPACE:
718 return true;
719 case C_ID_TYPENAME:
720 return true;
721 case C_ID_CLASSNAME:
722 gcc_assert (c_dialect_objc ());
723 return true;
724 default:
725 gcc_unreachable ();
726 }
727 case CPP_KEYWORD:
728 switch (token->keyword)
729 {
730 case RID_STATIC:
731 case RID_EXTERN:
732 case RID_REGISTER:
733 case RID_TYPEDEF:
734 case RID_INLINE:
735 case RID_NORETURN:
736 case RID_AUTO:
737 case RID_THREAD:
738 case RID_UNSIGNED:
739 case RID_LONG:
740 case RID_SHORT:
741 case RID_SIGNED:
742 case RID_COMPLEX:
743 case RID_INT:
744 case RID_CHAR:
745 case RID_FLOAT:
746 case RID_DOUBLE:
747 case RID_VOID:
748 case RID_DFLOAT32:
749 case RID_DFLOAT64:
750 case RID_DFLOAT128:
751 CASE_RID_FLOATN_NX:
752 case RID_BOOL:
753 case RID_ENUM:
754 case RID_STRUCT:
755 case RID_UNION:
756 case RID_TYPEOF:
757 case RID_CONST:
758 case RID_VOLATILE:
759 case RID_RESTRICT:
760 case RID_ATTRIBUTE:
761 case RID_FRACT:
762 case RID_ACCUM:
763 case RID_SAT:
764 case RID_ALIGNAS:
765 case RID_ATOMIC:
766 case RID_AUTO_TYPE:
767 return true;
768 default:
769 if (token->keyword >= RID_FIRST_INT_N
770 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
771 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
772 return true;
773 return false;
774 }
775 case CPP_LESS:
776 if (c_dialect_objc ())
777 return true;
778 return false;
779 default:
780 return false;
781 }
782 }
783
784
785 /* Return true if TOKEN can start declaration specifiers (not
786 including standard attributes) or a static assertion, false
787 otherwise. */
788 static bool
789 c_token_starts_declaration (c_token *token)
790 {
791 if (c_token_starts_declspecs (token)
792 || token->keyword == RID_STATIC_ASSERT)
793 return true;
794 else
795 return false;
796 }
797
798 /* Return true if the next token from PARSER can start declaration
799 specifiers (not including standard attributes), false
800 otherwise. */
801 bool
802 c_parser_next_token_starts_declspecs (c_parser *parser)
803 {
804 c_token *token = c_parser_peek_token (parser);
805
806 /* In Objective-C, a classname normally starts a declspecs unless it
807 is immediately followed by a dot. In that case, it is the
808 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
809 setter/getter on the class. c_token_starts_declspecs() can't
810 differentiate between the two cases because it only checks the
811 current token, so we have a special check here. */
812 if (c_dialect_objc ()
813 && token->type == CPP_NAME
814 && token->id_kind == C_ID_CLASSNAME
815 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
816 return false;
817
818 return c_token_starts_declspecs (token);
819 }
820
821 /* Return true if the next tokens from PARSER can start declaration
822 specifiers (not including standard attributes) or a static
823 assertion, false otherwise. */
824 bool
825 c_parser_next_tokens_start_declaration (c_parser *parser)
826 {
827 c_token *token = c_parser_peek_token (parser);
828
829 /* Same as above. */
830 if (c_dialect_objc ()
831 && token->type == CPP_NAME
832 && token->id_kind == C_ID_CLASSNAME
833 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
834 return false;
835
836 /* Labels do not start declarations. */
837 if (token->type == CPP_NAME
838 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
839 return false;
840
841 if (c_token_starts_declaration (token))
842 return true;
843
844 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
845 return true;
846
847 return false;
848 }
849
850 /* Consume the next token from PARSER. */
851
852 void
853 c_parser_consume_token (c_parser *parser)
854 {
855 gcc_assert (parser->tokens_avail >= 1);
856 gcc_assert (parser->tokens[0].type != CPP_EOF);
857 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
858 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
859 parser->last_token_location = parser->tokens[0].location;
860 if (parser->tokens != &parser->tokens_buf[0])
861 parser->tokens++;
862 else if (parser->tokens_avail >= 2)
863 {
864 parser->tokens[0] = parser->tokens[1];
865 if (parser->tokens_avail >= 3)
866 {
867 parser->tokens[1] = parser->tokens[2];
868 if (parser->tokens_avail >= 4)
869 parser->tokens[2] = parser->tokens[3];
870 }
871 }
872 parser->tokens_avail--;
873 parser->seen_string_literal = false;
874 }
875
876 /* Expect the current token to be a #pragma. Consume it and remember
877 that we've begun parsing a pragma. */
878
879 static void
880 c_parser_consume_pragma (c_parser *parser)
881 {
882 gcc_assert (!parser->in_pragma);
883 gcc_assert (parser->tokens_avail >= 1);
884 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
885 if (parser->tokens != &parser->tokens_buf[0])
886 parser->tokens++;
887 else if (parser->tokens_avail >= 2)
888 {
889 parser->tokens[0] = parser->tokens[1];
890 if (parser->tokens_avail >= 3)
891 parser->tokens[1] = parser->tokens[2];
892 }
893 parser->tokens_avail--;
894 parser->in_pragma = true;
895 }
896
897 /* Update the global input_location from TOKEN. */
898 static inline void
899 c_parser_set_source_position_from_token (c_token *token)
900 {
901 if (token->type != CPP_EOF)
902 {
903 input_location = token->location;
904 }
905 }
906
907 /* Helper function for c_parser_error.
908 Having peeked a token of kind TOK1_KIND that might signify
909 a conflict marker, peek successor tokens to determine
910 if we actually do have a conflict marker.
911 Specifically, we consider a run of 7 '<', '=' or '>' characters
912 at the start of a line as a conflict marker.
913 These come through the lexer as three pairs and a single,
914 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
915 If it returns true, *OUT_LOC is written to with the location/range
916 of the marker. */
917
918 static bool
919 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
920 location_t *out_loc)
921 {
922 c_token *token2 = c_parser_peek_2nd_token (parser);
923 if (token2->type != tok1_kind)
924 return false;
925 c_token *token3 = c_parser_peek_nth_token (parser, 3);
926 if (token3->type != tok1_kind)
927 return false;
928 c_token *token4 = c_parser_peek_nth_token (parser, 4);
929 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
930 return false;
931
932 /* It must be at the start of the line. */
933 location_t start_loc = c_parser_peek_token (parser)->location;
934 if (LOCATION_COLUMN (start_loc) != 1)
935 return false;
936
937 /* We have a conflict marker. Construct a location of the form:
938 <<<<<<<
939 ^~~~~~~
940 with start == caret, finishing at the end of the marker. */
941 location_t finish_loc = get_finish (token4->location);
942 *out_loc = make_location (start_loc, start_loc, finish_loc);
943
944 return true;
945 }
946
947 /* Issue a diagnostic of the form
948 FILE:LINE: MESSAGE before TOKEN
949 where TOKEN is the next token in the input stream of PARSER.
950 MESSAGE (specified by the caller) is usually of the form "expected
951 OTHER-TOKEN".
952
953 Use RICHLOC as the location of the diagnostic.
954
955 Do not issue a diagnostic if still recovering from an error.
956
957 Return true iff an error was actually emitted.
958
959 ??? This is taken from the C++ parser, but building up messages in
960 this way is not i18n-friendly and some other approach should be
961 used. */
962
963 static bool
964 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
965 rich_location *richloc)
966 {
967 c_token *token = c_parser_peek_token (parser);
968 if (parser->error)
969 return false;
970 parser->error = true;
971 if (!gmsgid)
972 return false;
973
974 /* If this is actually a conflict marker, report it as such. */
975 if (token->type == CPP_LSHIFT
976 || token->type == CPP_RSHIFT
977 || token->type == CPP_EQ_EQ)
978 {
979 location_t loc;
980 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
981 {
982 error_at (loc, "version control conflict marker in file");
983 return true;
984 }
985 }
986
987 /* If we were parsing a string-literal and there is an unknown name
988 token right after, then check to see if that could also have been
989 a literal string by checking the name against a list of known
990 standard string literal constants defined in header files. If
991 there is one, then add that as an hint to the error message. */
992 auto_diagnostic_group d;
993 name_hint h;
994 if (parser->seen_string_literal && token->type == CPP_NAME)
995 {
996 tree name = token->value;
997 const char *token_name = IDENTIFIER_POINTER (name);
998 const char *header_hint
999 = get_c_stdlib_header_for_string_macro_name (token_name);
1000 if (header_hint != NULL)
1001 h = name_hint (NULL, new suggest_missing_header (token->location,
1002 token_name,
1003 header_hint));
1004 }
1005
1006 c_parse_error (gmsgid,
1007 /* Because c_parse_error does not understand
1008 CPP_KEYWORD, keywords are treated like
1009 identifiers. */
1010 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1011 /* ??? The C parser does not save the cpp flags of a
1012 token, we need to pass 0 here and we will not get
1013 the source spelling of some tokens but rather the
1014 canonical spelling. */
1015 token->value, /*flags=*/0, richloc);
1016 return true;
1017 }
1018
1019 /* As c_parser_error_richloc, but issue the message at the
1020 location of PARSER's next token, or at input_location
1021 if the next token is EOF. */
1022
1023 bool
1024 c_parser_error (c_parser *parser, const char *gmsgid)
1025 {
1026 c_token *token = c_parser_peek_token (parser);
1027 c_parser_set_source_position_from_token (token);
1028 rich_location richloc (line_table, input_location);
1029 return c_parser_error_richloc (parser, gmsgid, &richloc);
1030 }
1031
1032 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1033 This class is for tracking such a matching pair of symbols.
1034 In particular, it tracks the location of the first token,
1035 so that if the second token is missing, we can highlight the
1036 location of the first token when notifying the user about the
1037 problem. */
1038
1039 template <typename traits_t>
1040 class token_pair
1041 {
1042 public:
1043 /* token_pair's ctor. */
1044 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1045
1046 /* If the next token is the opening symbol for this pair, consume it and
1047 return true.
1048 Otherwise, issue an error and return false.
1049 In either case, record the location of the opening token. */
1050
1051 bool require_open (c_parser *parser)
1052 {
1053 c_token *token = c_parser_peek_token (parser);
1054 if (token)
1055 m_open_loc = token->location;
1056
1057 return c_parser_require (parser, traits_t::open_token_type,
1058 traits_t::open_gmsgid);
1059 }
1060
1061 /* Consume the next token from PARSER, recording its location as
1062 that of the opening token within the pair. */
1063
1064 void consume_open (c_parser *parser)
1065 {
1066 c_token *token = c_parser_peek_token (parser);
1067 gcc_assert (token->type == traits_t::open_token_type);
1068 m_open_loc = token->location;
1069 c_parser_consume_token (parser);
1070 }
1071
1072 /* If the next token is the closing symbol for this pair, consume it
1073 and return true.
1074 Otherwise, issue an error, highlighting the location of the
1075 corresponding opening token, and return false. */
1076
1077 bool require_close (c_parser *parser) const
1078 {
1079 return c_parser_require (parser, traits_t::close_token_type,
1080 traits_t::close_gmsgid, m_open_loc);
1081 }
1082
1083 /* Like token_pair::require_close, except that tokens will be skipped
1084 until the desired token is found. An error message is still produced
1085 if the next token is not as expected. */
1086
1087 void skip_until_found_close (c_parser *parser) const
1088 {
1089 c_parser_skip_until_found (parser, traits_t::close_token_type,
1090 traits_t::close_gmsgid, m_open_loc);
1091 }
1092
1093 private:
1094 location_t m_open_loc;
1095 };
1096
1097 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1098
1099 struct matching_paren_traits
1100 {
1101 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1102 static const char * const open_gmsgid;
1103 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1104 static const char * const close_gmsgid;
1105 };
1106
1107 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1108 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1109
1110 /* "matching_parens" is a token_pair<T> class for tracking matching
1111 pairs of parentheses. */
1112
1113 typedef token_pair<matching_paren_traits> matching_parens;
1114
1115 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1116
1117 struct matching_brace_traits
1118 {
1119 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1120 static const char * const open_gmsgid;
1121 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1122 static const char * const close_gmsgid;
1123 };
1124
1125 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1126 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1127
1128 /* "matching_braces" is a token_pair<T> class for tracking matching
1129 pairs of braces. */
1130
1131 typedef token_pair<matching_brace_traits> matching_braces;
1132
1133 /* Get a description of the matching symbol to TYPE e.g. "(" for
1134 CPP_CLOSE_PAREN. */
1135
1136 static const char *
1137 get_matching_symbol (enum cpp_ttype type)
1138 {
1139 switch (type)
1140 {
1141 default:
1142 gcc_unreachable ();
1143 case CPP_CLOSE_PAREN:
1144 return "(";
1145 case CPP_CLOSE_BRACE:
1146 return "{";
1147 }
1148 }
1149
1150 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1151 issue the error MSGID. If MSGID is NULL then a message has already
1152 been produced and no message will be produced this time. Returns
1153 true if found, false otherwise.
1154
1155 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1156 within any error as the location of an "opening" token matching
1157 the close token TYPE (e.g. the location of the '(' when TYPE is
1158 CPP_CLOSE_PAREN).
1159
1160 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1161 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1162 attempt to generate a fix-it hint for the problem.
1163 Otherwise msgid describes multiple token types (e.g.
1164 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1165 generate a fix-it hint. */
1166
1167 bool
1168 c_parser_require (c_parser *parser,
1169 enum cpp_ttype type,
1170 const char *msgid,
1171 location_t matching_location,
1172 bool type_is_unique)
1173 {
1174 if (c_parser_next_token_is (parser, type))
1175 {
1176 c_parser_consume_token (parser);
1177 return true;
1178 }
1179 else
1180 {
1181 location_t next_token_loc = c_parser_peek_token (parser)->location;
1182 gcc_rich_location richloc (next_token_loc);
1183
1184 /* Potentially supply a fix-it hint, suggesting to add the
1185 missing token immediately after the *previous* token.
1186 This may move the primary location within richloc. */
1187 if (!parser->error && type_is_unique)
1188 maybe_suggest_missing_token_insertion (&richloc, type,
1189 parser->last_token_location);
1190
1191 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1192 Attempt to consolidate diagnostics by printing it as a
1193 secondary range within the main diagnostic. */
1194 bool added_matching_location = false;
1195 if (matching_location != UNKNOWN_LOCATION)
1196 added_matching_location
1197 = richloc.add_location_if_nearby (matching_location);
1198
1199 if (c_parser_error_richloc (parser, msgid, &richloc))
1200 /* If we weren't able to consolidate matching_location, then
1201 print it as a secondary diagnostic. */
1202 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1203 inform (matching_location, "to match this %qs",
1204 get_matching_symbol (type));
1205
1206 return false;
1207 }
1208 }
1209
1210 /* If the next token is the indicated keyword, consume it. Otherwise,
1211 issue the error MSGID. Returns true if found, false otherwise. */
1212
1213 static bool
1214 c_parser_require_keyword (c_parser *parser,
1215 enum rid keyword,
1216 const char *msgid)
1217 {
1218 if (c_parser_next_token_is_keyword (parser, keyword))
1219 {
1220 c_parser_consume_token (parser);
1221 return true;
1222 }
1223 else
1224 {
1225 c_parser_error (parser, msgid);
1226 return false;
1227 }
1228 }
1229
1230 /* Like c_parser_require, except that tokens will be skipped until the
1231 desired token is found. An error message is still produced if the
1232 next token is not as expected. If MSGID is NULL then a message has
1233 already been produced and no message will be produced this
1234 time.
1235
1236 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1237 within any error as the location of an "opening" token matching
1238 the close token TYPE (e.g. the location of the '(' when TYPE is
1239 CPP_CLOSE_PAREN). */
1240
1241 void
1242 c_parser_skip_until_found (c_parser *parser,
1243 enum cpp_ttype type,
1244 const char *msgid,
1245 location_t matching_location)
1246 {
1247 unsigned nesting_depth = 0;
1248
1249 if (c_parser_require (parser, type, msgid, matching_location))
1250 return;
1251
1252 /* Skip tokens until the desired token is found. */
1253 while (true)
1254 {
1255 /* Peek at the next token. */
1256 c_token *token = c_parser_peek_token (parser);
1257 /* If we've reached the token we want, consume it and stop. */
1258 if (token->type == type && !nesting_depth)
1259 {
1260 c_parser_consume_token (parser);
1261 break;
1262 }
1263
1264 /* If we've run out of tokens, stop. */
1265 if (token->type == CPP_EOF)
1266 return;
1267 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1268 return;
1269 if (token->type == CPP_OPEN_BRACE
1270 || token->type == CPP_OPEN_PAREN
1271 || token->type == CPP_OPEN_SQUARE)
1272 ++nesting_depth;
1273 else if (token->type == CPP_CLOSE_BRACE
1274 || token->type == CPP_CLOSE_PAREN
1275 || token->type == CPP_CLOSE_SQUARE)
1276 {
1277 if (nesting_depth-- == 0)
1278 break;
1279 }
1280 /* Consume this token. */
1281 c_parser_consume_token (parser);
1282 }
1283 parser->error = false;
1284 }
1285
1286 /* Skip tokens until the end of a parameter is found, but do not
1287 consume the comma, semicolon or closing delimiter. */
1288
1289 static void
1290 c_parser_skip_to_end_of_parameter (c_parser *parser)
1291 {
1292 unsigned nesting_depth = 0;
1293
1294 while (true)
1295 {
1296 c_token *token = c_parser_peek_token (parser);
1297 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1298 && !nesting_depth)
1299 break;
1300 /* If we've run out of tokens, stop. */
1301 if (token->type == CPP_EOF)
1302 return;
1303 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1304 return;
1305 if (token->type == CPP_OPEN_BRACE
1306 || token->type == CPP_OPEN_PAREN
1307 || token->type == CPP_OPEN_SQUARE)
1308 ++nesting_depth;
1309 else if (token->type == CPP_CLOSE_BRACE
1310 || token->type == CPP_CLOSE_PAREN
1311 || token->type == CPP_CLOSE_SQUARE)
1312 {
1313 if (nesting_depth-- == 0)
1314 break;
1315 }
1316 /* Consume this token. */
1317 c_parser_consume_token (parser);
1318 }
1319 parser->error = false;
1320 }
1321
1322 /* Expect to be at the end of the pragma directive and consume an
1323 end of line marker. */
1324
1325 static void
1326 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1327 {
1328 gcc_assert (parser->in_pragma);
1329 parser->in_pragma = false;
1330
1331 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1332 c_parser_error (parser, "expected end of line");
1333
1334 cpp_ttype token_type;
1335 do
1336 {
1337 c_token *token = c_parser_peek_token (parser);
1338 token_type = token->type;
1339 if (token_type == CPP_EOF)
1340 break;
1341 c_parser_consume_token (parser);
1342 }
1343 while (token_type != CPP_PRAGMA_EOL);
1344
1345 parser->error = false;
1346 }
1347
1348 /* Skip tokens until we have consumed an entire block, or until we
1349 have consumed a non-nested ';'. */
1350
1351 static void
1352 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1353 {
1354 unsigned nesting_depth = 0;
1355 bool save_error = parser->error;
1356
1357 while (true)
1358 {
1359 c_token *token;
1360
1361 /* Peek at the next token. */
1362 token = c_parser_peek_token (parser);
1363
1364 switch (token->type)
1365 {
1366 case CPP_EOF:
1367 return;
1368
1369 case CPP_PRAGMA_EOL:
1370 if (parser->in_pragma)
1371 return;
1372 break;
1373
1374 case CPP_SEMICOLON:
1375 /* If the next token is a ';', we have reached the
1376 end of the statement. */
1377 if (!nesting_depth)
1378 {
1379 /* Consume the ';'. */
1380 c_parser_consume_token (parser);
1381 goto finished;
1382 }
1383 break;
1384
1385 case CPP_CLOSE_BRACE:
1386 /* If the next token is a non-nested '}', then we have
1387 reached the end of the current block. */
1388 if (nesting_depth == 0 || --nesting_depth == 0)
1389 {
1390 c_parser_consume_token (parser);
1391 goto finished;
1392 }
1393 break;
1394
1395 case CPP_OPEN_BRACE:
1396 /* If it the next token is a '{', then we are entering a new
1397 block. Consume the entire block. */
1398 ++nesting_depth;
1399 break;
1400
1401 case CPP_PRAGMA:
1402 /* If we see a pragma, consume the whole thing at once. We
1403 have some safeguards against consuming pragmas willy-nilly.
1404 Normally, we'd expect to be here with parser->error set,
1405 which disables these safeguards. But it's possible to get
1406 here for secondary error recovery, after parser->error has
1407 been cleared. */
1408 c_parser_consume_pragma (parser);
1409 c_parser_skip_to_pragma_eol (parser);
1410 parser->error = save_error;
1411 continue;
1412
1413 default:
1414 break;
1415 }
1416
1417 c_parser_consume_token (parser);
1418 }
1419
1420 finished:
1421 parser->error = false;
1422 }
1423
1424 /* CPP's options (initialized by c-opts.cc). */
1425 extern cpp_options *cpp_opts;
1426
1427 /* Save the warning flags which are controlled by __extension__. */
1428
1429 static inline int
1430 disable_extension_diagnostics (void)
1431 {
1432 int ret = (pedantic
1433 | (warn_pointer_arith << 1)
1434 | (warn_traditional << 2)
1435 | (flag_iso << 3)
1436 | (warn_long_long << 4)
1437 | (warn_cxx_compat << 5)
1438 | (warn_overlength_strings << 6)
1439 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1440 play tricks to properly restore it. */
1441 | ((warn_c90_c99_compat == 1) << 7)
1442 | ((warn_c90_c99_compat == -1) << 8)
1443 /* Similarly for warn_c99_c11_compat. */
1444 | ((warn_c99_c11_compat == 1) << 9)
1445 | ((warn_c99_c11_compat == -1) << 10)
1446 /* Similarly for warn_c11_c2x_compat. */
1447 | ((warn_c11_c2x_compat == 1) << 11)
1448 | ((warn_c11_c2x_compat == -1) << 12)
1449 );
1450 cpp_opts->cpp_pedantic = pedantic = 0;
1451 warn_pointer_arith = 0;
1452 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1453 flag_iso = 0;
1454 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1455 warn_cxx_compat = 0;
1456 warn_overlength_strings = 0;
1457 warn_c90_c99_compat = 0;
1458 warn_c99_c11_compat = 0;
1459 warn_c11_c2x_compat = 0;
1460 return ret;
1461 }
1462
1463 /* Restore the warning flags which are controlled by __extension__.
1464 FLAGS is the return value from disable_extension_diagnostics. */
1465
1466 static inline void
1467 restore_extension_diagnostics (int flags)
1468 {
1469 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1470 warn_pointer_arith = (flags >> 1) & 1;
1471 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1472 flag_iso = (flags >> 3) & 1;
1473 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1474 warn_cxx_compat = (flags >> 5) & 1;
1475 warn_overlength_strings = (flags >> 6) & 1;
1476 /* See above for why is this needed. */
1477 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1478 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1479 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1480 }
1481
1482 /* Helper data structure for parsing #pragma acc routine. */
1483 struct oacc_routine_data {
1484 bool error_seen; /* Set if error has been reported. */
1485 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1486 tree clauses;
1487 location_t loc;
1488 };
1489
1490 /* Used for parsing objc foreach statements. */
1491 static tree objc_foreach_break_label, objc_foreach_continue_label;
1492
1493 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1494 unsigned int);
1495 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1496 static void c_parser_external_declaration (c_parser *);
1497 static void c_parser_asm_definition (c_parser *);
1498 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1499 bool, bool, tree * = NULL,
1500 vec<c_token> * = NULL,
1501 bool have_attrs = false,
1502 tree attrs = NULL,
1503 struct oacc_routine_data * = NULL,
1504 bool * = NULL);
1505 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1506 static void c_parser_static_assert_declaration (c_parser *);
1507 static struct c_typespec c_parser_enum_specifier (c_parser *);
1508 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1509 static tree c_parser_struct_declaration (c_parser *);
1510 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1511 static tree c_parser_alignas_specifier (c_parser *);
1512 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1513 c_dtr_syn, bool *);
1514 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1515 bool,
1516 struct c_declarator *);
1517 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1518 bool);
1519 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1520 tree, bool);
1521 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1522 static tree c_parser_simple_asm_expr (c_parser *);
1523 static tree c_parser_gnu_attributes (c_parser *);
1524 static struct c_expr c_parser_initializer (c_parser *);
1525 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1526 struct obstack *);
1527 static void c_parser_initelt (c_parser *, struct obstack *);
1528 static void c_parser_initval (c_parser *, struct c_expr *,
1529 struct obstack *);
1530 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1531 static location_t c_parser_compound_statement_nostart (c_parser *);
1532 static void c_parser_label (c_parser *, tree);
1533 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1534 static void c_parser_statement_after_labels (c_parser *, bool *,
1535 vec<tree> * = NULL);
1536 static tree c_parser_c99_block_statement (c_parser *, bool *,
1537 location_t * = NULL);
1538 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1539 static void c_parser_switch_statement (c_parser *, bool *);
1540 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1541 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1542 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1543 static tree c_parser_asm_statement (c_parser *);
1544 static tree c_parser_asm_operands (c_parser *);
1545 static tree c_parser_asm_goto_operands (c_parser *);
1546 static tree c_parser_asm_clobbers (c_parser *);
1547 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1548 tree = NULL_TREE);
1549 static struct c_expr c_parser_conditional_expression (c_parser *,
1550 struct c_expr *, tree);
1551 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1552 tree);
1553 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1554 static struct c_expr c_parser_unary_expression (c_parser *);
1555 static struct c_expr c_parser_sizeof_expression (c_parser *);
1556 static struct c_expr c_parser_alignof_expression (c_parser *);
1557 static struct c_expr c_parser_postfix_expression (c_parser *);
1558 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1559 struct c_type_name *,
1560 location_t);
1561 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1562 location_t loc,
1563 struct c_expr);
1564 static tree c_parser_transaction (c_parser *, enum rid);
1565 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1566 static tree c_parser_transaction_cancel (c_parser *);
1567 static struct c_expr c_parser_expression (c_parser *);
1568 static struct c_expr c_parser_expression_conv (c_parser *);
1569 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1570 vec<tree, va_gc> **, location_t *,
1571 tree *, vec<location_t> *,
1572 unsigned int * = NULL);
1573 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1574
1575 static void c_parser_oacc_declare (c_parser *);
1576 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1577 static void c_parser_oacc_update (c_parser *);
1578 static void c_parser_omp_construct (c_parser *, bool *);
1579 static void c_parser_omp_threadprivate (c_parser *);
1580 static void c_parser_omp_barrier (c_parser *);
1581 static void c_parser_omp_depobj (c_parser *);
1582 static void c_parser_omp_flush (c_parser *);
1583 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1584 tree, tree *, bool *);
1585 static void c_parser_omp_taskwait (c_parser *);
1586 static void c_parser_omp_taskyield (c_parser *);
1587 static void c_parser_omp_cancel (c_parser *);
1588 static void c_parser_omp_nothing (c_parser *);
1589
1590 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1591 pragma_stmt, pragma_compound };
1592 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1593 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1594 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1595 static void c_parser_omp_end_declare_target (c_parser *);
1596 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1597 static void c_parser_omp_requires (c_parser *);
1598 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1599 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1600 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1601
1602 /* These Objective-C parser functions are only ever called when
1603 compiling Objective-C. */
1604 static void c_parser_objc_class_definition (c_parser *, tree);
1605 static void c_parser_objc_class_instance_variables (c_parser *);
1606 static void c_parser_objc_class_declaration (c_parser *);
1607 static void c_parser_objc_alias_declaration (c_parser *);
1608 static void c_parser_objc_protocol_definition (c_parser *, tree);
1609 static bool c_parser_objc_method_type (c_parser *);
1610 static void c_parser_objc_method_definition (c_parser *);
1611 static void c_parser_objc_methodprotolist (c_parser *);
1612 static void c_parser_objc_methodproto (c_parser *);
1613 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1614 static tree c_parser_objc_type_name (c_parser *);
1615 static tree c_parser_objc_protocol_refs (c_parser *);
1616 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1617 static void c_parser_objc_synchronized_statement (c_parser *);
1618 static tree c_parser_objc_selector (c_parser *);
1619 static tree c_parser_objc_selector_arg (c_parser *);
1620 static tree c_parser_objc_receiver (c_parser *);
1621 static tree c_parser_objc_message_args (c_parser *);
1622 static tree c_parser_objc_keywordexpr (c_parser *);
1623 static void c_parser_objc_at_property_declaration (c_parser *);
1624 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1625 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1626 static bool c_parser_objc_diagnose_bad_element_prefix
1627 (c_parser *, struct c_declspecs *);
1628 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1629
1630 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1631
1632 translation-unit:
1633 external-declarations
1634
1635 external-declarations:
1636 external-declaration
1637 external-declarations external-declaration
1638
1639 GNU extensions:
1640
1641 translation-unit:
1642 empty
1643 */
1644
1645 static void
1646 c_parser_translation_unit (c_parser *parser)
1647 {
1648 if (c_parser_next_token_is (parser, CPP_EOF))
1649 {
1650 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1651 "ISO C forbids an empty translation unit");
1652 }
1653 else
1654 {
1655 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1656 mark_valid_location_for_stdc_pragma (false);
1657 do
1658 {
1659 ggc_collect ();
1660 c_parser_external_declaration (parser);
1661 obstack_free (&parser_obstack, obstack_position);
1662 }
1663 while (c_parser_next_token_is_not (parser, CPP_EOF));
1664 }
1665
1666 unsigned int i;
1667 tree decl;
1668 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1669 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1670 error ("storage size of %q+D isn%'t known", decl);
1671
1672 if (current_omp_declare_target_attribute)
1673 {
1674 if (!errorcount)
1675 error ("%<#pragma omp declare target%> without corresponding "
1676 "%<#pragma omp end declare target%>");
1677 current_omp_declare_target_attribute = 0;
1678 }
1679 }
1680
1681 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1682
1683 external-declaration:
1684 function-definition
1685 declaration
1686
1687 GNU extensions:
1688
1689 external-declaration:
1690 asm-definition
1691 ;
1692 __extension__ external-declaration
1693
1694 Objective-C:
1695
1696 external-declaration:
1697 objc-class-definition
1698 objc-class-declaration
1699 objc-alias-declaration
1700 objc-protocol-definition
1701 objc-method-definition
1702 @end
1703 */
1704
1705 static void
1706 c_parser_external_declaration (c_parser *parser)
1707 {
1708 int ext;
1709 switch (c_parser_peek_token (parser)->type)
1710 {
1711 case CPP_KEYWORD:
1712 switch (c_parser_peek_token (parser)->keyword)
1713 {
1714 case RID_EXTENSION:
1715 ext = disable_extension_diagnostics ();
1716 c_parser_consume_token (parser);
1717 c_parser_external_declaration (parser);
1718 restore_extension_diagnostics (ext);
1719 break;
1720 case RID_ASM:
1721 c_parser_asm_definition (parser);
1722 break;
1723 case RID_AT_INTERFACE:
1724 case RID_AT_IMPLEMENTATION:
1725 gcc_assert (c_dialect_objc ());
1726 c_parser_objc_class_definition (parser, NULL_TREE);
1727 break;
1728 case RID_AT_CLASS:
1729 gcc_assert (c_dialect_objc ());
1730 c_parser_objc_class_declaration (parser);
1731 break;
1732 case RID_AT_ALIAS:
1733 gcc_assert (c_dialect_objc ());
1734 c_parser_objc_alias_declaration (parser);
1735 break;
1736 case RID_AT_PROTOCOL:
1737 gcc_assert (c_dialect_objc ());
1738 c_parser_objc_protocol_definition (parser, NULL_TREE);
1739 break;
1740 case RID_AT_PROPERTY:
1741 gcc_assert (c_dialect_objc ());
1742 c_parser_objc_at_property_declaration (parser);
1743 break;
1744 case RID_AT_SYNTHESIZE:
1745 gcc_assert (c_dialect_objc ());
1746 c_parser_objc_at_synthesize_declaration (parser);
1747 break;
1748 case RID_AT_DYNAMIC:
1749 gcc_assert (c_dialect_objc ());
1750 c_parser_objc_at_dynamic_declaration (parser);
1751 break;
1752 case RID_AT_END:
1753 gcc_assert (c_dialect_objc ());
1754 c_parser_consume_token (parser);
1755 objc_finish_implementation ();
1756 break;
1757 default:
1758 goto decl_or_fndef;
1759 }
1760 break;
1761 case CPP_SEMICOLON:
1762 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1763 "ISO C does not allow extra %<;%> outside of a function");
1764 c_parser_consume_token (parser);
1765 break;
1766 case CPP_PRAGMA:
1767 mark_valid_location_for_stdc_pragma (true);
1768 c_parser_pragma (parser, pragma_external, NULL);
1769 mark_valid_location_for_stdc_pragma (false);
1770 break;
1771 case CPP_PLUS:
1772 case CPP_MINUS:
1773 if (c_dialect_objc ())
1774 {
1775 c_parser_objc_method_definition (parser);
1776 break;
1777 }
1778 /* Else fall through, and yield a syntax error trying to parse
1779 as a declaration or function definition. */
1780 /* FALLTHRU */
1781 default:
1782 decl_or_fndef:
1783 /* A declaration or a function definition (or, in Objective-C,
1784 an @interface or @protocol with prefix attributes). We can
1785 only tell which after parsing the declaration specifiers, if
1786 any, and the first declarator. */
1787 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1788 break;
1789 }
1790 }
1791
1792 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1793 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1794
1795 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1796
1797 static void
1798 add_debug_begin_stmt (location_t loc)
1799 {
1800 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1801 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1802 return;
1803
1804 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1805 SET_EXPR_LOCATION (stmt, loc);
1806 add_stmt (stmt);
1807 }
1808
1809 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1810 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1811 is accepted; otherwise (old-style parameter declarations) only other
1812 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1813 assertion is accepted; otherwise (old-style parameter declarations)
1814 it is not. If NESTED is true, we are inside a function or parsing
1815 old-style parameter declarations; any functions encountered are
1816 nested functions and declaration specifiers are required; otherwise
1817 we are at top level and functions are normal functions and
1818 declaration specifiers may be optional. If EMPTY_OK is true, empty
1819 declarations are OK (subject to all other constraints); otherwise
1820 (old-style parameter declarations) they are diagnosed. If
1821 START_ATTR_OK is true, the declaration specifiers may start with
1822 attributes (GNU or standard); otherwise they may not.
1823 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1824 declaration when parsing an Objective-C foreach statement.
1825 FALLTHRU_ATTR_P is used to signal whether this function parsed
1826 "__attribute__((fallthrough));". ATTRS are any standard attributes
1827 parsed in the caller (in contexts where such attributes had to be
1828 parsed to determine whether what follows is a declaration or a
1829 statement); HAVE_ATTRS says whether there were any such attributes
1830 (even empty).
1831
1832 declaration:
1833 declaration-specifiers init-declarator-list[opt] ;
1834 static_assert-declaration
1835
1836 function-definition:
1837 declaration-specifiers[opt] declarator declaration-list[opt]
1838 compound-statement
1839
1840 declaration-list:
1841 declaration
1842 declaration-list declaration
1843
1844 init-declarator-list:
1845 init-declarator
1846 init-declarator-list , init-declarator
1847
1848 init-declarator:
1849 declarator simple-asm-expr[opt] gnu-attributes[opt]
1850 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1851
1852 GNU extensions:
1853
1854 nested-function-definition:
1855 declaration-specifiers declarator declaration-list[opt]
1856 compound-statement
1857
1858 attribute ;
1859
1860 Objective-C:
1861 gnu-attributes objc-class-definition
1862 gnu-attributes objc-category-definition
1863 gnu-attributes objc-protocol-definition
1864
1865 The simple-asm-expr and gnu-attributes are GNU extensions.
1866
1867 This function does not handle __extension__; that is handled in its
1868 callers. ??? Following the old parser, __extension__ may start
1869 external declarations, declarations in functions and declarations
1870 at the start of "for" loops, but not old-style parameter
1871 declarations.
1872
1873 C99 requires declaration specifiers in a function definition; the
1874 absence is diagnosed through the diagnosis of implicit int. In GNU
1875 C we also allow but diagnose declarations without declaration
1876 specifiers, but only at top level (elsewhere they conflict with
1877 other syntax).
1878
1879 In Objective-C, declarations of the looping variable in a foreach
1880 statement are exceptionally terminated by 'in' (for example, 'for
1881 (NSObject *object in array) { ... }').
1882
1883 OpenMP:
1884
1885 declaration:
1886 threadprivate-directive
1887
1888 GIMPLE:
1889
1890 gimple-function-definition:
1891 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1892 declaration-list[opt] compound-statement
1893
1894 rtl-function-definition:
1895 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1896 declaration-list[opt] compound-statement */
1897
1898 static void
1899 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1900 bool static_assert_ok, bool empty_ok,
1901 bool nested, bool start_attr_ok,
1902 tree *objc_foreach_object_declaration
1903 /* = NULL */,
1904 vec<c_token> *omp_declare_simd_clauses
1905 /* = NULL */,
1906 bool have_attrs /* = false */,
1907 tree attrs /* = NULL_TREE */,
1908 struct oacc_routine_data *oacc_routine_data
1909 /* = NULL */,
1910 bool *fallthru_attr_p /* = NULL */)
1911 {
1912 struct c_declspecs *specs;
1913 tree prefix_attrs;
1914 tree all_prefix_attrs;
1915 bool diagnosed_no_specs = false;
1916 location_t here = c_parser_peek_token (parser)->location;
1917
1918 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1919
1920 if (static_assert_ok
1921 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1922 {
1923 c_parser_static_assert_declaration (parser);
1924 return;
1925 }
1926 specs = build_null_declspecs ();
1927
1928 /* Handle any standard attributes parsed in the caller. */
1929 if (have_attrs)
1930 {
1931 declspecs_add_attrs (here, specs, attrs);
1932 specs->non_std_attrs_seen_p = false;
1933 }
1934
1935 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1936 if (c_parser_peek_token (parser)->type == CPP_NAME
1937 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1938 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1939 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1940 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1941 {
1942 tree name = c_parser_peek_token (parser)->value;
1943
1944 /* Issue a warning about NAME being an unknown type name, perhaps
1945 with some kind of hint.
1946 If the user forgot a "struct" etc, suggest inserting
1947 it. Otherwise, attempt to look for misspellings. */
1948 gcc_rich_location richloc (here);
1949 if (tag_exists_p (RECORD_TYPE, name))
1950 {
1951 /* This is not C++ with its implicit typedef. */
1952 richloc.add_fixit_insert_before ("struct ");
1953 error_at (&richloc,
1954 "unknown type name %qE;"
1955 " use %<struct%> keyword to refer to the type",
1956 name);
1957 }
1958 else if (tag_exists_p (UNION_TYPE, name))
1959 {
1960 richloc.add_fixit_insert_before ("union ");
1961 error_at (&richloc,
1962 "unknown type name %qE;"
1963 " use %<union%> keyword to refer to the type",
1964 name);
1965 }
1966 else if (tag_exists_p (ENUMERAL_TYPE, name))
1967 {
1968 richloc.add_fixit_insert_before ("enum ");
1969 error_at (&richloc,
1970 "unknown type name %qE;"
1971 " use %<enum%> keyword to refer to the type",
1972 name);
1973 }
1974 else
1975 {
1976 auto_diagnostic_group d;
1977 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1978 here);
1979 if (const char *suggestion = hint.suggestion ())
1980 {
1981 richloc.add_fixit_replace (suggestion);
1982 error_at (&richloc,
1983 "unknown type name %qE; did you mean %qs?",
1984 name, suggestion);
1985 }
1986 else
1987 error_at (here, "unknown type name %qE", name);
1988 }
1989
1990 /* Parse declspecs normally to get a correct pointer type, but avoid
1991 a further "fails to be a type name" error. Refuse nested functions
1992 since it is not how the user likely wants us to recover. */
1993 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1994 c_parser_peek_token (parser)->keyword = RID_VOID;
1995 c_parser_peek_token (parser)->value = error_mark_node;
1996 fndef_ok = !nested;
1997 }
1998
1999 /* When there are standard attributes at the start of the
2000 declaration (to apply to the entity being declared), an
2001 init-declarator-list or function definition must be present. */
2002 if (c_parser_nth_token_starts_std_attributes (parser, 1))
2003 have_attrs = true;
2004
2005 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2006 true, true, start_attr_ok, true, cla_nonabstract_decl);
2007 if (parser->error)
2008 {
2009 c_parser_skip_to_end_of_block_or_statement (parser);
2010 return;
2011 }
2012 if (nested && !specs->declspecs_seen_p)
2013 {
2014 c_parser_error (parser, "expected declaration specifiers");
2015 c_parser_skip_to_end_of_block_or_statement (parser);
2016 return;
2017 }
2018
2019 finish_declspecs (specs);
2020 bool auto_type_p = specs->typespec_word == cts_auto_type;
2021 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2022 {
2023 if (auto_type_p)
2024 error_at (here, "%<__auto_type%> in empty declaration");
2025 else if (specs->typespec_kind == ctsk_none
2026 && attribute_fallthrough_p (specs->attrs))
2027 {
2028 if (fallthru_attr_p != NULL)
2029 *fallthru_attr_p = true;
2030 if (nested)
2031 {
2032 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2033 void_type_node, 0);
2034 add_stmt (fn);
2035 }
2036 else
2037 pedwarn (here, OPT_Wattributes,
2038 "%<fallthrough%> attribute at top level");
2039 }
2040 else if (empty_ok && !(have_attrs
2041 && specs->non_std_attrs_seen_p))
2042 shadow_tag (specs);
2043 else
2044 {
2045 shadow_tag_warned (specs, 1);
2046 pedwarn (here, 0, "empty declaration");
2047 }
2048 c_parser_consume_token (parser);
2049 if (oacc_routine_data)
2050 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2051 return;
2052 }
2053
2054 /* Provide better error recovery. Note that a type name here is usually
2055 better diagnosed as a redeclaration. */
2056 if (empty_ok
2057 && specs->typespec_kind == ctsk_tagdef
2058 && c_parser_next_token_starts_declspecs (parser)
2059 && !c_parser_next_token_is (parser, CPP_NAME))
2060 {
2061 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2062 parser->error = false;
2063 shadow_tag_warned (specs, 1);
2064 return;
2065 }
2066 else if (c_dialect_objc () && !auto_type_p)
2067 {
2068 /* Prefix attributes are an error on method decls. */
2069 switch (c_parser_peek_token (parser)->type)
2070 {
2071 case CPP_PLUS:
2072 case CPP_MINUS:
2073 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2074 return;
2075 if (specs->attrs)
2076 {
2077 warning_at (c_parser_peek_token (parser)->location,
2078 OPT_Wattributes,
2079 "prefix attributes are ignored for methods");
2080 specs->attrs = NULL_TREE;
2081 }
2082 if (fndef_ok)
2083 c_parser_objc_method_definition (parser);
2084 else
2085 c_parser_objc_methodproto (parser);
2086 return;
2087 break;
2088 default:
2089 break;
2090 }
2091 /* This is where we parse 'attributes @interface ...',
2092 'attributes @implementation ...', 'attributes @protocol ...'
2093 (where attributes could be, for example, __attribute__
2094 ((deprecated)).
2095 */
2096 switch (c_parser_peek_token (parser)->keyword)
2097 {
2098 case RID_AT_INTERFACE:
2099 {
2100 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2101 return;
2102 c_parser_objc_class_definition (parser, specs->attrs);
2103 return;
2104 }
2105 break;
2106 case RID_AT_IMPLEMENTATION:
2107 {
2108 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2109 return;
2110 if (specs->attrs)
2111 {
2112 warning_at (c_parser_peek_token (parser)->location,
2113 OPT_Wattributes,
2114 "prefix attributes are ignored for implementations");
2115 specs->attrs = NULL_TREE;
2116 }
2117 c_parser_objc_class_definition (parser, NULL_TREE);
2118 return;
2119 }
2120 break;
2121 case RID_AT_PROTOCOL:
2122 {
2123 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2124 return;
2125 c_parser_objc_protocol_definition (parser, specs->attrs);
2126 return;
2127 }
2128 break;
2129 case RID_AT_ALIAS:
2130 case RID_AT_CLASS:
2131 case RID_AT_END:
2132 case RID_AT_PROPERTY:
2133 if (specs->attrs)
2134 {
2135 c_parser_error (parser, "unexpected attribute");
2136 specs->attrs = NULL;
2137 }
2138 break;
2139 default:
2140 break;
2141 }
2142 }
2143 else if (attribute_fallthrough_p (specs->attrs))
2144 warning_at (here, OPT_Wattributes,
2145 "%<fallthrough%> attribute not followed by %<;%>");
2146
2147 pending_xref_error ();
2148 prefix_attrs = specs->attrs;
2149 all_prefix_attrs = prefix_attrs;
2150 specs->attrs = NULL_TREE;
2151 while (true)
2152 {
2153 struct c_declarator *declarator;
2154 bool dummy = false;
2155 timevar_id_t tv;
2156 tree fnbody = NULL_TREE;
2157 /* Declaring either one or more declarators (in which case we
2158 should diagnose if there were no declaration specifiers) or a
2159 function definition (in which case the diagnostic for
2160 implicit int suffices). */
2161 declarator = c_parser_declarator (parser,
2162 specs->typespec_kind != ctsk_none,
2163 C_DTR_NORMAL, &dummy);
2164 if (declarator == NULL)
2165 {
2166 if (omp_declare_simd_clauses)
2167 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2168 omp_declare_simd_clauses);
2169 if (oacc_routine_data)
2170 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2171 c_parser_skip_to_end_of_block_or_statement (parser);
2172 return;
2173 }
2174 if (auto_type_p && declarator->kind != cdk_id)
2175 {
2176 error_at (here,
2177 "%<__auto_type%> requires a plain identifier"
2178 " as declarator");
2179 c_parser_skip_to_end_of_block_or_statement (parser);
2180 return;
2181 }
2182 if (c_parser_next_token_is (parser, CPP_EQ)
2183 || c_parser_next_token_is (parser, CPP_COMMA)
2184 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2185 || c_parser_next_token_is_keyword (parser, RID_ASM)
2186 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2187 || c_parser_next_token_is_keyword (parser, RID_IN))
2188 {
2189 tree asm_name = NULL_TREE;
2190 tree postfix_attrs = NULL_TREE;
2191 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2192 {
2193 diagnosed_no_specs = true;
2194 pedwarn (here, 0, "data definition has no type or storage class");
2195 }
2196 /* Having seen a data definition, there cannot now be a
2197 function definition. */
2198 fndef_ok = false;
2199 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2200 asm_name = c_parser_simple_asm_expr (parser);
2201 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2202 {
2203 postfix_attrs = c_parser_gnu_attributes (parser);
2204 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2205 {
2206 /* This means there is an attribute specifier after
2207 the declarator in a function definition. Provide
2208 some more information for the user. */
2209 error_at (here, "attributes should be specified before the "
2210 "declarator in a function definition");
2211 c_parser_skip_to_end_of_block_or_statement (parser);
2212 return;
2213 }
2214 }
2215 if (c_parser_next_token_is (parser, CPP_EQ))
2216 {
2217 tree d;
2218 struct c_expr init;
2219 location_t init_loc;
2220 c_parser_consume_token (parser);
2221 if (auto_type_p)
2222 {
2223 init_loc = c_parser_peek_token (parser)->location;
2224 rich_location richloc (line_table, init_loc);
2225 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2226 /* A parameter is initialized, which is invalid. Don't
2227 attempt to instrument the initializer. */
2228 int flag_sanitize_save = flag_sanitize;
2229 if (nested && !empty_ok)
2230 flag_sanitize = 0;
2231 init = c_parser_expr_no_commas (parser, NULL);
2232 flag_sanitize = flag_sanitize_save;
2233 if (TREE_CODE (init.value) == COMPONENT_REF
2234 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2235 error_at (here,
2236 "%<__auto_type%> used with a bit-field"
2237 " initializer");
2238 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2239 tree init_type = TREE_TYPE (init.value);
2240 bool vm_type = variably_modified_type_p (init_type,
2241 NULL_TREE);
2242 if (vm_type)
2243 init.value = save_expr (init.value);
2244 finish_init ();
2245 specs->typespec_kind = ctsk_typeof;
2246 specs->locations[cdw_typedef] = init_loc;
2247 specs->typedef_p = true;
2248 specs->type = init_type;
2249 if (vm_type)
2250 {
2251 bool maybe_const = true;
2252 tree type_expr = c_fully_fold (init.value, false,
2253 &maybe_const);
2254 specs->expr_const_operands &= maybe_const;
2255 if (specs->expr)
2256 specs->expr = build2 (COMPOUND_EXPR,
2257 TREE_TYPE (type_expr),
2258 specs->expr, type_expr);
2259 else
2260 specs->expr = type_expr;
2261 }
2262 d = start_decl (declarator, specs, true,
2263 chainon (postfix_attrs, all_prefix_attrs));
2264 if (!d)
2265 d = error_mark_node;
2266 if (omp_declare_simd_clauses)
2267 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2268 omp_declare_simd_clauses);
2269 }
2270 else
2271 {
2272 /* The declaration of the variable is in effect while
2273 its initializer is parsed. */
2274 d = start_decl (declarator, specs, true,
2275 chainon (postfix_attrs, all_prefix_attrs));
2276 if (!d)
2277 d = error_mark_node;
2278 if (omp_declare_simd_clauses)
2279 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2280 omp_declare_simd_clauses);
2281 init_loc = c_parser_peek_token (parser)->location;
2282 rich_location richloc (line_table, init_loc);
2283 start_init (d, asm_name, global_bindings_p (), &richloc);
2284 /* A parameter is initialized, which is invalid. Don't
2285 attempt to instrument the initializer. */
2286 int flag_sanitize_save = flag_sanitize;
2287 if (TREE_CODE (d) == PARM_DECL)
2288 flag_sanitize = 0;
2289 init = c_parser_initializer (parser);
2290 flag_sanitize = flag_sanitize_save;
2291 finish_init ();
2292 }
2293 if (oacc_routine_data)
2294 c_finish_oacc_routine (oacc_routine_data, d, false);
2295 if (d != error_mark_node)
2296 {
2297 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2298 finish_decl (d, init_loc, init.value,
2299 init.original_type, asm_name);
2300 }
2301 }
2302 else
2303 {
2304 if (auto_type_p)
2305 {
2306 error_at (here,
2307 "%<__auto_type%> requires an initialized "
2308 "data declaration");
2309 c_parser_skip_to_end_of_block_or_statement (parser);
2310 return;
2311 }
2312
2313 location_t lastloc = UNKNOWN_LOCATION;
2314 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2315 tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2316 if (d && TREE_CODE (d) == FUNCTION_DECL)
2317 {
2318 /* Find the innermost declarator that is neither cdk_id
2319 nor cdk_attrs. */
2320 const struct c_declarator *decl = declarator;
2321 const struct c_declarator *last_non_id_attrs = NULL;
2322
2323 while (decl)
2324 switch (decl->kind)
2325 {
2326 case cdk_array:
2327 case cdk_function:
2328 case cdk_pointer:
2329 last_non_id_attrs = decl;
2330 decl = decl->declarator;
2331 break;
2332
2333 case cdk_attrs:
2334 decl = decl->declarator;
2335 break;
2336
2337 case cdk_id:
2338 decl = 0;
2339 break;
2340
2341 default:
2342 gcc_unreachable ();
2343 }
2344
2345 /* If it exists and is cdk_function declaration whose
2346 arguments have not been set yet, use its arguments. */
2347 if (last_non_id_attrs
2348 && last_non_id_attrs->kind == cdk_function)
2349 {
2350 tree parms = last_non_id_attrs->u.arg_info->parms;
2351 if (DECL_ARGUMENTS (d) == NULL_TREE
2352 && DECL_INITIAL (d) == NULL_TREE)
2353 DECL_ARGUMENTS (d) = parms;
2354
2355 warn_parm_array_mismatch (lastloc, d, parms);
2356 }
2357 }
2358 if (omp_declare_simd_clauses)
2359 {
2360 tree parms = NULL_TREE;
2361 if (d && TREE_CODE (d) == FUNCTION_DECL)
2362 {
2363 struct c_declarator *ce = declarator;
2364 while (ce != NULL)
2365 if (ce->kind == cdk_function)
2366 {
2367 parms = ce->u.arg_info->parms;
2368 break;
2369 }
2370 else
2371 ce = ce->declarator;
2372 }
2373 if (parms)
2374 temp_store_parm_decls (d, parms);
2375 c_finish_omp_declare_simd (parser, d, parms,
2376 omp_declare_simd_clauses);
2377 if (parms)
2378 temp_pop_parm_decls ();
2379 }
2380 if (oacc_routine_data)
2381 c_finish_oacc_routine (oacc_routine_data, d, false);
2382 if (d)
2383 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2384 NULL_TREE, asm_name);
2385
2386 if (c_parser_next_token_is_keyword (parser, RID_IN))
2387 {
2388 if (d)
2389 *objc_foreach_object_declaration = d;
2390 else
2391 *objc_foreach_object_declaration = error_mark_node;
2392 }
2393 }
2394 if (c_parser_next_token_is (parser, CPP_COMMA))
2395 {
2396 if (auto_type_p)
2397 {
2398 error_at (here,
2399 "%<__auto_type%> may only be used with"
2400 " a single declarator");
2401 c_parser_skip_to_end_of_block_or_statement (parser);
2402 return;
2403 }
2404 c_parser_consume_token (parser);
2405 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2406 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2407 prefix_attrs);
2408 else
2409 all_prefix_attrs = prefix_attrs;
2410 continue;
2411 }
2412 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2413 {
2414 c_parser_consume_token (parser);
2415 return;
2416 }
2417 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2418 {
2419 /* This can only happen in Objective-C: we found the
2420 'in' that terminates the declaration inside an
2421 Objective-C foreach statement. Do not consume the
2422 token, so that the caller can use it to determine
2423 that this indeed is a foreach context. */
2424 return;
2425 }
2426 else
2427 {
2428 c_parser_error (parser, "expected %<,%> or %<;%>");
2429 c_parser_skip_to_end_of_block_or_statement (parser);
2430 return;
2431 }
2432 }
2433 else if (auto_type_p)
2434 {
2435 error_at (here,
2436 "%<__auto_type%> requires an initialized data declaration");
2437 c_parser_skip_to_end_of_block_or_statement (parser);
2438 return;
2439 }
2440 else if (!fndef_ok)
2441 {
2442 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2443 "%<asm%> or %<__attribute__%>");
2444 c_parser_skip_to_end_of_block_or_statement (parser);
2445 return;
2446 }
2447 /* Function definition (nested or otherwise). */
2448 if (nested)
2449 {
2450 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2451 c_push_function_context ();
2452 }
2453 if (!start_function (specs, declarator, all_prefix_attrs))
2454 {
2455 /* At this point we've consumed:
2456 declaration-specifiers declarator
2457 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2458 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2459 but the
2460 declaration-specifiers declarator
2461 aren't grokkable as a function definition, so we have
2462 an error. */
2463 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2464 if (c_parser_next_token_starts_declspecs (parser))
2465 {
2466 /* If we have
2467 declaration-specifiers declarator decl-specs
2468 then assume we have a missing semicolon, which would
2469 give us:
2470 declaration-specifiers declarator decl-specs
2471 ^
2472 ;
2473 <~~~~~~~~~ declaration ~~~~~~~~~~>
2474 Use c_parser_require to get an error with a fix-it hint. */
2475 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2476 parser->error = false;
2477 }
2478 else
2479 {
2480 /* This can appear in many cases looking nothing like a
2481 function definition, so we don't give a more specific
2482 error suggesting there was one. */
2483 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2484 "or %<__attribute__%>");
2485 }
2486 if (nested)
2487 c_pop_function_context ();
2488 break;
2489 }
2490
2491 if (DECL_DECLARED_INLINE_P (current_function_decl))
2492 tv = TV_PARSE_INLINE;
2493 else
2494 tv = TV_PARSE_FUNC;
2495 auto_timevar at (g_timer, tv);
2496
2497 /* Parse old-style parameter declarations. ??? Attributes are
2498 not allowed to start declaration specifiers here because of a
2499 syntax conflict between a function declaration with attribute
2500 suffix and a function definition with an attribute prefix on
2501 first old-style parameter declaration. Following the old
2502 parser, they are not accepted on subsequent old-style
2503 parameter declarations either. However, there is no
2504 ambiguity after the first declaration, nor indeed on the
2505 first as long as we don't allow postfix attributes after a
2506 declarator with a nonempty identifier list in a definition;
2507 and postfix attributes have never been accepted here in
2508 function definitions either. */
2509 while (c_parser_next_token_is_not (parser, CPP_EOF)
2510 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2511 c_parser_declaration_or_fndef (parser, false, false, false,
2512 true, false);
2513 store_parm_decls ();
2514 if (omp_declare_simd_clauses)
2515 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2516 omp_declare_simd_clauses);
2517 if (oacc_routine_data)
2518 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2519 location_t startloc = c_parser_peek_token (parser)->location;
2520 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2521 = startloc;
2522 location_t endloc = startloc;
2523
2524 /* If the definition was marked with __RTL, use the RTL parser now,
2525 consuming the function body. */
2526 if (specs->declspec_il == cdil_rtl)
2527 {
2528 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2529
2530 /* Normally, store_parm_decls sets next_is_function_body,
2531 anticipating a function body. We need a push_scope/pop_scope
2532 pair to flush out this state, or subsequent function parsing
2533 will go wrong. */
2534 push_scope ();
2535 pop_scope ();
2536
2537 finish_function (endloc);
2538 return;
2539 }
2540 /* If the definition was marked with __GIMPLE then parse the
2541 function body as GIMPLE. */
2542 else if (specs->declspec_il != cdil_none)
2543 {
2544 bool saved = in_late_binary_op;
2545 in_late_binary_op = true;
2546 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2547 specs->declspec_il,
2548 specs->entry_bb_count);
2549 in_late_binary_op = saved;
2550 }
2551 else
2552 fnbody = c_parser_compound_statement (parser, &endloc);
2553 tree fndecl = current_function_decl;
2554 if (nested)
2555 {
2556 tree decl = current_function_decl;
2557 /* Mark nested functions as needing static-chain initially.
2558 lower_nested_functions will recompute it but the
2559 DECL_STATIC_CHAIN flag is also used before that happens,
2560 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2561 DECL_STATIC_CHAIN (decl) = 1;
2562 add_stmt (fnbody);
2563 finish_function (endloc);
2564 c_pop_function_context ();
2565 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2566 }
2567 else
2568 {
2569 if (fnbody)
2570 add_stmt (fnbody);
2571 finish_function (endloc);
2572 }
2573 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2574 if (specs->declspec_il != cdil_none)
2575 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2576
2577 break;
2578 }
2579 }
2580
2581 /* Parse an asm-definition (asm() outside a function body). This is a
2582 GNU extension.
2583
2584 asm-definition:
2585 simple-asm-expr ;
2586 */
2587
2588 static void
2589 c_parser_asm_definition (c_parser *parser)
2590 {
2591 tree asm_str = c_parser_simple_asm_expr (parser);
2592 if (asm_str)
2593 symtab->finalize_toplevel_asm (asm_str);
2594 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2595 }
2596
2597 /* Parse a static assertion (C11 6.7.10).
2598
2599 static_assert-declaration:
2600 static_assert-declaration-no-semi ;
2601 */
2602
2603 static void
2604 c_parser_static_assert_declaration (c_parser *parser)
2605 {
2606 c_parser_static_assert_declaration_no_semi (parser);
2607 if (parser->error
2608 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2609 c_parser_skip_to_end_of_block_or_statement (parser);
2610 }
2611
2612 /* Parse a static assertion (C11 6.7.10), without the trailing
2613 semicolon.
2614
2615 static_assert-declaration-no-semi:
2616 _Static_assert ( constant-expression , string-literal )
2617
2618 C2X:
2619 static_assert-declaration-no-semi:
2620 _Static_assert ( constant-expression )
2621 */
2622
2623 static void
2624 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2625 {
2626 location_t assert_loc, value_loc;
2627 tree value;
2628 tree string = NULL_TREE;
2629
2630 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2631 assert_loc = c_parser_peek_token (parser)->location;
2632 if (flag_isoc99)
2633 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2634 "ISO C99 does not support %<_Static_assert%>");
2635 else
2636 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2637 "ISO C90 does not support %<_Static_assert%>");
2638 c_parser_consume_token (parser);
2639 matching_parens parens;
2640 if (!parens.require_open (parser))
2641 return;
2642 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2643 value = c_parser_expr_no_commas (parser, NULL).value;
2644 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2645 if (c_parser_next_token_is (parser, CPP_COMMA))
2646 {
2647 c_parser_consume_token (parser);
2648 switch (c_parser_peek_token (parser)->type)
2649 {
2650 case CPP_STRING:
2651 case CPP_STRING16:
2652 case CPP_STRING32:
2653 case CPP_WSTRING:
2654 case CPP_UTF8STRING:
2655 string = c_parser_string_literal (parser, false, true).value;
2656 break;
2657 default:
2658 c_parser_error (parser, "expected string literal");
2659 return;
2660 }
2661 }
2662 else if (flag_isoc11)
2663 /* If pedantic for pre-C11, the use of _Static_assert itself will
2664 have been diagnosed, so do not also diagnose the use of this
2665 new C2X feature of _Static_assert. */
2666 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2667 "ISO C11 does not support omitting the string in "
2668 "%<_Static_assert%>");
2669 parens.require_close (parser);
2670
2671 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2672 {
2673 error_at (value_loc, "expression in static assertion is not an integer");
2674 return;
2675 }
2676 if (TREE_CODE (value) != INTEGER_CST)
2677 {
2678 value = c_fully_fold (value, false, NULL);
2679 /* Strip no-op conversions. */
2680 STRIP_TYPE_NOPS (value);
2681 if (TREE_CODE (value) == INTEGER_CST)
2682 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2683 "is not an integer constant expression");
2684 }
2685 if (TREE_CODE (value) != INTEGER_CST)
2686 {
2687 error_at (value_loc, "expression in static assertion is not constant");
2688 return;
2689 }
2690 constant_expression_warning (value);
2691 if (integer_zerop (value))
2692 {
2693 if (string)
2694 error_at (assert_loc, "static assertion failed: %E", string);
2695 else
2696 error_at (assert_loc, "static assertion failed");
2697 }
2698 }
2699
2700 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2701 6.7, C11 6.7), adding them to SPECS (which may already include some).
2702 Storage class specifiers are accepted iff SCSPEC_OK; type
2703 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2704 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2705 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2706 addition to the syntax shown, standard attributes are accepted at
2707 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2708 unlike gnu-attributes, they are not accepted in the middle of the
2709 list. (This combines various different syntax productions in the C
2710 standard, and in some cases gnu-attributes and standard attributes
2711 at the start may already have been parsed before this function is
2712 called.)
2713
2714 declaration-specifiers:
2715 storage-class-specifier declaration-specifiers[opt]
2716 type-specifier declaration-specifiers[opt]
2717 type-qualifier declaration-specifiers[opt]
2718 function-specifier declaration-specifiers[opt]
2719 alignment-specifier declaration-specifiers[opt]
2720
2721 Function specifiers (inline) are from C99, and are currently
2722 handled as storage class specifiers, as is __thread. Alignment
2723 specifiers are from C11.
2724
2725 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2726 storage-class-specifier:
2727 typedef
2728 extern
2729 static
2730 auto
2731 register
2732 _Thread_local
2733
2734 (_Thread_local is new in C11.)
2735
2736 C99 6.7.4, C11 6.7.4:
2737 function-specifier:
2738 inline
2739 _Noreturn
2740
2741 (_Noreturn is new in C11.)
2742
2743 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2744 type-specifier:
2745 void
2746 char
2747 short
2748 int
2749 long
2750 float
2751 double
2752 signed
2753 unsigned
2754 _Bool
2755 _Complex
2756 [_Imaginary removed in C99 TC2]
2757 struct-or-union-specifier
2758 enum-specifier
2759 typedef-name
2760 atomic-type-specifier
2761
2762 (_Bool and _Complex are new in C99.)
2763 (atomic-type-specifier is new in C11.)
2764
2765 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2766
2767 type-qualifier:
2768 const
2769 restrict
2770 volatile
2771 address-space-qualifier
2772 _Atomic
2773
2774 (restrict is new in C99.)
2775 (_Atomic is new in C11.)
2776
2777 GNU extensions:
2778
2779 declaration-specifiers:
2780 gnu-attributes declaration-specifiers[opt]
2781
2782 type-qualifier:
2783 address-space
2784
2785 address-space:
2786 identifier recognized by the target
2787
2788 storage-class-specifier:
2789 __thread
2790
2791 type-specifier:
2792 typeof-specifier
2793 __auto_type
2794 __intN
2795 _Decimal32
2796 _Decimal64
2797 _Decimal128
2798 _Fract
2799 _Accum
2800 _Sat
2801
2802 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2803 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2804
2805 atomic-type-specifier
2806 _Atomic ( type-name )
2807
2808 Objective-C:
2809
2810 type-specifier:
2811 class-name objc-protocol-refs[opt]
2812 typedef-name objc-protocol-refs
2813 objc-protocol-refs
2814 */
2815
2816 void
2817 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2818 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2819 bool alignspec_ok, bool auto_type_ok,
2820 bool start_std_attr_ok, bool end_std_attr_ok,
2821 enum c_lookahead_kind la)
2822 {
2823 bool attrs_ok = start_attr_ok;
2824 bool seen_type = specs->typespec_kind != ctsk_none;
2825
2826 if (!typespec_ok)
2827 gcc_assert (la == cla_prefer_id);
2828
2829 if (start_std_attr_ok
2830 && c_parser_nth_token_starts_std_attributes (parser, 1))
2831 {
2832 gcc_assert (!specs->non_std_attrs_seen_p);
2833 location_t loc = c_parser_peek_token (parser)->location;
2834 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2835 declspecs_add_attrs (loc, specs, attrs);
2836 specs->non_std_attrs_seen_p = false;
2837 }
2838
2839 while (c_parser_next_token_is (parser, CPP_NAME)
2840 || c_parser_next_token_is (parser, CPP_KEYWORD)
2841 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2842 {
2843 struct c_typespec t;
2844 tree attrs;
2845 tree align;
2846 location_t loc = c_parser_peek_token (parser)->location;
2847
2848 /* If we cannot accept a type, exit if the next token must start
2849 one. Also, if we already have seen a tagged definition,
2850 a typename would be an error anyway and likely the user
2851 has simply forgotten a semicolon, so we exit. */
2852 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2853 && c_parser_next_tokens_start_typename (parser, la)
2854 && !c_parser_next_token_is_qualifier (parser)
2855 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2856 break;
2857
2858 if (c_parser_next_token_is (parser, CPP_NAME))
2859 {
2860 c_token *name_token = c_parser_peek_token (parser);
2861 tree value = name_token->value;
2862 c_id_kind kind = name_token->id_kind;
2863
2864 if (kind == C_ID_ADDRSPACE)
2865 {
2866 addr_space_t as
2867 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2868 declspecs_add_addrspace (name_token->location, specs, as);
2869 c_parser_consume_token (parser);
2870 attrs_ok = true;
2871 continue;
2872 }
2873
2874 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2875
2876 /* If we cannot accept a type, and the next token must start one,
2877 exit. Do the same if we already have seen a tagged definition,
2878 since it would be an error anyway and likely the user has simply
2879 forgotten a semicolon. */
2880 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2881 break;
2882
2883 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2884 a C_ID_CLASSNAME. */
2885 c_parser_consume_token (parser);
2886 seen_type = true;
2887 attrs_ok = true;
2888 if (kind == C_ID_ID)
2889 {
2890 error_at (loc, "unknown type name %qE", value);
2891 t.kind = ctsk_typedef;
2892 t.spec = error_mark_node;
2893 }
2894 else if (kind == C_ID_TYPENAME
2895 && (!c_dialect_objc ()
2896 || c_parser_next_token_is_not (parser, CPP_LESS)))
2897 {
2898 t.kind = ctsk_typedef;
2899 /* For a typedef name, record the meaning, not the name.
2900 In case of 'foo foo, bar;'. */
2901 t.spec = lookup_name (value);
2902 }
2903 else
2904 {
2905 tree proto = NULL_TREE;
2906 gcc_assert (c_dialect_objc ());
2907 t.kind = ctsk_objc;
2908 if (c_parser_next_token_is (parser, CPP_LESS))
2909 proto = c_parser_objc_protocol_refs (parser);
2910 t.spec = objc_get_protocol_qualified_type (value, proto);
2911 }
2912 t.expr = NULL_TREE;
2913 t.expr_const_operands = true;
2914 declspecs_add_type (name_token->location, specs, t);
2915 continue;
2916 }
2917 if (c_parser_next_token_is (parser, CPP_LESS))
2918 {
2919 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2920 nisse@lysator.liu.se. */
2921 tree proto;
2922 gcc_assert (c_dialect_objc ());
2923 if (!typespec_ok || seen_type)
2924 break;
2925 proto = c_parser_objc_protocol_refs (parser);
2926 t.kind = ctsk_objc;
2927 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2928 t.expr = NULL_TREE;
2929 t.expr_const_operands = true;
2930 declspecs_add_type (loc, specs, t);
2931 continue;
2932 }
2933 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2934 switch (c_parser_peek_token (parser)->keyword)
2935 {
2936 case RID_STATIC:
2937 case RID_EXTERN:
2938 case RID_REGISTER:
2939 case RID_TYPEDEF:
2940 case RID_INLINE:
2941 case RID_NORETURN:
2942 case RID_AUTO:
2943 case RID_THREAD:
2944 if (!scspec_ok)
2945 goto out;
2946 attrs_ok = true;
2947 /* TODO: Distinguish between function specifiers (inline, noreturn)
2948 and storage class specifiers, either here or in
2949 declspecs_add_scspec. */
2950 declspecs_add_scspec (loc, specs,
2951 c_parser_peek_token (parser)->value);
2952 c_parser_consume_token (parser);
2953 break;
2954 case RID_AUTO_TYPE:
2955 if (!auto_type_ok)
2956 goto out;
2957 /* Fall through. */
2958 case RID_UNSIGNED:
2959 case RID_LONG:
2960 case RID_SHORT:
2961 case RID_SIGNED:
2962 case RID_COMPLEX:
2963 case RID_INT:
2964 case RID_CHAR:
2965 case RID_FLOAT:
2966 case RID_DOUBLE:
2967 case RID_VOID:
2968 case RID_DFLOAT32:
2969 case RID_DFLOAT64:
2970 case RID_DFLOAT128:
2971 CASE_RID_FLOATN_NX:
2972 case RID_BOOL:
2973 case RID_FRACT:
2974 case RID_ACCUM:
2975 case RID_SAT:
2976 case RID_INT_N_0:
2977 case RID_INT_N_1:
2978 case RID_INT_N_2:
2979 case RID_INT_N_3:
2980 if (!typespec_ok)
2981 goto out;
2982 attrs_ok = true;
2983 seen_type = true;
2984 if (c_dialect_objc ())
2985 parser->objc_need_raw_identifier = true;
2986 t.kind = ctsk_resword;
2987 t.spec = c_parser_peek_token (parser)->value;
2988 t.expr = NULL_TREE;
2989 t.expr_const_operands = true;
2990 declspecs_add_type (loc, specs, t);
2991 c_parser_consume_token (parser);
2992 break;
2993 case RID_ENUM:
2994 if (!typespec_ok)
2995 goto out;
2996 attrs_ok = true;
2997 seen_type = true;
2998 t = c_parser_enum_specifier (parser);
2999 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3000 declspecs_add_type (loc, specs, t);
3001 break;
3002 case RID_STRUCT:
3003 case RID_UNION:
3004 if (!typespec_ok)
3005 goto out;
3006 attrs_ok = true;
3007 seen_type = true;
3008 t = c_parser_struct_or_union_specifier (parser);
3009 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3010 declspecs_add_type (loc, specs, t);
3011 break;
3012 case RID_TYPEOF:
3013 /* ??? The old parser rejected typeof after other type
3014 specifiers, but is a syntax error the best way of
3015 handling this? */
3016 if (!typespec_ok || seen_type)
3017 goto out;
3018 attrs_ok = true;
3019 seen_type = true;
3020 t = c_parser_typeof_specifier (parser);
3021 declspecs_add_type (loc, specs, t);
3022 break;
3023 case RID_ATOMIC:
3024 /* C parser handling of Objective-C constructs needs
3025 checking for correct lvalue-to-rvalue conversions, and
3026 the code in build_modify_expr handling various
3027 Objective-C cases, and that in build_unary_op handling
3028 Objective-C cases for increment / decrement, also needs
3029 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3030 and objc_types_are_equivalent may also need updates. */
3031 if (c_dialect_objc ())
3032 sorry ("%<_Atomic%> in Objective-C");
3033 if (flag_isoc99)
3034 pedwarn_c99 (loc, OPT_Wpedantic,
3035 "ISO C99 does not support the %<_Atomic%> qualifier");
3036 else
3037 pedwarn_c99 (loc, OPT_Wpedantic,
3038 "ISO C90 does not support the %<_Atomic%> qualifier");
3039 attrs_ok = true;
3040 tree value;
3041 value = c_parser_peek_token (parser)->value;
3042 c_parser_consume_token (parser);
3043 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3044 {
3045 /* _Atomic ( type-name ). */
3046 seen_type = true;
3047 c_parser_consume_token (parser);
3048 struct c_type_name *type = c_parser_type_name (parser);
3049 t.kind = ctsk_typeof;
3050 t.spec = error_mark_node;
3051 t.expr = NULL_TREE;
3052 t.expr_const_operands = true;
3053 if (type != NULL)
3054 t.spec = groktypename (type, &t.expr,
3055 &t.expr_const_operands);
3056 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3057 "expected %<)%>");
3058 if (t.spec != error_mark_node)
3059 {
3060 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3061 error_at (loc, "%<_Atomic%>-qualified array type");
3062 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3063 error_at (loc, "%<_Atomic%>-qualified function type");
3064 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3065 error_at (loc, "%<_Atomic%> applied to a qualified type");
3066 else
3067 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3068 }
3069 declspecs_add_type (loc, specs, t);
3070 }
3071 else
3072 declspecs_add_qual (loc, specs, value);
3073 break;
3074 case RID_CONST:
3075 case RID_VOLATILE:
3076 case RID_RESTRICT:
3077 attrs_ok = true;
3078 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3079 c_parser_consume_token (parser);
3080 break;
3081 case RID_ATTRIBUTE:
3082 if (!attrs_ok)
3083 goto out;
3084 attrs = c_parser_gnu_attributes (parser);
3085 declspecs_add_attrs (loc, specs, attrs);
3086 break;
3087 case RID_ALIGNAS:
3088 if (!alignspec_ok)
3089 goto out;
3090 align = c_parser_alignas_specifier (parser);
3091 declspecs_add_alignas (loc, specs, align);
3092 break;
3093 case RID_GIMPLE:
3094 if (! flag_gimple)
3095 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3096 c_parser_consume_token (parser);
3097 specs->declspec_il = cdil_gimple;
3098 specs->locations[cdw_gimple] = loc;
3099 c_parser_gimple_or_rtl_pass_list (parser, specs);
3100 break;
3101 case RID_RTL:
3102 c_parser_consume_token (parser);
3103 specs->declspec_il = cdil_rtl;
3104 specs->locations[cdw_rtl] = loc;
3105 c_parser_gimple_or_rtl_pass_list (parser, specs);
3106 break;
3107 default:
3108 goto out;
3109 }
3110 }
3111 out:
3112 if (end_std_attr_ok
3113 && c_parser_nth_token_starts_std_attributes (parser, 1))
3114 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3115 }
3116
3117 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3118
3119 enum-specifier:
3120 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3121 gnu-attributes[opt]
3122 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3123 gnu-attributes[opt]
3124 enum gnu-attributes[opt] identifier
3125
3126 The form with trailing comma is new in C99. The forms with
3127 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3128 without commas in the syntax (assignment expressions, not just
3129 conditional expressions); assignment expressions will be diagnosed
3130 as non-constant.
3131
3132 enumerator-list:
3133 enumerator
3134 enumerator-list , enumerator
3135
3136 enumerator:
3137 enumeration-constant attribute-specifier-sequence[opt]
3138 enumeration-constant attribute-specifier-sequence[opt]
3139 = constant-expression
3140
3141 GNU Extensions:
3142
3143 enumerator:
3144 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3145 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3146 = constant-expression
3147
3148 */
3149
3150 static struct c_typespec
3151 c_parser_enum_specifier (c_parser *parser)
3152 {
3153 struct c_typespec ret;
3154 bool have_std_attrs;
3155 tree std_attrs = NULL_TREE;
3156 tree attrs;
3157 tree ident = NULL_TREE;
3158 location_t enum_loc;
3159 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3160 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3161 c_parser_consume_token (parser);
3162 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3163 if (have_std_attrs)
3164 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3165 attrs = c_parser_gnu_attributes (parser);
3166 enum_loc = c_parser_peek_token (parser)->location;
3167 /* Set the location in case we create a decl now. */
3168 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3169 if (c_parser_next_token_is (parser, CPP_NAME))
3170 {
3171 ident = c_parser_peek_token (parser)->value;
3172 ident_loc = c_parser_peek_token (parser)->location;
3173 enum_loc = ident_loc;
3174 c_parser_consume_token (parser);
3175 }
3176 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3177 {
3178 /* Parse an enum definition. */
3179 struct c_enum_contents the_enum;
3180 tree type;
3181 tree postfix_attrs;
3182 /* We chain the enumerators in reverse order, then put them in
3183 forward order at the end. */
3184 tree values;
3185 timevar_push (TV_PARSE_ENUM);
3186 type = start_enum (enum_loc, &the_enum, ident);
3187 values = NULL_TREE;
3188 c_parser_consume_token (parser);
3189 while (true)
3190 {
3191 tree enum_id;
3192 tree enum_value;
3193 tree enum_decl;
3194 bool seen_comma;
3195 c_token *token;
3196 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3197 location_t decl_loc, value_loc;
3198 if (c_parser_next_token_is_not (parser, CPP_NAME))
3199 {
3200 /* Give a nicer error for "enum {}". */
3201 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3202 && !parser->error)
3203 {
3204 error_at (c_parser_peek_token (parser)->location,
3205 "empty enum is invalid");
3206 parser->error = true;
3207 }
3208 else
3209 c_parser_error (parser, "expected identifier");
3210 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3211 values = error_mark_node;
3212 break;
3213 }
3214 token = c_parser_peek_token (parser);
3215 enum_id = token->value;
3216 /* Set the location in case we create a decl now. */
3217 c_parser_set_source_position_from_token (token);
3218 decl_loc = value_loc = token->location;
3219 c_parser_consume_token (parser);
3220 /* Parse any specified attributes. */
3221 tree std_attrs = NULL_TREE;
3222 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3223 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3224 tree enum_attrs = chainon (std_attrs,
3225 c_parser_gnu_attributes (parser));
3226 if (c_parser_next_token_is (parser, CPP_EQ))
3227 {
3228 c_parser_consume_token (parser);
3229 value_loc = c_parser_peek_token (parser)->location;
3230 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3231 }
3232 else
3233 enum_value = NULL_TREE;
3234 enum_decl = build_enumerator (decl_loc, value_loc,
3235 &the_enum, enum_id, enum_value);
3236 if (enum_attrs)
3237 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3238 TREE_CHAIN (enum_decl) = values;
3239 values = enum_decl;
3240 seen_comma = false;
3241 if (c_parser_next_token_is (parser, CPP_COMMA))
3242 {
3243 comma_loc = c_parser_peek_token (parser)->location;
3244 seen_comma = true;
3245 c_parser_consume_token (parser);
3246 }
3247 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3248 {
3249 if (seen_comma)
3250 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3251 "comma at end of enumerator list");
3252 c_parser_consume_token (parser);
3253 break;
3254 }
3255 if (!seen_comma)
3256 {
3257 c_parser_error (parser, "expected %<,%> or %<}%>");
3258 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3259 values = error_mark_node;
3260 break;
3261 }
3262 }
3263 postfix_attrs = c_parser_gnu_attributes (parser);
3264 ret.spec = finish_enum (type, nreverse (values),
3265 chainon (std_attrs,
3266 chainon (attrs, postfix_attrs)));
3267 ret.kind = ctsk_tagdef;
3268 ret.expr = NULL_TREE;
3269 ret.expr_const_operands = true;
3270 timevar_pop (TV_PARSE_ENUM);
3271 return ret;
3272 }
3273 else if (!ident)
3274 {
3275 c_parser_error (parser, "expected %<{%>");
3276 ret.spec = error_mark_node;
3277 ret.kind = ctsk_tagref;
3278 ret.expr = NULL_TREE;
3279 ret.expr_const_operands = true;
3280 return ret;
3281 }
3282 /* Attributes may only appear when the members are defined or in
3283 certain forward declarations (treat enum forward declarations in
3284 GNU C analogously to struct and union forward declarations in
3285 standard C). */
3286 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3287 c_parser_error (parser, "expected %<;%>");
3288 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3289 std_attrs);
3290 /* In ISO C, enumerated types can be referred to only if already
3291 defined. */
3292 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3293 {
3294 gcc_assert (ident);
3295 pedwarn (enum_loc, OPT_Wpedantic,
3296 "ISO C forbids forward references to %<enum%> types");
3297 }
3298 return ret;
3299 }
3300
3301 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3302
3303 struct-or-union-specifier:
3304 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3305 identifier[opt] { struct-contents } gnu-attributes[opt]
3306 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3307 identifier
3308
3309 struct-contents:
3310 struct-declaration-list
3311
3312 struct-declaration-list:
3313 struct-declaration ;
3314 struct-declaration-list struct-declaration ;
3315
3316 GNU extensions:
3317
3318 struct-contents:
3319 empty
3320 struct-declaration
3321 struct-declaration-list struct-declaration
3322
3323 struct-declaration-list:
3324 struct-declaration-list ;
3325 ;
3326
3327 (Note that in the syntax here, unlike that in ISO C, the semicolons
3328 are included here rather than in struct-declaration, in order to
3329 describe the syntax with extra semicolons and missing semicolon at
3330 end.)
3331
3332 Objective-C:
3333
3334 struct-declaration-list:
3335 @defs ( class-name )
3336
3337 (Note this does not include a trailing semicolon, but can be
3338 followed by further declarations, and gets a pedwarn-if-pedantic
3339 when followed by a semicolon.) */
3340
3341 static struct c_typespec
3342 c_parser_struct_or_union_specifier (c_parser *parser)
3343 {
3344 struct c_typespec ret;
3345 bool have_std_attrs;
3346 tree std_attrs = NULL_TREE;
3347 tree attrs;
3348 tree ident = NULL_TREE;
3349 location_t struct_loc;
3350 location_t ident_loc = UNKNOWN_LOCATION;
3351 enum tree_code code;
3352 switch (c_parser_peek_token (parser)->keyword)
3353 {
3354 case RID_STRUCT:
3355 code = RECORD_TYPE;
3356 break;
3357 case RID_UNION:
3358 code = UNION_TYPE;
3359 break;
3360 default:
3361 gcc_unreachable ();
3362 }
3363 struct_loc = c_parser_peek_token (parser)->location;
3364 c_parser_consume_token (parser);
3365 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3366 if (have_std_attrs)
3367 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3368 attrs = c_parser_gnu_attributes (parser);
3369
3370 /* Set the location in case we create a decl now. */
3371 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3372
3373 if (c_parser_next_token_is (parser, CPP_NAME))
3374 {
3375 ident = c_parser_peek_token (parser)->value;
3376 ident_loc = c_parser_peek_token (parser)->location;
3377 struct_loc = ident_loc;
3378 c_parser_consume_token (parser);
3379 }
3380 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3381 {
3382 /* Parse a struct or union definition. Start the scope of the
3383 tag before parsing components. */
3384 class c_struct_parse_info *struct_info;
3385 tree type = start_struct (struct_loc, code, ident, &struct_info);
3386 tree postfix_attrs;
3387 /* We chain the components in reverse order, then put them in
3388 forward order at the end. Each struct-declaration may
3389 declare multiple components (comma-separated), so we must use
3390 chainon to join them, although when parsing each
3391 struct-declaration we can use TREE_CHAIN directly.
3392
3393 The theory behind all this is that there will be more
3394 semicolon separated fields than comma separated fields, and
3395 so we'll be minimizing the number of node traversals required
3396 by chainon. */
3397 tree contents;
3398 timevar_push (TV_PARSE_STRUCT);
3399 contents = NULL_TREE;
3400 c_parser_consume_token (parser);
3401 /* Handle the Objective-C @defs construct,
3402 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3403 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3404 {
3405 tree name;
3406 gcc_assert (c_dialect_objc ());
3407 c_parser_consume_token (parser);
3408 matching_parens parens;
3409 if (!parens.require_open (parser))
3410 goto end_at_defs;
3411 if (c_parser_next_token_is (parser, CPP_NAME)
3412 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3413 {
3414 name = c_parser_peek_token (parser)->value;
3415 c_parser_consume_token (parser);
3416 }
3417 else
3418 {
3419 c_parser_error (parser, "expected class name");
3420 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3421 goto end_at_defs;
3422 }
3423 parens.skip_until_found_close (parser);
3424 contents = nreverse (objc_get_class_ivars (name));
3425 }
3426 end_at_defs:
3427 /* Parse the struct-declarations and semicolons. Problems with
3428 semicolons are diagnosed here; empty structures are diagnosed
3429 elsewhere. */
3430 while (true)
3431 {
3432 tree decls;
3433 /* Parse any stray semicolon. */
3434 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3435 {
3436 location_t semicolon_loc
3437 = c_parser_peek_token (parser)->location;
3438 gcc_rich_location richloc (semicolon_loc);
3439 richloc.add_fixit_remove ();
3440 pedwarn (&richloc, OPT_Wpedantic,
3441 "extra semicolon in struct or union specified");
3442 c_parser_consume_token (parser);
3443 continue;
3444 }
3445 /* Stop if at the end of the struct or union contents. */
3446 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3447 {
3448 c_parser_consume_token (parser);
3449 break;
3450 }
3451 /* Accept #pragmas at struct scope. */
3452 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3453 {
3454 c_parser_pragma (parser, pragma_struct, NULL);
3455 continue;
3456 }
3457 /* Parse some comma-separated declarations, but not the
3458 trailing semicolon if any. */
3459 decls = c_parser_struct_declaration (parser);
3460 contents = chainon (decls, contents);
3461 /* If no semicolon follows, either we have a parse error or
3462 are at the end of the struct or union and should
3463 pedwarn. */
3464 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3465 c_parser_consume_token (parser);
3466 else
3467 {
3468 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3469 pedwarn (c_parser_peek_token (parser)->location, 0,
3470 "no semicolon at end of struct or union");
3471 else if (parser->error
3472 || !c_parser_next_token_starts_declspecs (parser))
3473 {
3474 c_parser_error (parser, "expected %<;%>");
3475 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3476 break;
3477 }
3478
3479 /* If we come here, we have already emitted an error
3480 for an expected `;', identifier or `(', and we also
3481 recovered already. Go on with the next field. */
3482 }
3483 }
3484 postfix_attrs = c_parser_gnu_attributes (parser);
3485 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3486 chainon (std_attrs,
3487 chainon (attrs, postfix_attrs)),
3488 struct_info);
3489 ret.kind = ctsk_tagdef;
3490 ret.expr = NULL_TREE;
3491 ret.expr_const_operands = true;
3492 timevar_pop (TV_PARSE_STRUCT);
3493 return ret;
3494 }
3495 else if (!ident)
3496 {
3497 c_parser_error (parser, "expected %<{%>");
3498 ret.spec = error_mark_node;
3499 ret.kind = ctsk_tagref;
3500 ret.expr = NULL_TREE;
3501 ret.expr_const_operands = true;
3502 return ret;
3503 }
3504 /* Attributes may only appear when the members are defined or in
3505 certain forward declarations. */
3506 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3507 c_parser_error (parser, "expected %<;%>");
3508 /* ??? Existing practice is that GNU attributes are ignored after
3509 the struct or union keyword when not defining the members. */
3510 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3511 return ret;
3512 }
3513
3514 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3515 *without* the trailing semicolon.
3516
3517 struct-declaration:
3518 attribute-specifier-sequence[opt] specifier-qualifier-list
3519 attribute-specifier-sequence[opt] struct-declarator-list
3520 static_assert-declaration-no-semi
3521
3522 specifier-qualifier-list:
3523 type-specifier specifier-qualifier-list[opt]
3524 type-qualifier specifier-qualifier-list[opt]
3525 alignment-specifier specifier-qualifier-list[opt]
3526 gnu-attributes specifier-qualifier-list[opt]
3527
3528 struct-declarator-list:
3529 struct-declarator
3530 struct-declarator-list , gnu-attributes[opt] struct-declarator
3531
3532 struct-declarator:
3533 declarator gnu-attributes[opt]
3534 declarator[opt] : constant-expression gnu-attributes[opt]
3535
3536 GNU extensions:
3537
3538 struct-declaration:
3539 __extension__ struct-declaration
3540 specifier-qualifier-list
3541
3542 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3543 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3544 any expression without commas in the syntax (assignment
3545 expressions, not just conditional expressions); assignment
3546 expressions will be diagnosed as non-constant. */
3547
3548 static tree
3549 c_parser_struct_declaration (c_parser *parser)
3550 {
3551 struct c_declspecs *specs;
3552 tree prefix_attrs;
3553 tree all_prefix_attrs;
3554 tree decls;
3555 location_t decl_loc;
3556 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3557 {
3558 int ext;
3559 tree decl;
3560 ext = disable_extension_diagnostics ();
3561 c_parser_consume_token (parser);
3562 decl = c_parser_struct_declaration (parser);
3563 restore_extension_diagnostics (ext);
3564 return decl;
3565 }
3566 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3567 {
3568 c_parser_static_assert_declaration_no_semi (parser);
3569 return NULL_TREE;
3570 }
3571 specs = build_null_declspecs ();
3572 decl_loc = c_parser_peek_token (parser)->location;
3573 /* Strictly by the standard, we shouldn't allow _Alignas here,
3574 but it appears to have been intended to allow it there, so
3575 we're keeping it as it is until WG14 reaches a conclusion
3576 of N1731.
3577 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3578 c_parser_declspecs (parser, specs, false, true, true,
3579 true, false, true, true, cla_nonabstract_decl);
3580 if (parser->error)
3581 return NULL_TREE;
3582 if (!specs->declspecs_seen_p)
3583 {
3584 c_parser_error (parser, "expected specifier-qualifier-list");
3585 return NULL_TREE;
3586 }
3587 finish_declspecs (specs);
3588 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3589 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3590 {
3591 tree ret;
3592 if (specs->typespec_kind == ctsk_none)
3593 {
3594 pedwarn (decl_loc, OPT_Wpedantic,
3595 "ISO C forbids member declarations with no members");
3596 shadow_tag_warned (specs, pedantic);
3597 ret = NULL_TREE;
3598 }
3599 else
3600 {
3601 /* Support for unnamed structs or unions as members of
3602 structs or unions (which is [a] useful and [b] supports
3603 MS P-SDK). */
3604 tree attrs = NULL;
3605
3606 ret = grokfield (c_parser_peek_token (parser)->location,
3607 build_id_declarator (NULL_TREE), specs,
3608 NULL_TREE, &attrs);
3609 if (ret)
3610 decl_attributes (&ret, attrs, 0);
3611 }
3612 return ret;
3613 }
3614
3615 /* Provide better error recovery. Note that a type name here is valid,
3616 and will be treated as a field name. */
3617 if (specs->typespec_kind == ctsk_tagdef
3618 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3619 && c_parser_next_token_starts_declspecs (parser)
3620 && !c_parser_next_token_is (parser, CPP_NAME))
3621 {
3622 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3623 parser->error = false;
3624 return NULL_TREE;
3625 }
3626
3627 pending_xref_error ();
3628 prefix_attrs = specs->attrs;
3629 all_prefix_attrs = prefix_attrs;
3630 specs->attrs = NULL_TREE;
3631 decls = NULL_TREE;
3632 while (true)
3633 {
3634 /* Declaring one or more declarators or un-named bit-fields. */
3635 struct c_declarator *declarator;
3636 bool dummy = false;
3637 if (c_parser_next_token_is (parser, CPP_COLON))
3638 declarator = build_id_declarator (NULL_TREE);
3639 else
3640 declarator = c_parser_declarator (parser,
3641 specs->typespec_kind != ctsk_none,
3642 C_DTR_NORMAL, &dummy);
3643 if (declarator == NULL)
3644 {
3645 c_parser_skip_to_end_of_block_or_statement (parser);
3646 break;
3647 }
3648 if (c_parser_next_token_is (parser, CPP_COLON)
3649 || c_parser_next_token_is (parser, CPP_COMMA)
3650 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3651 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3652 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3653 {
3654 tree postfix_attrs = NULL_TREE;
3655 tree width = NULL_TREE;
3656 tree d;
3657 if (c_parser_next_token_is (parser, CPP_COLON))
3658 {
3659 c_parser_consume_token (parser);
3660 width = c_parser_expr_no_commas (parser, NULL).value;
3661 }
3662 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3663 postfix_attrs = c_parser_gnu_attributes (parser);
3664 d = grokfield (c_parser_peek_token (parser)->location,
3665 declarator, specs, width, &all_prefix_attrs);
3666 decl_attributes (&d, chainon (postfix_attrs,
3667 all_prefix_attrs), 0);
3668 DECL_CHAIN (d) = decls;
3669 decls = d;
3670 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3671 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3672 prefix_attrs);
3673 else
3674 all_prefix_attrs = prefix_attrs;
3675 if (c_parser_next_token_is (parser, CPP_COMMA))
3676 c_parser_consume_token (parser);
3677 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3678 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3679 {
3680 /* Semicolon consumed in caller. */
3681 break;
3682 }
3683 else
3684 {
3685 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3686 break;
3687 }
3688 }
3689 else
3690 {
3691 c_parser_error (parser,
3692 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3693 "%<__attribute__%>");
3694 break;
3695 }
3696 }
3697 return decls;
3698 }
3699
3700 /* Parse a typeof specifier (a GNU extension).
3701
3702 typeof-specifier:
3703 typeof ( expression )
3704 typeof ( type-name )
3705 */
3706
3707 static struct c_typespec
3708 c_parser_typeof_specifier (c_parser *parser)
3709 {
3710 struct c_typespec ret;
3711 ret.kind = ctsk_typeof;
3712 ret.spec = error_mark_node;
3713 ret.expr = NULL_TREE;
3714 ret.expr_const_operands = true;
3715 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3716 c_parser_consume_token (parser);
3717 c_inhibit_evaluation_warnings++;
3718 in_typeof++;
3719 matching_parens parens;
3720 if (!parens.require_open (parser))
3721 {
3722 c_inhibit_evaluation_warnings--;
3723 in_typeof--;
3724 return ret;
3725 }
3726 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3727 {
3728 struct c_type_name *type = c_parser_type_name (parser);
3729 c_inhibit_evaluation_warnings--;
3730 in_typeof--;
3731 if (type != NULL)
3732 {
3733 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3734 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3735 }
3736 }
3737 else
3738 {
3739 bool was_vm;
3740 location_t here = c_parser_peek_token (parser)->location;
3741 struct c_expr expr = c_parser_expression (parser);
3742 c_inhibit_evaluation_warnings--;
3743 in_typeof--;
3744 if (TREE_CODE (expr.value) == COMPONENT_REF
3745 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3746 error_at (here, "%<typeof%> applied to a bit-field");
3747 mark_exp_read (expr.value);
3748 ret.spec = TREE_TYPE (expr.value);
3749 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3750 /* This is returned with the type so that when the type is
3751 evaluated, this can be evaluated. */
3752 if (was_vm)
3753 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3754 pop_maybe_used (was_vm);
3755 }
3756 parens.skip_until_found_close (parser);
3757 return ret;
3758 }
3759
3760 /* Parse an alignment-specifier.
3761
3762 C11 6.7.5:
3763
3764 alignment-specifier:
3765 _Alignas ( type-name )
3766 _Alignas ( constant-expression )
3767 */
3768
3769 static tree
3770 c_parser_alignas_specifier (c_parser * parser)
3771 {
3772 tree ret = error_mark_node;
3773 location_t loc = c_parser_peek_token (parser)->location;
3774 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3775 c_parser_consume_token (parser);
3776 if (flag_isoc99)
3777 pedwarn_c99 (loc, OPT_Wpedantic,
3778 "ISO C99 does not support %<_Alignas%>");
3779 else
3780 pedwarn_c99 (loc, OPT_Wpedantic,
3781 "ISO C90 does not support %<_Alignas%>");
3782 matching_parens parens;
3783 if (!parens.require_open (parser))
3784 return ret;
3785 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3786 {
3787 struct c_type_name *type = c_parser_type_name (parser);
3788 if (type != NULL)
3789 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3790 false, true, 1);
3791 }
3792 else
3793 ret = c_parser_expr_no_commas (parser, NULL).value;
3794 parens.skip_until_found_close (parser);
3795 return ret;
3796 }
3797
3798 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3799 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3800 a typedef name may be redeclared; otherwise it may not. KIND
3801 indicates which kind of declarator is wanted. Returns a valid
3802 declarator except in the case of a syntax error in which case NULL is
3803 returned. *SEEN_ID is set to true if an identifier being declared is
3804 seen; this is used to diagnose bad forms of abstract array declarators
3805 and to determine whether an identifier list is syntactically permitted.
3806
3807 declarator:
3808 pointer[opt] direct-declarator
3809
3810 direct-declarator:
3811 identifier
3812 ( gnu-attributes[opt] declarator )
3813 direct-declarator array-declarator
3814 direct-declarator ( parameter-type-list )
3815 direct-declarator ( identifier-list[opt] )
3816
3817 pointer:
3818 * type-qualifier-list[opt]
3819 * type-qualifier-list[opt] pointer
3820
3821 type-qualifier-list:
3822 type-qualifier
3823 gnu-attributes
3824 type-qualifier-list type-qualifier
3825 type-qualifier-list gnu-attributes
3826
3827 array-declarator:
3828 [ type-qualifier-list[opt] assignment-expression[opt] ]
3829 [ static type-qualifier-list[opt] assignment-expression ]
3830 [ type-qualifier-list static assignment-expression ]
3831 [ type-qualifier-list[opt] * ]
3832
3833 parameter-type-list:
3834 parameter-list
3835 parameter-list , ...
3836
3837 parameter-list:
3838 parameter-declaration
3839 parameter-list , parameter-declaration
3840
3841 parameter-declaration:
3842 declaration-specifiers declarator gnu-attributes[opt]
3843 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3844
3845 identifier-list:
3846 identifier
3847 identifier-list , identifier
3848
3849 abstract-declarator:
3850 pointer
3851 pointer[opt] direct-abstract-declarator
3852
3853 direct-abstract-declarator:
3854 ( gnu-attributes[opt] abstract-declarator )
3855 direct-abstract-declarator[opt] array-declarator
3856 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3857
3858 GNU extensions:
3859
3860 direct-declarator:
3861 direct-declarator ( parameter-forward-declarations
3862 parameter-type-list[opt] )
3863
3864 direct-abstract-declarator:
3865 direct-abstract-declarator[opt] ( parameter-forward-declarations
3866 parameter-type-list[opt] )
3867
3868 parameter-forward-declarations:
3869 parameter-list ;
3870 parameter-forward-declarations parameter-list ;
3871
3872 The uses of gnu-attributes shown above are GNU extensions.
3873
3874 Some forms of array declarator are not included in C99 in the
3875 syntax for abstract declarators; these are disallowed elsewhere.
3876 This may be a defect (DR#289).
3877
3878 This function also accepts an omitted abstract declarator as being
3879 an abstract declarator, although not part of the formal syntax. */
3880
3881 struct c_declarator *
3882 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3883 bool *seen_id)
3884 {
3885 /* Parse any initial pointer part. */
3886 if (c_parser_next_token_is (parser, CPP_MULT))
3887 {
3888 struct c_declspecs *quals_attrs = build_null_declspecs ();
3889 struct c_declarator *inner;
3890 c_parser_consume_token (parser);
3891 c_parser_declspecs (parser, quals_attrs, false, false, true,
3892 false, false, true, false, cla_prefer_id);
3893 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3894 if (inner == NULL)
3895 return NULL;
3896 else
3897 return make_pointer_declarator (quals_attrs, inner);
3898 }
3899 /* Now we have a direct declarator, direct abstract declarator or
3900 nothing (which counts as a direct abstract declarator here). */
3901 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3902 }
3903
3904 /* Parse a direct declarator or direct abstract declarator; arguments
3905 as c_parser_declarator. */
3906
3907 static struct c_declarator *
3908 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3909 bool *seen_id)
3910 {
3911 /* The direct declarator must start with an identifier (possibly
3912 omitted) or a parenthesized declarator (possibly abstract). In
3913 an ordinary declarator, initial parentheses must start a
3914 parenthesized declarator. In an abstract declarator or parameter
3915 declarator, they could start a parenthesized declarator or a
3916 parameter list. To tell which, the open parenthesis and any
3917 following gnu-attributes must be read. If a declaration
3918 specifier or standard attributes follow, then it is a parameter
3919 list; if the specifier is a typedef name, there might be an
3920 ambiguity about redeclaring it, which is resolved in the
3921 direction of treating it as a typedef name. If a close
3922 parenthesis follows, it is also an empty parameter list, as the
3923 syntax does not permit empty abstract declarators. Otherwise, it
3924 is a parenthesized declarator (in which case the analysis may be
3925 repeated inside it, recursively).
3926
3927 ??? There is an ambiguity in a parameter declaration "int
3928 (__attribute__((foo)) x)", where x is not a typedef name: it
3929 could be an abstract declarator for a function, or declare x with
3930 parentheses. The proper resolution of this ambiguity needs
3931 documenting. At present we follow an accident of the old
3932 parser's implementation, whereby the first parameter must have
3933 some declaration specifiers other than just gnu-attributes. Thus as
3934 a parameter declaration it is treated as a parenthesized
3935 parameter named x, and as an abstract declarator it is
3936 rejected.
3937
3938 ??? Also following the old parser, gnu-attributes inside an empty
3939 parameter list are ignored, making it a list not yielding a
3940 prototype, rather than giving an error or making it have one
3941 parameter with implicit type int.
3942
3943 ??? Also following the old parser, typedef names may be
3944 redeclared in declarators, but not Objective-C class names. */
3945
3946 if (kind != C_DTR_ABSTRACT
3947 && c_parser_next_token_is (parser, CPP_NAME)
3948 && ((type_seen_p
3949 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3950 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3951 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3952 {
3953 struct c_declarator *inner
3954 = build_id_declarator (c_parser_peek_token (parser)->value);
3955 *seen_id = true;
3956 inner->id_loc = c_parser_peek_token (parser)->location;
3957 c_parser_consume_token (parser);
3958 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3959 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3960 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3961 }
3962
3963 if (kind != C_DTR_NORMAL
3964 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3965 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3966 {
3967 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3968 inner->id_loc = c_parser_peek_token (parser)->location;
3969 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3970 }
3971
3972 /* Either we are at the end of an abstract declarator, or we have
3973 parentheses. */
3974
3975 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3976 {
3977 tree attrs;
3978 struct c_declarator *inner;
3979 c_parser_consume_token (parser);
3980 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3981 RID_ATTRIBUTE);
3982 attrs = c_parser_gnu_attributes (parser);
3983 if (kind != C_DTR_NORMAL
3984 && (c_parser_next_token_starts_declspecs (parser)
3985 || (!have_gnu_attrs
3986 && c_parser_nth_token_starts_std_attributes (parser, 1))
3987 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3988 {
3989 struct c_arg_info *args
3990 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3991 attrs, have_gnu_attrs);
3992 if (args == NULL)
3993 return NULL;
3994 else
3995 {
3996 inner = build_id_declarator (NULL_TREE);
3997 if (!(args->types
3998 && args->types != error_mark_node
3999 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4000 && c_parser_nth_token_starts_std_attributes (parser, 1))
4001 {
4002 tree std_attrs
4003 = c_parser_std_attribute_specifier_sequence (parser);
4004 if (std_attrs)
4005 inner = build_attrs_declarator (std_attrs, inner);
4006 }
4007 inner = build_function_declarator (args, inner);
4008 return c_parser_direct_declarator_inner (parser, *seen_id,
4009 inner);
4010 }
4011 }
4012 /* A parenthesized declarator. */
4013 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4014 if (inner != NULL && attrs != NULL)
4015 inner = build_attrs_declarator (attrs, inner);
4016 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4017 {
4018 c_parser_consume_token (parser);
4019 if (inner == NULL)
4020 return NULL;
4021 else
4022 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4023 }
4024 else
4025 {
4026 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4027 "expected %<)%>");
4028 return NULL;
4029 }
4030 }
4031 else
4032 {
4033 if (kind == C_DTR_NORMAL)
4034 {
4035 c_parser_error (parser, "expected identifier or %<(%>");
4036 return NULL;
4037 }
4038 else
4039 return build_id_declarator (NULL_TREE);
4040 }
4041 }
4042
4043 /* Parse part of a direct declarator or direct abstract declarator,
4044 given that some (in INNER) has already been parsed; ID_PRESENT is
4045 true if an identifier is present, false for an abstract
4046 declarator. */
4047
4048 static struct c_declarator *
4049 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4050 struct c_declarator *inner)
4051 {
4052 /* Parse a sequence of array declarators and parameter lists. */
4053 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4054 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4055 {
4056 location_t brace_loc = c_parser_peek_token (parser)->location;
4057 struct c_declarator *declarator;
4058 struct c_declspecs *quals_attrs = build_null_declspecs ();
4059 bool static_seen;
4060 bool star_seen;
4061 struct c_expr dimen;
4062 dimen.value = NULL_TREE;
4063 dimen.original_code = ERROR_MARK;
4064 dimen.original_type = NULL_TREE;
4065 c_parser_consume_token (parser);
4066 c_parser_declspecs (parser, quals_attrs, false, false, true,
4067 false, false, false, false, cla_prefer_id);
4068 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4069 if (static_seen)
4070 c_parser_consume_token (parser);
4071 if (static_seen && !quals_attrs->declspecs_seen_p)
4072 c_parser_declspecs (parser, quals_attrs, false, false, true,
4073 false, false, false, false, cla_prefer_id);
4074 if (!quals_attrs->declspecs_seen_p)
4075 quals_attrs = NULL;
4076 /* If "static" is present, there must be an array dimension.
4077 Otherwise, there may be a dimension, "*", or no
4078 dimension. */
4079 if (static_seen)
4080 {
4081 star_seen = false;
4082 dimen = c_parser_expr_no_commas (parser, NULL);
4083 }
4084 else
4085 {
4086 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4087 {
4088 dimen.value = NULL_TREE;
4089 star_seen = false;
4090 }
4091 else if (c_parser_next_token_is (parser, CPP_MULT))
4092 {
4093 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4094 {
4095 dimen.value = NULL_TREE;
4096 star_seen = true;
4097 c_parser_consume_token (parser);
4098 }
4099 else
4100 {
4101 star_seen = false;
4102 dimen = c_parser_expr_no_commas (parser, NULL);
4103 }
4104 }
4105 else
4106 {
4107 star_seen = false;
4108 dimen = c_parser_expr_no_commas (parser, NULL);
4109 }
4110 }
4111 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4112 c_parser_consume_token (parser);
4113 else
4114 {
4115 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4116 "expected %<]%>");
4117 return NULL;
4118 }
4119 if (dimen.value)
4120 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4121 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4122 static_seen, star_seen);
4123 if (declarator == NULL)
4124 return NULL;
4125 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4126 {
4127 tree std_attrs
4128 = c_parser_std_attribute_specifier_sequence (parser);
4129 if (std_attrs)
4130 inner = build_attrs_declarator (std_attrs, inner);
4131 }
4132 inner = set_array_declarator_inner (declarator, inner);
4133 return c_parser_direct_declarator_inner (parser, id_present, inner);
4134 }
4135 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4136 {
4137 tree attrs;
4138 struct c_arg_info *args;
4139 c_parser_consume_token (parser);
4140 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4141 RID_ATTRIBUTE);
4142 attrs = c_parser_gnu_attributes (parser);
4143 args = c_parser_parms_declarator (parser, id_present, attrs,
4144 have_gnu_attrs);
4145 if (args == NULL)
4146 return NULL;
4147 else
4148 {
4149 if (!(args->types
4150 && args->types != error_mark_node
4151 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4152 && c_parser_nth_token_starts_std_attributes (parser, 1))
4153 {
4154 tree std_attrs
4155 = c_parser_std_attribute_specifier_sequence (parser);
4156 if (std_attrs)
4157 inner = build_attrs_declarator (std_attrs, inner);
4158 }
4159 inner = build_function_declarator (args, inner);
4160 return c_parser_direct_declarator_inner (parser, id_present, inner);
4161 }
4162 }
4163 return inner;
4164 }
4165
4166 /* Parse a parameter list or identifier list, including the closing
4167 parenthesis but not the opening one. ATTRS are the gnu-attributes
4168 at the start of the list. ID_LIST_OK is true if an identifier list
4169 is acceptable; such a list must not have attributes at the start.
4170 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4171 attributes) were present (in which case standard attributes cannot
4172 occur). */
4173
4174 static struct c_arg_info *
4175 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4176 bool have_gnu_attrs)
4177 {
4178 push_scope ();
4179 declare_parm_level ();
4180 /* If the list starts with an identifier, it is an identifier list.
4181 Otherwise, it is either a prototype list or an empty list. */
4182 if (id_list_ok
4183 && !attrs
4184 && c_parser_next_token_is (parser, CPP_NAME)
4185 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4186
4187 /* Look ahead to detect typos in type names. */
4188 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4189 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4190 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4191 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4192 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4193 {
4194 tree list = NULL_TREE, *nextp = &list;
4195 while (c_parser_next_token_is (parser, CPP_NAME)
4196 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4197 {
4198 *nextp = build_tree_list (NULL_TREE,
4199 c_parser_peek_token (parser)->value);
4200 nextp = & TREE_CHAIN (*nextp);
4201 c_parser_consume_token (parser);
4202 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4203 break;
4204 c_parser_consume_token (parser);
4205 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4206 {
4207 c_parser_error (parser, "expected identifier");
4208 break;
4209 }
4210 }
4211 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4212 {
4213 struct c_arg_info *ret = build_arg_info ();
4214 ret->types = list;
4215 c_parser_consume_token (parser);
4216 pop_scope ();
4217 return ret;
4218 }
4219 else
4220 {
4221 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4222 "expected %<)%>");
4223 pop_scope ();
4224 return NULL;
4225 }
4226 }
4227 else
4228 {
4229 struct c_arg_info *ret
4230 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4231 pop_scope ();
4232 return ret;
4233 }
4234 }
4235
4236 /* Parse a parameter list (possibly empty), including the closing
4237 parenthesis but not the opening one. ATTRS are the gnu-attributes
4238 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4239 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4240 which means standard attributes cannot start the list. EXPR is
4241 NULL or an expression that needs to be evaluated for the side
4242 effects of array size expressions in the parameters. */
4243
4244 static struct c_arg_info *
4245 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4246 bool have_gnu_attrs)
4247 {
4248 bool bad_parm = false;
4249
4250 /* ??? Following the old parser, forward parameter declarations may
4251 use abstract declarators, and if no real parameter declarations
4252 follow the forward declarations then this is not diagnosed. Also
4253 note as above that gnu-attributes are ignored as the only contents of
4254 the parentheses, or as the only contents after forward
4255 declarations. */
4256 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4257 {
4258 struct c_arg_info *ret = build_arg_info ();
4259 c_parser_consume_token (parser);
4260 return ret;
4261 }
4262 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4263 {
4264 struct c_arg_info *ret = build_arg_info ();
4265
4266 if (flag_allow_parameterless_variadic_functions)
4267 {
4268 /* F (...) is allowed. */
4269 ret->types = NULL_TREE;
4270 }
4271 else
4272 {
4273 /* Suppress -Wold-style-definition for this case. */
4274 ret->types = error_mark_node;
4275 error_at (c_parser_peek_token (parser)->location,
4276 "ISO C requires a named argument before %<...%>");
4277 }
4278 c_parser_consume_token (parser);
4279 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4280 {
4281 c_parser_consume_token (parser);
4282 return ret;
4283 }
4284 else
4285 {
4286 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4287 "expected %<)%>");
4288 return NULL;
4289 }
4290 }
4291 /* Nonempty list of parameters, either terminated with semicolon
4292 (forward declarations; recurse) or with close parenthesis (normal
4293 function) or with ", ... )" (variadic function). */
4294 while (true)
4295 {
4296 /* Parse a parameter. */
4297 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4298 have_gnu_attrs);
4299 attrs = NULL_TREE;
4300 have_gnu_attrs = false;
4301 if (parm == NULL)
4302 bad_parm = true;
4303 else
4304 push_parm_decl (parm, &expr);
4305 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4306 {
4307 tree new_attrs;
4308 c_parser_consume_token (parser);
4309 mark_forward_parm_decls ();
4310 bool new_have_gnu_attrs
4311 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4312 new_attrs = c_parser_gnu_attributes (parser);
4313 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4314 new_have_gnu_attrs);
4315 }
4316 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4317 {
4318 c_parser_consume_token (parser);
4319 if (bad_parm)
4320 return NULL;
4321 else
4322 return get_parm_info (false, expr);
4323 }
4324 if (!c_parser_require (parser, CPP_COMMA,
4325 "expected %<;%>, %<,%> or %<)%>",
4326 UNKNOWN_LOCATION, false))
4327 {
4328 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4329 return NULL;
4330 }
4331 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4332 {
4333 c_parser_consume_token (parser);
4334 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4335 {
4336 c_parser_consume_token (parser);
4337 if (bad_parm)
4338 return NULL;
4339 else
4340 return get_parm_info (true, expr);
4341 }
4342 else
4343 {
4344 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4345 "expected %<)%>");
4346 return NULL;
4347 }
4348 }
4349 }
4350 }
4351
4352 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4353 start of the declaration if it is the first parameter;
4354 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4355 empty) there. */
4356
4357 static struct c_parm *
4358 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4359 bool have_gnu_attrs)
4360 {
4361 struct c_declspecs *specs;
4362 struct c_declarator *declarator;
4363 tree prefix_attrs;
4364 tree postfix_attrs = NULL_TREE;
4365 bool dummy = false;
4366
4367 /* Accept #pragmas between parameter declarations. */
4368 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4369 c_parser_pragma (parser, pragma_param, NULL);
4370
4371 if (!c_parser_next_token_starts_declspecs (parser)
4372 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4373 {
4374 c_token *token = c_parser_peek_token (parser);
4375 if (parser->error)
4376 return NULL;
4377 c_parser_set_source_position_from_token (token);
4378 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4379 {
4380 auto_diagnostic_group d;
4381 name_hint hint = lookup_name_fuzzy (token->value,
4382 FUZZY_LOOKUP_TYPENAME,
4383 token->location);
4384 if (const char *suggestion = hint.suggestion ())
4385 {
4386 gcc_rich_location richloc (token->location);
4387 richloc.add_fixit_replace (suggestion);
4388 error_at (&richloc,
4389 "unknown type name %qE; did you mean %qs?",
4390 token->value, suggestion);
4391 }
4392 else
4393 error_at (token->location, "unknown type name %qE", token->value);
4394 parser->error = true;
4395 }
4396 /* ??? In some Objective-C cases '...' isn't applicable so there
4397 should be a different message. */
4398 else
4399 c_parser_error (parser,
4400 "expected declaration specifiers or %<...%>");
4401 c_parser_skip_to_end_of_parameter (parser);
4402 return NULL;
4403 }
4404
4405 location_t start_loc = c_parser_peek_token (parser)->location;
4406
4407 specs = build_null_declspecs ();
4408 if (attrs)
4409 {
4410 declspecs_add_attrs (input_location, specs, attrs);
4411 attrs = NULL_TREE;
4412 }
4413 c_parser_declspecs (parser, specs, true, true, true, true, false,
4414 !have_gnu_attrs, true, cla_nonabstract_decl);
4415 finish_declspecs (specs);
4416 pending_xref_error ();
4417 prefix_attrs = specs->attrs;
4418 specs->attrs = NULL_TREE;
4419 declarator = c_parser_declarator (parser,
4420 specs->typespec_kind != ctsk_none,
4421 C_DTR_PARM, &dummy);
4422 if (declarator == NULL)
4423 {
4424 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4425 return NULL;
4426 }
4427 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4428 postfix_attrs = c_parser_gnu_attributes (parser);
4429
4430 /* Generate a location for the parameter, ranging from the start of the
4431 initial token to the end of the final token.
4432
4433 If we have a identifier, then use it for the caret location, e.g.
4434
4435 extern int callee (int one, int (*two)(int, int), float three);
4436 ~~~~~~^~~~~~~~~~~~~~
4437
4438 otherwise, reuse the start location for the caret location e.g.:
4439
4440 extern int callee (int one, int (*)(int, int), float three);
4441 ^~~~~~~~~~~~~~~~~
4442 */
4443 location_t end_loc = parser->last_token_location;
4444
4445 /* Find any cdk_id declarator; determine if we have an identifier. */
4446 c_declarator *id_declarator = declarator;
4447 while (id_declarator && id_declarator->kind != cdk_id)
4448 id_declarator = id_declarator->declarator;
4449 location_t caret_loc = (id_declarator->u.id.id
4450 ? id_declarator->id_loc
4451 : start_loc);
4452 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4453
4454 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4455 declarator, param_loc);
4456 }
4457
4458 /* Parse a string literal in an asm expression. It should not be
4459 translated, and wide string literals are an error although
4460 permitted by the syntax. This is a GNU extension.
4461
4462 asm-string-literal:
4463 string-literal
4464 */
4465
4466 static tree
4467 c_parser_asm_string_literal (c_parser *parser)
4468 {
4469 tree str;
4470 int save_flag = warn_overlength_strings;
4471 warn_overlength_strings = 0;
4472 str = c_parser_string_literal (parser, false, false).value;
4473 warn_overlength_strings = save_flag;
4474 return str;
4475 }
4476
4477 /* Parse a simple asm expression. This is used in restricted
4478 contexts, where a full expression with inputs and outputs does not
4479 make sense. This is a GNU extension.
4480
4481 simple-asm-expr:
4482 asm ( asm-string-literal )
4483 */
4484
4485 static tree
4486 c_parser_simple_asm_expr (c_parser *parser)
4487 {
4488 tree str;
4489 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4490 c_parser_consume_token (parser);
4491 matching_parens parens;
4492 if (!parens.require_open (parser))
4493 return NULL_TREE;
4494 str = c_parser_asm_string_literal (parser);
4495 if (!parens.require_close (parser))
4496 {
4497 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4498 return NULL_TREE;
4499 }
4500 return str;
4501 }
4502
4503 static tree
4504 c_parser_gnu_attribute_any_word (c_parser *parser)
4505 {
4506 tree attr_name = NULL_TREE;
4507
4508 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4509 {
4510 /* ??? See comment above about what keywords are accepted here. */
4511 bool ok;
4512 switch (c_parser_peek_token (parser)->keyword)
4513 {
4514 case RID_STATIC:
4515 case RID_UNSIGNED:
4516 case RID_LONG:
4517 case RID_CONST:
4518 case RID_EXTERN:
4519 case RID_REGISTER:
4520 case RID_TYPEDEF:
4521 case RID_SHORT:
4522 case RID_INLINE:
4523 case RID_NORETURN:
4524 case RID_VOLATILE:
4525 case RID_SIGNED:
4526 case RID_AUTO:
4527 case RID_RESTRICT:
4528 case RID_COMPLEX:
4529 case RID_THREAD:
4530 case RID_INT:
4531 case RID_CHAR:
4532 case RID_FLOAT:
4533 case RID_DOUBLE:
4534 case RID_VOID:
4535 case RID_DFLOAT32:
4536 case RID_DFLOAT64:
4537 case RID_DFLOAT128:
4538 CASE_RID_FLOATN_NX:
4539 case RID_BOOL:
4540 case RID_FRACT:
4541 case RID_ACCUM:
4542 case RID_SAT:
4543 case RID_TRANSACTION_ATOMIC:
4544 case RID_TRANSACTION_CANCEL:
4545 case RID_ATOMIC:
4546 case RID_AUTO_TYPE:
4547 case RID_INT_N_0:
4548 case RID_INT_N_1:
4549 case RID_INT_N_2:
4550 case RID_INT_N_3:
4551 ok = true;
4552 break;
4553 default:
4554 ok = false;
4555 break;
4556 }
4557 if (!ok)
4558 return NULL_TREE;
4559
4560 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4561 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4562 }
4563 else if (c_parser_next_token_is (parser, CPP_NAME))
4564 attr_name = c_parser_peek_token (parser)->value;
4565
4566 return attr_name;
4567 }
4568
4569 /* Parse attribute arguments. This is a common form of syntax
4570 covering all currently valid GNU and standard attributes.
4571
4572 gnu-attribute-arguments:
4573 identifier
4574 identifier , nonempty-expr-list
4575 expr-list
4576
4577 where the "identifier" must not be declared as a type. ??? Why not
4578 allow identifiers declared as types to start the arguments? */
4579
4580 static tree
4581 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4582 bool require_string, bool allow_empty_args)
4583 {
4584 vec<tree, va_gc> *expr_list;
4585 tree attr_args;
4586 /* Parse the attribute contents. If they start with an
4587 identifier which is followed by a comma or close
4588 parenthesis, then the arguments start with that
4589 identifier; otherwise they are an expression list.
4590 In objective-c the identifier may be a classname. */
4591 if (c_parser_next_token_is (parser, CPP_NAME)
4592 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4593 || (c_dialect_objc ()
4594 && c_parser_peek_token (parser)->id_kind
4595 == C_ID_CLASSNAME))
4596 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4597 || (c_parser_peek_2nd_token (parser)->type
4598 == CPP_CLOSE_PAREN))
4599 && (takes_identifier
4600 || (c_dialect_objc ()
4601 && c_parser_peek_token (parser)->id_kind
4602 == C_ID_CLASSNAME)))
4603 {
4604 tree arg1 = c_parser_peek_token (parser)->value;
4605 c_parser_consume_token (parser);
4606 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4607 attr_args = build_tree_list (NULL_TREE, arg1);
4608 else
4609 {
4610 tree tree_list;
4611 c_parser_consume_token (parser);
4612 expr_list = c_parser_expr_list (parser, false, true,
4613 NULL, NULL, NULL, NULL);
4614 tree_list = build_tree_list_vec (expr_list);
4615 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4616 release_tree_vector (expr_list);
4617 }
4618 }
4619 else
4620 {
4621 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4622 {
4623 if (!allow_empty_args)
4624 error_at (c_parser_peek_token (parser)->location,
4625 "parentheses must be omitted if "
4626 "attribute argument list is empty");
4627 attr_args = NULL_TREE;
4628 }
4629 else if (require_string)
4630 {
4631 /* The only valid argument for this attribute is a string
4632 literal. Handle this specially here to avoid accepting
4633 string literals with excess parentheses. */
4634 tree string = c_parser_string_literal (parser, false, true).value;
4635 attr_args = build_tree_list (NULL_TREE, string);
4636 }
4637 else
4638 {
4639 expr_list = c_parser_expr_list (parser, false, true,
4640 NULL, NULL, NULL, NULL);
4641 attr_args = build_tree_list_vec (expr_list);
4642 release_tree_vector (expr_list);
4643 }
4644 }
4645 return attr_args;
4646 }
4647
4648 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4649
4650 gnu-attributes:
4651 empty
4652 gnu-attributes gnu-attribute
4653
4654 gnu-attribute:
4655 __attribute__ ( ( gnu-attribute-list ) )
4656
4657 gnu-attribute-list:
4658 gnu-attrib
4659 gnu-attribute_list , gnu-attrib
4660
4661 gnu-attrib:
4662 empty
4663 any-word
4664 any-word ( gnu-attribute-arguments )
4665
4666 where "any-word" may be any identifier (including one declared as a
4667 type), a reserved word storage class specifier, type specifier or
4668 type qualifier. ??? This still leaves out most reserved keywords
4669 (following the old parser), shouldn't we include them?
4670 When EXPECT_COMMA is true, expect the attribute to be preceded
4671 by a comma and fail if it isn't.
4672 When EMPTY_OK is true, allow and consume any number of consecutive
4673 commas with no attributes in between. */
4674
4675 static tree
4676 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4677 bool expect_comma = false, bool empty_ok = true)
4678 {
4679 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4680 if (!comma_first
4681 && !c_parser_next_token_is (parser, CPP_NAME)
4682 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4683 return NULL_TREE;
4684
4685 while (c_parser_next_token_is (parser, CPP_COMMA))
4686 {
4687 c_parser_consume_token (parser);
4688 if (!empty_ok)
4689 return attrs;
4690 }
4691
4692 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4693 if (attr_name == NULL_TREE)
4694 return NULL_TREE;
4695
4696 attr_name = canonicalize_attr_name (attr_name);
4697 c_parser_consume_token (parser);
4698
4699 tree attr;
4700 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4701 {
4702 if (expect_comma && !comma_first)
4703 {
4704 /* A comma is missing between the last attribute on the chain
4705 and this one. */
4706 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4707 "expected %<)%>");
4708 return error_mark_node;
4709 }
4710 attr = build_tree_list (attr_name, NULL_TREE);
4711 /* Add this attribute to the list. */
4712 attrs = chainon (attrs, attr);
4713 return attrs;
4714 }
4715 c_parser_consume_token (parser);
4716
4717 tree attr_args
4718 = c_parser_attribute_arguments (parser,
4719 attribute_takes_identifier_p (attr_name),
4720 false, true);
4721
4722 attr = build_tree_list (attr_name, attr_args);
4723 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4724 c_parser_consume_token (parser);
4725 else
4726 {
4727 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4728 "expected %<)%>");
4729 return error_mark_node;
4730 }
4731
4732 if (expect_comma && !comma_first)
4733 {
4734 /* A comma is missing between the last attribute on the chain
4735 and this one. */
4736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4737 "expected %<)%>");
4738 return error_mark_node;
4739 }
4740
4741 /* Add this attribute to the list. */
4742 attrs = chainon (attrs, attr);
4743 return attrs;
4744 }
4745
4746 static tree
4747 c_parser_gnu_attributes (c_parser *parser)
4748 {
4749 tree attrs = NULL_TREE;
4750 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4751 {
4752 bool save_translate_strings_p = parser->translate_strings_p;
4753 parser->translate_strings_p = false;
4754 /* Consume the `__attribute__' keyword. */
4755 c_parser_consume_token (parser);
4756 /* Look for the two `(' tokens. */
4757 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4758 {
4759 parser->translate_strings_p = save_translate_strings_p;
4760 return attrs;
4761 }
4762 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4763 {
4764 parser->translate_strings_p = save_translate_strings_p;
4765 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4766 return attrs;
4767 }
4768 /* Parse the attribute list. Require a comma between successive
4769 (possibly empty) attributes. */
4770 for (bool expect_comma = false; ; expect_comma = true)
4771 {
4772 /* Parse a single attribute. */
4773 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4774 if (attr == error_mark_node)
4775 return attrs;
4776 if (!attr)
4777 break;
4778 attrs = attr;
4779 }
4780
4781 /* Look for the two `)' tokens. */
4782 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4783 c_parser_consume_token (parser);
4784 else
4785 {
4786 parser->translate_strings_p = save_translate_strings_p;
4787 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4788 "expected %<)%>");
4789 return attrs;
4790 }
4791 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4792 c_parser_consume_token (parser);
4793 else
4794 {
4795 parser->translate_strings_p = save_translate_strings_p;
4796 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4797 "expected %<)%>");
4798 return attrs;
4799 }
4800 parser->translate_strings_p = save_translate_strings_p;
4801 }
4802
4803 return attrs;
4804 }
4805
4806 /* Parse an optional balanced token sequence.
4807
4808 balanced-token-sequence:
4809 balanced-token
4810 balanced-token-sequence balanced-token
4811
4812 balanced-token:
4813 ( balanced-token-sequence[opt] )
4814 [ balanced-token-sequence[opt] ]
4815 { balanced-token-sequence[opt] }
4816 any token other than ()[]{}
4817 */
4818
4819 static void
4820 c_parser_balanced_token_sequence (c_parser *parser)
4821 {
4822 while (true)
4823 {
4824 c_token *token = c_parser_peek_token (parser);
4825 switch (token->type)
4826 {
4827 case CPP_OPEN_BRACE:
4828 {
4829 matching_braces braces;
4830 braces.consume_open (parser);
4831 c_parser_balanced_token_sequence (parser);
4832 braces.require_close (parser);
4833 break;
4834 }
4835
4836 case CPP_OPEN_PAREN:
4837 {
4838 matching_parens parens;
4839 parens.consume_open (parser);
4840 c_parser_balanced_token_sequence (parser);
4841 parens.require_close (parser);
4842 break;
4843 }
4844
4845 case CPP_OPEN_SQUARE:
4846 c_parser_consume_token (parser);
4847 c_parser_balanced_token_sequence (parser);
4848 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4849 break;
4850
4851 case CPP_CLOSE_BRACE:
4852 case CPP_CLOSE_PAREN:
4853 case CPP_CLOSE_SQUARE:
4854 case CPP_EOF:
4855 return;
4856
4857 case CPP_PRAGMA:
4858 c_parser_consume_pragma (parser);
4859 c_parser_skip_to_pragma_eol (parser, false);
4860 break;
4861
4862 default:
4863 c_parser_consume_token (parser);
4864 break;
4865 }
4866 }
4867 }
4868
4869 /* Parse standard (C2X) attributes (including GNU attributes in the
4870 gnu:: namespace).
4871
4872 attribute-specifier-sequence:
4873 attribute-specifier-sequence[opt] attribute-specifier
4874
4875 attribute-specifier:
4876 [ [ attribute-list ] ]
4877
4878 attribute-list:
4879 attribute[opt]
4880 attribute-list, attribute[opt]
4881
4882 attribute:
4883 attribute-token attribute-argument-clause[opt]
4884
4885 attribute-token:
4886 standard-attribute
4887 attribute-prefixed-token
4888
4889 standard-attribute:
4890 identifier
4891
4892 attribute-prefixed-token:
4893 attribute-prefix :: identifier
4894
4895 attribute-prefix:
4896 identifier
4897
4898 attribute-argument-clause:
4899 ( balanced-token-sequence[opt] )
4900
4901 Keywords are accepted as identifiers for this purpose.
4902 */
4903
4904 static tree
4905 c_parser_std_attribute (c_parser *parser, bool for_tm)
4906 {
4907 c_token *token = c_parser_peek_token (parser);
4908 tree ns, name, attribute;
4909
4910 /* Parse the attribute-token. */
4911 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4912 {
4913 c_parser_error (parser, "expected identifier");
4914 return error_mark_node;
4915 }
4916 name = canonicalize_attr_name (token->value);
4917 c_parser_consume_token (parser);
4918 if (c_parser_next_token_is (parser, CPP_SCOPE))
4919 {
4920 ns = name;
4921 c_parser_consume_token (parser);
4922 token = c_parser_peek_token (parser);
4923 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4924 {
4925 c_parser_error (parser, "expected identifier");
4926 return error_mark_node;
4927 }
4928 name = canonicalize_attr_name (token->value);
4929 c_parser_consume_token (parser);
4930 }
4931 else
4932 ns = NULL_TREE;
4933 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4934
4935 /* Parse the arguments, if any. */
4936 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4937 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4938 goto out;
4939 {
4940 location_t open_loc = c_parser_peek_token (parser)->location;
4941 matching_parens parens;
4942 parens.consume_open (parser);
4943 if ((as && as->max_length == 0)
4944 /* Special-case the transactional-memory attribute "outer",
4945 which is specially handled but not registered as an
4946 attribute, to avoid allowing arbitrary balanced token
4947 sequences as arguments. */
4948 || is_attribute_p ("outer", name))
4949 {
4950 error_at (open_loc, "%qE attribute does not take any arguments", name);
4951 parens.skip_until_found_close (parser);
4952 return error_mark_node;
4953 }
4954 /* If this is a fake attribute created to handle -Wno-attributes,
4955 we must skip parsing the arguments. */
4956 if (as && !attribute_ignored_p (as))
4957 {
4958 bool takes_identifier
4959 = (ns != NULL_TREE
4960 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4961 && attribute_takes_identifier_p (name));
4962 bool require_string
4963 = (ns == NULL_TREE
4964 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4965 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4966 TREE_VALUE (attribute)
4967 = c_parser_attribute_arguments (parser, takes_identifier,
4968 require_string, false);
4969 }
4970 else
4971 c_parser_balanced_token_sequence (parser);
4972 parens.require_close (parser);
4973 }
4974 out:
4975 if (ns == NULL_TREE && !for_tm && !as)
4976 {
4977 /* An attribute with standard syntax and no namespace specified
4978 is a constraint violation if it is not one of the known
4979 standard attributes. Diagnose it here with a pedwarn and
4980 then discard it to prevent a duplicate warning later. */
4981 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4982 name);
4983 return error_mark_node;
4984 }
4985 return attribute;
4986 }
4987
4988 static tree
4989 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4990 {
4991 location_t loc = c_parser_peek_token (parser)->location;
4992 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4993 return NULL_TREE;
4994 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4995 {
4996 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4997 return NULL_TREE;
4998 }
4999 if (!for_tm)
5000 pedwarn_c11 (loc, OPT_Wpedantic,
5001 "ISO C does not support %<[[]]%> attributes before C2X");
5002 tree attributes = NULL_TREE;
5003 while (true)
5004 {
5005 c_token *token = c_parser_peek_token (parser);
5006 if (token->type == CPP_CLOSE_SQUARE)
5007 break;
5008 if (token->type == CPP_COMMA)
5009 {
5010 c_parser_consume_token (parser);
5011 continue;
5012 }
5013 tree attribute = c_parser_std_attribute (parser, for_tm);
5014 if (attribute != error_mark_node)
5015 {
5016 TREE_CHAIN (attribute) = attributes;
5017 attributes = attribute;
5018 }
5019 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5020 break;
5021 }
5022 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5023 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5024 return nreverse (attributes);
5025 }
5026
5027 /* Look past an optional balanced token sequence of raw look-ahead
5028 tokens starting with the *Nth token. *N is updated to point to the
5029 following token. Return true if such a sequence was found, false
5030 if the tokens parsed were not balanced. */
5031
5032 static bool
5033 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5034 {
5035 while (true)
5036 {
5037 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5038 switch (token->type)
5039 {
5040 case CPP_OPEN_BRACE:
5041 {
5042 ++*n;
5043 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5044 {
5045 token = c_parser_peek_nth_token_raw (parser, *n);
5046 if (token->type == CPP_CLOSE_BRACE)
5047 ++*n;
5048 else
5049 return false;
5050 }
5051 else
5052 return false;
5053 break;
5054 }
5055
5056 case CPP_OPEN_PAREN:
5057 {
5058 ++*n;
5059 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5060 {
5061 token = c_parser_peek_nth_token_raw (parser, *n);
5062 if (token->type == CPP_CLOSE_PAREN)
5063 ++*n;
5064 else
5065 return false;
5066 }
5067 else
5068 return false;
5069 break;
5070 }
5071
5072 case CPP_OPEN_SQUARE:
5073 {
5074 ++*n;
5075 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5076 {
5077 token = c_parser_peek_nth_token_raw (parser, *n);
5078 if (token->type == CPP_CLOSE_SQUARE)
5079 ++*n;
5080 else
5081 return false;
5082 }
5083 else
5084 return false;
5085 break;
5086 }
5087
5088 case CPP_CLOSE_BRACE:
5089 case CPP_CLOSE_PAREN:
5090 case CPP_CLOSE_SQUARE:
5091 case CPP_EOF:
5092 return true;
5093
5094 default:
5095 ++*n;
5096 break;
5097 }
5098 }
5099 }
5100
5101 /* Return whether standard attributes start with the Nth token. */
5102
5103 static bool
5104 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5105 {
5106 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5107 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5108 return false;
5109 /* In C, '[[' must start attributes. In Objective-C, we need to
5110 check whether '[[' is matched by ']]'. */
5111 if (!c_dialect_objc ())
5112 return true;
5113 n += 2;
5114 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5115 return false;
5116 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5117 if (token->type != CPP_CLOSE_SQUARE)
5118 return false;
5119 token = c_parser_peek_nth_token_raw (parser, n + 1);
5120 return token->type == CPP_CLOSE_SQUARE;
5121 }
5122
5123 static tree
5124 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5125 {
5126 tree attributes = NULL_TREE;
5127 do
5128 {
5129 tree attrs = c_parser_std_attribute_specifier (parser, false);
5130 attributes = chainon (attributes, attrs);
5131 }
5132 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5133 return attributes;
5134 }
5135
5136 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5137 says whether alignment specifiers are OK (only in cases that might
5138 be the type name of a compound literal).
5139
5140 type-name:
5141 specifier-qualifier-list abstract-declarator[opt]
5142 */
5143
5144 struct c_type_name *
5145 c_parser_type_name (c_parser *parser, bool alignas_ok)
5146 {
5147 struct c_declspecs *specs = build_null_declspecs ();
5148 struct c_declarator *declarator;
5149 struct c_type_name *ret;
5150 bool dummy = false;
5151 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5152 false, true, cla_prefer_type);
5153 if (!specs->declspecs_seen_p)
5154 {
5155 c_parser_error (parser, "expected specifier-qualifier-list");
5156 return NULL;
5157 }
5158 if (specs->type != error_mark_node)
5159 {
5160 pending_xref_error ();
5161 finish_declspecs (specs);
5162 }
5163 declarator = c_parser_declarator (parser,
5164 specs->typespec_kind != ctsk_none,
5165 C_DTR_ABSTRACT, &dummy);
5166 if (declarator == NULL)
5167 return NULL;
5168 ret = XOBNEW (&parser_obstack, struct c_type_name);
5169 ret->specs = specs;
5170 ret->declarator = declarator;
5171 return ret;
5172 }
5173
5174 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5175
5176 initializer:
5177 assignment-expression
5178 { initializer-list }
5179 { initializer-list , }
5180
5181 initializer-list:
5182 designation[opt] initializer
5183 initializer-list , designation[opt] initializer
5184
5185 designation:
5186 designator-list =
5187
5188 designator-list:
5189 designator
5190 designator-list designator
5191
5192 designator:
5193 array-designator
5194 . identifier
5195
5196 array-designator:
5197 [ constant-expression ]
5198
5199 GNU extensions:
5200
5201 initializer:
5202 { }
5203
5204 designation:
5205 array-designator
5206 identifier :
5207
5208 array-designator:
5209 [ constant-expression ... constant-expression ]
5210
5211 Any expression without commas is accepted in the syntax for the
5212 constant-expressions, with non-constant expressions rejected later.
5213
5214 This function is only used for top-level initializers; for nested
5215 ones, see c_parser_initval. */
5216
5217 static struct c_expr
5218 c_parser_initializer (c_parser *parser)
5219 {
5220 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5221 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5222 else
5223 {
5224 struct c_expr ret;
5225 location_t loc = c_parser_peek_token (parser)->location;
5226 ret = c_parser_expr_no_commas (parser, NULL);
5227 if (TREE_CODE (ret.value) != STRING_CST
5228 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5229 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5230 return ret;
5231 }
5232 }
5233
5234 /* The location of the last comma within the current initializer list,
5235 or UNKNOWN_LOCATION if not within one. */
5236
5237 location_t last_init_list_comma;
5238
5239 /* Parse a braced initializer list. TYPE is the type specified for a
5240 compound literal, and NULL_TREE for other initializers and for
5241 nested braced lists. NESTED_P is true for nested braced lists,
5242 false for the list of a compound literal or the list that is the
5243 top-level initializer in a declaration. */
5244
5245 static struct c_expr
5246 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5247 struct obstack *outer_obstack)
5248 {
5249 struct c_expr ret;
5250 struct obstack braced_init_obstack;
5251 location_t brace_loc = c_parser_peek_token (parser)->location;
5252 gcc_obstack_init (&braced_init_obstack);
5253 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5254 matching_braces braces;
5255 braces.consume_open (parser);
5256 if (nested_p)
5257 {
5258 finish_implicit_inits (brace_loc, outer_obstack);
5259 push_init_level (brace_loc, 0, &braced_init_obstack);
5260 }
5261 else
5262 really_start_incremental_init (type);
5263 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5264 {
5265 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5266 }
5267 else
5268 {
5269 /* Parse a non-empty initializer list, possibly with a trailing
5270 comma. */
5271 while (true)
5272 {
5273 c_parser_initelt (parser, &braced_init_obstack);
5274 if (parser->error)
5275 break;
5276 if (c_parser_next_token_is (parser, CPP_COMMA))
5277 {
5278 last_init_list_comma = c_parser_peek_token (parser)->location;
5279 c_parser_consume_token (parser);
5280 }
5281 else
5282 break;
5283 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5284 break;
5285 }
5286 }
5287 c_token *next_tok = c_parser_peek_token (parser);
5288 if (next_tok->type != CPP_CLOSE_BRACE)
5289 {
5290 ret.set_error ();
5291 ret.original_code = ERROR_MARK;
5292 ret.original_type = NULL;
5293 braces.skip_until_found_close (parser);
5294 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5295 obstack_free (&braced_init_obstack, NULL);
5296 return ret;
5297 }
5298 location_t close_loc = next_tok->location;
5299 c_parser_consume_token (parser);
5300 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5301 obstack_free (&braced_init_obstack, NULL);
5302 set_c_expr_source_range (&ret, brace_loc, close_loc);
5303 return ret;
5304 }
5305
5306 /* Parse a nested initializer, including designators. */
5307
5308 static void
5309 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5310 {
5311 /* Parse any designator or designator list. A single array
5312 designator may have the subsequent "=" omitted in GNU C, but a
5313 longer list or a structure member designator may not. */
5314 if (c_parser_next_token_is (parser, CPP_NAME)
5315 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5316 {
5317 /* Old-style structure member designator. */
5318 set_init_label (c_parser_peek_token (parser)->location,
5319 c_parser_peek_token (parser)->value,
5320 c_parser_peek_token (parser)->location,
5321 braced_init_obstack);
5322 /* Use the colon as the error location. */
5323 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5324 "obsolete use of designated initializer with %<:%>");
5325 c_parser_consume_token (parser);
5326 c_parser_consume_token (parser);
5327 }
5328 else
5329 {
5330 /* des_seen is 0 if there have been no designators, 1 if there
5331 has been a single array designator and 2 otherwise. */
5332 int des_seen = 0;
5333 /* Location of a designator. */
5334 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5335 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5336 || c_parser_next_token_is (parser, CPP_DOT))
5337 {
5338 int des_prev = des_seen;
5339 if (!des_seen)
5340 des_loc = c_parser_peek_token (parser)->location;
5341 if (des_seen < 2)
5342 des_seen++;
5343 if (c_parser_next_token_is (parser, CPP_DOT))
5344 {
5345 des_seen = 2;
5346 c_parser_consume_token (parser);
5347 if (c_parser_next_token_is (parser, CPP_NAME))
5348 {
5349 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5350 c_parser_peek_token (parser)->location,
5351 braced_init_obstack);
5352 c_parser_consume_token (parser);
5353 }
5354 else
5355 {
5356 struct c_expr init;
5357 init.set_error ();
5358 init.original_code = ERROR_MARK;
5359 init.original_type = NULL;
5360 c_parser_error (parser, "expected identifier");
5361 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5362 process_init_element (input_location, init, false,
5363 braced_init_obstack);
5364 return;
5365 }
5366 }
5367 else
5368 {
5369 tree first, second;
5370 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5371 location_t array_index_loc = UNKNOWN_LOCATION;
5372 /* ??? Following the old parser, [ objc-receiver
5373 objc-message-args ] is accepted as an initializer,
5374 being distinguished from a designator by what follows
5375 the first assignment expression inside the square
5376 brackets, but after a first array designator a
5377 subsequent square bracket is for Objective-C taken to
5378 start an expression, using the obsolete form of
5379 designated initializer without '=', rather than
5380 possibly being a second level of designation: in LALR
5381 terms, the '[' is shifted rather than reducing
5382 designator to designator-list. */
5383 if (des_prev == 1 && c_dialect_objc ())
5384 {
5385 des_seen = des_prev;
5386 break;
5387 }
5388 if (des_prev == 0 && c_dialect_objc ())
5389 {
5390 /* This might be an array designator or an
5391 Objective-C message expression. If the former,
5392 continue parsing here; if the latter, parse the
5393 remainder of the initializer given the starting
5394 primary-expression. ??? It might make sense to
5395 distinguish when des_prev == 1 as well; see
5396 previous comment. */
5397 tree rec, args;
5398 struct c_expr mexpr;
5399 c_parser_consume_token (parser);
5400 if (c_parser_peek_token (parser)->type == CPP_NAME
5401 && ((c_parser_peek_token (parser)->id_kind
5402 == C_ID_TYPENAME)
5403 || (c_parser_peek_token (parser)->id_kind
5404 == C_ID_CLASSNAME)))
5405 {
5406 /* Type name receiver. */
5407 tree id = c_parser_peek_token (parser)->value;
5408 c_parser_consume_token (parser);
5409 rec = objc_get_class_reference (id);
5410 goto parse_message_args;
5411 }
5412 first = c_parser_expr_no_commas (parser, NULL).value;
5413 mark_exp_read (first);
5414 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5415 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5416 goto array_desig_after_first;
5417 /* Expression receiver. So far only one part
5418 without commas has been parsed; there might be
5419 more of the expression. */
5420 rec = first;
5421 while (c_parser_next_token_is (parser, CPP_COMMA))
5422 {
5423 struct c_expr next;
5424 location_t comma_loc, exp_loc;
5425 comma_loc = c_parser_peek_token (parser)->location;
5426 c_parser_consume_token (parser);
5427 exp_loc = c_parser_peek_token (parser)->location;
5428 next = c_parser_expr_no_commas (parser, NULL);
5429 next = convert_lvalue_to_rvalue (exp_loc, next,
5430 true, true);
5431 rec = build_compound_expr (comma_loc, rec, next.value);
5432 }
5433 parse_message_args:
5434 /* Now parse the objc-message-args. */
5435 args = c_parser_objc_message_args (parser);
5436 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5437 "expected %<]%>");
5438 mexpr.value
5439 = objc_build_message_expr (rec, args);
5440 mexpr.original_code = ERROR_MARK;
5441 mexpr.original_type = NULL;
5442 /* Now parse and process the remainder of the
5443 initializer, starting with this message
5444 expression as a primary-expression. */
5445 c_parser_initval (parser, &mexpr, braced_init_obstack);
5446 return;
5447 }
5448 c_parser_consume_token (parser);
5449 array_index_loc = c_parser_peek_token (parser)->location;
5450 first = c_parser_expr_no_commas (parser, NULL).value;
5451 mark_exp_read (first);
5452 array_desig_after_first:
5453 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5454 {
5455 ellipsis_loc = c_parser_peek_token (parser)->location;
5456 c_parser_consume_token (parser);
5457 second = c_parser_expr_no_commas (parser, NULL).value;
5458 mark_exp_read (second);
5459 }
5460 else
5461 second = NULL_TREE;
5462 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5463 {
5464 c_parser_consume_token (parser);
5465 set_init_index (array_index_loc, first, second,
5466 braced_init_obstack);
5467 if (second)
5468 pedwarn (ellipsis_loc, OPT_Wpedantic,
5469 "ISO C forbids specifying range of elements to initialize");
5470 }
5471 else
5472 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5473 "expected %<]%>");
5474 }
5475 }
5476 if (des_seen >= 1)
5477 {
5478 if (c_parser_next_token_is (parser, CPP_EQ))
5479 {
5480 pedwarn_c90 (des_loc, OPT_Wpedantic,
5481 "ISO C90 forbids specifying subobject "
5482 "to initialize");
5483 c_parser_consume_token (parser);
5484 }
5485 else
5486 {
5487 if (des_seen == 1)
5488 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5489 "obsolete use of designated initializer without %<=%>");
5490 else
5491 {
5492 struct c_expr init;
5493 init.set_error ();
5494 init.original_code = ERROR_MARK;
5495 init.original_type = NULL;
5496 c_parser_error (parser, "expected %<=%>");
5497 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5498 process_init_element (input_location, init, false,
5499 braced_init_obstack);
5500 return;
5501 }
5502 }
5503 }
5504 }
5505 c_parser_initval (parser, NULL, braced_init_obstack);
5506 }
5507
5508 /* Parse a nested initializer; as c_parser_initializer but parses
5509 initializers within braced lists, after any designators have been
5510 applied. If AFTER is not NULL then it is an Objective-C message
5511 expression which is the primary-expression starting the
5512 initializer. */
5513
5514 static void
5515 c_parser_initval (c_parser *parser, struct c_expr *after,
5516 struct obstack * braced_init_obstack)
5517 {
5518 struct c_expr init;
5519 gcc_assert (!after || c_dialect_objc ());
5520 location_t loc = c_parser_peek_token (parser)->location;
5521
5522 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5523 init = c_parser_braced_init (parser, NULL_TREE, true,
5524 braced_init_obstack);
5525 else
5526 {
5527 init = c_parser_expr_no_commas (parser, after);
5528 if (init.value != NULL_TREE
5529 && TREE_CODE (init.value) != STRING_CST
5530 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5531 init = convert_lvalue_to_rvalue (loc, init, true, true);
5532 }
5533 process_init_element (loc, init, false, braced_init_obstack);
5534 }
5535
5536 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5537 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5538
5539 compound-statement:
5540 { block-item-list[opt] }
5541 { label-declarations block-item-list }
5542
5543 block-item-list:
5544 block-item
5545 block-item-list block-item
5546
5547 block-item:
5548 label
5549 nested-declaration
5550 statement
5551
5552 nested-declaration:
5553 declaration
5554
5555 GNU extensions:
5556
5557 compound-statement:
5558 { label-declarations block-item-list }
5559
5560 nested-declaration:
5561 __extension__ nested-declaration
5562 nested-function-definition
5563
5564 label-declarations:
5565 label-declaration
5566 label-declarations label-declaration
5567
5568 label-declaration:
5569 __label__ identifier-list ;
5570
5571 Allowing the mixing of declarations and code is new in C99. The
5572 GNU syntax also permits (not shown above) labels at the end of
5573 compound statements, which yield an error. We don't allow labels
5574 on declarations; this might seem like a natural extension, but
5575 there would be a conflict between gnu-attributes on the label and
5576 prefix gnu-attributes on the declaration. ??? The syntax follows the
5577 old parser in requiring something after label declarations.
5578 Although they are erroneous if the labels declared aren't defined,
5579 is it useful for the syntax to be this way?
5580
5581 OpenACC:
5582
5583 block-item:
5584 openacc-directive
5585
5586 openacc-directive:
5587 update-directive
5588
5589 OpenMP:
5590
5591 block-item:
5592 openmp-directive
5593
5594 openmp-directive:
5595 barrier-directive
5596 flush-directive
5597 taskwait-directive
5598 taskyield-directive
5599 cancel-directive
5600 cancellation-point-directive */
5601
5602 static tree
5603 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5604 {
5605 tree stmt;
5606 location_t brace_loc;
5607 brace_loc = c_parser_peek_token (parser)->location;
5608 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5609 {
5610 /* Ensure a scope is entered and left anyway to avoid confusion
5611 if we have just prepared to enter a function body. */
5612 stmt = c_begin_compound_stmt (true);
5613 c_end_compound_stmt (brace_loc, stmt, true);
5614 return error_mark_node;
5615 }
5616 stmt = c_begin_compound_stmt (true);
5617 location_t end_loc = c_parser_compound_statement_nostart (parser);
5618 if (endlocp)
5619 *endlocp = end_loc;
5620
5621 return c_end_compound_stmt (brace_loc, stmt, true);
5622 }
5623
5624 /* Parse a compound statement except for the opening brace. This is
5625 used for parsing both compound statements and statement expressions
5626 (which follow different paths to handling the opening). */
5627
5628 static location_t
5629 c_parser_compound_statement_nostart (c_parser *parser)
5630 {
5631 bool last_stmt = false;
5632 bool last_label = false;
5633 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5634 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5635 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5636 {
5637 location_t endloc = c_parser_peek_token (parser)->location;
5638 add_debug_begin_stmt (endloc);
5639 c_parser_consume_token (parser);
5640 return endloc;
5641 }
5642 mark_valid_location_for_stdc_pragma (true);
5643 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5644 {
5645 /* Read zero or more forward-declarations for labels that nested
5646 functions can jump to. */
5647 mark_valid_location_for_stdc_pragma (false);
5648 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5649 {
5650 label_loc = c_parser_peek_token (parser)->location;
5651 c_parser_consume_token (parser);
5652 /* Any identifiers, including those declared as type names,
5653 are OK here. */
5654 while (true)
5655 {
5656 tree label;
5657 if (c_parser_next_token_is_not (parser, CPP_NAME))
5658 {
5659 c_parser_error (parser, "expected identifier");
5660 break;
5661 }
5662 label
5663 = declare_label (c_parser_peek_token (parser)->value);
5664 C_DECLARED_LABEL_FLAG (label) = 1;
5665 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5666 c_parser_consume_token (parser);
5667 if (c_parser_next_token_is (parser, CPP_COMMA))
5668 c_parser_consume_token (parser);
5669 else
5670 break;
5671 }
5672 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5673 }
5674 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5675 }
5676 /* We must now have at least one statement, label or declaration. */
5677 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5678 {
5679 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5680 c_parser_error (parser, "expected declaration or statement");
5681 location_t endloc = c_parser_peek_token (parser)->location;
5682 c_parser_consume_token (parser);
5683 return endloc;
5684 }
5685 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5686 {
5687 location_t loc = c_parser_peek_token (parser)->location;
5688 loc = expansion_point_location_if_in_system_header (loc);
5689 /* Standard attributes may start a label, statement or declaration. */
5690 bool have_std_attrs
5691 = c_parser_nth_token_starts_std_attributes (parser, 1);
5692 tree std_attrs = NULL_TREE;
5693 if (have_std_attrs)
5694 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5695 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5696 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5697 || (c_parser_next_token_is (parser, CPP_NAME)
5698 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5699 {
5700 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5701 label_loc = c_parser_peek_2nd_token (parser)->location;
5702 else
5703 label_loc = c_parser_peek_token (parser)->location;
5704 last_label = true;
5705 last_stmt = false;
5706 mark_valid_location_for_stdc_pragma (false);
5707 c_parser_label (parser, std_attrs);
5708 }
5709 else if (c_parser_next_tokens_start_declaration (parser)
5710 || (have_std_attrs
5711 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5712 {
5713 if (last_label)
5714 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5715 "a label can only be part of a statement and "
5716 "a declaration is not a statement");
5717
5718 mark_valid_location_for_stdc_pragma (false);
5719 bool fallthru_attr_p = false;
5720 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5721 true, true, true, NULL,
5722 NULL, have_std_attrs, std_attrs,
5723 NULL, &fallthru_attr_p);
5724
5725 if (last_stmt && !fallthru_attr_p)
5726 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5727 "ISO C90 forbids mixed declarations and code");
5728 last_stmt = fallthru_attr_p;
5729 last_label = false;
5730 }
5731 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5732 {
5733 /* __extension__ can start a declaration, but is also an
5734 unary operator that can start an expression. Consume all
5735 but the last of a possible series of __extension__ to
5736 determine which. If standard attributes have already
5737 been seen, it must start a statement, not a declaration,
5738 but standard attributes starting a declaration may appear
5739 after __extension__. */
5740 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5741 && (c_parser_peek_2nd_token (parser)->keyword
5742 == RID_EXTENSION))
5743 c_parser_consume_token (parser);
5744 if (!have_std_attrs
5745 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5746 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5747 {
5748 int ext;
5749 ext = disable_extension_diagnostics ();
5750 c_parser_consume_token (parser);
5751 last_label = false;
5752 mark_valid_location_for_stdc_pragma (false);
5753 c_parser_declaration_or_fndef (parser, true, true, true, true,
5754 true);
5755 /* Following the old parser, __extension__ does not
5756 disable this diagnostic. */
5757 restore_extension_diagnostics (ext);
5758 if (last_stmt)
5759 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5760 "ISO C90 forbids mixed declarations and code");
5761 last_stmt = false;
5762 }
5763 else
5764 goto statement;
5765 }
5766 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5767 {
5768 if (have_std_attrs)
5769 c_parser_error (parser, "expected declaration or statement");
5770 /* External pragmas, and some omp pragmas, are not associated
5771 with regular c code, and so are not to be considered statements
5772 syntactically. This ensures that the user doesn't put them
5773 places that would turn into syntax errors if the directive
5774 were ignored. */
5775 if (c_parser_pragma (parser,
5776 last_label ? pragma_stmt : pragma_compound,
5777 NULL))
5778 last_label = false, last_stmt = true;
5779 }
5780 else if (c_parser_next_token_is (parser, CPP_EOF))
5781 {
5782 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5783 c_parser_error (parser, "expected declaration or statement");
5784 return c_parser_peek_token (parser)->location;
5785 }
5786 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5787 {
5788 if (parser->in_if_block)
5789 {
5790 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5791 error_at (loc, "expected %<}%> before %<else%>");
5792 return c_parser_peek_token (parser)->location;
5793 }
5794 else
5795 {
5796 error_at (loc, "%<else%> without a previous %<if%>");
5797 c_parser_consume_token (parser);
5798 continue;
5799 }
5800 }
5801 else
5802 {
5803 statement:
5804 c_warn_unused_attributes (std_attrs);
5805 last_label = false;
5806 last_stmt = true;
5807 mark_valid_location_for_stdc_pragma (false);
5808 c_parser_statement_after_labels (parser, NULL);
5809 }
5810
5811 parser->error = false;
5812 }
5813 if (last_label)
5814 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5815 location_t endloc = c_parser_peek_token (parser)->location;
5816 c_parser_consume_token (parser);
5817 /* Restore the value we started with. */
5818 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5819 return endloc;
5820 }
5821
5822 /* Parse all consecutive labels, possibly preceded by standard
5823 attributes. In this context, a statement is required, not a
5824 declaration, so attributes must be followed by a statement that is
5825 not just a semicolon. */
5826
5827 static void
5828 c_parser_all_labels (c_parser *parser)
5829 {
5830 tree std_attrs = NULL;
5831 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5832 {
5833 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5834 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5835 c_parser_error (parser, "expected statement");
5836 }
5837 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5838 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5839 || (c_parser_next_token_is (parser, CPP_NAME)
5840 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5841 {
5842 c_parser_label (parser, std_attrs);
5843 std_attrs = NULL;
5844 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5845 {
5846 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5847 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5848 c_parser_error (parser, "expected statement");
5849 }
5850 }
5851 if (std_attrs)
5852 c_warn_unused_attributes (std_attrs);
5853 }
5854
5855 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5856
5857 label:
5858 identifier : gnu-attributes[opt]
5859 case constant-expression :
5860 default :
5861
5862 GNU extensions:
5863
5864 label:
5865 case constant-expression ... constant-expression :
5866
5867 The use of gnu-attributes on labels is a GNU extension. The syntax in
5868 GNU C accepts any expressions without commas, non-constant
5869 expressions being rejected later. Any standard
5870 attribute-specifier-sequence before the first label has been parsed
5871 in the caller, to distinguish statements from declarations. Any
5872 attribute-specifier-sequence after the label is parsed in this
5873 function. */
5874 static void
5875 c_parser_label (c_parser *parser, tree std_attrs)
5876 {
5877 location_t loc1 = c_parser_peek_token (parser)->location;
5878 tree label = NULL_TREE;
5879
5880 /* Remember whether this case or a user-defined label is allowed to fall
5881 through to. */
5882 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5883
5884 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5885 {
5886 tree exp1, exp2;
5887 c_parser_consume_token (parser);
5888 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5889 if (c_parser_next_token_is (parser, CPP_COLON))
5890 {
5891 c_parser_consume_token (parser);
5892 label = do_case (loc1, exp1, NULL_TREE);
5893 }
5894 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5895 {
5896 c_parser_consume_token (parser);
5897 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5898 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5899 label = do_case (loc1, exp1, exp2);
5900 }
5901 else
5902 c_parser_error (parser, "expected %<:%> or %<...%>");
5903 }
5904 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5905 {
5906 c_parser_consume_token (parser);
5907 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5908 label = do_case (loc1, NULL_TREE, NULL_TREE);
5909 }
5910 else
5911 {
5912 tree name = c_parser_peek_token (parser)->value;
5913 tree tlab;
5914 tree attrs;
5915 location_t loc2 = c_parser_peek_token (parser)->location;
5916 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5917 c_parser_consume_token (parser);
5918 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5919 c_parser_consume_token (parser);
5920 attrs = c_parser_gnu_attributes (parser);
5921 tlab = define_label (loc2, name);
5922 if (tlab)
5923 {
5924 decl_attributes (&tlab, attrs, 0);
5925 decl_attributes (&tlab, std_attrs, 0);
5926 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5927 }
5928 if (attrs
5929 && c_parser_next_tokens_start_declaration (parser))
5930 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5931 " label and declaration appertains to the label");
5932 }
5933 if (label)
5934 {
5935 if (TREE_CODE (label) == LABEL_EXPR)
5936 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5937 else
5938 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5939 }
5940 }
5941
5942 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5943
5944 statement:
5945 labeled-statement
5946 attribute-specifier-sequence[opt] compound-statement
5947 expression-statement
5948 attribute-specifier-sequence[opt] selection-statement
5949 attribute-specifier-sequence[opt] iteration-statement
5950 attribute-specifier-sequence[opt] jump-statement
5951
5952 labeled-statement:
5953 attribute-specifier-sequence[opt] label statement
5954
5955 expression-statement:
5956 expression[opt] ;
5957 attribute-specifier-sequence expression ;
5958
5959 selection-statement:
5960 if-statement
5961 switch-statement
5962
5963 iteration-statement:
5964 while-statement
5965 do-statement
5966 for-statement
5967
5968 jump-statement:
5969 goto identifier ;
5970 continue ;
5971 break ;
5972 return expression[opt] ;
5973
5974 GNU extensions:
5975
5976 statement:
5977 attribute-specifier-sequence[opt] asm-statement
5978
5979 jump-statement:
5980 goto * expression ;
5981
5982 expression-statement:
5983 gnu-attributes ;
5984
5985 Objective-C:
5986
5987 statement:
5988 attribute-specifier-sequence[opt] objc-throw-statement
5989 attribute-specifier-sequence[opt] objc-try-catch-statement
5990 attribute-specifier-sequence[opt] objc-synchronized-statement
5991
5992 objc-throw-statement:
5993 @throw expression ;
5994 @throw ;
5995
5996 OpenACC:
5997
5998 statement:
5999 attribute-specifier-sequence[opt] openacc-construct
6000
6001 openacc-construct:
6002 parallel-construct
6003 kernels-construct
6004 data-construct
6005 loop-construct
6006
6007 parallel-construct:
6008 parallel-directive structured-block
6009
6010 kernels-construct:
6011 kernels-directive structured-block
6012
6013 data-construct:
6014 data-directive structured-block
6015
6016 loop-construct:
6017 loop-directive structured-block
6018
6019 OpenMP:
6020
6021 statement:
6022 attribute-specifier-sequence[opt] openmp-construct
6023
6024 openmp-construct:
6025 parallel-construct
6026 for-construct
6027 simd-construct
6028 for-simd-construct
6029 sections-construct
6030 single-construct
6031 parallel-for-construct
6032 parallel-for-simd-construct
6033 parallel-sections-construct
6034 master-construct
6035 critical-construct
6036 atomic-construct
6037 ordered-construct
6038
6039 parallel-construct:
6040 parallel-directive structured-block
6041
6042 for-construct:
6043 for-directive iteration-statement
6044
6045 simd-construct:
6046 simd-directive iteration-statements
6047
6048 for-simd-construct:
6049 for-simd-directive iteration-statements
6050
6051 sections-construct:
6052 sections-directive section-scope
6053
6054 single-construct:
6055 single-directive structured-block
6056
6057 parallel-for-construct:
6058 parallel-for-directive iteration-statement
6059
6060 parallel-for-simd-construct:
6061 parallel-for-simd-directive iteration-statement
6062
6063 parallel-sections-construct:
6064 parallel-sections-directive section-scope
6065
6066 master-construct:
6067 master-directive structured-block
6068
6069 critical-construct:
6070 critical-directive structured-block
6071
6072 atomic-construct:
6073 atomic-directive expression-statement
6074
6075 ordered-construct:
6076 ordered-directive structured-block
6077
6078 Transactional Memory:
6079
6080 statement:
6081 attribute-specifier-sequence[opt] transaction-statement
6082 attribute-specifier-sequence[opt] transaction-cancel-statement
6083
6084 IF_P is used to track whether there's a (possibly labeled) if statement
6085 which is not enclosed in braces and has an else clause. This is used to
6086 implement -Wparentheses. */
6087
6088 static void
6089 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6090 {
6091 c_parser_all_labels (parser);
6092 if (loc_after_labels)
6093 *loc_after_labels = c_parser_peek_token (parser)->location;
6094 c_parser_statement_after_labels (parser, if_p, NULL);
6095 }
6096
6097 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6098 of if-else-if conditions. All labels and standard attributes have
6099 been parsed in the caller.
6100
6101 IF_P is used to track whether there's a (possibly labeled) if statement
6102 which is not enclosed in braces and has an else clause. This is used to
6103 implement -Wparentheses. */
6104
6105 static void
6106 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6107 vec<tree> *chain)
6108 {
6109 location_t loc = c_parser_peek_token (parser)->location;
6110 tree stmt = NULL_TREE;
6111 bool in_if_block = parser->in_if_block;
6112 parser->in_if_block = false;
6113 if (if_p != NULL)
6114 *if_p = false;
6115
6116 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6117 add_debug_begin_stmt (loc);
6118
6119 restart:
6120 switch (c_parser_peek_token (parser)->type)
6121 {
6122 case CPP_OPEN_BRACE:
6123 add_stmt (c_parser_compound_statement (parser));
6124 break;
6125 case CPP_KEYWORD:
6126 switch (c_parser_peek_token (parser)->keyword)
6127 {
6128 case RID_IF:
6129 c_parser_if_statement (parser, if_p, chain);
6130 break;
6131 case RID_SWITCH:
6132 c_parser_switch_statement (parser, if_p);
6133 break;
6134 case RID_WHILE:
6135 c_parser_while_statement (parser, false, 0, if_p);
6136 break;
6137 case RID_DO:
6138 c_parser_do_statement (parser, false, 0);
6139 break;
6140 case RID_FOR:
6141 c_parser_for_statement (parser, false, 0, if_p);
6142 break;
6143 case RID_GOTO:
6144 c_parser_consume_token (parser);
6145 if (c_parser_next_token_is (parser, CPP_NAME))
6146 {
6147 stmt = c_finish_goto_label (loc,
6148 c_parser_peek_token (parser)->value);
6149 c_parser_consume_token (parser);
6150 }
6151 else if (c_parser_next_token_is (parser, CPP_MULT))
6152 {
6153 struct c_expr val;
6154
6155 c_parser_consume_token (parser);
6156 val = c_parser_expression (parser);
6157 val = convert_lvalue_to_rvalue (loc, val, false, true);
6158 stmt = c_finish_goto_ptr (loc, val);
6159 }
6160 else
6161 c_parser_error (parser, "expected identifier or %<*%>");
6162 goto expect_semicolon;
6163 case RID_CONTINUE:
6164 c_parser_consume_token (parser);
6165 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6166 goto expect_semicolon;
6167 case RID_BREAK:
6168 c_parser_consume_token (parser);
6169 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6170 goto expect_semicolon;
6171 case RID_RETURN:
6172 c_parser_consume_token (parser);
6173 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6174 {
6175 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6176 c_parser_consume_token (parser);
6177 }
6178 else
6179 {
6180 location_t xloc = c_parser_peek_token (parser)->location;
6181 struct c_expr expr = c_parser_expression_conv (parser);
6182 mark_exp_read (expr.value);
6183 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6184 expr.value, expr.original_type);
6185 goto expect_semicolon;
6186 }
6187 break;
6188 case RID_ASM:
6189 stmt = c_parser_asm_statement (parser);
6190 break;
6191 case RID_TRANSACTION_ATOMIC:
6192 case RID_TRANSACTION_RELAXED:
6193 stmt = c_parser_transaction (parser,
6194 c_parser_peek_token (parser)->keyword);
6195 break;
6196 case RID_TRANSACTION_CANCEL:
6197 stmt = c_parser_transaction_cancel (parser);
6198 goto expect_semicolon;
6199 case RID_AT_THROW:
6200 gcc_assert (c_dialect_objc ());
6201 c_parser_consume_token (parser);
6202 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6203 {
6204 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6205 c_parser_consume_token (parser);
6206 }
6207 else
6208 {
6209 struct c_expr expr = c_parser_expression (parser);
6210 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6211 expr.value = c_fully_fold (expr.value, false, NULL);
6212 stmt = objc_build_throw_stmt (loc, expr.value);
6213 goto expect_semicolon;
6214 }
6215 break;
6216 case RID_AT_TRY:
6217 gcc_assert (c_dialect_objc ());
6218 c_parser_objc_try_catch_finally_statement (parser);
6219 break;
6220 case RID_AT_SYNCHRONIZED:
6221 gcc_assert (c_dialect_objc ());
6222 c_parser_objc_synchronized_statement (parser);
6223 break;
6224 case RID_ATTRIBUTE:
6225 {
6226 /* Allow '__attribute__((fallthrough));'. */
6227 tree attrs = c_parser_gnu_attributes (parser);
6228 if (attribute_fallthrough_p (attrs))
6229 {
6230 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6231 {
6232 tree fn = build_call_expr_internal_loc (loc,
6233 IFN_FALLTHROUGH,
6234 void_type_node, 0);
6235 add_stmt (fn);
6236 /* Eat the ';'. */
6237 c_parser_consume_token (parser);
6238 }
6239 else
6240 warning_at (loc, OPT_Wattributes,
6241 "%<fallthrough%> attribute not followed "
6242 "by %<;%>");
6243 }
6244 else if (attrs != NULL_TREE)
6245 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6246 " can be applied to a null statement");
6247 break;
6248 }
6249 default:
6250 goto expr_stmt;
6251 }
6252 break;
6253 case CPP_SEMICOLON:
6254 c_parser_consume_token (parser);
6255 break;
6256 case CPP_CLOSE_PAREN:
6257 case CPP_CLOSE_SQUARE:
6258 /* Avoid infinite loop in error recovery:
6259 c_parser_skip_until_found stops at a closing nesting
6260 delimiter without consuming it, but here we need to consume
6261 it to proceed further. */
6262 c_parser_error (parser, "expected statement");
6263 c_parser_consume_token (parser);
6264 break;
6265 case CPP_PRAGMA:
6266 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6267 goto restart;
6268 break;
6269 default:
6270 expr_stmt:
6271 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6272 expect_semicolon:
6273 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6274 break;
6275 }
6276 /* Two cases cannot and do not have line numbers associated: If stmt
6277 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6278 cannot hold line numbers. But that's OK because the statement
6279 will either be changed to a MODIFY_EXPR during gimplification of
6280 the statement expr, or discarded. If stmt was compound, but
6281 without new variables, we will have skipped the creation of a
6282 BIND and will have a bare STATEMENT_LIST. But that's OK because
6283 (recursively) all of the component statements should already have
6284 line numbers assigned. ??? Can we discard no-op statements
6285 earlier? */
6286 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6287 protected_set_expr_location (stmt, loc);
6288
6289 parser->in_if_block = in_if_block;
6290 }
6291
6292 /* Parse the condition from an if, do, while or for statements. */
6293
6294 static tree
6295 c_parser_condition (c_parser *parser)
6296 {
6297 location_t loc = c_parser_peek_token (parser)->location;
6298 tree cond;
6299 cond = c_parser_expression_conv (parser).value;
6300 cond = c_objc_common_truthvalue_conversion (loc, cond);
6301 cond = c_fully_fold (cond, false, NULL);
6302 if (warn_sequence_point)
6303 verify_sequence_points (cond);
6304 return cond;
6305 }
6306
6307 /* Parse a parenthesized condition from an if, do or while statement.
6308
6309 condition:
6310 ( expression )
6311 */
6312 static tree
6313 c_parser_paren_condition (c_parser *parser)
6314 {
6315 tree cond;
6316 matching_parens parens;
6317 if (!parens.require_open (parser))
6318 return error_mark_node;
6319 cond = c_parser_condition (parser);
6320 parens.skip_until_found_close (parser);
6321 return cond;
6322 }
6323
6324 /* Parse a statement which is a block in C99.
6325
6326 IF_P is used to track whether there's a (possibly labeled) if statement
6327 which is not enclosed in braces and has an else clause. This is used to
6328 implement -Wparentheses. */
6329
6330 static tree
6331 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6332 location_t *loc_after_labels)
6333 {
6334 tree block = c_begin_compound_stmt (flag_isoc99);
6335 location_t loc = c_parser_peek_token (parser)->location;
6336 c_parser_statement (parser, if_p, loc_after_labels);
6337 return c_end_compound_stmt (loc, block, flag_isoc99);
6338 }
6339
6340 /* Parse the body of an if statement. This is just parsing a
6341 statement but (a) it is a block in C99, (b) we track whether the
6342 body is an if statement for the sake of -Wparentheses warnings, (c)
6343 we handle an empty body specially for the sake of -Wempty-body
6344 warnings, and (d) we call parser_compound_statement directly
6345 because c_parser_statement_after_labels resets
6346 parser->in_if_block.
6347
6348 IF_P is used to track whether there's a (possibly labeled) if statement
6349 which is not enclosed in braces and has an else clause. This is used to
6350 implement -Wparentheses. */
6351
6352 static tree
6353 c_parser_if_body (c_parser *parser, bool *if_p,
6354 const token_indent_info &if_tinfo)
6355 {
6356 tree block = c_begin_compound_stmt (flag_isoc99);
6357 location_t body_loc = c_parser_peek_token (parser)->location;
6358 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6359 token_indent_info body_tinfo
6360 = get_token_indent_info (c_parser_peek_token (parser));
6361
6362 c_parser_all_labels (parser);
6363 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6364 {
6365 location_t loc = c_parser_peek_token (parser)->location;
6366 add_stmt (build_empty_stmt (loc));
6367 c_parser_consume_token (parser);
6368 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6369 warning_at (loc, OPT_Wempty_body,
6370 "suggest braces around empty body in an %<if%> statement");
6371 }
6372 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6373 add_stmt (c_parser_compound_statement (parser));
6374 else
6375 {
6376 body_loc_after_labels = c_parser_peek_token (parser)->location;
6377 c_parser_statement_after_labels (parser, if_p);
6378 }
6379
6380 token_indent_info next_tinfo
6381 = get_token_indent_info (c_parser_peek_token (parser));
6382 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6383 if (body_loc_after_labels != UNKNOWN_LOCATION
6384 && next_tinfo.type != CPP_SEMICOLON)
6385 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6386 if_tinfo.location, RID_IF);
6387
6388 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6389 }
6390
6391 /* Parse the else body of an if statement. This is just parsing a
6392 statement but (a) it is a block in C99, (b) we handle an empty body
6393 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6394 of if-else-if conditions. */
6395
6396 static tree
6397 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6398 vec<tree> *chain)
6399 {
6400 location_t body_loc = c_parser_peek_token (parser)->location;
6401 tree block = c_begin_compound_stmt (flag_isoc99);
6402 token_indent_info body_tinfo
6403 = get_token_indent_info (c_parser_peek_token (parser));
6404 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6405
6406 c_parser_all_labels (parser);
6407 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6408 {
6409 location_t loc = c_parser_peek_token (parser)->location;
6410 warning_at (loc,
6411 OPT_Wempty_body,
6412 "suggest braces around empty body in an %<else%> statement");
6413 add_stmt (build_empty_stmt (loc));
6414 c_parser_consume_token (parser);
6415 }
6416 else
6417 {
6418 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6419 body_loc_after_labels = c_parser_peek_token (parser)->location;
6420 c_parser_statement_after_labels (parser, NULL, chain);
6421 }
6422
6423 token_indent_info next_tinfo
6424 = get_token_indent_info (c_parser_peek_token (parser));
6425 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6426 if (body_loc_after_labels != UNKNOWN_LOCATION
6427 && next_tinfo.type != CPP_SEMICOLON)
6428 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6429 else_tinfo.location, RID_ELSE);
6430
6431 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6432 }
6433
6434 /* We might need to reclassify any previously-lexed identifier, e.g.
6435 when we've left a for loop with an if-statement without else in the
6436 body - we might have used a wrong scope for the token. See PR67784. */
6437
6438 static void
6439 c_parser_maybe_reclassify_token (c_parser *parser)
6440 {
6441 if (c_parser_next_token_is (parser, CPP_NAME))
6442 {
6443 c_token *token = c_parser_peek_token (parser);
6444
6445 if (token->id_kind != C_ID_CLASSNAME)
6446 {
6447 tree decl = lookup_name (token->value);
6448
6449 token->id_kind = C_ID_ID;
6450 if (decl)
6451 {
6452 if (TREE_CODE (decl) == TYPE_DECL)
6453 token->id_kind = C_ID_TYPENAME;
6454 }
6455 else if (c_dialect_objc ())
6456 {
6457 tree objc_interface_decl = objc_is_class_name (token->value);
6458 /* Objective-C class names are in the same namespace as
6459 variables and typedefs, and hence are shadowed by local
6460 declarations. */
6461 if (objc_interface_decl)
6462 {
6463 token->value = objc_interface_decl;
6464 token->id_kind = C_ID_CLASSNAME;
6465 }
6466 }
6467 }
6468 }
6469 }
6470
6471 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6472
6473 if-statement:
6474 if ( expression ) statement
6475 if ( expression ) statement else statement
6476
6477 CHAIN is a vector of if-else-if conditions.
6478 IF_P is used to track whether there's a (possibly labeled) if statement
6479 which is not enclosed in braces and has an else clause. This is used to
6480 implement -Wparentheses. */
6481
6482 static void
6483 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6484 {
6485 tree block;
6486 location_t loc;
6487 tree cond;
6488 bool nested_if = false;
6489 tree first_body, second_body;
6490 bool in_if_block;
6491
6492 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6493 token_indent_info if_tinfo
6494 = get_token_indent_info (c_parser_peek_token (parser));
6495 c_parser_consume_token (parser);
6496 block = c_begin_compound_stmt (flag_isoc99);
6497 loc = c_parser_peek_token (parser)->location;
6498 cond = c_parser_paren_condition (parser);
6499 in_if_block = parser->in_if_block;
6500 parser->in_if_block = true;
6501 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6502 parser->in_if_block = in_if_block;
6503
6504 if (warn_duplicated_cond)
6505 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6506
6507 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6508 {
6509 token_indent_info else_tinfo
6510 = get_token_indent_info (c_parser_peek_token (parser));
6511 c_parser_consume_token (parser);
6512 if (warn_duplicated_cond)
6513 {
6514 if (c_parser_next_token_is_keyword (parser, RID_IF)
6515 && chain == NULL)
6516 {
6517 /* We've got "if (COND) else if (COND2)". Start the
6518 condition chain and add COND as the first element. */
6519 chain = new vec<tree> ();
6520 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6521 chain->safe_push (cond);
6522 }
6523 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6524 /* This is if-else without subsequent if. Zap the condition
6525 chain; we would have already warned at this point. */
6526 vec_free (chain);
6527 }
6528 second_body = c_parser_else_body (parser, else_tinfo, chain);
6529 /* Set IF_P to true to indicate that this if statement has an
6530 else clause. This may trigger the Wparentheses warning
6531 below when we get back up to the parent if statement. */
6532 if (if_p != NULL)
6533 *if_p = true;
6534 }
6535 else
6536 {
6537 second_body = NULL_TREE;
6538
6539 /* Diagnose an ambiguous else if if-then-else is nested inside
6540 if-then. */
6541 if (nested_if)
6542 warning_at (loc, OPT_Wdangling_else,
6543 "suggest explicit braces to avoid ambiguous %<else%>");
6544
6545 if (warn_duplicated_cond)
6546 /* This if statement does not have an else clause. We don't
6547 need the condition chain anymore. */
6548 vec_free (chain);
6549 }
6550 c_finish_if_stmt (loc, cond, first_body, second_body);
6551 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6552
6553 c_parser_maybe_reclassify_token (parser);
6554 }
6555
6556 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6557
6558 switch-statement:
6559 switch (expression) statement
6560 */
6561
6562 static void
6563 c_parser_switch_statement (c_parser *parser, bool *if_p)
6564 {
6565 struct c_expr ce;
6566 tree block, expr, body;
6567 unsigned char save_in_statement;
6568 location_t switch_loc = c_parser_peek_token (parser)->location;
6569 location_t switch_cond_loc;
6570 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6571 c_parser_consume_token (parser);
6572 block = c_begin_compound_stmt (flag_isoc99);
6573 bool explicit_cast_p = false;
6574 matching_parens parens;
6575 if (parens.require_open (parser))
6576 {
6577 switch_cond_loc = c_parser_peek_token (parser)->location;
6578 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6579 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6580 explicit_cast_p = true;
6581 ce = c_parser_expression (parser);
6582 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6583 expr = ce.value;
6584 /* ??? expr has no valid location? */
6585 parens.skip_until_found_close (parser);
6586 }
6587 else
6588 {
6589 switch_cond_loc = UNKNOWN_LOCATION;
6590 expr = error_mark_node;
6591 ce.original_type = error_mark_node;
6592 }
6593 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6594 save_in_statement = in_statement;
6595 in_statement |= IN_SWITCH_STMT;
6596 location_t loc_after_labels;
6597 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6598 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6599 location_t next_loc = c_parser_peek_token (parser)->location;
6600 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6601 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6602 RID_SWITCH);
6603 c_finish_switch (body, ce.original_type);
6604 in_statement = save_in_statement;
6605 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6606 c_parser_maybe_reclassify_token (parser);
6607 }
6608
6609 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6610
6611 while-statement:
6612 while (expression) statement
6613
6614 IF_P is used to track whether there's a (possibly labeled) if statement
6615 which is not enclosed in braces and has an else clause. This is used to
6616 implement -Wparentheses. */
6617
6618 static void
6619 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6620 bool *if_p)
6621 {
6622 tree block, cond, body;
6623 unsigned char save_in_statement;
6624 location_t loc;
6625 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6626 token_indent_info while_tinfo
6627 = get_token_indent_info (c_parser_peek_token (parser));
6628 c_parser_consume_token (parser);
6629 block = c_begin_compound_stmt (flag_isoc99);
6630 loc = c_parser_peek_token (parser)->location;
6631 cond = c_parser_paren_condition (parser);
6632 if (ivdep && cond != error_mark_node)
6633 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6634 build_int_cst (integer_type_node,
6635 annot_expr_ivdep_kind),
6636 integer_zero_node);
6637 if (unroll && cond != error_mark_node)
6638 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6639 build_int_cst (integer_type_node,
6640 annot_expr_unroll_kind),
6641 build_int_cst (integer_type_node, unroll));
6642 save_in_statement = in_statement;
6643 in_statement = IN_ITERATION_STMT;
6644
6645 token_indent_info body_tinfo
6646 = get_token_indent_info (c_parser_peek_token (parser));
6647
6648 location_t loc_after_labels;
6649 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6650 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6651 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6652 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6653 c_parser_maybe_reclassify_token (parser);
6654
6655 token_indent_info next_tinfo
6656 = get_token_indent_info (c_parser_peek_token (parser));
6657 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6658
6659 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6660 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6661 while_tinfo.location, RID_WHILE);
6662
6663 in_statement = save_in_statement;
6664 }
6665
6666 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6667
6668 do-statement:
6669 do statement while ( expression ) ;
6670 */
6671
6672 static void
6673 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6674 {
6675 tree block, cond, body;
6676 unsigned char save_in_statement;
6677 location_t loc;
6678 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6679 c_parser_consume_token (parser);
6680 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6681 warning_at (c_parser_peek_token (parser)->location,
6682 OPT_Wempty_body,
6683 "suggest braces around empty body in %<do%> statement");
6684 block = c_begin_compound_stmt (flag_isoc99);
6685 loc = c_parser_peek_token (parser)->location;
6686 save_in_statement = in_statement;
6687 in_statement = IN_ITERATION_STMT;
6688 body = c_parser_c99_block_statement (parser, NULL);
6689 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6690 in_statement = save_in_statement;
6691 cond = c_parser_paren_condition (parser);
6692 if (ivdep && cond != error_mark_node)
6693 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6694 build_int_cst (integer_type_node,
6695 annot_expr_ivdep_kind),
6696 integer_zero_node);
6697 if (unroll && cond != error_mark_node)
6698 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6699 build_int_cst (integer_type_node,
6700 annot_expr_unroll_kind),
6701 build_int_cst (integer_type_node, unroll));
6702 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6703 c_parser_skip_to_end_of_block_or_statement (parser);
6704
6705 add_stmt (build_stmt (loc, DO_STMT, cond, body));
6706 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6707 }
6708
6709 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6710
6711 for-statement:
6712 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6713 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6714
6715 The form with a declaration is new in C99.
6716
6717 ??? In accordance with the old parser, the declaration may be a
6718 nested function, which is then rejected in check_for_loop_decls,
6719 but does it make any sense for this to be included in the grammar?
6720 Note in particular that the nested function does not include a
6721 trailing ';', whereas the "declaration" production includes one.
6722 Also, can we reject bad declarations earlier and cheaper than
6723 check_for_loop_decls?
6724
6725 In Objective-C, there are two additional variants:
6726
6727 foreach-statement:
6728 for ( expression in expresssion ) statement
6729 for ( declaration in expression ) statement
6730
6731 This is inconsistent with C, because the second variant is allowed
6732 even if c99 is not enabled.
6733
6734 The rest of the comment documents these Objective-C foreach-statement.
6735
6736 Here is the canonical example of the first variant:
6737 for (object in array) { do something with object }
6738 we call the first expression ("object") the "object_expression" and
6739 the second expression ("array") the "collection_expression".
6740 object_expression must be an lvalue of type "id" (a generic Objective-C
6741 object) because the loop works by assigning to object_expression the
6742 various objects from the collection_expression. collection_expression
6743 must evaluate to something of type "id" which responds to the method
6744 countByEnumeratingWithState:objects:count:.
6745
6746 The canonical example of the second variant is:
6747 for (id object in array) { do something with object }
6748 which is completely equivalent to
6749 {
6750 id object;
6751 for (object in array) { do something with object }
6752 }
6753 Note that initizializing 'object' in some way (eg, "for ((object =
6754 xxx) in array) { do something with object }") is possibly
6755 technically valid, but completely pointless as 'object' will be
6756 assigned to something else as soon as the loop starts. We should
6757 most likely reject it (TODO).
6758
6759 The beginning of the Objective-C foreach-statement looks exactly
6760 like the beginning of the for-statement, and we can tell it is a
6761 foreach-statement only because the initial declaration or
6762 expression is terminated by 'in' instead of ';'.
6763
6764 IF_P is used to track whether there's a (possibly labeled) if statement
6765 which is not enclosed in braces and has an else clause. This is used to
6766 implement -Wparentheses. */
6767
6768 static void
6769 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6770 bool *if_p)
6771 {
6772 tree block, cond, incr, body;
6773 unsigned char save_in_statement;
6774 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6775 /* The following are only used when parsing an ObjC foreach statement. */
6776 tree object_expression;
6777 /* Silence the bogus uninitialized warning. */
6778 tree collection_expression = NULL;
6779 location_t loc = c_parser_peek_token (parser)->location;
6780 location_t for_loc = loc;
6781 bool is_foreach_statement = false;
6782 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6783 token_indent_info for_tinfo
6784 = get_token_indent_info (c_parser_peek_token (parser));
6785 c_parser_consume_token (parser);
6786 /* Open a compound statement in Objective-C as well, just in case this is
6787 as foreach expression. */
6788 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6789 cond = error_mark_node;
6790 incr = error_mark_node;
6791 matching_parens parens;
6792 if (parens.require_open (parser))
6793 {
6794 /* Parse the initialization declaration or expression. */
6795 object_expression = error_mark_node;
6796 parser->objc_could_be_foreach_context = c_dialect_objc ();
6797 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6798 {
6799 parser->objc_could_be_foreach_context = false;
6800 c_parser_consume_token (parser);
6801 c_finish_expr_stmt (loc, NULL_TREE);
6802 }
6803 else if (c_parser_next_tokens_start_declaration (parser)
6804 || c_parser_nth_token_starts_std_attributes (parser, 1))
6805 {
6806 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6807 &object_expression);
6808 parser->objc_could_be_foreach_context = false;
6809
6810 if (c_parser_next_token_is_keyword (parser, RID_IN))
6811 {
6812 c_parser_consume_token (parser);
6813 is_foreach_statement = true;
6814 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6815 c_parser_error (parser, "multiple iterating variables in "
6816 "fast enumeration");
6817 }
6818 else
6819 check_for_loop_decls (for_loc, flag_isoc99);
6820 }
6821 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6822 {
6823 /* __extension__ can start a declaration, but is also an
6824 unary operator that can start an expression. Consume all
6825 but the last of a possible series of __extension__ to
6826 determine which. */
6827 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6828 && (c_parser_peek_2nd_token (parser)->keyword
6829 == RID_EXTENSION))
6830 c_parser_consume_token (parser);
6831 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6832 || c_parser_nth_token_starts_std_attributes (parser, 2))
6833 {
6834 int ext;
6835 ext = disable_extension_diagnostics ();
6836 c_parser_consume_token (parser);
6837 c_parser_declaration_or_fndef (parser, true, true, true, true,
6838 true, &object_expression);
6839 parser->objc_could_be_foreach_context = false;
6840
6841 restore_extension_diagnostics (ext);
6842 if (c_parser_next_token_is_keyword (parser, RID_IN))
6843 {
6844 c_parser_consume_token (parser);
6845 is_foreach_statement = true;
6846 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6847 c_parser_error (parser, "multiple iterating variables in "
6848 "fast enumeration");
6849 }
6850 else
6851 check_for_loop_decls (for_loc, flag_isoc99);
6852 }
6853 else
6854 goto init_expr;
6855 }
6856 else
6857 {
6858 init_expr:
6859 {
6860 struct c_expr ce;
6861 tree init_expression;
6862 ce = c_parser_expression (parser);
6863 init_expression = ce.value;
6864 parser->objc_could_be_foreach_context = false;
6865 if (c_parser_next_token_is_keyword (parser, RID_IN))
6866 {
6867 c_parser_consume_token (parser);
6868 is_foreach_statement = true;
6869 if (! lvalue_p (init_expression))
6870 c_parser_error (parser, "invalid iterating variable in "
6871 "fast enumeration");
6872 object_expression
6873 = c_fully_fold (init_expression, false, NULL);
6874 }
6875 else
6876 {
6877 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6878 init_expression = ce.value;
6879 c_finish_expr_stmt (loc, init_expression);
6880 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6881 "expected %<;%>");
6882 }
6883 }
6884 }
6885 /* Parse the loop condition. In the case of a foreach
6886 statement, there is no loop condition. */
6887 gcc_assert (!parser->objc_could_be_foreach_context);
6888 if (!is_foreach_statement)
6889 {
6890 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6891 {
6892 if (ivdep)
6893 {
6894 c_parser_error (parser, "missing loop condition in loop "
6895 "with %<GCC ivdep%> pragma");
6896 cond = error_mark_node;
6897 }
6898 else if (unroll)
6899 {
6900 c_parser_error (parser, "missing loop condition in loop "
6901 "with %<GCC unroll%> pragma");
6902 cond = error_mark_node;
6903 }
6904 else
6905 {
6906 c_parser_consume_token (parser);
6907 cond = NULL_TREE;
6908 }
6909 }
6910 else
6911 {
6912 cond = c_parser_condition (parser);
6913 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6914 "expected %<;%>");
6915 }
6916 if (ivdep && cond != error_mark_node)
6917 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6918 build_int_cst (integer_type_node,
6919 annot_expr_ivdep_kind),
6920 integer_zero_node);
6921 if (unroll && cond != error_mark_node)
6922 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6923 build_int_cst (integer_type_node,
6924 annot_expr_unroll_kind),
6925 build_int_cst (integer_type_node, unroll));
6926 }
6927 /* Parse the increment expression (the third expression in a
6928 for-statement). In the case of a foreach-statement, this is
6929 the expression that follows the 'in'. */
6930 loc = c_parser_peek_token (parser)->location;
6931 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6932 {
6933 if (is_foreach_statement)
6934 {
6935 c_parser_error (parser,
6936 "missing collection in fast enumeration");
6937 collection_expression = error_mark_node;
6938 }
6939 else
6940 incr = c_process_expr_stmt (loc, NULL_TREE);
6941 }
6942 else
6943 {
6944 if (is_foreach_statement)
6945 collection_expression
6946 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6947 else
6948 {
6949 struct c_expr ce = c_parser_expression (parser);
6950 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6951 incr = c_process_expr_stmt (loc, ce.value);
6952 }
6953 }
6954 parens.skip_until_found_close (parser);
6955 }
6956 save_in_statement = in_statement;
6957 if (is_foreach_statement)
6958 {
6959 in_statement = IN_OBJC_FOREACH;
6960 save_objc_foreach_break_label = objc_foreach_break_label;
6961 save_objc_foreach_continue_label = objc_foreach_continue_label;
6962 objc_foreach_break_label = create_artificial_label (loc);
6963 objc_foreach_continue_label = create_artificial_label (loc);
6964 }
6965 else
6966 in_statement = IN_ITERATION_STMT;
6967
6968 token_indent_info body_tinfo
6969 = get_token_indent_info (c_parser_peek_token (parser));
6970
6971 location_t loc_after_labels;
6972 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6973 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6974
6975 if (is_foreach_statement)
6976 objc_finish_foreach_loop (for_loc, object_expression,
6977 collection_expression, body,
6978 objc_foreach_break_label,
6979 objc_foreach_continue_label);
6980 else
6981 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
6982 body, NULL_TREE));
6983 add_stmt (c_end_compound_stmt (for_loc, block,
6984 flag_isoc99 || c_dialect_objc ()));
6985 c_parser_maybe_reclassify_token (parser);
6986
6987 token_indent_info next_tinfo
6988 = get_token_indent_info (c_parser_peek_token (parser));
6989 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
6990
6991 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6992 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6993 for_tinfo.location, RID_FOR);
6994
6995 in_statement = save_in_statement;
6996 if (is_foreach_statement)
6997 {
6998 objc_foreach_break_label = save_objc_foreach_break_label;
6999 objc_foreach_continue_label = save_objc_foreach_continue_label;
7000 }
7001 }
7002
7003 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7004 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7005 tags allowed.
7006
7007 asm-qualifier:
7008 volatile
7009 inline
7010 goto
7011
7012 asm-qualifier-list:
7013 asm-qualifier-list asm-qualifier
7014 asm-qualifier
7015
7016 asm-statement:
7017 asm asm-qualifier-list[opt] ( asm-argument ) ;
7018
7019 asm-argument:
7020 asm-string-literal
7021 asm-string-literal : asm-operands[opt]
7022 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7023 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7024 : asm-clobbers[opt]
7025 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7026 : asm-goto-operands
7027
7028 The form with asm-goto-operands is valid if and only if the
7029 asm-qualifier-list contains goto, and is the only allowed form in that case.
7030 Duplicate asm-qualifiers are not allowed.
7031
7032 The :: token is considered equivalent to two consecutive : tokens. */
7033
7034 static tree
7035 c_parser_asm_statement (c_parser *parser)
7036 {
7037 tree str, outputs, inputs, clobbers, labels, ret;
7038 bool simple;
7039 location_t asm_loc = c_parser_peek_token (parser)->location;
7040 int section, nsections;
7041
7042 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7043 c_parser_consume_token (parser);
7044
7045 /* Handle the asm-qualifier-list. */
7046 location_t volatile_loc = UNKNOWN_LOCATION;
7047 location_t inline_loc = UNKNOWN_LOCATION;
7048 location_t goto_loc = UNKNOWN_LOCATION;
7049 for (;;)
7050 {
7051 c_token *token = c_parser_peek_token (parser);
7052 location_t loc = token->location;
7053 switch (token->keyword)
7054 {
7055 case RID_VOLATILE:
7056 if (volatile_loc)
7057 {
7058 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7059 inform (volatile_loc, "first seen here");
7060 }
7061 else
7062 volatile_loc = loc;
7063 c_parser_consume_token (parser);
7064 continue;
7065
7066 case RID_INLINE:
7067 if (inline_loc)
7068 {
7069 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7070 inform (inline_loc, "first seen here");
7071 }
7072 else
7073 inline_loc = loc;
7074 c_parser_consume_token (parser);
7075 continue;
7076
7077 case RID_GOTO:
7078 if (goto_loc)
7079 {
7080 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7081 inform (goto_loc, "first seen here");
7082 }
7083 else
7084 goto_loc = loc;
7085 c_parser_consume_token (parser);
7086 continue;
7087
7088 case RID_CONST:
7089 case RID_RESTRICT:
7090 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7091 c_parser_consume_token (parser);
7092 continue;
7093
7094 default:
7095 break;
7096 }
7097 break;
7098 }
7099
7100 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7101 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7102 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7103
7104 ret = NULL;
7105
7106 matching_parens parens;
7107 if (!parens.require_open (parser))
7108 goto error;
7109
7110 str = c_parser_asm_string_literal (parser);
7111 if (str == NULL_TREE)
7112 goto error_close_paren;
7113
7114 simple = true;
7115 outputs = NULL_TREE;
7116 inputs = NULL_TREE;
7117 clobbers = NULL_TREE;
7118 labels = NULL_TREE;
7119
7120 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7121 goto done_asm;
7122
7123 /* Parse each colon-delimited section of operands. */
7124 nsections = 3 + is_goto;
7125 for (section = 0; section < nsections; ++section)
7126 {
7127 if (c_parser_next_token_is (parser, CPP_SCOPE))
7128 {
7129 ++section;
7130 if (section == nsections)
7131 {
7132 c_parser_error (parser, "expected %<)%>");
7133 goto error_close_paren;
7134 }
7135 c_parser_consume_token (parser);
7136 }
7137 else if (!c_parser_require (parser, CPP_COLON,
7138 is_goto
7139 ? G_("expected %<:%>")
7140 : G_("expected %<:%> or %<)%>"),
7141 UNKNOWN_LOCATION, is_goto))
7142 goto error_close_paren;
7143
7144 /* Once past any colon, we're no longer a simple asm. */
7145 simple = false;
7146
7147 if ((!c_parser_next_token_is (parser, CPP_COLON)
7148 && !c_parser_next_token_is (parser, CPP_SCOPE)
7149 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7150 || section == 3)
7151 switch (section)
7152 {
7153 case 0:
7154 outputs = c_parser_asm_operands (parser);
7155 break;
7156 case 1:
7157 inputs = c_parser_asm_operands (parser);
7158 break;
7159 case 2:
7160 clobbers = c_parser_asm_clobbers (parser);
7161 break;
7162 case 3:
7163 labels = c_parser_asm_goto_operands (parser);
7164 break;
7165 default:
7166 gcc_unreachable ();
7167 }
7168
7169 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7170 goto done_asm;
7171 }
7172
7173 done_asm:
7174 if (!parens.require_close (parser))
7175 {
7176 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7177 goto error;
7178 }
7179
7180 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7181 c_parser_skip_to_end_of_block_or_statement (parser);
7182
7183 ret = build_asm_stmt (is_volatile,
7184 build_asm_expr (asm_loc, str, outputs, inputs,
7185 clobbers, labels, simple, is_inline));
7186
7187 error:
7188 return ret;
7189
7190 error_close_paren:
7191 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7192 goto error;
7193 }
7194
7195 /* Parse asm operands, a GNU extension.
7196
7197 asm-operands:
7198 asm-operand
7199 asm-operands , asm-operand
7200
7201 asm-operand:
7202 asm-string-literal ( expression )
7203 [ identifier ] asm-string-literal ( expression )
7204 */
7205
7206 static tree
7207 c_parser_asm_operands (c_parser *parser)
7208 {
7209 tree list = NULL_TREE;
7210 while (true)
7211 {
7212 tree name, str;
7213 struct c_expr expr;
7214 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7215 {
7216 c_parser_consume_token (parser);
7217 if (c_parser_next_token_is (parser, CPP_NAME))
7218 {
7219 tree id = c_parser_peek_token (parser)->value;
7220 c_parser_consume_token (parser);
7221 name = build_string (IDENTIFIER_LENGTH (id),
7222 IDENTIFIER_POINTER (id));
7223 }
7224 else
7225 {
7226 c_parser_error (parser, "expected identifier");
7227 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7228 return NULL_TREE;
7229 }
7230 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7231 "expected %<]%>");
7232 }
7233 else
7234 name = NULL_TREE;
7235 str = c_parser_asm_string_literal (parser);
7236 if (str == NULL_TREE)
7237 return NULL_TREE;
7238 matching_parens parens;
7239 if (!parens.require_open (parser))
7240 return NULL_TREE;
7241 expr = c_parser_expression (parser);
7242 mark_exp_read (expr.value);
7243 if (!parens.require_close (parser))
7244 {
7245 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7246 return NULL_TREE;
7247 }
7248 list = chainon (list, build_tree_list (build_tree_list (name, str),
7249 expr.value));
7250 if (c_parser_next_token_is (parser, CPP_COMMA))
7251 c_parser_consume_token (parser);
7252 else
7253 break;
7254 }
7255 return list;
7256 }
7257
7258 /* Parse asm clobbers, a GNU extension.
7259
7260 asm-clobbers:
7261 asm-string-literal
7262 asm-clobbers , asm-string-literal
7263 */
7264
7265 static tree
7266 c_parser_asm_clobbers (c_parser *parser)
7267 {
7268 tree list = NULL_TREE;
7269 while (true)
7270 {
7271 tree str = c_parser_asm_string_literal (parser);
7272 if (str)
7273 list = tree_cons (NULL_TREE, str, list);
7274 else
7275 return NULL_TREE;
7276 if (c_parser_next_token_is (parser, CPP_COMMA))
7277 c_parser_consume_token (parser);
7278 else
7279 break;
7280 }
7281 return list;
7282 }
7283
7284 /* Parse asm goto labels, a GNU extension.
7285
7286 asm-goto-operands:
7287 identifier
7288 asm-goto-operands , identifier
7289 */
7290
7291 static tree
7292 c_parser_asm_goto_operands (c_parser *parser)
7293 {
7294 tree list = NULL_TREE;
7295 while (true)
7296 {
7297 tree name, label;
7298
7299 if (c_parser_next_token_is (parser, CPP_NAME))
7300 {
7301 c_token *tok = c_parser_peek_token (parser);
7302 name = tok->value;
7303 label = lookup_label_for_goto (tok->location, name);
7304 c_parser_consume_token (parser);
7305 TREE_USED (label) = 1;
7306 }
7307 else
7308 {
7309 c_parser_error (parser, "expected identifier");
7310 return NULL_TREE;
7311 }
7312
7313 name = build_string (IDENTIFIER_LENGTH (name),
7314 IDENTIFIER_POINTER (name));
7315 list = tree_cons (name, label, list);
7316 if (c_parser_next_token_is (parser, CPP_COMMA))
7317 c_parser_consume_token (parser);
7318 else
7319 return nreverse (list);
7320 }
7321 }
7322
7323 /* Parse a possibly concatenated sequence of string literals.
7324 TRANSLATE says whether to translate them to the execution character
7325 set; WIDE_OK says whether any kind of prefixed string literal is
7326 permitted in this context. This code is based on that in
7327 lex_string. */
7328
7329 struct c_expr
7330 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7331 {
7332 struct c_expr ret;
7333 size_t count;
7334 struct obstack str_ob;
7335 struct obstack loc_ob;
7336 cpp_string str, istr, *strs;
7337 c_token *tok;
7338 location_t loc, last_tok_loc;
7339 enum cpp_ttype type;
7340 tree value, string_tree;
7341
7342 tok = c_parser_peek_token (parser);
7343 loc = tok->location;
7344 last_tok_loc = linemap_resolve_location (line_table, loc,
7345 LRK_MACRO_DEFINITION_LOCATION,
7346 NULL);
7347 type = tok->type;
7348 switch (type)
7349 {
7350 case CPP_STRING:
7351 case CPP_WSTRING:
7352 case CPP_STRING16:
7353 case CPP_STRING32:
7354 case CPP_UTF8STRING:
7355 string_tree = tok->value;
7356 break;
7357
7358 default:
7359 c_parser_error (parser, "expected string literal");
7360 ret.set_error ();
7361 ret.value = NULL_TREE;
7362 ret.original_code = ERROR_MARK;
7363 ret.original_type = NULL_TREE;
7364 return ret;
7365 }
7366
7367 /* Try to avoid the overhead of creating and destroying an obstack
7368 for the common case of just one string. */
7369 switch (c_parser_peek_2nd_token (parser)->type)
7370 {
7371 default:
7372 c_parser_consume_token (parser);
7373 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7374 str.len = TREE_STRING_LENGTH (string_tree);
7375 count = 1;
7376 strs = &str;
7377 break;
7378
7379 case CPP_STRING:
7380 case CPP_WSTRING:
7381 case CPP_STRING16:
7382 case CPP_STRING32:
7383 case CPP_UTF8STRING:
7384 gcc_obstack_init (&str_ob);
7385 gcc_obstack_init (&loc_ob);
7386 count = 0;
7387 do
7388 {
7389 c_parser_consume_token (parser);
7390 count++;
7391 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7392 str.len = TREE_STRING_LENGTH (string_tree);
7393 if (type != tok->type)
7394 {
7395 if (type == CPP_STRING)
7396 type = tok->type;
7397 else if (tok->type != CPP_STRING)
7398 error ("unsupported non-standard concatenation "
7399 "of string literals");
7400 }
7401 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7402 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7403 tok = c_parser_peek_token (parser);
7404 string_tree = tok->value;
7405 last_tok_loc
7406 = linemap_resolve_location (line_table, tok->location,
7407 LRK_MACRO_DEFINITION_LOCATION, NULL);
7408 }
7409 while (tok->type == CPP_STRING
7410 || tok->type == CPP_WSTRING
7411 || tok->type == CPP_STRING16
7412 || tok->type == CPP_STRING32
7413 || tok->type == CPP_UTF8STRING);
7414 strs = (cpp_string *) obstack_finish (&str_ob);
7415 }
7416
7417 if (count > 1 && !in_system_header_at (input_location))
7418 warning (OPT_Wtraditional,
7419 "traditional C rejects string constant concatenation");
7420
7421 if ((type == CPP_STRING || wide_ok)
7422 && ((translate
7423 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7424 (parse_in, strs, count, &istr, type)))
7425 {
7426 value = build_string (istr.len, (const char *) istr.text);
7427 free (CONST_CAST (unsigned char *, istr.text));
7428 if (count > 1)
7429 {
7430 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7431 gcc_assert (g_string_concat_db);
7432 g_string_concat_db->record_string_concatenation (count, locs);
7433 }
7434 }
7435 else
7436 {
7437 if (type != CPP_STRING && !wide_ok)
7438 {
7439 error_at (loc, "a wide string is invalid in this context");
7440 type = CPP_STRING;
7441 }
7442 /* Callers cannot generally handle error_mark_node in this
7443 context, so return the empty string instead. An error has
7444 been issued, either above or from cpp_interpret_string. */
7445 switch (type)
7446 {
7447 default:
7448 case CPP_STRING:
7449 case CPP_UTF8STRING:
7450 value = build_string (1, "");
7451 break;
7452 case CPP_STRING16:
7453 value = build_string (TYPE_PRECISION (char16_type_node)
7454 / TYPE_PRECISION (char_type_node),
7455 "\0"); /* char16_t is 16 bits */
7456 break;
7457 case CPP_STRING32:
7458 value = build_string (TYPE_PRECISION (char32_type_node)
7459 / TYPE_PRECISION (char_type_node),
7460 "\0\0\0"); /* char32_t is 32 bits */
7461 break;
7462 case CPP_WSTRING:
7463 value = build_string (TYPE_PRECISION (wchar_type_node)
7464 / TYPE_PRECISION (char_type_node),
7465 "\0\0\0"); /* widest supported wchar_t
7466 is 32 bits */
7467 break;
7468 }
7469 }
7470
7471 switch (type)
7472 {
7473 default:
7474 case CPP_STRING:
7475 case CPP_UTF8STRING:
7476 TREE_TYPE (value) = char_array_type_node;
7477 break;
7478 case CPP_STRING16:
7479 TREE_TYPE (value) = char16_array_type_node;
7480 break;
7481 case CPP_STRING32:
7482 TREE_TYPE (value) = char32_array_type_node;
7483 break;
7484 case CPP_WSTRING:
7485 TREE_TYPE (value) = wchar_array_type_node;
7486 }
7487 value = fix_string_type (value);
7488
7489 if (count > 1)
7490 {
7491 obstack_free (&str_ob, 0);
7492 obstack_free (&loc_ob, 0);
7493 }
7494
7495 ret.value = value;
7496 ret.original_code = STRING_CST;
7497 ret.original_type = NULL_TREE;
7498 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7499 parser->seen_string_literal = true;
7500 return ret;
7501 }
7502
7503 /* Parse an expression other than a compound expression; that is, an
7504 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7505 AFTER is not NULL then it is an Objective-C message expression which
7506 is the primary-expression starting the expression as an initializer.
7507
7508 assignment-expression:
7509 conditional-expression
7510 unary-expression assignment-operator assignment-expression
7511
7512 assignment-operator: one of
7513 = *= /= %= += -= <<= >>= &= ^= |=
7514
7515 In GNU C we accept any conditional expression on the LHS and
7516 diagnose the invalid lvalue rather than producing a syntax
7517 error. */
7518
7519 static struct c_expr
7520 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7521 tree omp_atomic_lhs)
7522 {
7523 struct c_expr lhs, rhs, ret;
7524 enum tree_code code;
7525 location_t op_location, exp_location;
7526 bool save_in_omp_for = c_in_omp_for;
7527 c_in_omp_for = false;
7528 gcc_assert (!after || c_dialect_objc ());
7529 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7530 op_location = c_parser_peek_token (parser)->location;
7531 switch (c_parser_peek_token (parser)->type)
7532 {
7533 case CPP_EQ:
7534 code = NOP_EXPR;
7535 break;
7536 case CPP_MULT_EQ:
7537 code = MULT_EXPR;
7538 break;
7539 case CPP_DIV_EQ:
7540 code = TRUNC_DIV_EXPR;
7541 break;
7542 case CPP_MOD_EQ:
7543 code = TRUNC_MOD_EXPR;
7544 break;
7545 case CPP_PLUS_EQ:
7546 code = PLUS_EXPR;
7547 break;
7548 case CPP_MINUS_EQ:
7549 code = MINUS_EXPR;
7550 break;
7551 case CPP_LSHIFT_EQ:
7552 code = LSHIFT_EXPR;
7553 break;
7554 case CPP_RSHIFT_EQ:
7555 code = RSHIFT_EXPR;
7556 break;
7557 case CPP_AND_EQ:
7558 code = BIT_AND_EXPR;
7559 break;
7560 case CPP_XOR_EQ:
7561 code = BIT_XOR_EXPR;
7562 break;
7563 case CPP_OR_EQ:
7564 code = BIT_IOR_EXPR;
7565 break;
7566 default:
7567 c_in_omp_for = save_in_omp_for;
7568 return lhs;
7569 }
7570 c_parser_consume_token (parser);
7571 exp_location = c_parser_peek_token (parser)->location;
7572 rhs = c_parser_expr_no_commas (parser, NULL);
7573 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7574
7575 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7576 code, exp_location, rhs.value,
7577 rhs.original_type);
7578 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7579 if (code == NOP_EXPR)
7580 ret.original_code = MODIFY_EXPR;
7581 else
7582 {
7583 suppress_warning (ret.value, OPT_Wparentheses);
7584 ret.original_code = ERROR_MARK;
7585 }
7586 ret.original_type = NULL;
7587 c_in_omp_for = save_in_omp_for;
7588 return ret;
7589 }
7590
7591 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7592 AFTER is not NULL then it is an Objective-C message expression which is
7593 the primary-expression starting the expression as an initializer.
7594
7595 conditional-expression:
7596 logical-OR-expression
7597 logical-OR-expression ? expression : conditional-expression
7598
7599 GNU extensions:
7600
7601 conditional-expression:
7602 logical-OR-expression ? : conditional-expression
7603 */
7604
7605 static struct c_expr
7606 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7607 tree omp_atomic_lhs)
7608 {
7609 struct c_expr cond, exp1, exp2, ret;
7610 location_t start, cond_loc, colon_loc;
7611
7612 gcc_assert (!after || c_dialect_objc ());
7613
7614 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7615
7616 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7617 return cond;
7618 if (cond.value != error_mark_node)
7619 start = cond.get_start ();
7620 else
7621 start = UNKNOWN_LOCATION;
7622 cond_loc = c_parser_peek_token (parser)->location;
7623 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7624 c_parser_consume_token (parser);
7625 if (c_parser_next_token_is (parser, CPP_COLON))
7626 {
7627 tree eptype = NULL_TREE;
7628
7629 location_t middle_loc = c_parser_peek_token (parser)->location;
7630 pedwarn (middle_loc, OPT_Wpedantic,
7631 "ISO C forbids omitting the middle term of a %<?:%> expression");
7632 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7633 {
7634 eptype = TREE_TYPE (cond.value);
7635 cond.value = TREE_OPERAND (cond.value, 0);
7636 }
7637 tree e = cond.value;
7638 while (TREE_CODE (e) == COMPOUND_EXPR)
7639 e = TREE_OPERAND (e, 1);
7640 warn_for_omitted_condop (middle_loc, e);
7641 /* Make sure first operand is calculated only once. */
7642 exp1.value = save_expr (default_conversion (cond.value));
7643 if (eptype)
7644 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7645 exp1.original_type = NULL;
7646 exp1.src_range = cond.src_range;
7647 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7648 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7649 }
7650 else
7651 {
7652 cond.value
7653 = c_objc_common_truthvalue_conversion
7654 (cond_loc, default_conversion (cond.value));
7655 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7656 exp1 = c_parser_expression_conv (parser);
7657 mark_exp_read (exp1.value);
7658 c_inhibit_evaluation_warnings +=
7659 ((cond.value == truthvalue_true_node)
7660 - (cond.value == truthvalue_false_node));
7661 }
7662
7663 colon_loc = c_parser_peek_token (parser)->location;
7664 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7665 {
7666 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7667 ret.set_error ();
7668 ret.original_code = ERROR_MARK;
7669 ret.original_type = NULL;
7670 return ret;
7671 }
7672 {
7673 location_t exp2_loc = c_parser_peek_token (parser)->location;
7674 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7675 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7676 }
7677 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7678 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7679 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7680 if (UNLIKELY (omp_atomic_lhs != NULL)
7681 && (TREE_CODE (cond.value) == GT_EXPR
7682 || TREE_CODE (cond.value) == LT_EXPR
7683 || TREE_CODE (cond.value) == EQ_EXPR)
7684 && c_tree_equal (exp2.value, omp_atomic_lhs)
7685 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
7686 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
7687 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
7688 cond.value, exp1.value, exp2.value);
7689 else
7690 ret.value
7691 = build_conditional_expr (colon_loc, cond.value,
7692 cond.original_code == C_MAYBE_CONST_EXPR,
7693 exp1.value, exp1.original_type, loc1,
7694 exp2.value, exp2.original_type, loc2);
7695 ret.original_code = ERROR_MARK;
7696 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7697 ret.original_type = NULL;
7698 else
7699 {
7700 tree t1, t2;
7701
7702 /* If both sides are enum type, the default conversion will have
7703 made the type of the result be an integer type. We want to
7704 remember the enum types we started with. */
7705 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7706 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7707 ret.original_type = ((t1 != error_mark_node
7708 && t2 != error_mark_node
7709 && (TYPE_MAIN_VARIANT (t1)
7710 == TYPE_MAIN_VARIANT (t2)))
7711 ? t1
7712 : NULL);
7713 }
7714 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7715 return ret;
7716 }
7717
7718 /* Parse a binary expression; that is, a logical-OR-expression (C90
7719 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7720 NULL then it is an Objective-C message expression which is the
7721 primary-expression starting the expression as an initializer.
7722
7723 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7724 when it should be the unfolded lhs. In a valid OpenMP source,
7725 one of the operands of the toplevel binary expression must be equal
7726 to it. In that case, just return a build2 created binary operation
7727 rather than result of parser_build_binary_op.
7728
7729 multiplicative-expression:
7730 cast-expression
7731 multiplicative-expression * cast-expression
7732 multiplicative-expression / cast-expression
7733 multiplicative-expression % cast-expression
7734
7735 additive-expression:
7736 multiplicative-expression
7737 additive-expression + multiplicative-expression
7738 additive-expression - multiplicative-expression
7739
7740 shift-expression:
7741 additive-expression
7742 shift-expression << additive-expression
7743 shift-expression >> additive-expression
7744
7745 relational-expression:
7746 shift-expression
7747 relational-expression < shift-expression
7748 relational-expression > shift-expression
7749 relational-expression <= shift-expression
7750 relational-expression >= shift-expression
7751
7752 equality-expression:
7753 relational-expression
7754 equality-expression == relational-expression
7755 equality-expression != relational-expression
7756
7757 AND-expression:
7758 equality-expression
7759 AND-expression & equality-expression
7760
7761 exclusive-OR-expression:
7762 AND-expression
7763 exclusive-OR-expression ^ AND-expression
7764
7765 inclusive-OR-expression:
7766 exclusive-OR-expression
7767 inclusive-OR-expression | exclusive-OR-expression
7768
7769 logical-AND-expression:
7770 inclusive-OR-expression
7771 logical-AND-expression && inclusive-OR-expression
7772
7773 logical-OR-expression:
7774 logical-AND-expression
7775 logical-OR-expression || logical-AND-expression
7776 */
7777
7778 static struct c_expr
7779 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7780 tree omp_atomic_lhs)
7781 {
7782 /* A binary expression is parsed using operator-precedence parsing,
7783 with the operands being cast expressions. All the binary
7784 operators are left-associative. Thus a binary expression is of
7785 form:
7786
7787 E0 op1 E1 op2 E2 ...
7788
7789 which we represent on a stack. On the stack, the precedence
7790 levels are strictly increasing. When a new operator is
7791 encountered of higher precedence than that at the top of the
7792 stack, it is pushed; its LHS is the top expression, and its RHS
7793 is everything parsed until it is popped. When a new operator is
7794 encountered with precedence less than or equal to that at the top
7795 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7796 by the result of the operation until the operator at the top of
7797 the stack has lower precedence than the new operator or there is
7798 only one element on the stack; then the top expression is the LHS
7799 of the new operator. In the case of logical AND and OR
7800 expressions, we also need to adjust c_inhibit_evaluation_warnings
7801 as appropriate when the operators are pushed and popped. */
7802
7803 struct {
7804 /* The expression at this stack level. */
7805 struct c_expr expr;
7806 /* The precedence of the operator on its left, PREC_NONE at the
7807 bottom of the stack. */
7808 enum c_parser_prec prec;
7809 /* The operation on its left. */
7810 enum tree_code op;
7811 /* The source location of this operation. */
7812 location_t loc;
7813 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7814 tree sizeof_arg;
7815 } stack[NUM_PRECS];
7816 int sp;
7817 /* Location of the binary operator. */
7818 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7819 #define POP \
7820 do { \
7821 switch (stack[sp].op) \
7822 { \
7823 case TRUTH_ANDIF_EXPR: \
7824 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7825 == truthvalue_false_node); \
7826 break; \
7827 case TRUTH_ORIF_EXPR: \
7828 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7829 == truthvalue_true_node); \
7830 break; \
7831 case TRUNC_DIV_EXPR: \
7832 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7833 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7834 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7835 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7836 { \
7837 tree type0 = stack[sp - 1].sizeof_arg; \
7838 tree type1 = stack[sp].sizeof_arg; \
7839 tree first_arg = type0; \
7840 if (!TYPE_P (type0)) \
7841 type0 = TREE_TYPE (type0); \
7842 if (!TYPE_P (type1)) \
7843 type1 = TREE_TYPE (type1); \
7844 if (POINTER_TYPE_P (type0) \
7845 && comptypes (TREE_TYPE (type0), type1) \
7846 && !(TREE_CODE (first_arg) == PARM_DECL \
7847 && C_ARRAY_PARAMETER (first_arg) \
7848 && warn_sizeof_array_argument)) \
7849 { \
7850 auto_diagnostic_group d; \
7851 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7852 "division %<sizeof (%T) / sizeof (%T)%> " \
7853 "does not compute the number of array " \
7854 "elements", \
7855 type0, type1)) \
7856 if (DECL_P (first_arg)) \
7857 inform (DECL_SOURCE_LOCATION (first_arg), \
7858 "first %<sizeof%> operand was declared here"); \
7859 } \
7860 else if (TREE_CODE (type0) == ARRAY_TYPE \
7861 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7862 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7863 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7864 stack[sp].sizeof_arg, type1); \
7865 } \
7866 break; \
7867 default: \
7868 break; \
7869 } \
7870 stack[sp - 1].expr \
7871 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7872 stack[sp - 1].expr, true, true); \
7873 stack[sp].expr \
7874 = convert_lvalue_to_rvalue (stack[sp].loc, \
7875 stack[sp].expr, true, true); \
7876 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
7877 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
7878 && ((1 << stack[sp].prec) \
7879 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
7880 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
7881 | (1 << PREC_ADD) | (1 << PREC_MULT) \
7882 | (1 << PREC_EQ)))) \
7883 || ((c_parser_next_token_is (parser, CPP_QUERY) \
7884 || (omp_atomic_lhs == void_list_node \
7885 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
7886 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7887 && stack[sp].op != TRUNC_MOD_EXPR \
7888 && stack[sp].op != GE_EXPR \
7889 && stack[sp].op != LE_EXPR \
7890 && stack[sp].op != NE_EXPR \
7891 && stack[0].expr.value != error_mark_node \
7892 && stack[1].expr.value != error_mark_node \
7893 && (omp_atomic_lhs == void_list_node \
7894 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7895 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
7896 || (stack[sp].op == EQ_EXPR \
7897 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
7898 { \
7899 tree t = make_node (stack[1].op); \
7900 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7901 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7902 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7903 stack[0].expr.value = t; \
7904 } \
7905 else \
7906 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7907 stack[sp].op, \
7908 stack[sp - 1].expr, \
7909 stack[sp].expr); \
7910 sp--; \
7911 } while (0)
7912 gcc_assert (!after || c_dialect_objc ());
7913 stack[0].loc = c_parser_peek_token (parser)->location;
7914 stack[0].expr = c_parser_cast_expression (parser, after);
7915 stack[0].prec = PREC_NONE;
7916 stack[0].sizeof_arg = c_last_sizeof_arg;
7917 sp = 0;
7918 while (true)
7919 {
7920 enum c_parser_prec oprec;
7921 enum tree_code ocode;
7922 source_range src_range;
7923 if (parser->error)
7924 goto out;
7925 switch (c_parser_peek_token (parser)->type)
7926 {
7927 case CPP_MULT:
7928 oprec = PREC_MULT;
7929 ocode = MULT_EXPR;
7930 break;
7931 case CPP_DIV:
7932 oprec = PREC_MULT;
7933 ocode = TRUNC_DIV_EXPR;
7934 break;
7935 case CPP_MOD:
7936 oprec = PREC_MULT;
7937 ocode = TRUNC_MOD_EXPR;
7938 break;
7939 case CPP_PLUS:
7940 oprec = PREC_ADD;
7941 ocode = PLUS_EXPR;
7942 break;
7943 case CPP_MINUS:
7944 oprec = PREC_ADD;
7945 ocode = MINUS_EXPR;
7946 break;
7947 case CPP_LSHIFT:
7948 oprec = PREC_SHIFT;
7949 ocode = LSHIFT_EXPR;
7950 break;
7951 case CPP_RSHIFT:
7952 oprec = PREC_SHIFT;
7953 ocode = RSHIFT_EXPR;
7954 break;
7955 case CPP_LESS:
7956 oprec = PREC_REL;
7957 ocode = LT_EXPR;
7958 break;
7959 case CPP_GREATER:
7960 oprec = PREC_REL;
7961 ocode = GT_EXPR;
7962 break;
7963 case CPP_LESS_EQ:
7964 oprec = PREC_REL;
7965 ocode = LE_EXPR;
7966 break;
7967 case CPP_GREATER_EQ:
7968 oprec = PREC_REL;
7969 ocode = GE_EXPR;
7970 break;
7971 case CPP_EQ_EQ:
7972 oprec = PREC_EQ;
7973 ocode = EQ_EXPR;
7974 break;
7975 case CPP_NOT_EQ:
7976 oprec = PREC_EQ;
7977 ocode = NE_EXPR;
7978 break;
7979 case CPP_AND:
7980 oprec = PREC_BITAND;
7981 ocode = BIT_AND_EXPR;
7982 break;
7983 case CPP_XOR:
7984 oprec = PREC_BITXOR;
7985 ocode = BIT_XOR_EXPR;
7986 break;
7987 case CPP_OR:
7988 oprec = PREC_BITOR;
7989 ocode = BIT_IOR_EXPR;
7990 break;
7991 case CPP_AND_AND:
7992 oprec = PREC_LOGAND;
7993 ocode = TRUTH_ANDIF_EXPR;
7994 break;
7995 case CPP_OR_OR:
7996 oprec = PREC_LOGOR;
7997 ocode = TRUTH_ORIF_EXPR;
7998 break;
7999 default:
8000 /* Not a binary operator, so end of the binary
8001 expression. */
8002 goto out;
8003 }
8004 binary_loc = c_parser_peek_token (parser)->location;
8005 while (oprec <= stack[sp].prec)
8006 POP;
8007 c_parser_consume_token (parser);
8008 switch (ocode)
8009 {
8010 case TRUTH_ANDIF_EXPR:
8011 src_range = stack[sp].expr.src_range;
8012 stack[sp].expr
8013 = convert_lvalue_to_rvalue (stack[sp].loc,
8014 stack[sp].expr, true, true);
8015 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8016 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8017 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8018 == truthvalue_false_node);
8019 set_c_expr_source_range (&stack[sp].expr, src_range);
8020 break;
8021 case TRUTH_ORIF_EXPR:
8022 src_range = stack[sp].expr.src_range;
8023 stack[sp].expr
8024 = convert_lvalue_to_rvalue (stack[sp].loc,
8025 stack[sp].expr, true, true);
8026 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8027 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8028 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8029 == truthvalue_true_node);
8030 set_c_expr_source_range (&stack[sp].expr, src_range);
8031 break;
8032 default:
8033 break;
8034 }
8035 sp++;
8036 stack[sp].loc = binary_loc;
8037 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8038 stack[sp].prec = oprec;
8039 stack[sp].op = ocode;
8040 stack[sp].sizeof_arg = c_last_sizeof_arg;
8041 }
8042 out:
8043 while (sp > 0)
8044 POP;
8045 return stack[0].expr;
8046 #undef POP
8047 }
8048
8049 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8050 is not NULL then it is an Objective-C message expression which is the
8051 primary-expression starting the expression as an initializer.
8052
8053 cast-expression:
8054 unary-expression
8055 ( type-name ) unary-expression
8056 */
8057
8058 static struct c_expr
8059 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8060 {
8061 location_t cast_loc = c_parser_peek_token (parser)->location;
8062 gcc_assert (!after || c_dialect_objc ());
8063 if (after)
8064 return c_parser_postfix_expression_after_primary (parser,
8065 cast_loc, *after);
8066 /* If the expression begins with a parenthesized type name, it may
8067 be either a cast or a compound literal; we need to see whether
8068 the next character is '{' to tell the difference. If not, it is
8069 an unary expression. Full detection of unknown typenames here
8070 would require a 3-token lookahead. */
8071 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8072 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8073 {
8074 struct c_type_name *type_name;
8075 struct c_expr ret;
8076 struct c_expr expr;
8077 matching_parens parens;
8078 parens.consume_open (parser);
8079 type_name = c_parser_type_name (parser, true);
8080 parens.skip_until_found_close (parser);
8081 if (type_name == NULL)
8082 {
8083 ret.set_error ();
8084 ret.original_code = ERROR_MARK;
8085 ret.original_type = NULL;
8086 return ret;
8087 }
8088
8089 /* Save casted types in the function's used types hash table. */
8090 used_types_insert (type_name->specs->type);
8091
8092 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8093 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8094 cast_loc);
8095 if (type_name->specs->alignas_p)
8096 error_at (type_name->specs->locations[cdw_alignas],
8097 "alignment specified for type name in cast");
8098 {
8099 location_t expr_loc = c_parser_peek_token (parser)->location;
8100 expr = c_parser_cast_expression (parser, NULL);
8101 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8102 }
8103 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8104 if (ret.value && expr.value)
8105 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8106 ret.original_code = ERROR_MARK;
8107 ret.original_type = NULL;
8108 return ret;
8109 }
8110 else
8111 return c_parser_unary_expression (parser);
8112 }
8113
8114 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8115
8116 unary-expression:
8117 postfix-expression
8118 ++ unary-expression
8119 -- unary-expression
8120 unary-operator cast-expression
8121 sizeof unary-expression
8122 sizeof ( type-name )
8123
8124 unary-operator: one of
8125 & * + - ~ !
8126
8127 GNU extensions:
8128
8129 unary-expression:
8130 __alignof__ unary-expression
8131 __alignof__ ( type-name )
8132 && identifier
8133
8134 (C11 permits _Alignof with type names only.)
8135
8136 unary-operator: one of
8137 __extension__ __real__ __imag__
8138
8139 Transactional Memory:
8140
8141 unary-expression:
8142 transaction-expression
8143
8144 In addition, the GNU syntax treats ++ and -- as unary operators, so
8145 they may be applied to cast expressions with errors for non-lvalues
8146 given later. */
8147
8148 static struct c_expr
8149 c_parser_unary_expression (c_parser *parser)
8150 {
8151 int ext;
8152 struct c_expr ret, op;
8153 location_t op_loc = c_parser_peek_token (parser)->location;
8154 location_t exp_loc;
8155 location_t finish;
8156 ret.original_code = ERROR_MARK;
8157 ret.original_type = NULL;
8158 switch (c_parser_peek_token (parser)->type)
8159 {
8160 case CPP_PLUS_PLUS:
8161 c_parser_consume_token (parser);
8162 exp_loc = c_parser_peek_token (parser)->location;
8163 op = c_parser_cast_expression (parser, NULL);
8164
8165 op = default_function_array_read_conversion (exp_loc, op);
8166 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8167 case CPP_MINUS_MINUS:
8168 c_parser_consume_token (parser);
8169 exp_loc = c_parser_peek_token (parser)->location;
8170 op = c_parser_cast_expression (parser, NULL);
8171
8172 op = default_function_array_read_conversion (exp_loc, op);
8173 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8174 case CPP_AND:
8175 c_parser_consume_token (parser);
8176 op = c_parser_cast_expression (parser, NULL);
8177 mark_exp_read (op.value);
8178 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8179 case CPP_MULT:
8180 {
8181 c_parser_consume_token (parser);
8182 exp_loc = c_parser_peek_token (parser)->location;
8183 op = c_parser_cast_expression (parser, NULL);
8184 finish = op.get_finish ();
8185 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8186 location_t combined_loc = make_location (op_loc, op_loc, finish);
8187 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8188 ret.src_range.m_start = op_loc;
8189 ret.src_range.m_finish = finish;
8190 return ret;
8191 }
8192 case CPP_PLUS:
8193 if (!c_dialect_objc () && !in_system_header_at (input_location))
8194 warning_at (op_loc,
8195 OPT_Wtraditional,
8196 "traditional C rejects the unary plus operator");
8197 c_parser_consume_token (parser);
8198 exp_loc = c_parser_peek_token (parser)->location;
8199 op = c_parser_cast_expression (parser, NULL);
8200 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8201 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8202 case CPP_MINUS:
8203 c_parser_consume_token (parser);
8204 exp_loc = c_parser_peek_token (parser)->location;
8205 op = c_parser_cast_expression (parser, NULL);
8206 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8207 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8208 case CPP_COMPL:
8209 c_parser_consume_token (parser);
8210 exp_loc = c_parser_peek_token (parser)->location;
8211 op = c_parser_cast_expression (parser, NULL);
8212 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8213 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8214 case CPP_NOT:
8215 c_parser_consume_token (parser);
8216 exp_loc = c_parser_peek_token (parser)->location;
8217 op = c_parser_cast_expression (parser, NULL);
8218 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8219 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8220 case CPP_AND_AND:
8221 /* Refer to the address of a label as a pointer. */
8222 c_parser_consume_token (parser);
8223 if (c_parser_next_token_is (parser, CPP_NAME))
8224 {
8225 ret.value = finish_label_address_expr
8226 (c_parser_peek_token (parser)->value, op_loc);
8227 set_c_expr_source_range (&ret, op_loc,
8228 c_parser_peek_token (parser)->get_finish ());
8229 c_parser_consume_token (parser);
8230 }
8231 else
8232 {
8233 c_parser_error (parser, "expected identifier");
8234 ret.set_error ();
8235 }
8236 return ret;
8237 case CPP_KEYWORD:
8238 switch (c_parser_peek_token (parser)->keyword)
8239 {
8240 case RID_SIZEOF:
8241 return c_parser_sizeof_expression (parser);
8242 case RID_ALIGNOF:
8243 return c_parser_alignof_expression (parser);
8244 case RID_BUILTIN_HAS_ATTRIBUTE:
8245 return c_parser_has_attribute_expression (parser);
8246 case RID_EXTENSION:
8247 c_parser_consume_token (parser);
8248 ext = disable_extension_diagnostics ();
8249 ret = c_parser_cast_expression (parser, NULL);
8250 restore_extension_diagnostics (ext);
8251 return ret;
8252 case RID_REALPART:
8253 c_parser_consume_token (parser);
8254 exp_loc = c_parser_peek_token (parser)->location;
8255 op = c_parser_cast_expression (parser, NULL);
8256 op = default_function_array_conversion (exp_loc, op);
8257 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8258 case RID_IMAGPART:
8259 c_parser_consume_token (parser);
8260 exp_loc = c_parser_peek_token (parser)->location;
8261 op = c_parser_cast_expression (parser, NULL);
8262 op = default_function_array_conversion (exp_loc, op);
8263 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8264 case RID_TRANSACTION_ATOMIC:
8265 case RID_TRANSACTION_RELAXED:
8266 return c_parser_transaction_expression (parser,
8267 c_parser_peek_token (parser)->keyword);
8268 default:
8269 return c_parser_postfix_expression (parser);
8270 }
8271 default:
8272 return c_parser_postfix_expression (parser);
8273 }
8274 }
8275
8276 /* Parse a sizeof expression. */
8277
8278 static struct c_expr
8279 c_parser_sizeof_expression (c_parser *parser)
8280 {
8281 struct c_expr expr;
8282 struct c_expr result;
8283 location_t expr_loc;
8284 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8285
8286 location_t start;
8287 location_t finish = UNKNOWN_LOCATION;
8288
8289 start = c_parser_peek_token (parser)->location;
8290
8291 c_parser_consume_token (parser);
8292 c_inhibit_evaluation_warnings++;
8293 in_sizeof++;
8294 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8295 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8296 {
8297 /* Either sizeof ( type-name ) or sizeof unary-expression
8298 starting with a compound literal. */
8299 struct c_type_name *type_name;
8300 matching_parens parens;
8301 parens.consume_open (parser);
8302 expr_loc = c_parser_peek_token (parser)->location;
8303 type_name = c_parser_type_name (parser, true);
8304 parens.skip_until_found_close (parser);
8305 finish = parser->tokens_buf[0].location;
8306 if (type_name == NULL)
8307 {
8308 struct c_expr ret;
8309 c_inhibit_evaluation_warnings--;
8310 in_sizeof--;
8311 ret.set_error ();
8312 ret.original_code = ERROR_MARK;
8313 ret.original_type = NULL;
8314 return ret;
8315 }
8316 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8317 {
8318 expr = c_parser_postfix_expression_after_paren_type (parser,
8319 type_name,
8320 expr_loc);
8321 finish = expr.get_finish ();
8322 goto sizeof_expr;
8323 }
8324 /* sizeof ( type-name ). */
8325 if (type_name->specs->alignas_p)
8326 error_at (type_name->specs->locations[cdw_alignas],
8327 "alignment specified for type name in %<sizeof%>");
8328 c_inhibit_evaluation_warnings--;
8329 in_sizeof--;
8330 result = c_expr_sizeof_type (expr_loc, type_name);
8331 }
8332 else
8333 {
8334 expr_loc = c_parser_peek_token (parser)->location;
8335 expr = c_parser_unary_expression (parser);
8336 finish = expr.get_finish ();
8337 sizeof_expr:
8338 c_inhibit_evaluation_warnings--;
8339 in_sizeof--;
8340 mark_exp_read (expr.value);
8341 if (TREE_CODE (expr.value) == COMPONENT_REF
8342 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8343 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8344 result = c_expr_sizeof_expr (expr_loc, expr);
8345 }
8346 if (finish == UNKNOWN_LOCATION)
8347 finish = start;
8348 set_c_expr_source_range (&result, start, finish);
8349 return result;
8350 }
8351
8352 /* Parse an alignof expression. */
8353
8354 static struct c_expr
8355 c_parser_alignof_expression (c_parser *parser)
8356 {
8357 struct c_expr expr;
8358 location_t start_loc = c_parser_peek_token (parser)->location;
8359 location_t end_loc;
8360 tree alignof_spelling = c_parser_peek_token (parser)->value;
8361 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8362 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8363 "_Alignof") == 0;
8364 /* A diagnostic is not required for the use of this identifier in
8365 the implementation namespace; only diagnose it for the C11
8366 spelling because of existing code using the other spellings. */
8367 if (is_c11_alignof)
8368 {
8369 if (flag_isoc99)
8370 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8371 alignof_spelling);
8372 else
8373 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8374 alignof_spelling);
8375 }
8376 c_parser_consume_token (parser);
8377 c_inhibit_evaluation_warnings++;
8378 in_alignof++;
8379 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8380 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8381 {
8382 /* Either __alignof__ ( type-name ) or __alignof__
8383 unary-expression starting with a compound literal. */
8384 location_t loc;
8385 struct c_type_name *type_name;
8386 struct c_expr ret;
8387 matching_parens parens;
8388 parens.consume_open (parser);
8389 loc = c_parser_peek_token (parser)->location;
8390 type_name = c_parser_type_name (parser, true);
8391 end_loc = c_parser_peek_token (parser)->location;
8392 parens.skip_until_found_close (parser);
8393 if (type_name == NULL)
8394 {
8395 struct c_expr ret;
8396 c_inhibit_evaluation_warnings--;
8397 in_alignof--;
8398 ret.set_error ();
8399 ret.original_code = ERROR_MARK;
8400 ret.original_type = NULL;
8401 return ret;
8402 }
8403 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8404 {
8405 expr = c_parser_postfix_expression_after_paren_type (parser,
8406 type_name,
8407 loc);
8408 goto alignof_expr;
8409 }
8410 /* alignof ( type-name ). */
8411 if (type_name->specs->alignas_p)
8412 error_at (type_name->specs->locations[cdw_alignas],
8413 "alignment specified for type name in %qE",
8414 alignof_spelling);
8415 c_inhibit_evaluation_warnings--;
8416 in_alignof--;
8417 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8418 NULL, NULL),
8419 false, is_c11_alignof, 1);
8420 ret.original_code = ERROR_MARK;
8421 ret.original_type = NULL;
8422 set_c_expr_source_range (&ret, start_loc, end_loc);
8423 return ret;
8424 }
8425 else
8426 {
8427 struct c_expr ret;
8428 expr = c_parser_unary_expression (parser);
8429 end_loc = expr.src_range.m_finish;
8430 alignof_expr:
8431 mark_exp_read (expr.value);
8432 c_inhibit_evaluation_warnings--;
8433 in_alignof--;
8434 if (is_c11_alignof)
8435 pedwarn (start_loc,
8436 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8437 alignof_spelling);
8438 ret.value = c_alignof_expr (start_loc, expr.value);
8439 ret.original_code = ERROR_MARK;
8440 ret.original_type = NULL;
8441 set_c_expr_source_range (&ret, start_loc, end_loc);
8442 return ret;
8443 }
8444 }
8445
8446 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8447 expression. */
8448
8449 static struct c_expr
8450 c_parser_has_attribute_expression (c_parser *parser)
8451 {
8452 gcc_assert (c_parser_next_token_is_keyword (parser,
8453 RID_BUILTIN_HAS_ATTRIBUTE));
8454 location_t start = c_parser_peek_token (parser)->location;
8455 c_parser_consume_token (parser);
8456
8457 c_inhibit_evaluation_warnings++;
8458
8459 matching_parens parens;
8460 if (!parens.require_open (parser))
8461 {
8462 c_inhibit_evaluation_warnings--;
8463 in_typeof--;
8464
8465 struct c_expr result;
8466 result.set_error ();
8467 result.original_code = ERROR_MARK;
8468 result.original_type = NULL;
8469 return result;
8470 }
8471
8472 /* Treat the type argument the same way as in typeof for the purposes
8473 of warnings. FIXME: Generalize this so the warning refers to
8474 __builtin_has_attribute rather than typeof. */
8475 in_typeof++;
8476
8477 /* The first operand: one of DECL, EXPR, or TYPE. */
8478 tree oper = NULL_TREE;
8479 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8480 {
8481 struct c_type_name *tname = c_parser_type_name (parser);
8482 in_typeof--;
8483 if (tname)
8484 {
8485 oper = groktypename (tname, NULL, NULL);
8486 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8487 }
8488 }
8489 else
8490 {
8491 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8492 c_inhibit_evaluation_warnings--;
8493 in_typeof--;
8494 if (cexpr.value != error_mark_node)
8495 {
8496 mark_exp_read (cexpr.value);
8497 oper = cexpr.value;
8498 tree etype = TREE_TYPE (oper);
8499 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8500 /* This is returned with the type so that when the type is
8501 evaluated, this can be evaluated. */
8502 if (was_vm)
8503 oper = c_fully_fold (oper, false, NULL);
8504 pop_maybe_used (was_vm);
8505 }
8506 }
8507
8508 struct c_expr result;
8509 result.original_code = ERROR_MARK;
8510 result.original_type = NULL;
8511
8512 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8513 {
8514 /* Consume the closing parenthesis if that's the next token
8515 in the likely case the built-in was invoked with fewer
8516 than two arguments. */
8517 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8518 c_parser_consume_token (parser);
8519 c_inhibit_evaluation_warnings--;
8520 result.set_error ();
8521 return result;
8522 }
8523
8524 bool save_translate_strings_p = parser->translate_strings_p;
8525
8526 location_t atloc = c_parser_peek_token (parser)->location;
8527 /* Parse a single attribute. Require no leading comma and do not
8528 allow empty attributes. */
8529 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8530
8531 parser->translate_strings_p = save_translate_strings_p;
8532
8533 location_t finish = c_parser_peek_token (parser)->location;
8534 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8535 c_parser_consume_token (parser);
8536 else
8537 {
8538 c_parser_error (parser, "expected identifier");
8539 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8540
8541 result.set_error ();
8542 return result;
8543 }
8544
8545 if (!attr)
8546 {
8547 error_at (atloc, "expected identifier");
8548 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8549 "expected %<)%>");
8550 result.set_error ();
8551 return result;
8552 }
8553
8554 result.original_code = INTEGER_CST;
8555 result.original_type = boolean_type_node;
8556
8557 if (has_attribute (atloc, oper, attr, default_conversion))
8558 result.value = boolean_true_node;
8559 else
8560 result.value = boolean_false_node;
8561
8562 set_c_expr_source_range (&result, start, finish);
8563 return result;
8564 }
8565
8566 /* Helper function to read arguments of builtins which are interfaces
8567 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8568 others. The name of the builtin is passed using BNAME parameter.
8569 Function returns true if there were no errors while parsing and
8570 stores the arguments in CEXPR_LIST. If it returns true,
8571 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8572 parenthesis. */
8573 static bool
8574 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8575 vec<c_expr_t, va_gc> **ret_cexpr_list,
8576 bool choose_expr_p,
8577 location_t *out_close_paren_loc)
8578 {
8579 location_t loc = c_parser_peek_token (parser)->location;
8580 vec<c_expr_t, va_gc> *cexpr_list;
8581 c_expr_t expr;
8582 bool saved_force_folding_builtin_constant_p;
8583
8584 *ret_cexpr_list = NULL;
8585 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8586 {
8587 error_at (loc, "cannot take address of %qs", bname);
8588 return false;
8589 }
8590
8591 c_parser_consume_token (parser);
8592
8593 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8594 {
8595 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8596 c_parser_consume_token (parser);
8597 return true;
8598 }
8599
8600 saved_force_folding_builtin_constant_p
8601 = force_folding_builtin_constant_p;
8602 force_folding_builtin_constant_p |= choose_expr_p;
8603 expr = c_parser_expr_no_commas (parser, NULL);
8604 force_folding_builtin_constant_p
8605 = saved_force_folding_builtin_constant_p;
8606 vec_alloc (cexpr_list, 1);
8607 vec_safe_push (cexpr_list, expr);
8608 while (c_parser_next_token_is (parser, CPP_COMMA))
8609 {
8610 c_parser_consume_token (parser);
8611 expr = c_parser_expr_no_commas (parser, NULL);
8612 vec_safe_push (cexpr_list, expr);
8613 }
8614
8615 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8616 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8617 return false;
8618
8619 *ret_cexpr_list = cexpr_list;
8620 return true;
8621 }
8622
8623 /* This represents a single generic-association. */
8624
8625 struct c_generic_association
8626 {
8627 /* The location of the starting token of the type. */
8628 location_t type_location;
8629 /* The association's type, or NULL_TREE for 'default'. */
8630 tree type;
8631 /* The association's expression. */
8632 struct c_expr expression;
8633 };
8634
8635 /* Parse a generic-selection. (C11 6.5.1.1).
8636
8637 generic-selection:
8638 _Generic ( assignment-expression , generic-assoc-list )
8639
8640 generic-assoc-list:
8641 generic-association
8642 generic-assoc-list , generic-association
8643
8644 generic-association:
8645 type-name : assignment-expression
8646 default : assignment-expression
8647 */
8648
8649 static struct c_expr
8650 c_parser_generic_selection (c_parser *parser)
8651 {
8652 struct c_expr selector, error_expr;
8653 tree selector_type;
8654 struct c_generic_association matched_assoc;
8655 int match_found = -1;
8656 location_t generic_loc, selector_loc;
8657
8658 error_expr.original_code = ERROR_MARK;
8659 error_expr.original_type = NULL;
8660 error_expr.set_error ();
8661 matched_assoc.type_location = UNKNOWN_LOCATION;
8662 matched_assoc.type = NULL_TREE;
8663 matched_assoc.expression = error_expr;
8664
8665 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8666 generic_loc = c_parser_peek_token (parser)->location;
8667 c_parser_consume_token (parser);
8668 if (flag_isoc99)
8669 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8670 "ISO C99 does not support %<_Generic%>");
8671 else
8672 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8673 "ISO C90 does not support %<_Generic%>");
8674
8675 matching_parens parens;
8676 if (!parens.require_open (parser))
8677 return error_expr;
8678
8679 c_inhibit_evaluation_warnings++;
8680 selector_loc = c_parser_peek_token (parser)->location;
8681 selector = c_parser_expr_no_commas (parser, NULL);
8682 selector = default_function_array_conversion (selector_loc, selector);
8683 c_inhibit_evaluation_warnings--;
8684
8685 if (selector.value == error_mark_node)
8686 {
8687 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8688 return selector;
8689 }
8690 mark_exp_read (selector.value);
8691 selector_type = TREE_TYPE (selector.value);
8692 /* In ISO C terms, rvalues (including the controlling expression of
8693 _Generic) do not have qualified types. */
8694 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8695 selector_type = TYPE_MAIN_VARIANT (selector_type);
8696 /* In ISO C terms, _Noreturn is not part of the type of expressions
8697 such as &abort, but in GCC it is represented internally as a type
8698 qualifier. */
8699 if (FUNCTION_POINTER_TYPE_P (selector_type)
8700 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8701 selector_type
8702 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8703
8704 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8705 {
8706 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8707 return error_expr;
8708 }
8709
8710 auto_vec<c_generic_association> associations;
8711 while (1)
8712 {
8713 struct c_generic_association assoc, *iter;
8714 unsigned int ix;
8715 c_token *token = c_parser_peek_token (parser);
8716
8717 assoc.type_location = token->location;
8718 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8719 {
8720 c_parser_consume_token (parser);
8721 assoc.type = NULL_TREE;
8722 }
8723 else
8724 {
8725 struct c_type_name *type_name;
8726
8727 type_name = c_parser_type_name (parser);
8728 if (type_name == NULL)
8729 {
8730 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8731 return error_expr;
8732 }
8733 assoc.type = groktypename (type_name, NULL, NULL);
8734 if (assoc.type == error_mark_node)
8735 {
8736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8737 return error_expr;
8738 }
8739
8740 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8741 error_at (assoc.type_location,
8742 "%<_Generic%> association has function type");
8743 else if (!COMPLETE_TYPE_P (assoc.type))
8744 error_at (assoc.type_location,
8745 "%<_Generic%> association has incomplete type");
8746
8747 if (variably_modified_type_p (assoc.type, NULL_TREE))
8748 error_at (assoc.type_location,
8749 "%<_Generic%> association has "
8750 "variable length type");
8751 }
8752
8753 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8754 {
8755 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8756 return error_expr;
8757 }
8758
8759 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8760 if (assoc.expression.value == error_mark_node)
8761 {
8762 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8763 return error_expr;
8764 }
8765
8766 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8767 {
8768 if (assoc.type == NULL_TREE)
8769 {
8770 if (iter->type == NULL_TREE)
8771 {
8772 error_at (assoc.type_location,
8773 "duplicate %<default%> case in %<_Generic%>");
8774 inform (iter->type_location, "original %<default%> is here");
8775 }
8776 }
8777 else if (iter->type != NULL_TREE)
8778 {
8779 if (comptypes (assoc.type, iter->type))
8780 {
8781 error_at (assoc.type_location,
8782 "%<_Generic%> specifies two compatible types");
8783 inform (iter->type_location, "compatible type is here");
8784 }
8785 }
8786 }
8787
8788 if (assoc.type == NULL_TREE)
8789 {
8790 if (match_found < 0)
8791 {
8792 matched_assoc = assoc;
8793 match_found = associations.length ();
8794 }
8795 }
8796 else if (comptypes (assoc.type, selector_type))
8797 {
8798 if (match_found < 0 || matched_assoc.type == NULL_TREE)
8799 {
8800 matched_assoc = assoc;
8801 match_found = associations.length ();
8802 }
8803 else
8804 {
8805 error_at (assoc.type_location,
8806 "%<_Generic%> selector matches multiple associations");
8807 inform (matched_assoc.type_location,
8808 "other match is here");
8809 }
8810 }
8811
8812 associations.safe_push (assoc);
8813
8814 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8815 break;
8816 c_parser_consume_token (parser);
8817 }
8818
8819 unsigned int ix;
8820 struct c_generic_association *iter;
8821 FOR_EACH_VEC_ELT (associations, ix, iter)
8822 if (ix != (unsigned) match_found)
8823 mark_exp_read (iter->expression.value);
8824
8825 if (!parens.require_close (parser))
8826 {
8827 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8828 return error_expr;
8829 }
8830
8831 if (match_found < 0)
8832 {
8833 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8834 "compatible with any association",
8835 selector_type);
8836 return error_expr;
8837 }
8838
8839 return matched_assoc.expression;
8840 }
8841
8842 /* Check the validity of a function pointer argument *EXPR (argument
8843 position POS) to __builtin_tgmath. Return the number of function
8844 arguments if possibly valid; return 0 having reported an error if
8845 not valid. */
8846
8847 static unsigned int
8848 check_tgmath_function (c_expr *expr, unsigned int pos)
8849 {
8850 tree type = TREE_TYPE (expr->value);
8851 if (!FUNCTION_POINTER_TYPE_P (type))
8852 {
8853 error_at (expr->get_location (),
8854 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8855 pos);
8856 return 0;
8857 }
8858 type = TREE_TYPE (type);
8859 if (!prototype_p (type))
8860 {
8861 error_at (expr->get_location (),
8862 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8863 return 0;
8864 }
8865 if (stdarg_p (type))
8866 {
8867 error_at (expr->get_location (),
8868 "argument %u of %<__builtin_tgmath%> has variable arguments",
8869 pos);
8870 return 0;
8871 }
8872 unsigned int nargs = 0;
8873 function_args_iterator iter;
8874 tree t;
8875 FOREACH_FUNCTION_ARGS (type, t, iter)
8876 {
8877 if (t == void_type_node)
8878 break;
8879 nargs++;
8880 }
8881 if (nargs == 0)
8882 {
8883 error_at (expr->get_location (),
8884 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8885 return 0;
8886 }
8887 return nargs;
8888 }
8889
8890 /* Ways in which a parameter or return value of a type-generic macro
8891 may vary between the different functions the macro may call. */
8892 enum tgmath_parm_kind
8893 {
8894 tgmath_fixed, tgmath_real, tgmath_complex
8895 };
8896
8897 /* Helper function for c_parser_postfix_expression. Parse predefined
8898 identifiers. */
8899
8900 static struct c_expr
8901 c_parser_predefined_identifier (c_parser *parser)
8902 {
8903 location_t loc = c_parser_peek_token (parser)->location;
8904 switch (c_parser_peek_token (parser)->keyword)
8905 {
8906 case RID_FUNCTION_NAME:
8907 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8908 "identifier", "__FUNCTION__");
8909 break;
8910 case RID_PRETTY_FUNCTION_NAME:
8911 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8912 "identifier", "__PRETTY_FUNCTION__");
8913 break;
8914 case RID_C99_FUNCTION_NAME:
8915 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8916 "%<__func__%> predefined identifier");
8917 break;
8918 default:
8919 gcc_unreachable ();
8920 }
8921
8922 struct c_expr expr;
8923 expr.original_code = ERROR_MARK;
8924 expr.original_type = NULL;
8925 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8926 c_parser_peek_token (parser)->value);
8927 set_c_expr_source_range (&expr, loc, loc);
8928 c_parser_consume_token (parser);
8929 return expr;
8930 }
8931
8932 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8933 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8934 call c_parser_postfix_expression_after_paren_type on encountering them.
8935
8936 postfix-expression:
8937 primary-expression
8938 postfix-expression [ expression ]
8939 postfix-expression ( argument-expression-list[opt] )
8940 postfix-expression . identifier
8941 postfix-expression -> identifier
8942 postfix-expression ++
8943 postfix-expression --
8944 ( type-name ) { initializer-list }
8945 ( type-name ) { initializer-list , }
8946
8947 argument-expression-list:
8948 argument-expression
8949 argument-expression-list , argument-expression
8950
8951 primary-expression:
8952 identifier
8953 constant
8954 string-literal
8955 ( expression )
8956 generic-selection
8957
8958 GNU extensions:
8959
8960 primary-expression:
8961 __func__
8962 (treated as a keyword in GNU C)
8963 __FUNCTION__
8964 __PRETTY_FUNCTION__
8965 ( compound-statement )
8966 __builtin_va_arg ( assignment-expression , type-name )
8967 __builtin_offsetof ( type-name , offsetof-member-designator )
8968 __builtin_choose_expr ( assignment-expression ,
8969 assignment-expression ,
8970 assignment-expression )
8971 __builtin_types_compatible_p ( type-name , type-name )
8972 __builtin_tgmath ( expr-list )
8973 __builtin_complex ( assignment-expression , assignment-expression )
8974 __builtin_shuffle ( assignment-expression , assignment-expression )
8975 __builtin_shuffle ( assignment-expression ,
8976 assignment-expression ,
8977 assignment-expression, )
8978 __builtin_convertvector ( assignment-expression , type-name )
8979 __builtin_assoc_barrier ( assignment-expression )
8980
8981 offsetof-member-designator:
8982 identifier
8983 offsetof-member-designator . identifier
8984 offsetof-member-designator [ expression ]
8985
8986 Objective-C:
8987
8988 primary-expression:
8989 [ objc-receiver objc-message-args ]
8990 @selector ( objc-selector-arg )
8991 @protocol ( identifier )
8992 @encode ( type-name )
8993 objc-string-literal
8994 Classname . identifier
8995 */
8996
8997 static struct c_expr
8998 c_parser_postfix_expression (c_parser *parser)
8999 {
9000 struct c_expr expr, e1;
9001 struct c_type_name *t1, *t2;
9002 location_t loc = c_parser_peek_token (parser)->location;
9003 source_range tok_range = c_parser_peek_token (parser)->get_range ();
9004 expr.original_code = ERROR_MARK;
9005 expr.original_type = NULL;
9006 switch (c_parser_peek_token (parser)->type)
9007 {
9008 case CPP_NUMBER:
9009 expr.value = c_parser_peek_token (parser)->value;
9010 set_c_expr_source_range (&expr, tok_range);
9011 loc = c_parser_peek_token (parser)->location;
9012 c_parser_consume_token (parser);
9013 if (TREE_CODE (expr.value) == FIXED_CST
9014 && !targetm.fixed_point_supported_p ())
9015 {
9016 error_at (loc, "fixed-point types not supported for this target");
9017 expr.set_error ();
9018 }
9019 break;
9020 case CPP_CHAR:
9021 case CPP_CHAR16:
9022 case CPP_CHAR32:
9023 case CPP_UTF8CHAR:
9024 case CPP_WCHAR:
9025 expr.value = c_parser_peek_token (parser)->value;
9026 /* For the purpose of warning when a pointer is compared with
9027 a zero character constant. */
9028 expr.original_type = char_type_node;
9029 set_c_expr_source_range (&expr, tok_range);
9030 c_parser_consume_token (parser);
9031 break;
9032 case CPP_STRING:
9033 case CPP_STRING16:
9034 case CPP_STRING32:
9035 case CPP_WSTRING:
9036 case CPP_UTF8STRING:
9037 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9038 true);
9039 break;
9040 case CPP_OBJC_STRING:
9041 gcc_assert (c_dialect_objc ());
9042 expr.value
9043 = objc_build_string_object (c_parser_peek_token (parser)->value);
9044 set_c_expr_source_range (&expr, tok_range);
9045 c_parser_consume_token (parser);
9046 break;
9047 case CPP_NAME:
9048 switch (c_parser_peek_token (parser)->id_kind)
9049 {
9050 case C_ID_ID:
9051 {
9052 tree id = c_parser_peek_token (parser)->value;
9053 c_parser_consume_token (parser);
9054 expr.value = build_external_ref (loc, id,
9055 (c_parser_peek_token (parser)->type
9056 == CPP_OPEN_PAREN),
9057 &expr.original_type);
9058 set_c_expr_source_range (&expr, tok_range);
9059 break;
9060 }
9061 case C_ID_CLASSNAME:
9062 {
9063 /* Here we parse the Objective-C 2.0 Class.name dot
9064 syntax. */
9065 tree class_name = c_parser_peek_token (parser)->value;
9066 tree component;
9067 c_parser_consume_token (parser);
9068 gcc_assert (c_dialect_objc ());
9069 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9070 {
9071 expr.set_error ();
9072 break;
9073 }
9074 if (c_parser_next_token_is_not (parser, CPP_NAME))
9075 {
9076 c_parser_error (parser, "expected identifier");
9077 expr.set_error ();
9078 break;
9079 }
9080 c_token *component_tok = c_parser_peek_token (parser);
9081 component = component_tok->value;
9082 location_t end_loc = component_tok->get_finish ();
9083 c_parser_consume_token (parser);
9084 expr.value = objc_build_class_component_ref (class_name,
9085 component);
9086 set_c_expr_source_range (&expr, loc, end_loc);
9087 break;
9088 }
9089 default:
9090 c_parser_error (parser, "expected expression");
9091 expr.set_error ();
9092 break;
9093 }
9094 break;
9095 case CPP_OPEN_PAREN:
9096 /* A parenthesized expression, statement expression or compound
9097 literal. */
9098 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9099 {
9100 /* A statement expression. */
9101 tree stmt;
9102 location_t brace_loc;
9103 c_parser_consume_token (parser);
9104 brace_loc = c_parser_peek_token (parser)->location;
9105 c_parser_consume_token (parser);
9106 /* If we've not yet started the current function's statement list,
9107 or we're in the parameter scope of an old-style function
9108 declaration, statement expressions are not allowed. */
9109 if (!building_stmt_list_p () || old_style_parameter_scope ())
9110 {
9111 error_at (loc, "braced-group within expression allowed "
9112 "only inside a function");
9113 parser->error = true;
9114 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9115 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9116 expr.set_error ();
9117 break;
9118 }
9119 stmt = c_begin_stmt_expr ();
9120 c_parser_compound_statement_nostart (parser);
9121 location_t close_loc = c_parser_peek_token (parser)->location;
9122 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9123 "expected %<)%>");
9124 pedwarn (loc, OPT_Wpedantic,
9125 "ISO C forbids braced-groups within expressions");
9126 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9127 set_c_expr_source_range (&expr, loc, close_loc);
9128 mark_exp_read (expr.value);
9129 }
9130 else
9131 {
9132 /* A parenthesized expression. */
9133 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9134 c_parser_consume_token (parser);
9135 expr = c_parser_expression (parser);
9136 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9137 suppress_warning (expr.value, OPT_Wparentheses);
9138 if (expr.original_code != C_MAYBE_CONST_EXPR
9139 && expr.original_code != SIZEOF_EXPR)
9140 expr.original_code = ERROR_MARK;
9141 /* Remember that we saw ( ) around the sizeof. */
9142 if (expr.original_code == SIZEOF_EXPR)
9143 expr.original_code = PAREN_SIZEOF_EXPR;
9144 /* Don't change EXPR.ORIGINAL_TYPE. */
9145 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9146 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9147 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9148 "expected %<)%>", loc_open_paren);
9149 }
9150 break;
9151 case CPP_KEYWORD:
9152 switch (c_parser_peek_token (parser)->keyword)
9153 {
9154 case RID_FUNCTION_NAME:
9155 case RID_PRETTY_FUNCTION_NAME:
9156 case RID_C99_FUNCTION_NAME:
9157 expr = c_parser_predefined_identifier (parser);
9158 break;
9159 case RID_VA_ARG:
9160 {
9161 location_t start_loc = loc;
9162 c_parser_consume_token (parser);
9163 matching_parens parens;
9164 if (!parens.require_open (parser))
9165 {
9166 expr.set_error ();
9167 break;
9168 }
9169 e1 = c_parser_expr_no_commas (parser, NULL);
9170 mark_exp_read (e1.value);
9171 e1.value = c_fully_fold (e1.value, false, NULL);
9172 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9173 {
9174 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9175 expr.set_error ();
9176 break;
9177 }
9178 loc = c_parser_peek_token (parser)->location;
9179 t1 = c_parser_type_name (parser);
9180 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9181 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9182 "expected %<)%>");
9183 if (t1 == NULL)
9184 {
9185 expr.set_error ();
9186 }
9187 else
9188 {
9189 tree type_expr = NULL_TREE;
9190 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9191 groktypename (t1, &type_expr, NULL));
9192 if (type_expr)
9193 {
9194 expr.value = build2 (C_MAYBE_CONST_EXPR,
9195 TREE_TYPE (expr.value), type_expr,
9196 expr.value);
9197 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9198 }
9199 set_c_expr_source_range (&expr, start_loc, end_loc);
9200 }
9201 }
9202 break;
9203 case RID_OFFSETOF:
9204 {
9205 c_parser_consume_token (parser);
9206 matching_parens parens;
9207 if (!parens.require_open (parser))
9208 {
9209 expr.set_error ();
9210 break;
9211 }
9212 t1 = c_parser_type_name (parser);
9213 if (t1 == NULL)
9214 parser->error = true;
9215 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9216 gcc_assert (parser->error);
9217 if (parser->error)
9218 {
9219 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9220 expr.set_error ();
9221 break;
9222 }
9223 tree type = groktypename (t1, NULL, NULL);
9224 tree offsetof_ref;
9225 if (type == error_mark_node)
9226 offsetof_ref = error_mark_node;
9227 else
9228 {
9229 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9230 SET_EXPR_LOCATION (offsetof_ref, loc);
9231 }
9232 /* Parse the second argument to __builtin_offsetof. We
9233 must have one identifier, and beyond that we want to
9234 accept sub structure and sub array references. */
9235 if (c_parser_next_token_is (parser, CPP_NAME))
9236 {
9237 c_token *comp_tok = c_parser_peek_token (parser);
9238 offsetof_ref
9239 = build_component_ref (loc, offsetof_ref, comp_tok->value,
9240 comp_tok->location, UNKNOWN_LOCATION);
9241 c_parser_consume_token (parser);
9242 while (c_parser_next_token_is (parser, CPP_DOT)
9243 || c_parser_next_token_is (parser,
9244 CPP_OPEN_SQUARE)
9245 || c_parser_next_token_is (parser,
9246 CPP_DEREF))
9247 {
9248 if (c_parser_next_token_is (parser, CPP_DEREF))
9249 {
9250 loc = c_parser_peek_token (parser)->location;
9251 offsetof_ref = build_array_ref (loc,
9252 offsetof_ref,
9253 integer_zero_node);
9254 goto do_dot;
9255 }
9256 else if (c_parser_next_token_is (parser, CPP_DOT))
9257 {
9258 do_dot:
9259 c_parser_consume_token (parser);
9260 if (c_parser_next_token_is_not (parser,
9261 CPP_NAME))
9262 {
9263 c_parser_error (parser, "expected identifier");
9264 break;
9265 }
9266 c_token *comp_tok = c_parser_peek_token (parser);
9267 offsetof_ref
9268 = build_component_ref (loc, offsetof_ref,
9269 comp_tok->value,
9270 comp_tok->location,
9271 UNKNOWN_LOCATION);
9272 c_parser_consume_token (parser);
9273 }
9274 else
9275 {
9276 struct c_expr ce;
9277 tree idx;
9278 loc = c_parser_peek_token (parser)->location;
9279 c_parser_consume_token (parser);
9280 ce = c_parser_expression (parser);
9281 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9282 idx = ce.value;
9283 idx = c_fully_fold (idx, false, NULL);
9284 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9285 "expected %<]%>");
9286 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9287 }
9288 }
9289 }
9290 else
9291 c_parser_error (parser, "expected identifier");
9292 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9293 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9294 "expected %<)%>");
9295 expr.value = fold_offsetof (offsetof_ref);
9296 set_c_expr_source_range (&expr, loc, end_loc);
9297 }
9298 break;
9299 case RID_CHOOSE_EXPR:
9300 {
9301 vec<c_expr_t, va_gc> *cexpr_list;
9302 c_expr_t *e1_p, *e2_p, *e3_p;
9303 tree c;
9304 location_t close_paren_loc;
9305
9306 c_parser_consume_token (parser);
9307 if (!c_parser_get_builtin_args (parser,
9308 "__builtin_choose_expr",
9309 &cexpr_list, true,
9310 &close_paren_loc))
9311 {
9312 expr.set_error ();
9313 break;
9314 }
9315
9316 if (vec_safe_length (cexpr_list) != 3)
9317 {
9318 error_at (loc, "wrong number of arguments to "
9319 "%<__builtin_choose_expr%>");
9320 expr.set_error ();
9321 break;
9322 }
9323
9324 e1_p = &(*cexpr_list)[0];
9325 e2_p = &(*cexpr_list)[1];
9326 e3_p = &(*cexpr_list)[2];
9327
9328 c = e1_p->value;
9329 mark_exp_read (e2_p->value);
9330 mark_exp_read (e3_p->value);
9331 if (TREE_CODE (c) != INTEGER_CST
9332 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9333 error_at (loc,
9334 "first argument to %<__builtin_choose_expr%> not"
9335 " a constant");
9336 constant_expression_warning (c);
9337 expr = integer_zerop (c) ? *e3_p : *e2_p;
9338 set_c_expr_source_range (&expr, loc, close_paren_loc);
9339 break;
9340 }
9341 case RID_TYPES_COMPATIBLE_P:
9342 {
9343 c_parser_consume_token (parser);
9344 matching_parens parens;
9345 if (!parens.require_open (parser))
9346 {
9347 expr.set_error ();
9348 break;
9349 }
9350 t1 = c_parser_type_name (parser);
9351 if (t1 == NULL)
9352 {
9353 expr.set_error ();
9354 break;
9355 }
9356 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9357 {
9358 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9359 expr.set_error ();
9360 break;
9361 }
9362 t2 = c_parser_type_name (parser);
9363 if (t2 == NULL)
9364 {
9365 expr.set_error ();
9366 break;
9367 }
9368 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9369 parens.skip_until_found_close (parser);
9370 tree e1, e2;
9371 e1 = groktypename (t1, NULL, NULL);
9372 e2 = groktypename (t2, NULL, NULL);
9373 if (e1 == error_mark_node || e2 == error_mark_node)
9374 {
9375 expr.set_error ();
9376 break;
9377 }
9378
9379 e1 = TYPE_MAIN_VARIANT (e1);
9380 e2 = TYPE_MAIN_VARIANT (e2);
9381
9382 expr.value
9383 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9384 set_c_expr_source_range (&expr, loc, close_paren_loc);
9385 }
9386 break;
9387 case RID_BUILTIN_TGMATH:
9388 {
9389 vec<c_expr_t, va_gc> *cexpr_list;
9390 location_t close_paren_loc;
9391
9392 c_parser_consume_token (parser);
9393 if (!c_parser_get_builtin_args (parser,
9394 "__builtin_tgmath",
9395 &cexpr_list, false,
9396 &close_paren_loc))
9397 {
9398 expr.set_error ();
9399 break;
9400 }
9401
9402 if (vec_safe_length (cexpr_list) < 3)
9403 {
9404 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9405 expr.set_error ();
9406 break;
9407 }
9408
9409 unsigned int i;
9410 c_expr_t *p;
9411 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9412 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9413 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9414 if (nargs == 0)
9415 {
9416 expr.set_error ();
9417 break;
9418 }
9419 if (vec_safe_length (cexpr_list) < nargs)
9420 {
9421 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9422 expr.set_error ();
9423 break;
9424 }
9425 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9426 if (num_functions < 2)
9427 {
9428 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9429 expr.set_error ();
9430 break;
9431 }
9432
9433 /* The first NUM_FUNCTIONS expressions are the function
9434 pointers. The remaining NARGS expressions are the
9435 arguments that are to be passed to one of those
9436 functions, chosen following <tgmath.h> rules. */
9437 for (unsigned int j = 1; j < num_functions; j++)
9438 {
9439 unsigned int this_nargs
9440 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9441 if (this_nargs == 0)
9442 {
9443 expr.set_error ();
9444 goto out;
9445 }
9446 if (this_nargs != nargs)
9447 {
9448 error_at ((*cexpr_list)[j].get_location (),
9449 "argument %u of %<__builtin_tgmath%> has "
9450 "wrong number of arguments", j + 1);
9451 expr.set_error ();
9452 goto out;
9453 }
9454 }
9455
9456 /* The functions all have the same number of arguments.
9457 Determine whether arguments and return types vary in
9458 ways permitted for <tgmath.h> functions. */
9459 /* The first entry in each of these vectors is for the
9460 return type, subsequent entries for parameter
9461 types. */
9462 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9463 auto_vec<tree> parm_first (nargs + 1);
9464 auto_vec<bool> parm_complex (nargs + 1);
9465 auto_vec<bool> parm_varies (nargs + 1);
9466 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9467 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9468 parm_first.quick_push (first_ret);
9469 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9470 parm_varies.quick_push (false);
9471 function_args_iterator iter;
9472 tree t;
9473 unsigned int argpos;
9474 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9475 {
9476 if (t == void_type_node)
9477 break;
9478 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9479 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9480 parm_varies.quick_push (false);
9481 }
9482 for (unsigned int j = 1; j < num_functions; j++)
9483 {
9484 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9485 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9486 if (ret != parm_first[0])
9487 {
9488 parm_varies[0] = true;
9489 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9490 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9491 {
9492 error_at ((*cexpr_list)[0].get_location (),
9493 "invalid type-generic return type for "
9494 "argument %u of %<__builtin_tgmath%>",
9495 1);
9496 expr.set_error ();
9497 goto out;
9498 }
9499 if (!SCALAR_FLOAT_TYPE_P (ret)
9500 && !COMPLEX_FLOAT_TYPE_P (ret))
9501 {
9502 error_at ((*cexpr_list)[j].get_location (),
9503 "invalid type-generic return type for "
9504 "argument %u of %<__builtin_tgmath%>",
9505 j + 1);
9506 expr.set_error ();
9507 goto out;
9508 }
9509 }
9510 if (TREE_CODE (ret) == COMPLEX_TYPE)
9511 parm_complex[0] = true;
9512 argpos = 1;
9513 FOREACH_FUNCTION_ARGS (type, t, iter)
9514 {
9515 if (t == void_type_node)
9516 break;
9517 t = TYPE_MAIN_VARIANT (t);
9518 if (t != parm_first[argpos])
9519 {
9520 parm_varies[argpos] = true;
9521 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9522 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9523 {
9524 error_at ((*cexpr_list)[0].get_location (),
9525 "invalid type-generic type for "
9526 "argument %u of argument %u of "
9527 "%<__builtin_tgmath%>", argpos, 1);
9528 expr.set_error ();
9529 goto out;
9530 }
9531 if (!SCALAR_FLOAT_TYPE_P (t)
9532 && !COMPLEX_FLOAT_TYPE_P (t))
9533 {
9534 error_at ((*cexpr_list)[j].get_location (),
9535 "invalid type-generic type for "
9536 "argument %u of argument %u of "
9537 "%<__builtin_tgmath%>", argpos, j + 1);
9538 expr.set_error ();
9539 goto out;
9540 }
9541 }
9542 if (TREE_CODE (t) == COMPLEX_TYPE)
9543 parm_complex[argpos] = true;
9544 argpos++;
9545 }
9546 }
9547 enum tgmath_parm_kind max_variation = tgmath_fixed;
9548 for (unsigned int j = 0; j <= nargs; j++)
9549 {
9550 enum tgmath_parm_kind this_kind;
9551 if (parm_varies[j])
9552 {
9553 if (parm_complex[j])
9554 max_variation = this_kind = tgmath_complex;
9555 else
9556 {
9557 this_kind = tgmath_real;
9558 if (max_variation != tgmath_complex)
9559 max_variation = tgmath_real;
9560 }
9561 }
9562 else
9563 this_kind = tgmath_fixed;
9564 parm_kind.quick_push (this_kind);
9565 }
9566 if (max_variation == tgmath_fixed)
9567 {
9568 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9569 "all have the same type");
9570 expr.set_error ();
9571 break;
9572 }
9573
9574 /* Identify a parameter (not the return type) that varies,
9575 including with complex types if any variation includes
9576 complex types; there must be at least one such
9577 parameter. */
9578 unsigned int tgarg = 0;
9579 for (unsigned int j = 1; j <= nargs; j++)
9580 if (parm_kind[j] == max_variation)
9581 {
9582 tgarg = j;
9583 break;
9584 }
9585 if (tgarg == 0)
9586 {
9587 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9588 "lack type-generic parameter");
9589 expr.set_error ();
9590 break;
9591 }
9592
9593 /* Determine the type of the relevant parameter for each
9594 function. */
9595 auto_vec<tree> tg_type (num_functions);
9596 for (unsigned int j = 0; j < num_functions; j++)
9597 {
9598 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9599 argpos = 1;
9600 FOREACH_FUNCTION_ARGS (type, t, iter)
9601 {
9602 if (argpos == tgarg)
9603 {
9604 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9605 break;
9606 }
9607 argpos++;
9608 }
9609 }
9610
9611 /* Verify that the corresponding types are different for
9612 all the listed functions. Also determine whether all
9613 the types are complex, whether all the types are
9614 standard or binary, and whether all the types are
9615 decimal. */
9616 bool all_complex = true;
9617 bool all_binary = true;
9618 bool all_decimal = true;
9619 hash_set<tree> tg_types;
9620 FOR_EACH_VEC_ELT (tg_type, i, t)
9621 {
9622 if (TREE_CODE (t) == COMPLEX_TYPE)
9623 all_decimal = false;
9624 else
9625 {
9626 all_complex = false;
9627 if (DECIMAL_FLOAT_TYPE_P (t))
9628 all_binary = false;
9629 else
9630 all_decimal = false;
9631 }
9632 if (tg_types.add (t))
9633 {
9634 error_at ((*cexpr_list)[i].get_location (),
9635 "duplicate type-generic parameter type for "
9636 "function argument %u of %<__builtin_tgmath%>",
9637 i + 1);
9638 expr.set_error ();
9639 goto out;
9640 }
9641 }
9642
9643 /* Verify that other parameters and the return type whose
9644 types vary have their types varying in the correct
9645 way. */
9646 for (unsigned int j = 0; j < num_functions; j++)
9647 {
9648 tree exp_type = tg_type[j];
9649 tree exp_real_type = exp_type;
9650 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9651 exp_real_type = TREE_TYPE (exp_type);
9652 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9653 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9654 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9655 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9656 {
9657 error_at ((*cexpr_list)[j].get_location (),
9658 "bad return type for function argument %u "
9659 "of %<__builtin_tgmath%>", j + 1);
9660 expr.set_error ();
9661 goto out;
9662 }
9663 argpos = 1;
9664 FOREACH_FUNCTION_ARGS (type, t, iter)
9665 {
9666 if (t == void_type_node)
9667 break;
9668 t = TYPE_MAIN_VARIANT (t);
9669 if ((parm_kind[argpos] == tgmath_complex
9670 && t != exp_type)
9671 || (parm_kind[argpos] == tgmath_real
9672 && t != exp_real_type))
9673 {
9674 error_at ((*cexpr_list)[j].get_location (),
9675 "bad type for argument %u of "
9676 "function argument %u of "
9677 "%<__builtin_tgmath%>", argpos, j + 1);
9678 expr.set_error ();
9679 goto out;
9680 }
9681 argpos++;
9682 }
9683 }
9684
9685 /* The functions listed are a valid set of functions for a
9686 <tgmath.h> macro to select between. Identify the
9687 matching function, if any. First, the argument types
9688 must be combined following <tgmath.h> rules. Integer
9689 types are treated as _Decimal64 if any type-generic
9690 argument is decimal, or if the only alternatives for
9691 type-generic arguments are of decimal types, and are
9692 otherwise treated as double (or _Complex double for
9693 complex integer types, or _Float64 or _Complex _Float64
9694 if all the return types are the same _FloatN or
9695 _FloatNx type). After that adjustment, types are
9696 combined following the usual arithmetic conversions.
9697 If the function only accepts complex arguments, a
9698 complex type is produced. */
9699 bool arg_complex = all_complex;
9700 bool arg_binary = all_binary;
9701 bool arg_int_decimal = all_decimal;
9702 for (unsigned int j = 1; j <= nargs; j++)
9703 {
9704 if (parm_kind[j] == tgmath_fixed)
9705 continue;
9706 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9707 tree type = TREE_TYPE (ce->value);
9708 if (!INTEGRAL_TYPE_P (type)
9709 && !SCALAR_FLOAT_TYPE_P (type)
9710 && TREE_CODE (type) != COMPLEX_TYPE)
9711 {
9712 error_at (ce->get_location (),
9713 "invalid type of argument %u of type-generic "
9714 "function", j);
9715 expr.set_error ();
9716 goto out;
9717 }
9718 if (DECIMAL_FLOAT_TYPE_P (type))
9719 {
9720 arg_int_decimal = true;
9721 if (all_complex)
9722 {
9723 error_at (ce->get_location (),
9724 "decimal floating-point argument %u to "
9725 "complex-only type-generic function", j);
9726 expr.set_error ();
9727 goto out;
9728 }
9729 else if (all_binary)
9730 {
9731 error_at (ce->get_location (),
9732 "decimal floating-point argument %u to "
9733 "binary-only type-generic function", j);
9734 expr.set_error ();
9735 goto out;
9736 }
9737 else if (arg_complex)
9738 {
9739 error_at (ce->get_location (),
9740 "both complex and decimal floating-point "
9741 "arguments to type-generic function");
9742 expr.set_error ();
9743 goto out;
9744 }
9745 else if (arg_binary)
9746 {
9747 error_at (ce->get_location (),
9748 "both binary and decimal floating-point "
9749 "arguments to type-generic function");
9750 expr.set_error ();
9751 goto out;
9752 }
9753 }
9754 else if (TREE_CODE (type) == COMPLEX_TYPE)
9755 {
9756 arg_complex = true;
9757 if (COMPLEX_FLOAT_TYPE_P (type))
9758 arg_binary = true;
9759 if (all_decimal)
9760 {
9761 error_at (ce->get_location (),
9762 "complex argument %u to "
9763 "decimal-only type-generic function", j);
9764 expr.set_error ();
9765 goto out;
9766 }
9767 else if (arg_int_decimal)
9768 {
9769 error_at (ce->get_location (),
9770 "both complex and decimal floating-point "
9771 "arguments to type-generic function");
9772 expr.set_error ();
9773 goto out;
9774 }
9775 }
9776 else if (SCALAR_FLOAT_TYPE_P (type))
9777 {
9778 arg_binary = true;
9779 if (all_decimal)
9780 {
9781 error_at (ce->get_location (),
9782 "binary argument %u to "
9783 "decimal-only type-generic function", j);
9784 expr.set_error ();
9785 goto out;
9786 }
9787 else if (arg_int_decimal)
9788 {
9789 error_at (ce->get_location (),
9790 "both binary and decimal floating-point "
9791 "arguments to type-generic function");
9792 expr.set_error ();
9793 goto out;
9794 }
9795 }
9796 }
9797 /* For a macro rounding its result to a narrower type, map
9798 integer types to _Float64 not double if the return type
9799 is a _FloatN or _FloatNx type. */
9800 bool arg_int_float64 = false;
9801 if (parm_kind[0] == tgmath_fixed
9802 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9803 && float64_type_node != NULL_TREE)
9804 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9805 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9806 {
9807 arg_int_float64 = true;
9808 break;
9809 }
9810 tree arg_real = NULL_TREE;
9811 for (unsigned int j = 1; j <= nargs; j++)
9812 {
9813 if (parm_kind[j] == tgmath_fixed)
9814 continue;
9815 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9816 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9817 if (TREE_CODE (type) == COMPLEX_TYPE)
9818 type = TREE_TYPE (type);
9819 if (INTEGRAL_TYPE_P (type))
9820 type = (arg_int_decimal
9821 ? dfloat64_type_node
9822 : arg_int_float64
9823 ? float64_type_node
9824 : double_type_node);
9825 if (arg_real == NULL_TREE)
9826 arg_real = type;
9827 else
9828 arg_real = common_type (arg_real, type);
9829 if (arg_real == error_mark_node)
9830 {
9831 expr.set_error ();
9832 goto out;
9833 }
9834 }
9835 tree arg_type = (arg_complex
9836 ? build_complex_type (arg_real)
9837 : arg_real);
9838
9839 /* Look for a function to call with type-generic parameter
9840 type ARG_TYPE. */
9841 c_expr_t *fn = NULL;
9842 for (unsigned int j = 0; j < num_functions; j++)
9843 {
9844 if (tg_type[j] == arg_type)
9845 {
9846 fn = &(*cexpr_list)[j];
9847 break;
9848 }
9849 }
9850 if (fn == NULL
9851 && parm_kind[0] == tgmath_fixed
9852 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9853 {
9854 /* Presume this is a macro that rounds its result to a
9855 narrower type, and look for the first function with
9856 at least the range and precision of the argument
9857 type. */
9858 for (unsigned int j = 0; j < num_functions; j++)
9859 {
9860 if (arg_complex
9861 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9862 continue;
9863 tree real_tg_type = (arg_complex
9864 ? TREE_TYPE (tg_type[j])
9865 : tg_type[j]);
9866 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9867 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9868 continue;
9869 scalar_float_mode arg_mode
9870 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9871 scalar_float_mode tg_mode
9872 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9873 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9874 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9875 if (arg_fmt->b == tg_fmt->b
9876 && arg_fmt->p <= tg_fmt->p
9877 && arg_fmt->emax <= tg_fmt->emax
9878 && (arg_fmt->emin - arg_fmt->p
9879 >= tg_fmt->emin - tg_fmt->p))
9880 {
9881 fn = &(*cexpr_list)[j];
9882 break;
9883 }
9884 }
9885 }
9886 if (fn == NULL)
9887 {
9888 error_at (loc, "no matching function for type-generic call");
9889 expr.set_error ();
9890 break;
9891 }
9892
9893 /* Construct a call to FN. */
9894 vec<tree, va_gc> *args;
9895 vec_alloc (args, nargs);
9896 vec<tree, va_gc> *origtypes;
9897 vec_alloc (origtypes, nargs);
9898 auto_vec<location_t> arg_loc (nargs);
9899 for (unsigned int j = 0; j < nargs; j++)
9900 {
9901 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9902 args->quick_push (ce->value);
9903 arg_loc.quick_push (ce->get_location ());
9904 origtypes->quick_push (ce->original_type);
9905 }
9906 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9907 args, origtypes);
9908 set_c_expr_source_range (&expr, loc, close_paren_loc);
9909 break;
9910 }
9911 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9912 {
9913 vec<c_expr_t, va_gc> *cexpr_list;
9914 c_expr_t *e2_p;
9915 tree chain_value;
9916 location_t close_paren_loc;
9917
9918 c_parser_consume_token (parser);
9919 if (!c_parser_get_builtin_args (parser,
9920 "__builtin_call_with_static_chain",
9921 &cexpr_list, false,
9922 &close_paren_loc))
9923 {
9924 expr.set_error ();
9925 break;
9926 }
9927 if (vec_safe_length (cexpr_list) != 2)
9928 {
9929 error_at (loc, "wrong number of arguments to "
9930 "%<__builtin_call_with_static_chain%>");
9931 expr.set_error ();
9932 break;
9933 }
9934
9935 expr = (*cexpr_list)[0];
9936 e2_p = &(*cexpr_list)[1];
9937 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9938 chain_value = e2_p->value;
9939 mark_exp_read (chain_value);
9940
9941 if (TREE_CODE (expr.value) != CALL_EXPR)
9942 error_at (loc, "first argument to "
9943 "%<__builtin_call_with_static_chain%> "
9944 "must be a call expression");
9945 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9946 error_at (loc, "second argument to "
9947 "%<__builtin_call_with_static_chain%> "
9948 "must be a pointer type");
9949 else
9950 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9951 set_c_expr_source_range (&expr, loc, close_paren_loc);
9952 break;
9953 }
9954 case RID_BUILTIN_COMPLEX:
9955 {
9956 vec<c_expr_t, va_gc> *cexpr_list;
9957 c_expr_t *e1_p, *e2_p;
9958 location_t close_paren_loc;
9959
9960 c_parser_consume_token (parser);
9961 if (!c_parser_get_builtin_args (parser,
9962 "__builtin_complex",
9963 &cexpr_list, false,
9964 &close_paren_loc))
9965 {
9966 expr.set_error ();
9967 break;
9968 }
9969
9970 if (vec_safe_length (cexpr_list) != 2)
9971 {
9972 error_at (loc, "wrong number of arguments to "
9973 "%<__builtin_complex%>");
9974 expr.set_error ();
9975 break;
9976 }
9977
9978 e1_p = &(*cexpr_list)[0];
9979 e2_p = &(*cexpr_list)[1];
9980
9981 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9982 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9983 e1_p->value = convert (TREE_TYPE (e1_p->value),
9984 TREE_OPERAND (e1_p->value, 0));
9985 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9986 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9987 e2_p->value = convert (TREE_TYPE (e2_p->value),
9988 TREE_OPERAND (e2_p->value, 0));
9989 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9990 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9991 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9992 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9993 {
9994 error_at (loc, "%<__builtin_complex%> operand "
9995 "not of real binary floating-point type");
9996 expr.set_error ();
9997 break;
9998 }
9999 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10000 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10001 {
10002 error_at (loc,
10003 "%<__builtin_complex%> operands of different types");
10004 expr.set_error ();
10005 break;
10006 }
10007 pedwarn_c90 (loc, OPT_Wpedantic,
10008 "ISO C90 does not support complex types");
10009 expr.value = build2_loc (loc, COMPLEX_EXPR,
10010 build_complex_type
10011 (TYPE_MAIN_VARIANT
10012 (TREE_TYPE (e1_p->value))),
10013 e1_p->value, e2_p->value);
10014 set_c_expr_source_range (&expr, loc, close_paren_loc);
10015 break;
10016 }
10017 case RID_BUILTIN_SHUFFLE:
10018 {
10019 vec<c_expr_t, va_gc> *cexpr_list;
10020 unsigned int i;
10021 c_expr_t *p;
10022 location_t close_paren_loc;
10023
10024 c_parser_consume_token (parser);
10025 if (!c_parser_get_builtin_args (parser,
10026 "__builtin_shuffle",
10027 &cexpr_list, false,
10028 &close_paren_loc))
10029 {
10030 expr.set_error ();
10031 break;
10032 }
10033
10034 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10035 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10036
10037 if (vec_safe_length (cexpr_list) == 2)
10038 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10039 NULL_TREE,
10040 (*cexpr_list)[1].value);
10041
10042 else if (vec_safe_length (cexpr_list) == 3)
10043 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10044 (*cexpr_list)[1].value,
10045 (*cexpr_list)[2].value);
10046 else
10047 {
10048 error_at (loc, "wrong number of arguments to "
10049 "%<__builtin_shuffle%>");
10050 expr.set_error ();
10051 }
10052 set_c_expr_source_range (&expr, loc, close_paren_loc);
10053 break;
10054 }
10055 case RID_BUILTIN_SHUFFLEVECTOR:
10056 {
10057 vec<c_expr_t, va_gc> *cexpr_list;
10058 unsigned int i;
10059 c_expr_t *p;
10060 location_t close_paren_loc;
10061
10062 c_parser_consume_token (parser);
10063 if (!c_parser_get_builtin_args (parser,
10064 "__builtin_shufflevector",
10065 &cexpr_list, false,
10066 &close_paren_loc))
10067 {
10068 expr.set_error ();
10069 break;
10070 }
10071
10072 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10073 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10074
10075 if (vec_safe_length (cexpr_list) < 3)
10076 {
10077 error_at (loc, "wrong number of arguments to "
10078 "%<__builtin_shuffle%>");
10079 expr.set_error ();
10080 }
10081 else
10082 {
10083 auto_vec<tree, 16> mask;
10084 for (i = 2; i < cexpr_list->length (); ++i)
10085 mask.safe_push ((*cexpr_list)[i].value);
10086 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10087 (*cexpr_list)[1].value,
10088 mask);
10089 }
10090 set_c_expr_source_range (&expr, loc, close_paren_loc);
10091 break;
10092 }
10093 case RID_BUILTIN_CONVERTVECTOR:
10094 {
10095 location_t start_loc = loc;
10096 c_parser_consume_token (parser);
10097 matching_parens parens;
10098 if (!parens.require_open (parser))
10099 {
10100 expr.set_error ();
10101 break;
10102 }
10103 e1 = c_parser_expr_no_commas (parser, NULL);
10104 mark_exp_read (e1.value);
10105 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10106 {
10107 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10108 expr.set_error ();
10109 break;
10110 }
10111 loc = c_parser_peek_token (parser)->location;
10112 t1 = c_parser_type_name (parser);
10113 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10114 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10115 "expected %<)%>");
10116 if (t1 == NULL)
10117 expr.set_error ();
10118 else
10119 {
10120 tree type_expr = NULL_TREE;
10121 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10122 groktypename (t1, &type_expr,
10123 NULL));
10124 set_c_expr_source_range (&expr, start_loc, end_loc);
10125 }
10126 }
10127 break;
10128 case RID_BUILTIN_ASSOC_BARRIER:
10129 {
10130 location_t start_loc = loc;
10131 c_parser_consume_token (parser);
10132 matching_parens parens;
10133 if (!parens.require_open (parser))
10134 {
10135 expr.set_error ();
10136 break;
10137 }
10138 e1 = c_parser_expr_no_commas (parser, NULL);
10139 mark_exp_read (e1.value);
10140 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10141 parens.skip_until_found_close (parser);
10142 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10143 set_c_expr_source_range (&expr, start_loc, end_loc);
10144 }
10145 break;
10146 case RID_AT_SELECTOR:
10147 {
10148 gcc_assert (c_dialect_objc ());
10149 c_parser_consume_token (parser);
10150 matching_parens parens;
10151 if (!parens.require_open (parser))
10152 {
10153 expr.set_error ();
10154 break;
10155 }
10156 tree sel = c_parser_objc_selector_arg (parser);
10157 location_t close_loc = c_parser_peek_token (parser)->location;
10158 parens.skip_until_found_close (parser);
10159 expr.value = objc_build_selector_expr (loc, sel);
10160 set_c_expr_source_range (&expr, loc, close_loc);
10161 }
10162 break;
10163 case RID_AT_PROTOCOL:
10164 {
10165 gcc_assert (c_dialect_objc ());
10166 c_parser_consume_token (parser);
10167 matching_parens parens;
10168 if (!parens.require_open (parser))
10169 {
10170 expr.set_error ();
10171 break;
10172 }
10173 if (c_parser_next_token_is_not (parser, CPP_NAME))
10174 {
10175 c_parser_error (parser, "expected identifier");
10176 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10177 expr.set_error ();
10178 break;
10179 }
10180 tree id = c_parser_peek_token (parser)->value;
10181 c_parser_consume_token (parser);
10182 location_t close_loc = c_parser_peek_token (parser)->location;
10183 parens.skip_until_found_close (parser);
10184 expr.value = objc_build_protocol_expr (id);
10185 set_c_expr_source_range (&expr, loc, close_loc);
10186 }
10187 break;
10188 case RID_AT_ENCODE:
10189 {
10190 /* Extension to support C-structures in the archiver. */
10191 gcc_assert (c_dialect_objc ());
10192 c_parser_consume_token (parser);
10193 matching_parens parens;
10194 if (!parens.require_open (parser))
10195 {
10196 expr.set_error ();
10197 break;
10198 }
10199 t1 = c_parser_type_name (parser);
10200 if (t1 == NULL)
10201 {
10202 expr.set_error ();
10203 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10204 break;
10205 }
10206 location_t close_loc = c_parser_peek_token (parser)->location;
10207 parens.skip_until_found_close (parser);
10208 tree type = groktypename (t1, NULL, NULL);
10209 expr.value = objc_build_encode_expr (type);
10210 set_c_expr_source_range (&expr, loc, close_loc);
10211 }
10212 break;
10213 case RID_GENERIC:
10214 expr = c_parser_generic_selection (parser);
10215 break;
10216 case RID_OMP_ALL_MEMORY:
10217 gcc_assert (flag_openmp);
10218 c_parser_consume_token (parser);
10219 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
10220 "%<depend%> clause");
10221 expr.set_error ();
10222 break;
10223 default:
10224 c_parser_error (parser, "expected expression");
10225 expr.set_error ();
10226 break;
10227 }
10228 break;
10229 case CPP_OPEN_SQUARE:
10230 if (c_dialect_objc ())
10231 {
10232 tree receiver, args;
10233 c_parser_consume_token (parser);
10234 receiver = c_parser_objc_receiver (parser);
10235 args = c_parser_objc_message_args (parser);
10236 location_t close_loc = c_parser_peek_token (parser)->location;
10237 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10238 "expected %<]%>");
10239 expr.value = objc_build_message_expr (receiver, args);
10240 set_c_expr_source_range (&expr, loc, close_loc);
10241 break;
10242 }
10243 /* Else fall through to report error. */
10244 /* FALLTHRU */
10245 default:
10246 c_parser_error (parser, "expected expression");
10247 expr.set_error ();
10248 break;
10249 }
10250 out:
10251 return c_parser_postfix_expression_after_primary
10252 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10253 }
10254
10255 /* Parse a postfix expression after a parenthesized type name: the
10256 brace-enclosed initializer of a compound literal, possibly followed
10257 by some postfix operators. This is separate because it is not
10258 possible to tell until after the type name whether a cast
10259 expression has a cast or a compound literal, or whether the operand
10260 of sizeof is a parenthesized type name or starts with a compound
10261 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10262 location of the first token after the parentheses around the type
10263 name. */
10264
10265 static struct c_expr
10266 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10267 struct c_type_name *type_name,
10268 location_t type_loc)
10269 {
10270 tree type;
10271 struct c_expr init;
10272 bool non_const;
10273 struct c_expr expr;
10274 location_t start_loc;
10275 tree type_expr = NULL_TREE;
10276 bool type_expr_const = true;
10277 check_compound_literal_type (type_loc, type_name);
10278 rich_location richloc (line_table, type_loc);
10279 start_init (NULL_TREE, NULL, 0, &richloc);
10280 type = groktypename (type_name, &type_expr, &type_expr_const);
10281 start_loc = c_parser_peek_token (parser)->location;
10282 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10283 {
10284 error_at (type_loc, "compound literal has variable size");
10285 type = error_mark_node;
10286 }
10287 init = c_parser_braced_init (parser, type, false, NULL);
10288 finish_init ();
10289 maybe_warn_string_init (type_loc, type, init);
10290
10291 if (type != error_mark_node
10292 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10293 && current_function_decl)
10294 {
10295 error ("compound literal qualified by address-space qualifier");
10296 type = error_mark_node;
10297 }
10298
10299 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10300 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10301 ? CONSTRUCTOR_NON_CONST (init.value)
10302 : init.original_code == C_MAYBE_CONST_EXPR);
10303 non_const |= !type_expr_const;
10304 unsigned int alignas_align = 0;
10305 if (type != error_mark_node
10306 && type_name->specs->align_log != -1)
10307 {
10308 alignas_align = 1U << type_name->specs->align_log;
10309 if (alignas_align < min_align_of_type (type))
10310 {
10311 error_at (type_name->specs->locations[cdw_alignas],
10312 "%<_Alignas%> specifiers cannot reduce "
10313 "alignment of compound literal");
10314 alignas_align = 0;
10315 }
10316 }
10317 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10318 alignas_align);
10319 set_c_expr_source_range (&expr, init.src_range);
10320 expr.original_code = ERROR_MARK;
10321 expr.original_type = NULL;
10322 if (type != error_mark_node
10323 && expr.value != error_mark_node
10324 && type_expr)
10325 {
10326 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10327 {
10328 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10329 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10330 }
10331 else
10332 {
10333 gcc_assert (!non_const);
10334 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10335 type_expr, expr.value);
10336 }
10337 }
10338 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10339 }
10340
10341 /* Callback function for sizeof_pointer_memaccess_warning to compare
10342 types. */
10343
10344 static bool
10345 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10346 {
10347 return comptypes (type1, type2) == 1;
10348 }
10349
10350 /* Warn for patterns where abs-like function appears to be used incorrectly,
10351 gracefully ignore any non-abs-like function. The warning location should
10352 be LOC. FNDECL is the declaration of called function, it must be a
10353 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10354 call. */
10355
10356 static void
10357 warn_for_abs (location_t loc, tree fndecl, tree arg)
10358 {
10359 /* Avoid warning in unreachable subexpressions. */
10360 if (c_inhibit_evaluation_warnings)
10361 return;
10362
10363 tree atype = TREE_TYPE (arg);
10364
10365 /* Casts from pointers (and thus arrays and fndecls) will generate
10366 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10367 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10368 types and possibly other exotic types. */
10369 if (!INTEGRAL_TYPE_P (atype)
10370 && !SCALAR_FLOAT_TYPE_P (atype)
10371 && TREE_CODE (atype) != COMPLEX_TYPE)
10372 return;
10373
10374 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10375
10376 switch (fcode)
10377 {
10378 case BUILT_IN_ABS:
10379 case BUILT_IN_LABS:
10380 case BUILT_IN_LLABS:
10381 case BUILT_IN_IMAXABS:
10382 if (!INTEGRAL_TYPE_P (atype))
10383 {
10384 if (SCALAR_FLOAT_TYPE_P (atype))
10385 warning_at (loc, OPT_Wabsolute_value,
10386 "using integer absolute value function %qD when "
10387 "argument is of floating-point type %qT",
10388 fndecl, atype);
10389 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10390 warning_at (loc, OPT_Wabsolute_value,
10391 "using integer absolute value function %qD when "
10392 "argument is of complex type %qT", fndecl, atype);
10393 else
10394 gcc_unreachable ();
10395 return;
10396 }
10397 if (TYPE_UNSIGNED (atype))
10398 warning_at (loc, OPT_Wabsolute_value,
10399 "taking the absolute value of unsigned type %qT "
10400 "has no effect", atype);
10401 break;
10402
10403 CASE_FLT_FN (BUILT_IN_FABS):
10404 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10405 if (!SCALAR_FLOAT_TYPE_P (atype)
10406 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10407 {
10408 if (INTEGRAL_TYPE_P (atype))
10409 warning_at (loc, OPT_Wabsolute_value,
10410 "using floating-point absolute value function %qD "
10411 "when argument is of integer type %qT", fndecl, atype);
10412 else if (DECIMAL_FLOAT_TYPE_P (atype))
10413 warning_at (loc, OPT_Wabsolute_value,
10414 "using floating-point absolute value function %qD "
10415 "when argument is of decimal floating-point type %qT",
10416 fndecl, atype);
10417 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10418 warning_at (loc, OPT_Wabsolute_value,
10419 "using floating-point absolute value function %qD when "
10420 "argument is of complex type %qT", fndecl, atype);
10421 else
10422 gcc_unreachable ();
10423 return;
10424 }
10425 break;
10426
10427 CASE_FLT_FN (BUILT_IN_CABS):
10428 if (TREE_CODE (atype) != COMPLEX_TYPE)
10429 {
10430 if (INTEGRAL_TYPE_P (atype))
10431 warning_at (loc, OPT_Wabsolute_value,
10432 "using complex absolute value function %qD when "
10433 "argument is of integer type %qT", fndecl, atype);
10434 else if (SCALAR_FLOAT_TYPE_P (atype))
10435 warning_at (loc, OPT_Wabsolute_value,
10436 "using complex absolute value function %qD when "
10437 "argument is of floating-point type %qT",
10438 fndecl, atype);
10439 else
10440 gcc_unreachable ();
10441
10442 return;
10443 }
10444 break;
10445
10446 case BUILT_IN_FABSD32:
10447 case BUILT_IN_FABSD64:
10448 case BUILT_IN_FABSD128:
10449 if (!DECIMAL_FLOAT_TYPE_P (atype))
10450 {
10451 if (INTEGRAL_TYPE_P (atype))
10452 warning_at (loc, OPT_Wabsolute_value,
10453 "using decimal floating-point absolute value "
10454 "function %qD when argument is of integer type %qT",
10455 fndecl, atype);
10456 else if (SCALAR_FLOAT_TYPE_P (atype))
10457 warning_at (loc, OPT_Wabsolute_value,
10458 "using decimal floating-point absolute value "
10459 "function %qD when argument is of floating-point "
10460 "type %qT", fndecl, atype);
10461 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10462 warning_at (loc, OPT_Wabsolute_value,
10463 "using decimal floating-point absolute value "
10464 "function %qD when argument is of complex type %qT",
10465 fndecl, atype);
10466 else
10467 gcc_unreachable ();
10468 return;
10469 }
10470 break;
10471
10472 default:
10473 return;
10474 }
10475
10476 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10477 return;
10478
10479 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10480 if (TREE_CODE (atype) == COMPLEX_TYPE)
10481 {
10482 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10483 atype = TREE_TYPE (atype);
10484 ftype = TREE_TYPE (ftype);
10485 }
10486
10487 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10488 warning_at (loc, OPT_Wabsolute_value,
10489 "absolute value function %qD given an argument of type %qT "
10490 "but has parameter of type %qT which may cause truncation "
10491 "of value", fndecl, atype, ftype);
10492 }
10493
10494
10495 /* Parse a postfix expression after the initial primary or compound
10496 literal; that is, parse a series of postfix operators.
10497
10498 EXPR_LOC is the location of the primary expression. */
10499
10500 static struct c_expr
10501 c_parser_postfix_expression_after_primary (c_parser *parser,
10502 location_t expr_loc,
10503 struct c_expr expr)
10504 {
10505 struct c_expr orig_expr;
10506 tree ident, idx;
10507 location_t sizeof_arg_loc[3], comp_loc;
10508 tree sizeof_arg[3];
10509 unsigned int literal_zero_mask;
10510 unsigned int i;
10511 vec<tree, va_gc> *exprlist;
10512 vec<tree, va_gc> *origtypes = NULL;
10513 vec<location_t> arg_loc = vNULL;
10514 location_t start;
10515 location_t finish;
10516
10517 while (true)
10518 {
10519 location_t op_loc = c_parser_peek_token (parser)->location;
10520 switch (c_parser_peek_token (parser)->type)
10521 {
10522 case CPP_OPEN_SQUARE:
10523 /* Array reference. */
10524 c_parser_consume_token (parser);
10525 idx = c_parser_expression (parser).value;
10526 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10527 "expected %<]%>");
10528 start = expr.get_start ();
10529 finish = parser->tokens_buf[0].location;
10530 expr.value = build_array_ref (op_loc, expr.value, idx);
10531 set_c_expr_source_range (&expr, start, finish);
10532 expr.original_code = ERROR_MARK;
10533 expr.original_type = NULL;
10534 break;
10535 case CPP_OPEN_PAREN:
10536 /* Function call. */
10537 {
10538 matching_parens parens;
10539 parens.consume_open (parser);
10540 for (i = 0; i < 3; i++)
10541 {
10542 sizeof_arg[i] = NULL_TREE;
10543 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10544 }
10545 literal_zero_mask = 0;
10546 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10547 exprlist = NULL;
10548 else
10549 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10550 sizeof_arg_loc, sizeof_arg,
10551 &arg_loc, &literal_zero_mask);
10552 parens.skip_until_found_close (parser);
10553 }
10554 orig_expr = expr;
10555 mark_exp_read (expr.value);
10556 if (warn_sizeof_pointer_memaccess)
10557 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10558 expr.value, exprlist,
10559 sizeof_arg,
10560 sizeof_ptr_memacc_comptypes);
10561 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10562 {
10563 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10564 && vec_safe_length (exprlist) == 3)
10565 {
10566 tree arg0 = (*exprlist)[0];
10567 tree arg2 = (*exprlist)[2];
10568 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10569 }
10570 if (warn_absolute_value
10571 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10572 && vec_safe_length (exprlist) == 1)
10573 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10574 }
10575
10576 start = expr.get_start ();
10577 finish = parser->tokens_buf[0].get_finish ();
10578 expr.value
10579 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10580 exprlist, origtypes);
10581 set_c_expr_source_range (&expr, start, finish);
10582
10583 expr.original_code = ERROR_MARK;
10584 if (TREE_CODE (expr.value) == INTEGER_CST
10585 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10586 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10587 expr.original_code = C_MAYBE_CONST_EXPR;
10588 expr.original_type = NULL;
10589 if (exprlist)
10590 {
10591 release_tree_vector (exprlist);
10592 release_tree_vector (origtypes);
10593 }
10594 arg_loc.release ();
10595 break;
10596 case CPP_DOT:
10597 /* Structure element reference. */
10598 c_parser_consume_token (parser);
10599 expr = default_function_array_conversion (expr_loc, expr);
10600 if (c_parser_next_token_is (parser, CPP_NAME))
10601 {
10602 c_token *comp_tok = c_parser_peek_token (parser);
10603 ident = comp_tok->value;
10604 comp_loc = comp_tok->location;
10605 }
10606 else
10607 {
10608 c_parser_error (parser, "expected identifier");
10609 expr.set_error ();
10610 expr.original_code = ERROR_MARK;
10611 expr.original_type = NULL;
10612 return expr;
10613 }
10614 start = expr.get_start ();
10615 finish = c_parser_peek_token (parser)->get_finish ();
10616 c_parser_consume_token (parser);
10617 expr.value = build_component_ref (op_loc, expr.value, ident,
10618 comp_loc, UNKNOWN_LOCATION);
10619 set_c_expr_source_range (&expr, start, finish);
10620 expr.original_code = ERROR_MARK;
10621 if (TREE_CODE (expr.value) != COMPONENT_REF)
10622 expr.original_type = NULL;
10623 else
10624 {
10625 /* Remember the original type of a bitfield. */
10626 tree field = TREE_OPERAND (expr.value, 1);
10627 if (TREE_CODE (field) != FIELD_DECL)
10628 expr.original_type = NULL;
10629 else
10630 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10631 }
10632 break;
10633 case CPP_DEREF:
10634 /* Structure element reference. */
10635 c_parser_consume_token (parser);
10636 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10637 if (c_parser_next_token_is (parser, CPP_NAME))
10638 {
10639 c_token *comp_tok = c_parser_peek_token (parser);
10640 ident = comp_tok->value;
10641 comp_loc = comp_tok->location;
10642 }
10643 else
10644 {
10645 c_parser_error (parser, "expected identifier");
10646 expr.set_error ();
10647 expr.original_code = ERROR_MARK;
10648 expr.original_type = NULL;
10649 return expr;
10650 }
10651 start = expr.get_start ();
10652 finish = c_parser_peek_token (parser)->get_finish ();
10653 c_parser_consume_token (parser);
10654 expr.value = build_component_ref (op_loc,
10655 build_indirect_ref (op_loc,
10656 expr.value,
10657 RO_ARROW),
10658 ident, comp_loc,
10659 expr.get_location ());
10660 set_c_expr_source_range (&expr, start, finish);
10661 expr.original_code = ERROR_MARK;
10662 if (TREE_CODE (expr.value) != COMPONENT_REF)
10663 expr.original_type = NULL;
10664 else
10665 {
10666 /* Remember the original type of a bitfield. */
10667 tree field = TREE_OPERAND (expr.value, 1);
10668 if (TREE_CODE (field) != FIELD_DECL)
10669 expr.original_type = NULL;
10670 else
10671 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10672 }
10673 break;
10674 case CPP_PLUS_PLUS:
10675 /* Postincrement. */
10676 start = expr.get_start ();
10677 finish = c_parser_peek_token (parser)->get_finish ();
10678 c_parser_consume_token (parser);
10679 expr = default_function_array_read_conversion (expr_loc, expr);
10680 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10681 expr.value, false);
10682 set_c_expr_source_range (&expr, start, finish);
10683 expr.original_code = ERROR_MARK;
10684 expr.original_type = NULL;
10685 break;
10686 case CPP_MINUS_MINUS:
10687 /* Postdecrement. */
10688 start = expr.get_start ();
10689 finish = c_parser_peek_token (parser)->get_finish ();
10690 c_parser_consume_token (parser);
10691 expr = default_function_array_read_conversion (expr_loc, expr);
10692 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10693 expr.value, false);
10694 set_c_expr_source_range (&expr, start, finish);
10695 expr.original_code = ERROR_MARK;
10696 expr.original_type = NULL;
10697 break;
10698 default:
10699 return expr;
10700 }
10701 }
10702 }
10703
10704 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10705
10706 expression:
10707 assignment-expression
10708 expression , assignment-expression
10709 */
10710
10711 static struct c_expr
10712 c_parser_expression (c_parser *parser)
10713 {
10714 location_t tloc = c_parser_peek_token (parser)->location;
10715 struct c_expr expr;
10716 expr = c_parser_expr_no_commas (parser, NULL);
10717 if (c_parser_next_token_is (parser, CPP_COMMA))
10718 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10719 while (c_parser_next_token_is (parser, CPP_COMMA))
10720 {
10721 struct c_expr next;
10722 tree lhsval;
10723 location_t loc = c_parser_peek_token (parser)->location;
10724 location_t expr_loc;
10725 c_parser_consume_token (parser);
10726 expr_loc = c_parser_peek_token (parser)->location;
10727 lhsval = expr.value;
10728 while (TREE_CODE (lhsval) == COMPOUND_EXPR
10729 || TREE_CODE (lhsval) == NOP_EXPR)
10730 {
10731 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10732 lhsval = TREE_OPERAND (lhsval, 1);
10733 else
10734 lhsval = TREE_OPERAND (lhsval, 0);
10735 }
10736 if (DECL_P (lhsval) || handled_component_p (lhsval))
10737 mark_exp_read (lhsval);
10738 next = c_parser_expr_no_commas (parser, NULL);
10739 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10740 expr.value = build_compound_expr (loc, expr.value, next.value);
10741 expr.original_code = COMPOUND_EXPR;
10742 expr.original_type = next.original_type;
10743 }
10744 return expr;
10745 }
10746
10747 /* Parse an expression and convert functions or arrays to pointers and
10748 lvalues to rvalues. */
10749
10750 static struct c_expr
10751 c_parser_expression_conv (c_parser *parser)
10752 {
10753 struct c_expr expr;
10754 location_t loc = c_parser_peek_token (parser)->location;
10755 expr = c_parser_expression (parser);
10756 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10757 return expr;
10758 }
10759
10760 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10761 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10762
10763 static inline void
10764 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10765 unsigned int idx)
10766 {
10767 if (idx >= HOST_BITS_PER_INT)
10768 return;
10769
10770 c_token *tok = c_parser_peek_token (parser);
10771 switch (tok->type)
10772 {
10773 case CPP_NUMBER:
10774 case CPP_CHAR:
10775 case CPP_WCHAR:
10776 case CPP_CHAR16:
10777 case CPP_CHAR32:
10778 case CPP_UTF8CHAR:
10779 /* If a parameter is literal zero alone, remember it
10780 for -Wmemset-transposed-args warning. */
10781 if (integer_zerop (tok->value)
10782 && !TREE_OVERFLOW (tok->value)
10783 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10784 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10785 *literal_zero_mask |= 1U << idx;
10786 default:
10787 break;
10788 }
10789 }
10790
10791 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10792 functions and arrays to pointers and lvalues to rvalues. If
10793 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10794 locations of function arguments into this vector.
10795
10796 nonempty-expr-list:
10797 assignment-expression
10798 nonempty-expr-list , assignment-expression
10799 */
10800
10801 static vec<tree, va_gc> *
10802 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10803 vec<tree, va_gc> **p_orig_types,
10804 location_t *sizeof_arg_loc, tree *sizeof_arg,
10805 vec<location_t> *locations,
10806 unsigned int *literal_zero_mask)
10807 {
10808 vec<tree, va_gc> *ret;
10809 vec<tree, va_gc> *orig_types;
10810 struct c_expr expr;
10811 unsigned int idx = 0;
10812
10813 ret = make_tree_vector ();
10814 if (p_orig_types == NULL)
10815 orig_types = NULL;
10816 else
10817 orig_types = make_tree_vector ();
10818
10819 if (literal_zero_mask)
10820 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10821 expr = c_parser_expr_no_commas (parser, NULL);
10822 if (convert_p)
10823 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10824 if (fold_p)
10825 expr.value = c_fully_fold (expr.value, false, NULL);
10826 ret->quick_push (expr.value);
10827 if (orig_types)
10828 orig_types->quick_push (expr.original_type);
10829 if (locations)
10830 locations->safe_push (expr.get_location ());
10831 if (sizeof_arg != NULL
10832 && (expr.original_code == SIZEOF_EXPR
10833 || expr.original_code == PAREN_SIZEOF_EXPR))
10834 {
10835 sizeof_arg[0] = c_last_sizeof_arg;
10836 sizeof_arg_loc[0] = c_last_sizeof_loc;
10837 }
10838 while (c_parser_next_token_is (parser, CPP_COMMA))
10839 {
10840 c_parser_consume_token (parser);
10841 if (literal_zero_mask)
10842 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10843 expr = c_parser_expr_no_commas (parser, NULL);
10844 if (convert_p)
10845 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10846 true);
10847 if (fold_p)
10848 expr.value = c_fully_fold (expr.value, false, NULL);
10849 vec_safe_push (ret, expr.value);
10850 if (orig_types)
10851 vec_safe_push (orig_types, expr.original_type);
10852 if (locations)
10853 locations->safe_push (expr.get_location ());
10854 if (++idx < 3
10855 && sizeof_arg != NULL
10856 && (expr.original_code == SIZEOF_EXPR
10857 || expr.original_code == PAREN_SIZEOF_EXPR))
10858 {
10859 sizeof_arg[idx] = c_last_sizeof_arg;
10860 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10861 }
10862 }
10863 if (orig_types)
10864 *p_orig_types = orig_types;
10865 return ret;
10866 }
10867 \f
10868 /* Parse Objective-C-specific constructs. */
10869
10870 /* Parse an objc-class-definition.
10871
10872 objc-class-definition:
10873 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10874 objc-class-instance-variables[opt] objc-methodprotolist @end
10875 @implementation identifier objc-superclass[opt]
10876 objc-class-instance-variables[opt]
10877 @interface identifier ( identifier ) objc-protocol-refs[opt]
10878 objc-methodprotolist @end
10879 @interface identifier ( ) objc-protocol-refs[opt]
10880 objc-methodprotolist @end
10881 @implementation identifier ( identifier )
10882
10883 objc-superclass:
10884 : identifier
10885
10886 "@interface identifier (" must start "@interface identifier (
10887 identifier ) ...": objc-methodprotolist in the first production may
10888 not start with a parenthesized identifier as a declarator of a data
10889 definition with no declaration specifiers if the objc-superclass,
10890 objc-protocol-refs and objc-class-instance-variables are omitted. */
10891
10892 static void
10893 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10894 {
10895 bool iface_p;
10896 tree id1;
10897 tree superclass;
10898 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10899 iface_p = true;
10900 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10901 iface_p = false;
10902 else
10903 gcc_unreachable ();
10904
10905 c_parser_consume_token (parser);
10906 if (c_parser_next_token_is_not (parser, CPP_NAME))
10907 {
10908 c_parser_error (parser, "expected identifier");
10909 return;
10910 }
10911 id1 = c_parser_peek_token (parser)->value;
10912 location_t loc1 = c_parser_peek_token (parser)->location;
10913 c_parser_consume_token (parser);
10914 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10915 {
10916 /* We have a category or class extension. */
10917 tree id2;
10918 tree proto = NULL_TREE;
10919 matching_parens parens;
10920 parens.consume_open (parser);
10921 if (c_parser_next_token_is_not (parser, CPP_NAME))
10922 {
10923 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10924 {
10925 /* We have a class extension. */
10926 id2 = NULL_TREE;
10927 }
10928 else
10929 {
10930 c_parser_error (parser, "expected identifier or %<)%>");
10931 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10932 return;
10933 }
10934 }
10935 else
10936 {
10937 id2 = c_parser_peek_token (parser)->value;
10938 c_parser_consume_token (parser);
10939 }
10940 parens.skip_until_found_close (parser);
10941 if (!iface_p)
10942 {
10943 objc_start_category_implementation (id1, id2);
10944 return;
10945 }
10946 if (c_parser_next_token_is (parser, CPP_LESS))
10947 proto = c_parser_objc_protocol_refs (parser);
10948 objc_start_category_interface (id1, id2, proto, attributes);
10949 c_parser_objc_methodprotolist (parser);
10950 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10951 objc_finish_interface ();
10952 return;
10953 }
10954 if (c_parser_next_token_is (parser, CPP_COLON))
10955 {
10956 c_parser_consume_token (parser);
10957 if (c_parser_next_token_is_not (parser, CPP_NAME))
10958 {
10959 c_parser_error (parser, "expected identifier");
10960 return;
10961 }
10962 superclass = c_parser_peek_token (parser)->value;
10963 c_parser_consume_token (parser);
10964 }
10965 else
10966 superclass = NULL_TREE;
10967 if (iface_p)
10968 {
10969 tree proto = NULL_TREE;
10970 if (c_parser_next_token_is (parser, CPP_LESS))
10971 proto = c_parser_objc_protocol_refs (parser);
10972 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
10973 }
10974 else
10975 objc_start_class_implementation (id1, superclass);
10976 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10977 c_parser_objc_class_instance_variables (parser);
10978 if (iface_p)
10979 {
10980 objc_continue_interface ();
10981 c_parser_objc_methodprotolist (parser);
10982 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10983 objc_finish_interface ();
10984 }
10985 else
10986 {
10987 objc_continue_implementation ();
10988 return;
10989 }
10990 }
10991
10992 /* Parse objc-class-instance-variables.
10993
10994 objc-class-instance-variables:
10995 { objc-instance-variable-decl-list[opt] }
10996
10997 objc-instance-variable-decl-list:
10998 objc-visibility-spec
10999 objc-instance-variable-decl ;
11000 ;
11001 objc-instance-variable-decl-list objc-visibility-spec
11002 objc-instance-variable-decl-list objc-instance-variable-decl ;
11003 objc-instance-variable-decl-list ;
11004
11005 objc-visibility-spec:
11006 @private
11007 @protected
11008 @public
11009
11010 objc-instance-variable-decl:
11011 struct-declaration
11012 */
11013
11014 static void
11015 c_parser_objc_class_instance_variables (c_parser *parser)
11016 {
11017 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
11018 c_parser_consume_token (parser);
11019 while (c_parser_next_token_is_not (parser, CPP_EOF))
11020 {
11021 tree decls;
11022 /* Parse any stray semicolon. */
11023 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11024 {
11025 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11026 "extra semicolon");
11027 c_parser_consume_token (parser);
11028 continue;
11029 }
11030 /* Stop if at the end of the instance variables. */
11031 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11032 {
11033 c_parser_consume_token (parser);
11034 break;
11035 }
11036 /* Parse any objc-visibility-spec. */
11037 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11038 {
11039 c_parser_consume_token (parser);
11040 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11041 continue;
11042 }
11043 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11044 {
11045 c_parser_consume_token (parser);
11046 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11047 continue;
11048 }
11049 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11050 {
11051 c_parser_consume_token (parser);
11052 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11053 continue;
11054 }
11055 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11056 {
11057 c_parser_consume_token (parser);
11058 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11059 continue;
11060 }
11061 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11062 {
11063 c_parser_pragma (parser, pragma_external, NULL);
11064 continue;
11065 }
11066
11067 /* Parse some comma-separated declarations. */
11068 decls = c_parser_struct_declaration (parser);
11069 if (decls == NULL)
11070 {
11071 /* There is a syntax error. We want to skip the offending
11072 tokens up to the next ';' (included) or '}'
11073 (excluded). */
11074
11075 /* First, skip manually a ')' or ']'. This is because they
11076 reduce the nesting level, so c_parser_skip_until_found()
11077 wouldn't be able to skip past them. */
11078 c_token *token = c_parser_peek_token (parser);
11079 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11080 c_parser_consume_token (parser);
11081
11082 /* Then, do the standard skipping. */
11083 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11084
11085 /* We hopefully recovered. Start normal parsing again. */
11086 parser->error = false;
11087 continue;
11088 }
11089 else
11090 {
11091 /* Comma-separated instance variables are chained together
11092 in reverse order; add them one by one. */
11093 tree ivar = nreverse (decls);
11094 for (; ivar; ivar = DECL_CHAIN (ivar))
11095 objc_add_instance_variable (copy_node (ivar));
11096 }
11097 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11098 }
11099 }
11100
11101 /* Parse an objc-class-declaration.
11102
11103 objc-class-declaration:
11104 @class identifier-list ;
11105 */
11106
11107 static void
11108 c_parser_objc_class_declaration (c_parser *parser)
11109 {
11110 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11111 c_parser_consume_token (parser);
11112 /* Any identifiers, including those declared as type names, are OK
11113 here. */
11114 while (true)
11115 {
11116 tree id;
11117 if (c_parser_next_token_is_not (parser, CPP_NAME))
11118 {
11119 c_parser_error (parser, "expected identifier");
11120 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11121 parser->error = false;
11122 return;
11123 }
11124 id = c_parser_peek_token (parser)->value;
11125 objc_declare_class (id);
11126 c_parser_consume_token (parser);
11127 if (c_parser_next_token_is (parser, CPP_COMMA))
11128 c_parser_consume_token (parser);
11129 else
11130 break;
11131 }
11132 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11133 }
11134
11135 /* Parse an objc-alias-declaration.
11136
11137 objc-alias-declaration:
11138 @compatibility_alias identifier identifier ;
11139 */
11140
11141 static void
11142 c_parser_objc_alias_declaration (c_parser *parser)
11143 {
11144 tree id1, id2;
11145 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11146 c_parser_consume_token (parser);
11147 if (c_parser_next_token_is_not (parser, CPP_NAME))
11148 {
11149 c_parser_error (parser, "expected identifier");
11150 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11151 return;
11152 }
11153 id1 = c_parser_peek_token (parser)->value;
11154 c_parser_consume_token (parser);
11155 if (c_parser_next_token_is_not (parser, CPP_NAME))
11156 {
11157 c_parser_error (parser, "expected identifier");
11158 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11159 return;
11160 }
11161 id2 = c_parser_peek_token (parser)->value;
11162 c_parser_consume_token (parser);
11163 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11164 objc_declare_alias (id1, id2);
11165 }
11166
11167 /* Parse an objc-protocol-definition.
11168
11169 objc-protocol-definition:
11170 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11171 @protocol identifier-list ;
11172
11173 "@protocol identifier ;" should be resolved as "@protocol
11174 identifier-list ;": objc-methodprotolist may not start with a
11175 semicolon in the first alternative if objc-protocol-refs are
11176 omitted. */
11177
11178 static void
11179 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11180 {
11181 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11182
11183 c_parser_consume_token (parser);
11184 if (c_parser_next_token_is_not (parser, CPP_NAME))
11185 {
11186 c_parser_error (parser, "expected identifier");
11187 return;
11188 }
11189 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11190 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11191 {
11192 /* Any identifiers, including those declared as type names, are
11193 OK here. */
11194 while (true)
11195 {
11196 tree id;
11197 if (c_parser_next_token_is_not (parser, CPP_NAME))
11198 {
11199 c_parser_error (parser, "expected identifier");
11200 break;
11201 }
11202 id = c_parser_peek_token (parser)->value;
11203 objc_declare_protocol (id, attributes);
11204 c_parser_consume_token (parser);
11205 if (c_parser_next_token_is (parser, CPP_COMMA))
11206 c_parser_consume_token (parser);
11207 else
11208 break;
11209 }
11210 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11211 }
11212 else
11213 {
11214 tree id = c_parser_peek_token (parser)->value;
11215 tree proto = NULL_TREE;
11216 c_parser_consume_token (parser);
11217 if (c_parser_next_token_is (parser, CPP_LESS))
11218 proto = c_parser_objc_protocol_refs (parser);
11219 parser->objc_pq_context = true;
11220 objc_start_protocol (id, proto, attributes);
11221 c_parser_objc_methodprotolist (parser);
11222 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11223 parser->objc_pq_context = false;
11224 objc_finish_interface ();
11225 }
11226 }
11227
11228 /* Parse an objc-method-type.
11229
11230 objc-method-type:
11231 +
11232 -
11233
11234 Return true if it is a class method (+) and false if it is
11235 an instance method (-).
11236 */
11237 static inline bool
11238 c_parser_objc_method_type (c_parser *parser)
11239 {
11240 switch (c_parser_peek_token (parser)->type)
11241 {
11242 case CPP_PLUS:
11243 c_parser_consume_token (parser);
11244 return true;
11245 case CPP_MINUS:
11246 c_parser_consume_token (parser);
11247 return false;
11248 default:
11249 gcc_unreachable ();
11250 }
11251 }
11252
11253 /* Parse an objc-method-definition.
11254
11255 objc-method-definition:
11256 objc-method-type objc-method-decl ;[opt] compound-statement
11257 */
11258
11259 static void
11260 c_parser_objc_method_definition (c_parser *parser)
11261 {
11262 bool is_class_method = c_parser_objc_method_type (parser);
11263 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11264 parser->objc_pq_context = true;
11265 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11266 &expr);
11267 if (decl == error_mark_node)
11268 return; /* Bail here. */
11269
11270 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11271 {
11272 c_parser_consume_token (parser);
11273 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11274 "extra semicolon in method definition specified");
11275 }
11276
11277 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11278 {
11279 c_parser_error (parser, "expected %<{%>");
11280 return;
11281 }
11282
11283 parser->objc_pq_context = false;
11284 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11285 {
11286 add_stmt (c_parser_compound_statement (parser));
11287 objc_finish_method_definition (current_function_decl);
11288 }
11289 else
11290 {
11291 /* This code is executed when we find a method definition
11292 outside of an @implementation context (or invalid for other
11293 reasons). Parse the method (to keep going) but do not emit
11294 any code.
11295 */
11296 c_parser_compound_statement (parser);
11297 }
11298 }
11299
11300 /* Parse an objc-methodprotolist.
11301
11302 objc-methodprotolist:
11303 empty
11304 objc-methodprotolist objc-methodproto
11305 objc-methodprotolist declaration
11306 objc-methodprotolist ;
11307 @optional
11308 @required
11309
11310 The declaration is a data definition, which may be missing
11311 declaration specifiers under the same rules and diagnostics as
11312 other data definitions outside functions, and the stray semicolon
11313 is diagnosed the same way as a stray semicolon outside a
11314 function. */
11315
11316 static void
11317 c_parser_objc_methodprotolist (c_parser *parser)
11318 {
11319 while (true)
11320 {
11321 /* The list is terminated by @end. */
11322 switch (c_parser_peek_token (parser)->type)
11323 {
11324 case CPP_SEMICOLON:
11325 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11326 "ISO C does not allow extra %<;%> outside of a function");
11327 c_parser_consume_token (parser);
11328 break;
11329 case CPP_PLUS:
11330 case CPP_MINUS:
11331 c_parser_objc_methodproto (parser);
11332 break;
11333 case CPP_PRAGMA:
11334 c_parser_pragma (parser, pragma_external, NULL);
11335 break;
11336 case CPP_EOF:
11337 return;
11338 default:
11339 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11340 return;
11341 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11342 c_parser_objc_at_property_declaration (parser);
11343 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11344 {
11345 objc_set_method_opt (true);
11346 c_parser_consume_token (parser);
11347 }
11348 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11349 {
11350 objc_set_method_opt (false);
11351 c_parser_consume_token (parser);
11352 }
11353 else
11354 c_parser_declaration_or_fndef (parser, false, false, true,
11355 false, true);
11356 break;
11357 }
11358 }
11359 }
11360
11361 /* Parse an objc-methodproto.
11362
11363 objc-methodproto:
11364 objc-method-type objc-method-decl ;
11365 */
11366
11367 static void
11368 c_parser_objc_methodproto (c_parser *parser)
11369 {
11370 bool is_class_method = c_parser_objc_method_type (parser);
11371 tree decl, attributes = NULL_TREE;
11372
11373 /* Remember protocol qualifiers in prototypes. */
11374 parser->objc_pq_context = true;
11375 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11376 NULL);
11377 /* Forget protocol qualifiers now. */
11378 parser->objc_pq_context = false;
11379
11380 /* Do not allow the presence of attributes to hide an erroneous
11381 method implementation in the interface section. */
11382 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11383 {
11384 c_parser_error (parser, "expected %<;%>");
11385 return;
11386 }
11387
11388 if (decl != error_mark_node)
11389 objc_add_method_declaration (is_class_method, decl, attributes);
11390
11391 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11392 }
11393
11394 /* If we are at a position that method attributes may be present, check that
11395 there are not any parsed already (a syntax error) and then collect any
11396 specified at the current location. Finally, if new attributes were present,
11397 check that the next token is legal ( ';' for decls and '{' for defs). */
11398
11399 static bool
11400 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11401 {
11402 bool bad = false;
11403 if (*attributes)
11404 {
11405 c_parser_error (parser,
11406 "method attributes must be specified at the end only");
11407 *attributes = NULL_TREE;
11408 bad = true;
11409 }
11410
11411 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11412 *attributes = c_parser_gnu_attributes (parser);
11413
11414 /* If there were no attributes here, just report any earlier error. */
11415 if (*attributes == NULL_TREE || bad)
11416 return bad;
11417
11418 /* If the attributes are followed by a ; or {, then just report any earlier
11419 error. */
11420 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11421 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11422 return bad;
11423
11424 /* We've got attributes, but not at the end. */
11425 c_parser_error (parser,
11426 "expected %<;%> or %<{%> after method attribute definition");
11427 return true;
11428 }
11429
11430 /* Parse an objc-method-decl.
11431
11432 objc-method-decl:
11433 ( objc-type-name ) objc-selector
11434 objc-selector
11435 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11436 objc-keyword-selector objc-optparmlist
11437 gnu-attributes
11438
11439 objc-keyword-selector:
11440 objc-keyword-decl
11441 objc-keyword-selector objc-keyword-decl
11442
11443 objc-keyword-decl:
11444 objc-selector : ( objc-type-name ) identifier
11445 objc-selector : identifier
11446 : ( objc-type-name ) identifier
11447 : identifier
11448
11449 objc-optparmlist:
11450 objc-optparms objc-optellipsis
11451
11452 objc-optparms:
11453 empty
11454 objc-opt-parms , parameter-declaration
11455
11456 objc-optellipsis:
11457 empty
11458 , ...
11459 */
11460
11461 static tree
11462 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11463 tree *attributes, tree *expr)
11464 {
11465 tree type = NULL_TREE;
11466 tree sel;
11467 tree parms = NULL_TREE;
11468 bool ellipsis = false;
11469 bool attr_err = false;
11470
11471 *attributes = NULL_TREE;
11472 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11473 {
11474 matching_parens parens;
11475 parens.consume_open (parser);
11476 type = c_parser_objc_type_name (parser);
11477 parens.skip_until_found_close (parser);
11478 }
11479 sel = c_parser_objc_selector (parser);
11480 /* If there is no selector, or a colon follows, we have an
11481 objc-keyword-selector. If there is a selector, and a colon does
11482 not follow, that selector ends the objc-method-decl. */
11483 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11484 {
11485 tree tsel = sel;
11486 tree list = NULL_TREE;
11487 while (true)
11488 {
11489 tree atype = NULL_TREE, id, keyworddecl;
11490 tree param_attr = NULL_TREE;
11491 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11492 break;
11493 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11494 {
11495 c_parser_consume_token (parser);
11496 atype = c_parser_objc_type_name (parser);
11497 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11498 "expected %<)%>");
11499 }
11500 /* New ObjC allows attributes on method parameters. */
11501 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11502 param_attr = c_parser_gnu_attributes (parser);
11503 if (c_parser_next_token_is_not (parser, CPP_NAME))
11504 {
11505 c_parser_error (parser, "expected identifier");
11506 return error_mark_node;
11507 }
11508 id = c_parser_peek_token (parser)->value;
11509 c_parser_consume_token (parser);
11510 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11511 list = chainon (list, keyworddecl);
11512 tsel = c_parser_objc_selector (parser);
11513 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11514 break;
11515 }
11516
11517 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11518
11519 /* Parse the optional parameter list. Optional Objective-C
11520 method parameters follow the C syntax, and may include '...'
11521 to denote a variable number of arguments. */
11522 parms = make_node (TREE_LIST);
11523 while (c_parser_next_token_is (parser, CPP_COMMA))
11524 {
11525 struct c_parm *parm;
11526 c_parser_consume_token (parser);
11527 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11528 {
11529 ellipsis = true;
11530 c_parser_consume_token (parser);
11531 attr_err |= c_parser_objc_maybe_method_attributes
11532 (parser, attributes) ;
11533 break;
11534 }
11535 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11536 if (parm == NULL)
11537 break;
11538 parms = chainon (parms,
11539 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11540 }
11541 sel = list;
11542 }
11543 else
11544 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11545
11546 if (sel == NULL)
11547 {
11548 c_parser_error (parser, "objective-c method declaration is expected");
11549 return error_mark_node;
11550 }
11551
11552 if (attr_err)
11553 return error_mark_node;
11554
11555 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11556 }
11557
11558 /* Parse an objc-type-name.
11559
11560 objc-type-name:
11561 objc-type-qualifiers[opt] type-name
11562 objc-type-qualifiers[opt]
11563
11564 objc-type-qualifiers:
11565 objc-type-qualifier
11566 objc-type-qualifiers objc-type-qualifier
11567
11568 objc-type-qualifier: one of
11569 in out inout bycopy byref oneway
11570 */
11571
11572 static tree
11573 c_parser_objc_type_name (c_parser *parser)
11574 {
11575 tree quals = NULL_TREE;
11576 struct c_type_name *type_name = NULL;
11577 tree type = NULL_TREE;
11578 while (true)
11579 {
11580 c_token *token = c_parser_peek_token (parser);
11581 if (token->type == CPP_KEYWORD
11582 && (token->keyword == RID_IN
11583 || token->keyword == RID_OUT
11584 || token->keyword == RID_INOUT
11585 || token->keyword == RID_BYCOPY
11586 || token->keyword == RID_BYREF
11587 || token->keyword == RID_ONEWAY))
11588 {
11589 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11590 c_parser_consume_token (parser);
11591 }
11592 else
11593 break;
11594 }
11595 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11596 type_name = c_parser_type_name (parser);
11597 if (type_name)
11598 type = groktypename (type_name, NULL, NULL);
11599
11600 /* If the type is unknown, and error has already been produced and
11601 we need to recover from the error. In that case, use NULL_TREE
11602 for the type, as if no type had been specified; this will use the
11603 default type ('id') which is good for error recovery. */
11604 if (type == error_mark_node)
11605 type = NULL_TREE;
11606
11607 return build_tree_list (quals, type);
11608 }
11609
11610 /* Parse objc-protocol-refs.
11611
11612 objc-protocol-refs:
11613 < identifier-list >
11614 */
11615
11616 static tree
11617 c_parser_objc_protocol_refs (c_parser *parser)
11618 {
11619 tree list = NULL_TREE;
11620 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11621 c_parser_consume_token (parser);
11622 /* Any identifiers, including those declared as type names, are OK
11623 here. */
11624 while (true)
11625 {
11626 tree id;
11627 if (c_parser_next_token_is_not (parser, CPP_NAME))
11628 {
11629 c_parser_error (parser, "expected identifier");
11630 break;
11631 }
11632 id = c_parser_peek_token (parser)->value;
11633 list = chainon (list, build_tree_list (NULL_TREE, id));
11634 c_parser_consume_token (parser);
11635 if (c_parser_next_token_is (parser, CPP_COMMA))
11636 c_parser_consume_token (parser);
11637 else
11638 break;
11639 }
11640 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11641 return list;
11642 }
11643
11644 /* Parse an objc-try-catch-finally-statement.
11645
11646 objc-try-catch-finally-statement:
11647 @try compound-statement objc-catch-list[opt]
11648 @try compound-statement objc-catch-list[opt] @finally compound-statement
11649
11650 objc-catch-list:
11651 @catch ( objc-catch-parameter-declaration ) compound-statement
11652 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11653
11654 objc-catch-parameter-declaration:
11655 parameter-declaration
11656 '...'
11657
11658 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11659
11660 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11661 for C++. Keep them in sync. */
11662
11663 static void
11664 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11665 {
11666 location_t location;
11667 tree stmt;
11668
11669 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11670 c_parser_consume_token (parser);
11671 location = c_parser_peek_token (parser)->location;
11672 objc_maybe_warn_exceptions (location);
11673 stmt = c_parser_compound_statement (parser);
11674 objc_begin_try_stmt (location, stmt);
11675
11676 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11677 {
11678 struct c_parm *parm;
11679 tree parameter_declaration = error_mark_node;
11680 bool seen_open_paren = false;
11681
11682 c_parser_consume_token (parser);
11683 matching_parens parens;
11684 if (!parens.require_open (parser))
11685 seen_open_paren = true;
11686 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11687 {
11688 /* We have "@catch (...)" (where the '...' are literally
11689 what is in the code). Skip the '...'.
11690 parameter_declaration is set to NULL_TREE, and
11691 objc_being_catch_clauses() knows that that means
11692 '...'. */
11693 c_parser_consume_token (parser);
11694 parameter_declaration = NULL_TREE;
11695 }
11696 else
11697 {
11698 /* We have "@catch (NSException *exception)" or something
11699 like that. Parse the parameter declaration. */
11700 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11701 if (parm == NULL)
11702 parameter_declaration = error_mark_node;
11703 else
11704 parameter_declaration = grokparm (parm, NULL);
11705 }
11706 if (seen_open_paren)
11707 parens.require_close (parser);
11708 else
11709 {
11710 /* If there was no open parenthesis, we are recovering from
11711 an error, and we are trying to figure out what mistake
11712 the user has made. */
11713
11714 /* If there is an immediate closing parenthesis, the user
11715 probably forgot the opening one (ie, they typed "@catch
11716 NSException *e)". Parse the closing parenthesis and keep
11717 going. */
11718 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11719 c_parser_consume_token (parser);
11720
11721 /* If these is no immediate closing parenthesis, the user
11722 probably doesn't know that parenthesis are required at
11723 all (ie, they typed "@catch NSException *e"). So, just
11724 forget about the closing parenthesis and keep going. */
11725 }
11726 objc_begin_catch_clause (parameter_declaration);
11727 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11728 c_parser_compound_statement_nostart (parser);
11729 objc_finish_catch_clause ();
11730 }
11731 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11732 {
11733 c_parser_consume_token (parser);
11734 location = c_parser_peek_token (parser)->location;
11735 stmt = c_parser_compound_statement (parser);
11736 objc_build_finally_clause (location, stmt);
11737 }
11738 objc_finish_try_stmt ();
11739 }
11740
11741 /* Parse an objc-synchronized-statement.
11742
11743 objc-synchronized-statement:
11744 @synchronized ( expression ) compound-statement
11745 */
11746
11747 static void
11748 c_parser_objc_synchronized_statement (c_parser *parser)
11749 {
11750 location_t loc;
11751 tree expr, stmt;
11752 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11753 c_parser_consume_token (parser);
11754 loc = c_parser_peek_token (parser)->location;
11755 objc_maybe_warn_exceptions (loc);
11756 matching_parens parens;
11757 if (parens.require_open (parser))
11758 {
11759 struct c_expr ce = c_parser_expression (parser);
11760 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11761 expr = ce.value;
11762 expr = c_fully_fold (expr, false, NULL);
11763 parens.skip_until_found_close (parser);
11764 }
11765 else
11766 expr = error_mark_node;
11767 stmt = c_parser_compound_statement (parser);
11768 objc_build_synchronized (loc, expr, stmt);
11769 }
11770
11771 /* Parse an objc-selector; return NULL_TREE without an error if the
11772 next token is not an objc-selector.
11773
11774 objc-selector:
11775 identifier
11776 one of
11777 enum struct union if else while do for switch case default
11778 break continue return goto asm sizeof typeof __alignof
11779 unsigned long const short volatile signed restrict _Complex
11780 in out inout bycopy byref oneway int char float double void _Bool
11781 _Atomic
11782
11783 ??? Why this selection of keywords but not, for example, storage
11784 class specifiers? */
11785
11786 static tree
11787 c_parser_objc_selector (c_parser *parser)
11788 {
11789 c_token *token = c_parser_peek_token (parser);
11790 tree value = token->value;
11791 if (token->type == CPP_NAME)
11792 {
11793 c_parser_consume_token (parser);
11794 return value;
11795 }
11796 if (token->type != CPP_KEYWORD)
11797 return NULL_TREE;
11798 switch (token->keyword)
11799 {
11800 case RID_ENUM:
11801 case RID_STRUCT:
11802 case RID_UNION:
11803 case RID_IF:
11804 case RID_ELSE:
11805 case RID_WHILE:
11806 case RID_DO:
11807 case RID_FOR:
11808 case RID_SWITCH:
11809 case RID_CASE:
11810 case RID_DEFAULT:
11811 case RID_BREAK:
11812 case RID_CONTINUE:
11813 case RID_RETURN:
11814 case RID_GOTO:
11815 case RID_ASM:
11816 case RID_SIZEOF:
11817 case RID_TYPEOF:
11818 case RID_ALIGNOF:
11819 case RID_UNSIGNED:
11820 case RID_LONG:
11821 case RID_CONST:
11822 case RID_SHORT:
11823 case RID_VOLATILE:
11824 case RID_SIGNED:
11825 case RID_RESTRICT:
11826 case RID_COMPLEX:
11827 case RID_IN:
11828 case RID_OUT:
11829 case RID_INOUT:
11830 case RID_BYCOPY:
11831 case RID_BYREF:
11832 case RID_ONEWAY:
11833 case RID_INT:
11834 case RID_CHAR:
11835 case RID_FLOAT:
11836 case RID_DOUBLE:
11837 CASE_RID_FLOATN_NX:
11838 case RID_VOID:
11839 case RID_BOOL:
11840 case RID_ATOMIC:
11841 case RID_AUTO_TYPE:
11842 case RID_INT_N_0:
11843 case RID_INT_N_1:
11844 case RID_INT_N_2:
11845 case RID_INT_N_3:
11846 c_parser_consume_token (parser);
11847 return value;
11848 default:
11849 return NULL_TREE;
11850 }
11851 }
11852
11853 /* Parse an objc-selector-arg.
11854
11855 objc-selector-arg:
11856 objc-selector
11857 objc-keywordname-list
11858
11859 objc-keywordname-list:
11860 objc-keywordname
11861 objc-keywordname-list objc-keywordname
11862
11863 objc-keywordname:
11864 objc-selector :
11865 :
11866 */
11867
11868 static tree
11869 c_parser_objc_selector_arg (c_parser *parser)
11870 {
11871 tree sel = c_parser_objc_selector (parser);
11872 tree list = NULL_TREE;
11873 if (sel
11874 && c_parser_next_token_is_not (parser, CPP_COLON)
11875 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11876 return sel;
11877 while (true)
11878 {
11879 if (c_parser_next_token_is (parser, CPP_SCOPE))
11880 {
11881 c_parser_consume_token (parser);
11882 list = chainon (list, build_tree_list (sel, NULL_TREE));
11883 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11884 }
11885 else
11886 {
11887 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11888 return list;
11889 list = chainon (list, build_tree_list (sel, NULL_TREE));
11890 }
11891 sel = c_parser_objc_selector (parser);
11892 if (!sel
11893 && c_parser_next_token_is_not (parser, CPP_COLON)
11894 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11895 break;
11896 }
11897 return list;
11898 }
11899
11900 /* Parse an objc-receiver.
11901
11902 objc-receiver:
11903 expression
11904 class-name
11905 type-name
11906 */
11907
11908 static tree
11909 c_parser_objc_receiver (c_parser *parser)
11910 {
11911 location_t loc = c_parser_peek_token (parser)->location;
11912
11913 if (c_parser_peek_token (parser)->type == CPP_NAME
11914 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11915 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11916 {
11917 tree id = c_parser_peek_token (parser)->value;
11918 c_parser_consume_token (parser);
11919 return objc_get_class_reference (id);
11920 }
11921 struct c_expr ce = c_parser_expression (parser);
11922 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11923 return c_fully_fold (ce.value, false, NULL);
11924 }
11925
11926 /* Parse objc-message-args.
11927
11928 objc-message-args:
11929 objc-selector
11930 objc-keywordarg-list
11931
11932 objc-keywordarg-list:
11933 objc-keywordarg
11934 objc-keywordarg-list objc-keywordarg
11935
11936 objc-keywordarg:
11937 objc-selector : objc-keywordexpr
11938 : objc-keywordexpr
11939 */
11940
11941 static tree
11942 c_parser_objc_message_args (c_parser *parser)
11943 {
11944 tree sel = c_parser_objc_selector (parser);
11945 tree list = NULL_TREE;
11946 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11947 return sel;
11948 while (true)
11949 {
11950 tree keywordexpr;
11951 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11952 return error_mark_node;
11953 keywordexpr = c_parser_objc_keywordexpr (parser);
11954 list = chainon (list, build_tree_list (sel, keywordexpr));
11955 sel = c_parser_objc_selector (parser);
11956 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11957 break;
11958 }
11959 return list;
11960 }
11961
11962 /* Parse an objc-keywordexpr.
11963
11964 objc-keywordexpr:
11965 nonempty-expr-list
11966 */
11967
11968 static tree
11969 c_parser_objc_keywordexpr (c_parser *parser)
11970 {
11971 tree ret;
11972 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11973 NULL, NULL, NULL, NULL);
11974 if (vec_safe_length (expr_list) == 1)
11975 {
11976 /* Just return the expression, remove a level of
11977 indirection. */
11978 ret = (*expr_list)[0];
11979 }
11980 else
11981 {
11982 /* We have a comma expression, we will collapse later. */
11983 ret = build_tree_list_vec (expr_list);
11984 }
11985 release_tree_vector (expr_list);
11986 return ret;
11987 }
11988
11989 /* A check, needed in several places, that ObjC interface, implementation or
11990 method definitions are not prefixed by incorrect items. */
11991 static bool
11992 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11993 struct c_declspecs *specs)
11994 {
11995 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11996 || specs->typespec_kind != ctsk_none)
11997 {
11998 c_parser_error (parser,
11999 "no type or storage class may be specified here,");
12000 c_parser_skip_to_end_of_block_or_statement (parser);
12001 return true;
12002 }
12003 return false;
12004 }
12005
12006 /* Parse an Objective-C @property declaration. The syntax is:
12007
12008 objc-property-declaration:
12009 '@property' objc-property-attributes[opt] struct-declaration ;
12010
12011 objc-property-attributes:
12012 '(' objc-property-attribute-list ')'
12013
12014 objc-property-attribute-list:
12015 objc-property-attribute
12016 objc-property-attribute-list, objc-property-attribute
12017
12018 objc-property-attribute
12019 'getter' = identifier
12020 'setter' = identifier
12021 'readonly'
12022 'readwrite'
12023 'assign'
12024 'retain'
12025 'copy'
12026 'nonatomic'
12027
12028 For example:
12029 @property NSString *name;
12030 @property (readonly) id object;
12031 @property (retain, nonatomic, getter=getTheName) id name;
12032 @property int a, b, c;
12033
12034 PS: This function is identical to cp_parser_objc_at_propery_declaration
12035 for C++. Keep them in sync. */
12036 static void
12037 c_parser_objc_at_property_declaration (c_parser *parser)
12038 {
12039 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12040 location_t loc = c_parser_peek_token (parser)->location;
12041 c_parser_consume_token (parser); /* Eat '@property'. */
12042
12043 /* Parse the optional attribute list.
12044
12045 A list of parsed, but not verified, attributes. */
12046 vec<property_attribute_info *> prop_attr_list = vNULL;
12047
12048 bool syntax_error = false;
12049 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12050 {
12051 matching_parens parens;
12052
12053 location_t attr_start = c_parser_peek_token (parser)->location;
12054 /* Eat the '(' */
12055 parens.consume_open (parser);
12056
12057 /* Property attribute keywords are valid now. */
12058 parser->objc_property_attr_context = true;
12059
12060 /* Allow @property (), with a warning. */
12061 location_t attr_end = c_parser_peek_token (parser)->location;
12062
12063 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12064 {
12065 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12066 warning_at (attr_comb, OPT_Wattributes,
12067 "empty property attribute list");
12068 }
12069 else
12070 while (true)
12071 {
12072 c_token *token = c_parser_peek_token (parser);
12073 attr_start = token->location;
12074 attr_end = get_finish (token->location);
12075 location_t attr_comb = make_location (attr_start, attr_start,
12076 attr_end);
12077
12078 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12079 {
12080 warning_at (attr_comb, OPT_Wattributes,
12081 "missing property attribute");
12082 if (token->type == CPP_CLOSE_PAREN)
12083 break;
12084 c_parser_consume_token (parser);
12085 continue;
12086 }
12087
12088 tree attr_name = NULL_TREE;
12089 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12090 bool add_at = false;
12091 if (token->type == CPP_KEYWORD)
12092 {
12093 keyword = token->keyword;
12094 if (OBJC_IS_AT_KEYWORD (keyword))
12095 {
12096 /* For '@' keywords the token value has the keyword,
12097 prepend the '@' for diagnostics. */
12098 attr_name = token->value;
12099 add_at = true;
12100 }
12101 else
12102 attr_name = ridpointers[(int)keyword];
12103 }
12104 else if (token->type == CPP_NAME)
12105 attr_name = token->value;
12106 c_parser_consume_token (parser);
12107
12108 enum objc_property_attribute_kind prop_kind
12109 = objc_prop_attr_kind_for_rid (keyword);
12110 property_attribute_info *prop
12111 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12112 prop_attr_list.safe_push (prop);
12113
12114 tree meth_name;
12115 switch (prop->prop_kind)
12116 {
12117 default: break;
12118 case OBJC_PROPERTY_ATTR_UNKNOWN:
12119 if (attr_name)
12120 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12121 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12122 else
12123 error_at (attr_comb, "unknown property attribute");
12124 prop->parse_error = syntax_error = true;
12125 break;
12126
12127 case OBJC_PROPERTY_ATTR_GETTER:
12128 case OBJC_PROPERTY_ATTR_SETTER:
12129 if (c_parser_next_token_is_not (parser, CPP_EQ))
12130 {
12131 attr_comb = make_location (attr_end, attr_start, attr_end);
12132 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12133 attr_name);
12134 prop->parse_error = syntax_error = true;
12135 break;
12136 }
12137 token = c_parser_peek_token (parser);
12138 attr_end = token->location;
12139 c_parser_consume_token (parser); /* eat the = */
12140 if (c_parser_next_token_is_not (parser, CPP_NAME))
12141 {
12142 attr_comb = make_location (attr_end, attr_start, attr_end);
12143 error_at (attr_comb, "expected %qE selector name",
12144 attr_name);
12145 prop->parse_error = syntax_error = true;
12146 break;
12147 }
12148 /* Get the end of the method name, and consume the name. */
12149 token = c_parser_peek_token (parser);
12150 attr_end = get_finish (token->location);
12151 meth_name = token->value;
12152 c_parser_consume_token (parser);
12153 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12154 {
12155 if (c_parser_next_token_is_not (parser, CPP_COLON))
12156 {
12157 attr_comb = make_location (attr_end, attr_start,
12158 attr_end);
12159 error_at (attr_comb, "setter method names must"
12160 " terminate with %<:%>");
12161 prop->parse_error = syntax_error = true;
12162 }
12163 else
12164 {
12165 attr_end = get_finish (c_parser_peek_token
12166 (parser)->location);
12167 c_parser_consume_token (parser);
12168 }
12169 attr_comb = make_location (attr_start, attr_start,
12170 attr_end);
12171 }
12172 else
12173 attr_comb = make_location (attr_start, attr_start,
12174 attr_end);
12175 prop->ident = meth_name;
12176 /* Updated location including all that was successfully
12177 parsed. */
12178 prop->prop_loc = attr_comb;
12179 break;
12180 }
12181
12182 /* If we see a comma here, then keep going - even if we already
12183 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12184 this makes a more useful output and avoid spurious warnings about
12185 missing attributes that are, in fact, specified after the one with
12186 the syntax error. */
12187 if (c_parser_next_token_is (parser, CPP_COMMA))
12188 c_parser_consume_token (parser);
12189 else
12190 break;
12191 }
12192 parser->objc_property_attr_context = false;
12193
12194 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12195 /* We don't really want to chew the whole of the file looking for a
12196 matching closing parenthesis, so we will try to read the decl and
12197 let the error handling for that close out the statement. */
12198 ;
12199 else
12200 syntax_error = false, parens.skip_until_found_close (parser);
12201 }
12202
12203 /* 'properties' is the list of properties that we read. Usually a
12204 single one, but maybe more (eg, in "@property int a, b, c;" there
12205 are three). */
12206 tree properties = c_parser_struct_declaration (parser);
12207
12208 if (properties == error_mark_node)
12209 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12210 else
12211 {
12212 if (properties == NULL_TREE)
12213 c_parser_error (parser, "expected identifier");
12214 else
12215 {
12216 /* Comma-separated properties are chained together in reverse order;
12217 add them one by one. */
12218 properties = nreverse (properties);
12219 for (; properties; properties = TREE_CHAIN (properties))
12220 objc_add_property_declaration (loc, copy_node (properties),
12221 prop_attr_list);
12222 }
12223 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12224 }
12225
12226 while (!prop_attr_list.is_empty())
12227 delete prop_attr_list.pop ();
12228 prop_attr_list.release ();
12229 parser->error = false;
12230 }
12231
12232 /* Parse an Objective-C @synthesize declaration. The syntax is:
12233
12234 objc-synthesize-declaration:
12235 @synthesize objc-synthesize-identifier-list ;
12236
12237 objc-synthesize-identifier-list:
12238 objc-synthesize-identifier
12239 objc-synthesize-identifier-list, objc-synthesize-identifier
12240
12241 objc-synthesize-identifier
12242 identifier
12243 identifier = identifier
12244
12245 For example:
12246 @synthesize MyProperty;
12247 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12248
12249 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12250 for C++. Keep them in sync.
12251 */
12252 static void
12253 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12254 {
12255 tree list = NULL_TREE;
12256 location_t loc;
12257 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12258 loc = c_parser_peek_token (parser)->location;
12259
12260 c_parser_consume_token (parser);
12261 while (true)
12262 {
12263 tree property, ivar;
12264 if (c_parser_next_token_is_not (parser, CPP_NAME))
12265 {
12266 c_parser_error (parser, "expected identifier");
12267 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12268 /* Once we find the semicolon, we can resume normal parsing.
12269 We have to reset parser->error manually because
12270 c_parser_skip_until_found() won't reset it for us if the
12271 next token is precisely a semicolon. */
12272 parser->error = false;
12273 return;
12274 }
12275 property = c_parser_peek_token (parser)->value;
12276 c_parser_consume_token (parser);
12277 if (c_parser_next_token_is (parser, CPP_EQ))
12278 {
12279 c_parser_consume_token (parser);
12280 if (c_parser_next_token_is_not (parser, CPP_NAME))
12281 {
12282 c_parser_error (parser, "expected identifier");
12283 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12284 parser->error = false;
12285 return;
12286 }
12287 ivar = c_parser_peek_token (parser)->value;
12288 c_parser_consume_token (parser);
12289 }
12290 else
12291 ivar = NULL_TREE;
12292 list = chainon (list, build_tree_list (ivar, property));
12293 if (c_parser_next_token_is (parser, CPP_COMMA))
12294 c_parser_consume_token (parser);
12295 else
12296 break;
12297 }
12298 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12299 objc_add_synthesize_declaration (loc, list);
12300 }
12301
12302 /* Parse an Objective-C @dynamic declaration. The syntax is:
12303
12304 objc-dynamic-declaration:
12305 @dynamic identifier-list ;
12306
12307 For example:
12308 @dynamic MyProperty;
12309 @dynamic MyProperty, AnotherProperty;
12310
12311 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12312 for C++. Keep them in sync.
12313 */
12314 static void
12315 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12316 {
12317 tree list = NULL_TREE;
12318 location_t loc;
12319 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12320 loc = c_parser_peek_token (parser)->location;
12321
12322 c_parser_consume_token (parser);
12323 while (true)
12324 {
12325 tree property;
12326 if (c_parser_next_token_is_not (parser, CPP_NAME))
12327 {
12328 c_parser_error (parser, "expected identifier");
12329 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12330 parser->error = false;
12331 return;
12332 }
12333 property = c_parser_peek_token (parser)->value;
12334 list = chainon (list, build_tree_list (NULL_TREE, property));
12335 c_parser_consume_token (parser);
12336 if (c_parser_next_token_is (parser, CPP_COMMA))
12337 c_parser_consume_token (parser);
12338 else
12339 break;
12340 }
12341 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12342 objc_add_dynamic_declaration (loc, list);
12343 }
12344
12345 \f
12346 /* Parse a pragma GCC ivdep. */
12347
12348 static bool
12349 c_parse_pragma_ivdep (c_parser *parser)
12350 {
12351 c_parser_consume_pragma (parser);
12352 c_parser_skip_to_pragma_eol (parser);
12353 return true;
12354 }
12355
12356 /* Parse a pragma GCC unroll. */
12357
12358 static unsigned short
12359 c_parser_pragma_unroll (c_parser *parser)
12360 {
12361 unsigned short unroll;
12362 c_parser_consume_pragma (parser);
12363 location_t location = c_parser_peek_token (parser)->location;
12364 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12365 mark_exp_read (expr);
12366 expr = c_fully_fold (expr, false, NULL);
12367 HOST_WIDE_INT lunroll = 0;
12368 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12369 || TREE_CODE (expr) != INTEGER_CST
12370 || (lunroll = tree_to_shwi (expr)) < 0
12371 || lunroll >= USHRT_MAX)
12372 {
12373 error_at (location, "%<#pragma GCC unroll%> requires an"
12374 " assignment-expression that evaluates to a non-negative"
12375 " integral constant less than %u", USHRT_MAX);
12376 unroll = 0;
12377 }
12378 else
12379 {
12380 unroll = (unsigned short)lunroll;
12381 if (unroll == 0)
12382 unroll = 1;
12383 }
12384
12385 c_parser_skip_to_pragma_eol (parser);
12386 return unroll;
12387 }
12388
12389 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12390 should be considered, statements. ALLOW_STMT is true if we're within
12391 the context of a function and such pragmas are to be allowed. Returns
12392 true if we actually parsed such a pragma. */
12393
12394 static bool
12395 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12396 {
12397 unsigned int id;
12398 const char *construct = NULL;
12399
12400 id = c_parser_peek_token (parser)->pragma_kind;
12401 gcc_assert (id != PRAGMA_NONE);
12402
12403 switch (id)
12404 {
12405 case PRAGMA_OACC_DECLARE:
12406 c_parser_oacc_declare (parser);
12407 return false;
12408
12409 case PRAGMA_OACC_ENTER_DATA:
12410 if (context != pragma_compound)
12411 {
12412 construct = "acc enter data";
12413 in_compound:
12414 if (context == pragma_stmt)
12415 {
12416 error_at (c_parser_peek_token (parser)->location,
12417 "%<#pragma %s%> may only be used in compound "
12418 "statements", construct);
12419 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12420 return true;
12421 }
12422 goto bad_stmt;
12423 }
12424 c_parser_oacc_enter_exit_data (parser, true);
12425 return false;
12426
12427 case PRAGMA_OACC_EXIT_DATA:
12428 if (context != pragma_compound)
12429 {
12430 construct = "acc exit data";
12431 goto in_compound;
12432 }
12433 c_parser_oacc_enter_exit_data (parser, false);
12434 return false;
12435
12436 case PRAGMA_OACC_ROUTINE:
12437 if (context != pragma_external)
12438 {
12439 error_at (c_parser_peek_token (parser)->location,
12440 "%<#pragma acc routine%> must be at file scope");
12441 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12442 return false;
12443 }
12444 c_parser_oacc_routine (parser, context);
12445 return false;
12446
12447 case PRAGMA_OACC_UPDATE:
12448 if (context != pragma_compound)
12449 {
12450 construct = "acc update";
12451 goto in_compound;
12452 }
12453 c_parser_oacc_update (parser);
12454 return false;
12455
12456 case PRAGMA_OMP_BARRIER:
12457 if (context != pragma_compound)
12458 {
12459 construct = "omp barrier";
12460 goto in_compound;
12461 }
12462 c_parser_omp_barrier (parser);
12463 return false;
12464
12465 case PRAGMA_OMP_DEPOBJ:
12466 if (context != pragma_compound)
12467 {
12468 construct = "omp depobj";
12469 goto in_compound;
12470 }
12471 c_parser_omp_depobj (parser);
12472 return false;
12473
12474 case PRAGMA_OMP_FLUSH:
12475 if (context != pragma_compound)
12476 {
12477 construct = "omp flush";
12478 goto in_compound;
12479 }
12480 c_parser_omp_flush (parser);
12481 return false;
12482
12483 case PRAGMA_OMP_TASKWAIT:
12484 if (context != pragma_compound)
12485 {
12486 construct = "omp taskwait";
12487 goto in_compound;
12488 }
12489 c_parser_omp_taskwait (parser);
12490 return false;
12491
12492 case PRAGMA_OMP_TASKYIELD:
12493 if (context != pragma_compound)
12494 {
12495 construct = "omp taskyield";
12496 goto in_compound;
12497 }
12498 c_parser_omp_taskyield (parser);
12499 return false;
12500
12501 case PRAGMA_OMP_CANCEL:
12502 if (context != pragma_compound)
12503 {
12504 construct = "omp cancel";
12505 goto in_compound;
12506 }
12507 c_parser_omp_cancel (parser);
12508 return false;
12509
12510 case PRAGMA_OMP_CANCELLATION_POINT:
12511 return c_parser_omp_cancellation_point (parser, context);
12512
12513 case PRAGMA_OMP_THREADPRIVATE:
12514 c_parser_omp_threadprivate (parser);
12515 return false;
12516
12517 case PRAGMA_OMP_TARGET:
12518 return c_parser_omp_target (parser, context, if_p);
12519
12520 case PRAGMA_OMP_END_DECLARE_TARGET:
12521 c_parser_omp_end_declare_target (parser);
12522 return false;
12523
12524 case PRAGMA_OMP_SCAN:
12525 error_at (c_parser_peek_token (parser)->location,
12526 "%<#pragma omp scan%> may only be used in "
12527 "a loop construct with %<inscan%> %<reduction%> clause");
12528 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12529 return false;
12530
12531 case PRAGMA_OMP_SECTION:
12532 error_at (c_parser_peek_token (parser)->location,
12533 "%<#pragma omp section%> may only be used in "
12534 "%<#pragma omp sections%> construct");
12535 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12536 return false;
12537
12538 case PRAGMA_OMP_DECLARE:
12539 return c_parser_omp_declare (parser, context);
12540
12541 case PRAGMA_OMP_REQUIRES:
12542 if (context != pragma_external)
12543 {
12544 error_at (c_parser_peek_token (parser)->location,
12545 "%<#pragma omp requires%> may only be used at file scope");
12546 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12547 return false;
12548 }
12549 c_parser_omp_requires (parser);
12550 return false;
12551
12552 case PRAGMA_OMP_NOTHING:
12553 c_parser_omp_nothing (parser);
12554 return false;
12555
12556 case PRAGMA_OMP_ERROR:
12557 return c_parser_omp_error (parser, context);
12558
12559 case PRAGMA_OMP_ORDERED:
12560 return c_parser_omp_ordered (parser, context, if_p);
12561
12562 case PRAGMA_IVDEP:
12563 {
12564 const bool ivdep = c_parse_pragma_ivdep (parser);
12565 unsigned short unroll;
12566 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12567 unroll = c_parser_pragma_unroll (parser);
12568 else
12569 unroll = 0;
12570 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12571 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12572 && !c_parser_next_token_is_keyword (parser, RID_DO))
12573 {
12574 c_parser_error (parser, "for, while or do statement expected");
12575 return false;
12576 }
12577 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12578 c_parser_for_statement (parser, ivdep, unroll, if_p);
12579 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12580 c_parser_while_statement (parser, ivdep, unroll, if_p);
12581 else
12582 c_parser_do_statement (parser, ivdep, unroll);
12583 }
12584 return true;
12585
12586 case PRAGMA_UNROLL:
12587 {
12588 unsigned short unroll = c_parser_pragma_unroll (parser);
12589 bool ivdep;
12590 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12591 ivdep = c_parse_pragma_ivdep (parser);
12592 else
12593 ivdep = false;
12594 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12595 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12596 && !c_parser_next_token_is_keyword (parser, RID_DO))
12597 {
12598 c_parser_error (parser, "for, while or do statement expected");
12599 return false;
12600 }
12601 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12602 c_parser_for_statement (parser, ivdep, unroll, if_p);
12603 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12604 c_parser_while_statement (parser, ivdep, unroll, if_p);
12605 else
12606 c_parser_do_statement (parser, ivdep, unroll);
12607 }
12608 return true;
12609
12610 case PRAGMA_GCC_PCH_PREPROCESS:
12611 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12612 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12613 return false;
12614
12615 case PRAGMA_OACC_WAIT:
12616 if (context != pragma_compound)
12617 {
12618 construct = "acc wait";
12619 goto in_compound;
12620 }
12621 /* FALL THROUGH. */
12622
12623 default:
12624 if (id < PRAGMA_FIRST_EXTERNAL)
12625 {
12626 if (context != pragma_stmt && context != pragma_compound)
12627 {
12628 bad_stmt:
12629 c_parser_error (parser, "expected declaration specifiers");
12630 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12631 return false;
12632 }
12633 c_parser_omp_construct (parser, if_p);
12634 return true;
12635 }
12636 break;
12637 }
12638
12639 c_parser_consume_pragma (parser);
12640 c_invoke_pragma_handler (id);
12641
12642 /* Skip to EOL, but suppress any error message. Those will have been
12643 generated by the handler routine through calling error, as opposed
12644 to calling c_parser_error. */
12645 parser->error = true;
12646 c_parser_skip_to_pragma_eol (parser);
12647
12648 return false;
12649 }
12650
12651 /* The interface the pragma parsers have to the lexer. */
12652
12653 enum cpp_ttype
12654 pragma_lex (tree *value, location_t *loc)
12655 {
12656 c_token *tok = c_parser_peek_token (the_parser);
12657 enum cpp_ttype ret = tok->type;
12658
12659 *value = tok->value;
12660 if (loc)
12661 *loc = tok->location;
12662
12663 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12664 ret = CPP_EOF;
12665 else if (ret == CPP_STRING)
12666 *value = c_parser_string_literal (the_parser, false, false).value;
12667 else
12668 {
12669 if (ret == CPP_KEYWORD)
12670 ret = CPP_NAME;
12671 c_parser_consume_token (the_parser);
12672 }
12673
12674 return ret;
12675 }
12676
12677 static void
12678 c_parser_pragma_pch_preprocess (c_parser *parser)
12679 {
12680 tree name = NULL;
12681
12682 parser->lex_joined_string = true;
12683 c_parser_consume_pragma (parser);
12684 if (c_parser_next_token_is (parser, CPP_STRING))
12685 {
12686 name = c_parser_peek_token (parser)->value;
12687 c_parser_consume_token (parser);
12688 }
12689 else
12690 c_parser_error (parser, "expected string literal");
12691 c_parser_skip_to_pragma_eol (parser);
12692 parser->lex_joined_string = false;
12693
12694 if (name)
12695 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12696 }
12697 \f
12698 /* OpenACC and OpenMP parsing routines. */
12699
12700 /* Returns name of the next clause.
12701 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12702 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12703 returned and the token is consumed. */
12704
12705 static pragma_omp_clause
12706 c_parser_omp_clause_name (c_parser *parser)
12707 {
12708 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12709
12710 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12711 result = PRAGMA_OACC_CLAUSE_AUTO;
12712 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12713 result = PRAGMA_OMP_CLAUSE_IF;
12714 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12715 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12716 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12717 result = PRAGMA_OMP_CLAUSE_FOR;
12718 else if (c_parser_next_token_is (parser, CPP_NAME))
12719 {
12720 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12721
12722 switch (p[0])
12723 {
12724 case 'a':
12725 if (!strcmp ("affinity", p))
12726 result = PRAGMA_OMP_CLAUSE_AFFINITY;
12727 else if (!strcmp ("aligned", p))
12728 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12729 else if (!strcmp ("allocate", p))
12730 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12731 else if (!strcmp ("async", p))
12732 result = PRAGMA_OACC_CLAUSE_ASYNC;
12733 else if (!strcmp ("attach", p))
12734 result = PRAGMA_OACC_CLAUSE_ATTACH;
12735 break;
12736 case 'b':
12737 if (!strcmp ("bind", p))
12738 result = PRAGMA_OMP_CLAUSE_BIND;
12739 break;
12740 case 'c':
12741 if (!strcmp ("collapse", p))
12742 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12743 else if (!strcmp ("copy", p))
12744 result = PRAGMA_OACC_CLAUSE_COPY;
12745 else if (!strcmp ("copyin", p))
12746 result = PRAGMA_OMP_CLAUSE_COPYIN;
12747 else if (!strcmp ("copyout", p))
12748 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12749 else if (!strcmp ("copyprivate", p))
12750 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12751 else if (!strcmp ("create", p))
12752 result = PRAGMA_OACC_CLAUSE_CREATE;
12753 break;
12754 case 'd':
12755 if (!strcmp ("defaultmap", p))
12756 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12757 else if (!strcmp ("delete", p))
12758 result = PRAGMA_OACC_CLAUSE_DELETE;
12759 else if (!strcmp ("depend", p))
12760 result = PRAGMA_OMP_CLAUSE_DEPEND;
12761 else if (!strcmp ("detach", p))
12762 result = PRAGMA_OACC_CLAUSE_DETACH;
12763 else if (!strcmp ("device", p))
12764 result = PRAGMA_OMP_CLAUSE_DEVICE;
12765 else if (!strcmp ("deviceptr", p))
12766 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12767 else if (!strcmp ("device_resident", p))
12768 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12769 else if (!strcmp ("device_type", p))
12770 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12771 else if (!strcmp ("dist_schedule", p))
12772 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12773 break;
12774 case 'e':
12775 if (!strcmp ("enter", p))
12776 result = PRAGMA_OMP_CLAUSE_ENTER;
12777 break;
12778 case 'f':
12779 if (!strcmp ("filter", p))
12780 result = PRAGMA_OMP_CLAUSE_FILTER;
12781 else if (!strcmp ("final", p))
12782 result = PRAGMA_OMP_CLAUSE_FINAL;
12783 else if (!strcmp ("finalize", p))
12784 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12785 else if (!strcmp ("firstprivate", p))
12786 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12787 else if (!strcmp ("from", p))
12788 result = PRAGMA_OMP_CLAUSE_FROM;
12789 break;
12790 case 'g':
12791 if (!strcmp ("gang", p))
12792 result = PRAGMA_OACC_CLAUSE_GANG;
12793 else if (!strcmp ("grainsize", p))
12794 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12795 break;
12796 case 'h':
12797 if (!strcmp ("has_device_addr", p))
12798 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
12799 else if (!strcmp ("hint", p))
12800 result = PRAGMA_OMP_CLAUSE_HINT;
12801 else if (!strcmp ("host", p))
12802 result = PRAGMA_OACC_CLAUSE_HOST;
12803 break;
12804 case 'i':
12805 if (!strcmp ("if_present", p))
12806 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12807 else if (!strcmp ("in_reduction", p))
12808 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12809 else if (!strcmp ("inbranch", p))
12810 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12811 else if (!strcmp ("independent", p))
12812 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12813 else if (!strcmp ("is_device_ptr", p))
12814 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12815 break;
12816 case 'l':
12817 if (!strcmp ("lastprivate", p))
12818 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12819 else if (!strcmp ("linear", p))
12820 result = PRAGMA_OMP_CLAUSE_LINEAR;
12821 else if (!strcmp ("link", p))
12822 result = PRAGMA_OMP_CLAUSE_LINK;
12823 break;
12824 case 'm':
12825 if (!strcmp ("map", p))
12826 result = PRAGMA_OMP_CLAUSE_MAP;
12827 else if (!strcmp ("mergeable", p))
12828 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12829 break;
12830 case 'n':
12831 if (!strcmp ("no_create", p))
12832 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12833 else if (!strcmp ("nogroup", p))
12834 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12835 else if (!strcmp ("nohost", p))
12836 result = PRAGMA_OACC_CLAUSE_NOHOST;
12837 else if (!strcmp ("nontemporal", p))
12838 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12839 else if (!strcmp ("notinbranch", p))
12840 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12841 else if (!strcmp ("nowait", p))
12842 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12843 else if (!strcmp ("num_gangs", p))
12844 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12845 else if (!strcmp ("num_tasks", p))
12846 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12847 else if (!strcmp ("num_teams", p))
12848 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12849 else if (!strcmp ("num_threads", p))
12850 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12851 else if (!strcmp ("num_workers", p))
12852 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12853 break;
12854 case 'o':
12855 if (!strcmp ("ordered", p))
12856 result = PRAGMA_OMP_CLAUSE_ORDERED;
12857 else if (!strcmp ("order", p))
12858 result = PRAGMA_OMP_CLAUSE_ORDER;
12859 break;
12860 case 'p':
12861 if (!strcmp ("parallel", p))
12862 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12863 else if (!strcmp ("present", p))
12864 result = PRAGMA_OACC_CLAUSE_PRESENT;
12865 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12866 clauses. */
12867 else if (!strcmp ("present_or_copy", p)
12868 || !strcmp ("pcopy", p))
12869 result = PRAGMA_OACC_CLAUSE_COPY;
12870 else if (!strcmp ("present_or_copyin", p)
12871 || !strcmp ("pcopyin", p))
12872 result = PRAGMA_OACC_CLAUSE_COPYIN;
12873 else if (!strcmp ("present_or_copyout", p)
12874 || !strcmp ("pcopyout", p))
12875 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12876 else if (!strcmp ("present_or_create", p)
12877 || !strcmp ("pcreate", p))
12878 result = PRAGMA_OACC_CLAUSE_CREATE;
12879 else if (!strcmp ("priority", p))
12880 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12881 else if (!strcmp ("private", p))
12882 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12883 else if (!strcmp ("proc_bind", p))
12884 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12885 break;
12886 case 'r':
12887 if (!strcmp ("reduction", p))
12888 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12889 break;
12890 case 's':
12891 if (!strcmp ("safelen", p))
12892 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12893 else if (!strcmp ("schedule", p))
12894 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12895 else if (!strcmp ("sections", p))
12896 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12897 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12898 result = PRAGMA_OACC_CLAUSE_HOST;
12899 else if (!strcmp ("seq", p))
12900 result = PRAGMA_OACC_CLAUSE_SEQ;
12901 else if (!strcmp ("shared", p))
12902 result = PRAGMA_OMP_CLAUSE_SHARED;
12903 else if (!strcmp ("simd", p))
12904 result = PRAGMA_OMP_CLAUSE_SIMD;
12905 else if (!strcmp ("simdlen", p))
12906 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12907 break;
12908 case 't':
12909 if (!strcmp ("task_reduction", p))
12910 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12911 else if (!strcmp ("taskgroup", p))
12912 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12913 else if (!strcmp ("thread_limit", p))
12914 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12915 else if (!strcmp ("threads", p))
12916 result = PRAGMA_OMP_CLAUSE_THREADS;
12917 else if (!strcmp ("tile", p))
12918 result = PRAGMA_OACC_CLAUSE_TILE;
12919 else if (!strcmp ("to", p))
12920 result = PRAGMA_OMP_CLAUSE_TO;
12921 break;
12922 case 'u':
12923 if (!strcmp ("uniform", p))
12924 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12925 else if (!strcmp ("untied", p))
12926 result = PRAGMA_OMP_CLAUSE_UNTIED;
12927 else if (!strcmp ("use_device", p))
12928 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12929 else if (!strcmp ("use_device_addr", p))
12930 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12931 else if (!strcmp ("use_device_ptr", p))
12932 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12933 break;
12934 case 'v':
12935 if (!strcmp ("vector", p))
12936 result = PRAGMA_OACC_CLAUSE_VECTOR;
12937 else if (!strcmp ("vector_length", p))
12938 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12939 break;
12940 case 'w':
12941 if (!strcmp ("wait", p))
12942 result = PRAGMA_OACC_CLAUSE_WAIT;
12943 else if (!strcmp ("worker", p))
12944 result = PRAGMA_OACC_CLAUSE_WORKER;
12945 break;
12946 }
12947 }
12948
12949 if (result != PRAGMA_OMP_CLAUSE_NONE)
12950 c_parser_consume_token (parser);
12951
12952 return result;
12953 }
12954
12955 /* Validate that a clause of the given type does not already exist. */
12956
12957 static void
12958 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12959 const char *name)
12960 {
12961 if (tree c = omp_find_clause (clauses, code))
12962 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12963 }
12964
12965 /* OpenACC 2.0
12966 Parse wait clause or wait directive parameters. */
12967
12968 static tree
12969 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12970 {
12971 vec<tree, va_gc> *args;
12972 tree t, args_tree;
12973
12974 matching_parens parens;
12975 if (!parens.require_open (parser))
12976 return list;
12977
12978 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12979 args_tree = build_tree_list_vec (args);
12980
12981 for (t = args_tree; t; t = TREE_CHAIN (t))
12982 {
12983 tree targ = TREE_VALUE (t);
12984
12985 if (targ != error_mark_node)
12986 {
12987 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12988 {
12989 c_parser_error (parser, "expression must be integral");
12990 targ = error_mark_node;
12991 }
12992 else
12993 {
12994 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12995
12996 OMP_CLAUSE_DECL (c) = targ;
12997 OMP_CLAUSE_CHAIN (c) = list;
12998 list = c;
12999 }
13000 }
13001 }
13002
13003 release_tree_vector (args);
13004 parens.require_close (parser);
13005 return list;
13006 }
13007
13008 /* OpenACC 2.0, OpenMP 2.5:
13009 variable-list:
13010 identifier
13011 variable-list , identifier
13012
13013 If KIND is nonzero, create the appropriate node and install the
13014 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13015 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13016
13017 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13018 return the list created.
13019
13020 The optional ALLOW_DEREF argument is true if list items can use the deref
13021 (->) operator. */
13022
13023 struct omp_dim
13024 {
13025 tree low_bound, length;
13026 location_t loc;
13027 bool no_colon;
13028 omp_dim (tree lb, tree len, location_t lo, bool nc)
13029 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13030 };
13031
13032 static tree
13033 c_parser_omp_variable_list (c_parser *parser,
13034 location_t clause_loc,
13035 enum omp_clause_code kind, tree list,
13036 bool allow_deref = false)
13037 {
13038 auto_vec<omp_dim> dims;
13039 bool array_section_p;
13040 auto_vec<c_token> tokens;
13041 unsigned int tokens_avail = 0;
13042 bool first = true;
13043
13044 while (1)
13045 {
13046 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13047 {
13048 if (c_parser_next_token_is_not (parser, CPP_NAME)
13049 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13050 {
13051 struct c_expr expr;
13052 if (kind == OMP_CLAUSE_DEPEND
13053 && c_parser_next_token_is_keyword (parser,
13054 RID_OMP_ALL_MEMORY)
13055 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13056 || (c_parser_peek_2nd_token (parser)->type
13057 == CPP_CLOSE_PAREN)))
13058 {
13059 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
13060 c_parser_consume_token (parser);
13061 }
13062 else
13063 expr = c_parser_expr_no_commas (parser, NULL);
13064 if (expr.value != error_mark_node)
13065 {
13066 tree u = build_omp_clause (clause_loc, kind);
13067 OMP_CLAUSE_DECL (u) = expr.value;
13068 OMP_CLAUSE_CHAIN (u) = list;
13069 list = u;
13070 }
13071
13072 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13073 break;
13074
13075 c_parser_consume_token (parser);
13076 first = false;
13077 continue;
13078 }
13079
13080 tokens.truncate (0);
13081 unsigned int nesting_depth = 0;
13082 while (1)
13083 {
13084 c_token *token = c_parser_peek_token (parser);
13085 switch (token->type)
13086 {
13087 case CPP_EOF:
13088 case CPP_PRAGMA_EOL:
13089 break;
13090 case CPP_OPEN_BRACE:
13091 case CPP_OPEN_PAREN:
13092 case CPP_OPEN_SQUARE:
13093 ++nesting_depth;
13094 goto add;
13095 case CPP_CLOSE_BRACE:
13096 case CPP_CLOSE_PAREN:
13097 case CPP_CLOSE_SQUARE:
13098 if (nesting_depth-- == 0)
13099 break;
13100 goto add;
13101 case CPP_COMMA:
13102 if (nesting_depth == 0)
13103 break;
13104 goto add;
13105 default:
13106 add:
13107 tokens.safe_push (*token);
13108 c_parser_consume_token (parser);
13109 continue;
13110 }
13111 break;
13112 }
13113
13114 /* Make sure nothing tries to read past the end of the tokens. */
13115 c_token eof_token;
13116 memset (&eof_token, 0, sizeof (eof_token));
13117 eof_token.type = CPP_EOF;
13118 tokens.safe_push (eof_token);
13119 tokens.safe_push (eof_token);
13120
13121 tokens_avail = parser->tokens_avail;
13122 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13123 parser->tokens = tokens.address ();
13124 parser->tokens_avail = tokens.length ();
13125 }
13126
13127 tree t = NULL_TREE;
13128
13129 if (c_parser_next_token_is (parser, CPP_NAME)
13130 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13131 {
13132 t = lookup_name (c_parser_peek_token (parser)->value);
13133
13134 if (t == NULL_TREE)
13135 {
13136 undeclared_variable (c_parser_peek_token (parser)->location,
13137 c_parser_peek_token (parser)->value);
13138 t = error_mark_node;
13139 }
13140
13141 c_parser_consume_token (parser);
13142 }
13143 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13144 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13145 || (c_parser_peek_token (parser)->keyword
13146 == RID_PRETTY_FUNCTION_NAME)
13147 || (c_parser_peek_token (parser)->keyword
13148 == RID_C99_FUNCTION_NAME)))
13149 t = c_parser_predefined_identifier (parser).value;
13150 else
13151 {
13152 if (first)
13153 c_parser_error (parser, "expected identifier");
13154 break;
13155 }
13156
13157 if (t == error_mark_node)
13158 ;
13159 else if (kind != 0)
13160 {
13161 switch (kind)
13162 {
13163 case OMP_CLAUSE__CACHE_:
13164 /* The OpenACC cache directive explicitly only allows "array
13165 elements or subarrays". */
13166 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13167 {
13168 c_parser_error (parser, "expected %<[%>");
13169 t = error_mark_node;
13170 break;
13171 }
13172 /* FALLTHROUGH */
13173 case OMP_CLAUSE_MAP:
13174 case OMP_CLAUSE_FROM:
13175 case OMP_CLAUSE_TO:
13176 start_component_ref:
13177 while (c_parser_next_token_is (parser, CPP_DOT)
13178 || (allow_deref
13179 && c_parser_next_token_is (parser, CPP_DEREF)))
13180 {
13181 location_t op_loc = c_parser_peek_token (parser)->location;
13182 location_t arrow_loc = UNKNOWN_LOCATION;
13183 if (c_parser_next_token_is (parser, CPP_DEREF))
13184 {
13185 c_expr t_expr;
13186 t_expr.value = t;
13187 t_expr.original_code = ERROR_MARK;
13188 t_expr.original_type = NULL;
13189 set_c_expr_source_range (&t_expr, op_loc, op_loc);
13190 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13191 true, false);
13192 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13193 arrow_loc = t_expr.get_location ();
13194 }
13195 c_parser_consume_token (parser);
13196 if (!c_parser_next_token_is (parser, CPP_NAME))
13197 {
13198 c_parser_error (parser, "expected identifier");
13199 t = error_mark_node;
13200 break;
13201 }
13202
13203 c_token *comp_tok = c_parser_peek_token (parser);
13204 tree ident = comp_tok->value;
13205 location_t comp_loc = comp_tok->location;
13206 c_parser_consume_token (parser);
13207 t = build_component_ref (op_loc, t, ident, comp_loc,
13208 arrow_loc);
13209 }
13210 /* FALLTHROUGH */
13211 case OMP_CLAUSE_AFFINITY:
13212 case OMP_CLAUSE_DEPEND:
13213 case OMP_CLAUSE_REDUCTION:
13214 case OMP_CLAUSE_IN_REDUCTION:
13215 case OMP_CLAUSE_TASK_REDUCTION:
13216 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13217 array_section_p = false;
13218 dims.truncate (0);
13219 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13220 {
13221 location_t loc = UNKNOWN_LOCATION;
13222 tree low_bound = NULL_TREE, length = NULL_TREE;
13223 bool no_colon = false;
13224
13225 c_parser_consume_token (parser);
13226 if (!c_parser_next_token_is (parser, CPP_COLON))
13227 {
13228 location_t expr_loc
13229 = c_parser_peek_token (parser)->location;
13230 c_expr expr = c_parser_expression (parser);
13231 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13232 false, true);
13233 low_bound = expr.value;
13234 loc = expr_loc;
13235 }
13236 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13237 {
13238 length = integer_one_node;
13239 no_colon = true;
13240 }
13241 else
13242 {
13243 /* Look for `:'. */
13244 if (!c_parser_require (parser, CPP_COLON,
13245 "expected %<:%>"))
13246 {
13247 t = error_mark_node;
13248 break;
13249 }
13250 array_section_p = true;
13251 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13252 {
13253 location_t expr_loc
13254 = c_parser_peek_token (parser)->location;
13255 c_expr expr = c_parser_expression (parser);
13256 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13257 false, true);
13258 length = expr.value;
13259 }
13260 }
13261 /* Look for the closing `]'. */
13262 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13263 "expected %<]%>"))
13264 {
13265 t = error_mark_node;
13266 break;
13267 }
13268
13269 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13270 }
13271
13272 if (t != error_mark_node)
13273 {
13274 if ((kind == OMP_CLAUSE_MAP
13275 || kind == OMP_CLAUSE_FROM
13276 || kind == OMP_CLAUSE_TO)
13277 && !array_section_p
13278 && (c_parser_next_token_is (parser, CPP_DOT)
13279 || (allow_deref
13280 && c_parser_next_token_is (parser,
13281 CPP_DEREF))))
13282 {
13283 for (unsigned i = 0; i < dims.length (); i++)
13284 {
13285 gcc_assert (dims[i].length == integer_one_node);
13286 t = build_array_ref (dims[i].loc,
13287 t, dims[i].low_bound);
13288 }
13289 goto start_component_ref;
13290 }
13291 else
13292 for (unsigned i = 0; i < dims.length (); i++)
13293 t = tree_cons (dims[i].low_bound, dims[i].length, t);
13294 }
13295
13296 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13297 && t != error_mark_node
13298 && parser->tokens_avail != 2)
13299 {
13300 if (array_section_p)
13301 {
13302 error_at (c_parser_peek_token (parser)->location,
13303 "expected %<)%> or %<,%>");
13304 t = error_mark_node;
13305 }
13306 else
13307 {
13308 parser->tokens = tokens.address ();
13309 parser->tokens_avail = tokens.length ();
13310
13311 t = c_parser_expr_no_commas (parser, NULL).value;
13312 if (t != error_mark_node && parser->tokens_avail != 2)
13313 {
13314 error_at (c_parser_peek_token (parser)->location,
13315 "expected %<)%> or %<,%>");
13316 t = error_mark_node;
13317 }
13318 }
13319 }
13320 break;
13321 default:
13322 break;
13323 }
13324
13325 if (t != error_mark_node)
13326 {
13327 tree u = build_omp_clause (clause_loc, kind);
13328 OMP_CLAUSE_DECL (u) = t;
13329 OMP_CLAUSE_CHAIN (u) = list;
13330 list = u;
13331 }
13332 }
13333 else
13334 list = tree_cons (t, NULL_TREE, list);
13335
13336 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13337 {
13338 parser->tokens = &parser->tokens_buf[0];
13339 parser->tokens_avail = tokens_avail;
13340 }
13341 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13342 break;
13343
13344 c_parser_consume_token (parser);
13345 first = false;
13346 }
13347
13348 return list;
13349 }
13350
13351 /* Similarly, but expect leading and trailing parenthesis. This is a very
13352 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13353 argument is true if list items can use the deref (->) operator. */
13354
13355 static tree
13356 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13357 tree list, bool allow_deref = false)
13358 {
13359 /* The clauses location. */
13360 location_t loc = c_parser_peek_token (parser)->location;
13361
13362 matching_parens parens;
13363 if (parens.require_open (parser))
13364 {
13365 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13366 parens.skip_until_found_close (parser);
13367 }
13368 return list;
13369 }
13370
13371 /* OpenACC 2.0:
13372 copy ( variable-list )
13373 copyin ( variable-list )
13374 copyout ( variable-list )
13375 create ( variable-list )
13376 delete ( variable-list )
13377 present ( variable-list )
13378
13379 OpenACC 2.6:
13380 no_create ( variable-list )
13381 attach ( variable-list )
13382 detach ( variable-list ) */
13383
13384 static tree
13385 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13386 tree list)
13387 {
13388 enum gomp_map_kind kind;
13389 switch (c_kind)
13390 {
13391 case PRAGMA_OACC_CLAUSE_ATTACH:
13392 kind = GOMP_MAP_ATTACH;
13393 break;
13394 case PRAGMA_OACC_CLAUSE_COPY:
13395 kind = GOMP_MAP_TOFROM;
13396 break;
13397 case PRAGMA_OACC_CLAUSE_COPYIN:
13398 kind = GOMP_MAP_TO;
13399 break;
13400 case PRAGMA_OACC_CLAUSE_COPYOUT:
13401 kind = GOMP_MAP_FROM;
13402 break;
13403 case PRAGMA_OACC_CLAUSE_CREATE:
13404 kind = GOMP_MAP_ALLOC;
13405 break;
13406 case PRAGMA_OACC_CLAUSE_DELETE:
13407 kind = GOMP_MAP_RELEASE;
13408 break;
13409 case PRAGMA_OACC_CLAUSE_DETACH:
13410 kind = GOMP_MAP_DETACH;
13411 break;
13412 case PRAGMA_OACC_CLAUSE_DEVICE:
13413 kind = GOMP_MAP_FORCE_TO;
13414 break;
13415 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13416 kind = GOMP_MAP_DEVICE_RESIDENT;
13417 break;
13418 case PRAGMA_OACC_CLAUSE_HOST:
13419 kind = GOMP_MAP_FORCE_FROM;
13420 break;
13421 case PRAGMA_OACC_CLAUSE_LINK:
13422 kind = GOMP_MAP_LINK;
13423 break;
13424 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13425 kind = GOMP_MAP_IF_PRESENT;
13426 break;
13427 case PRAGMA_OACC_CLAUSE_PRESENT:
13428 kind = GOMP_MAP_FORCE_PRESENT;
13429 break;
13430 default:
13431 gcc_unreachable ();
13432 }
13433 tree nl, c;
13434 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13435
13436 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13437 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13438
13439 return nl;
13440 }
13441
13442 /* OpenACC 2.0:
13443 deviceptr ( variable-list ) */
13444
13445 static tree
13446 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13447 {
13448 location_t loc = c_parser_peek_token (parser)->location;
13449 tree vars, t;
13450
13451 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13452 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13453 variable-list must only allow for pointer variables. */
13454 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13455 for (t = vars; t && t; t = TREE_CHAIN (t))
13456 {
13457 tree v = TREE_PURPOSE (t);
13458
13459 /* FIXME diagnostics: Ideally we should keep individual
13460 locations for all the variables in the var list to make the
13461 following errors more precise. Perhaps
13462 c_parser_omp_var_list_parens() should construct a list of
13463 locations to go along with the var list. */
13464
13465 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13466 error_at (loc, "%qD is not a variable", v);
13467 else if (TREE_TYPE (v) == error_mark_node)
13468 ;
13469 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13470 error_at (loc, "%qD is not a pointer variable", v);
13471
13472 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13473 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13474 OMP_CLAUSE_DECL (u) = v;
13475 OMP_CLAUSE_CHAIN (u) = list;
13476 list = u;
13477 }
13478
13479 return list;
13480 }
13481
13482 /* OpenACC 2.0, OpenMP 3.0:
13483 collapse ( constant-expression ) */
13484
13485 static tree
13486 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13487 {
13488 tree c, num = error_mark_node;
13489 HOST_WIDE_INT n;
13490 location_t loc;
13491
13492 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13493 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13494
13495 loc = c_parser_peek_token (parser)->location;
13496 matching_parens parens;
13497 if (parens.require_open (parser))
13498 {
13499 num = c_parser_expr_no_commas (parser, NULL).value;
13500 parens.skip_until_found_close (parser);
13501 }
13502 if (num == error_mark_node)
13503 return list;
13504 mark_exp_read (num);
13505 num = c_fully_fold (num, false, NULL);
13506 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13507 || !tree_fits_shwi_p (num)
13508 || (n = tree_to_shwi (num)) <= 0
13509 || (int) n != n)
13510 {
13511 error_at (loc,
13512 "collapse argument needs positive constant integer expression");
13513 return list;
13514 }
13515 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13516 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13517 OMP_CLAUSE_CHAIN (c) = list;
13518 return c;
13519 }
13520
13521 /* OpenMP 2.5:
13522 copyin ( variable-list ) */
13523
13524 static tree
13525 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13526 {
13527 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13528 }
13529
13530 /* OpenMP 2.5:
13531 copyprivate ( variable-list ) */
13532
13533 static tree
13534 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13535 {
13536 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13537 }
13538
13539 /* OpenMP 2.5:
13540 default ( none | shared )
13541
13542 OpenMP 5.1:
13543 default ( private | firstprivate )
13544
13545 OpenACC:
13546 default ( none | present ) */
13547
13548 static tree
13549 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13550 {
13551 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13552 location_t loc = c_parser_peek_token (parser)->location;
13553 tree c;
13554
13555 matching_parens parens;
13556 if (!parens.require_open (parser))
13557 return list;
13558 if (c_parser_next_token_is (parser, CPP_NAME))
13559 {
13560 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13561
13562 switch (p[0])
13563 {
13564 case 'n':
13565 if (strcmp ("none", p) != 0)
13566 goto invalid_kind;
13567 kind = OMP_CLAUSE_DEFAULT_NONE;
13568 break;
13569
13570 case 'p':
13571 if (is_oacc)
13572 {
13573 if (strcmp ("present", p) != 0)
13574 goto invalid_kind;
13575 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13576 }
13577 else
13578 {
13579 if (strcmp ("private", p) != 0)
13580 goto invalid_kind;
13581 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
13582 }
13583 break;
13584
13585 case 'f':
13586 if (strcmp ("firstprivate", p) != 0 || is_oacc)
13587 goto invalid_kind;
13588 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13589 break;
13590
13591 case 's':
13592 if (strcmp ("shared", p) != 0 || is_oacc)
13593 goto invalid_kind;
13594 kind = OMP_CLAUSE_DEFAULT_SHARED;
13595 break;
13596
13597 default:
13598 goto invalid_kind;
13599 }
13600
13601 c_parser_consume_token (parser);
13602 }
13603 else
13604 {
13605 invalid_kind:
13606 if (is_oacc)
13607 c_parser_error (parser, "expected %<none%> or %<present%>");
13608 else
13609 c_parser_error (parser, "expected %<none%>, %<shared%>, "
13610 "%<private%> or %<firstprivate%>");
13611 }
13612 parens.skip_until_found_close (parser);
13613
13614 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13615 return list;
13616
13617 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13618 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13619 OMP_CLAUSE_CHAIN (c) = list;
13620 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13621
13622 return c;
13623 }
13624
13625 /* OpenMP 2.5:
13626 firstprivate ( variable-list ) */
13627
13628 static tree
13629 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13630 {
13631 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13632 }
13633
13634 /* OpenMP 3.1:
13635 final ( expression ) */
13636
13637 static tree
13638 c_parser_omp_clause_final (c_parser *parser, tree list)
13639 {
13640 location_t loc = c_parser_peek_token (parser)->location;
13641 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13642 {
13643 matching_parens parens;
13644 tree t, c;
13645 if (!parens.require_open (parser))
13646 t = error_mark_node;
13647 else
13648 {
13649 location_t eloc = c_parser_peek_token (parser)->location;
13650 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13651 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13652 t = c_objc_common_truthvalue_conversion (eloc, t);
13653 t = c_fully_fold (t, false, NULL);
13654 parens.skip_until_found_close (parser);
13655 }
13656
13657 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13658
13659 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13660 OMP_CLAUSE_FINAL_EXPR (c) = t;
13661 OMP_CLAUSE_CHAIN (c) = list;
13662 list = c;
13663 }
13664 else
13665 c_parser_error (parser, "expected %<(%>");
13666
13667 return list;
13668 }
13669
13670 /* OpenACC, OpenMP 2.5:
13671 if ( expression )
13672
13673 OpenMP 4.5:
13674 if ( directive-name-modifier : expression )
13675
13676 directive-name-modifier:
13677 parallel | task | taskloop | target data | target | target update
13678 | target enter data | target exit data
13679
13680 OpenMP 5.0:
13681 directive-name-modifier:
13682 ... | simd | cancel */
13683
13684 static tree
13685 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13686 {
13687 location_t location = c_parser_peek_token (parser)->location;
13688 enum tree_code if_modifier = ERROR_MARK;
13689
13690 matching_parens parens;
13691 if (!parens.require_open (parser))
13692 return list;
13693
13694 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13695 {
13696 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13697 int n = 2;
13698 if (strcmp (p, "cancel") == 0)
13699 if_modifier = VOID_CST;
13700 else if (strcmp (p, "parallel") == 0)
13701 if_modifier = OMP_PARALLEL;
13702 else if (strcmp (p, "simd") == 0)
13703 if_modifier = OMP_SIMD;
13704 else if (strcmp (p, "task") == 0)
13705 if_modifier = OMP_TASK;
13706 else if (strcmp (p, "taskloop") == 0)
13707 if_modifier = OMP_TASKLOOP;
13708 else if (strcmp (p, "target") == 0)
13709 {
13710 if_modifier = OMP_TARGET;
13711 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13712 {
13713 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13714 if (strcmp ("data", p) == 0)
13715 if_modifier = OMP_TARGET_DATA;
13716 else if (strcmp ("update", p) == 0)
13717 if_modifier = OMP_TARGET_UPDATE;
13718 else if (strcmp ("enter", p) == 0)
13719 if_modifier = OMP_TARGET_ENTER_DATA;
13720 else if (strcmp ("exit", p) == 0)
13721 if_modifier = OMP_TARGET_EXIT_DATA;
13722 if (if_modifier != OMP_TARGET)
13723 {
13724 n = 3;
13725 c_parser_consume_token (parser);
13726 }
13727 else
13728 {
13729 location_t loc = c_parser_peek_2nd_token (parser)->location;
13730 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13731 "or %<exit%>");
13732 if_modifier = ERROR_MARK;
13733 }
13734 if (if_modifier == OMP_TARGET_ENTER_DATA
13735 || if_modifier == OMP_TARGET_EXIT_DATA)
13736 {
13737 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13738 {
13739 p = IDENTIFIER_POINTER
13740 (c_parser_peek_2nd_token (parser)->value);
13741 if (strcmp ("data", p) == 0)
13742 n = 4;
13743 }
13744 if (n == 4)
13745 c_parser_consume_token (parser);
13746 else
13747 {
13748 location_t loc
13749 = c_parser_peek_2nd_token (parser)->location;
13750 error_at (loc, "expected %<data%>");
13751 if_modifier = ERROR_MARK;
13752 }
13753 }
13754 }
13755 }
13756 if (if_modifier != ERROR_MARK)
13757 {
13758 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13759 {
13760 c_parser_consume_token (parser);
13761 c_parser_consume_token (parser);
13762 }
13763 else
13764 {
13765 if (n > 2)
13766 {
13767 location_t loc = c_parser_peek_2nd_token (parser)->location;
13768 error_at (loc, "expected %<:%>");
13769 }
13770 if_modifier = ERROR_MARK;
13771 }
13772 }
13773 }
13774
13775 location_t loc = c_parser_peek_token (parser)->location;
13776 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13777 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13778 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13779 t = c_fully_fold (t, false, NULL);
13780 parens.skip_until_found_close (parser);
13781
13782 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13783 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13784 {
13785 if (if_modifier != ERROR_MARK
13786 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13787 {
13788 const char *p = NULL;
13789 switch (if_modifier)
13790 {
13791 case VOID_CST: p = "cancel"; break;
13792 case OMP_PARALLEL: p = "parallel"; break;
13793 case OMP_SIMD: p = "simd"; break;
13794 case OMP_TASK: p = "task"; break;
13795 case OMP_TASKLOOP: p = "taskloop"; break;
13796 case OMP_TARGET_DATA: p = "target data"; break;
13797 case OMP_TARGET: p = "target"; break;
13798 case OMP_TARGET_UPDATE: p = "target update"; break;
13799 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13800 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13801 default: gcc_unreachable ();
13802 }
13803 error_at (location, "too many %<if%> clauses with %qs modifier",
13804 p);
13805 return list;
13806 }
13807 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13808 {
13809 if (!is_omp)
13810 error_at (location, "too many %<if%> clauses");
13811 else
13812 error_at (location, "too many %<if%> clauses without modifier");
13813 return list;
13814 }
13815 else if (if_modifier == ERROR_MARK
13816 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13817 {
13818 error_at (location, "if any %<if%> clause has modifier, then all "
13819 "%<if%> clauses have to use modifier");
13820 return list;
13821 }
13822 }
13823
13824 c = build_omp_clause (location, OMP_CLAUSE_IF);
13825 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13826 OMP_CLAUSE_IF_EXPR (c) = t;
13827 OMP_CLAUSE_CHAIN (c) = list;
13828 return c;
13829 }
13830
13831 /* OpenMP 2.5:
13832 lastprivate ( variable-list )
13833
13834 OpenMP 5.0:
13835 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13836
13837 static tree
13838 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13839 {
13840 /* The clauses location. */
13841 location_t loc = c_parser_peek_token (parser)->location;
13842
13843 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13844 {
13845 bool conditional = false;
13846 if (c_parser_next_token_is (parser, CPP_NAME)
13847 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13848 {
13849 const char *p
13850 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13851 if (strcmp (p, "conditional") == 0)
13852 {
13853 conditional = true;
13854 c_parser_consume_token (parser);
13855 c_parser_consume_token (parser);
13856 }
13857 }
13858 tree nlist = c_parser_omp_variable_list (parser, loc,
13859 OMP_CLAUSE_LASTPRIVATE, list);
13860 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13861 if (conditional)
13862 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13863 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13864 return nlist;
13865 }
13866 return list;
13867 }
13868
13869 /* OpenMP 3.1:
13870 mergeable */
13871
13872 static tree
13873 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13874 {
13875 tree c;
13876
13877 /* FIXME: Should we allow duplicates? */
13878 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13879
13880 c = build_omp_clause (c_parser_peek_token (parser)->location,
13881 OMP_CLAUSE_MERGEABLE);
13882 OMP_CLAUSE_CHAIN (c) = list;
13883
13884 return c;
13885 }
13886
13887 /* OpenMP 2.5:
13888 nowait */
13889
13890 static tree
13891 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13892 {
13893 tree c;
13894 location_t loc = c_parser_peek_token (parser)->location;
13895
13896 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13897
13898 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13899 OMP_CLAUSE_CHAIN (c) = list;
13900 return c;
13901 }
13902
13903 /* OpenMP 2.5:
13904 num_threads ( expression ) */
13905
13906 static tree
13907 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13908 {
13909 location_t num_threads_loc = c_parser_peek_token (parser)->location;
13910 matching_parens parens;
13911 if (parens.require_open (parser))
13912 {
13913 location_t expr_loc = c_parser_peek_token (parser)->location;
13914 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13915 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13916 tree c, t = expr.value;
13917 t = c_fully_fold (t, false, NULL);
13918
13919 parens.skip_until_found_close (parser);
13920
13921 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13922 {
13923 c_parser_error (parser, "expected integer expression");
13924 return list;
13925 }
13926
13927 /* Attempt to statically determine when the number isn't positive. */
13928 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13929 build_int_cst (TREE_TYPE (t), 0));
13930 protected_set_expr_location (c, expr_loc);
13931 if (c == boolean_true_node)
13932 {
13933 warning_at (expr_loc, 0,
13934 "%<num_threads%> value must be positive");
13935 t = integer_one_node;
13936 }
13937
13938 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13939
13940 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13941 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13942 OMP_CLAUSE_CHAIN (c) = list;
13943 list = c;
13944 }
13945
13946 return list;
13947 }
13948
13949 /* OpenMP 4.5:
13950 num_tasks ( expression )
13951
13952 OpenMP 5.1:
13953 num_tasks ( strict : expression ) */
13954
13955 static tree
13956 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13957 {
13958 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13959 matching_parens parens;
13960 if (parens.require_open (parser))
13961 {
13962 bool strict = false;
13963 if (c_parser_next_token_is (parser, CPP_NAME)
13964 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
13965 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
13966 "strict") == 0)
13967 {
13968 strict = true;
13969 c_parser_consume_token (parser);
13970 c_parser_consume_token (parser);
13971 }
13972
13973 location_t expr_loc = c_parser_peek_token (parser)->location;
13974 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13975 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13976 tree c, t = expr.value;
13977 t = c_fully_fold (t, false, NULL);
13978
13979 parens.skip_until_found_close (parser);
13980
13981 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13982 {
13983 c_parser_error (parser, "expected integer expression");
13984 return list;
13985 }
13986
13987 /* Attempt to statically determine when the number isn't positive. */
13988 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13989 build_int_cst (TREE_TYPE (t), 0));
13990 if (CAN_HAVE_LOCATION_P (c))
13991 SET_EXPR_LOCATION (c, expr_loc);
13992 if (c == boolean_true_node)
13993 {
13994 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13995 t = integer_one_node;
13996 }
13997
13998 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13999
14000 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
14001 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
14002 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
14003 OMP_CLAUSE_CHAIN (c) = list;
14004 list = c;
14005 }
14006
14007 return list;
14008 }
14009
14010 /* OpenMP 4.5:
14011 grainsize ( expression )
14012
14013 OpenMP 5.1:
14014 grainsize ( strict : expression ) */
14015
14016 static tree
14017 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
14018 {
14019 location_t grainsize_loc = c_parser_peek_token (parser)->location;
14020 matching_parens parens;
14021 if (parens.require_open (parser))
14022 {
14023 bool strict = false;
14024 if (c_parser_next_token_is (parser, CPP_NAME)
14025 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14026 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14027 "strict") == 0)
14028 {
14029 strict = true;
14030 c_parser_consume_token (parser);
14031 c_parser_consume_token (parser);
14032 }
14033
14034 location_t expr_loc = c_parser_peek_token (parser)->location;
14035 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14036 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14037 tree c, t = expr.value;
14038 t = c_fully_fold (t, false, NULL);
14039
14040 parens.skip_until_found_close (parser);
14041
14042 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14043 {
14044 c_parser_error (parser, "expected integer expression");
14045 return list;
14046 }
14047
14048 /* Attempt to statically determine when the number isn't positive. */
14049 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14050 build_int_cst (TREE_TYPE (t), 0));
14051 if (CAN_HAVE_LOCATION_P (c))
14052 SET_EXPR_LOCATION (c, expr_loc);
14053 if (c == boolean_true_node)
14054 {
14055 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14056 t = integer_one_node;
14057 }
14058
14059 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14060
14061 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14062 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14063 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14064 OMP_CLAUSE_CHAIN (c) = list;
14065 list = c;
14066 }
14067
14068 return list;
14069 }
14070
14071 /* OpenMP 4.5:
14072 priority ( expression ) */
14073
14074 static tree
14075 c_parser_omp_clause_priority (c_parser *parser, tree list)
14076 {
14077 location_t priority_loc = c_parser_peek_token (parser)->location;
14078 matching_parens parens;
14079 if (parens.require_open (parser))
14080 {
14081 location_t expr_loc = c_parser_peek_token (parser)->location;
14082 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14083 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14084 tree c, t = expr.value;
14085 t = c_fully_fold (t, false, NULL);
14086
14087 parens.skip_until_found_close (parser);
14088
14089 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14090 {
14091 c_parser_error (parser, "expected integer expression");
14092 return list;
14093 }
14094
14095 /* Attempt to statically determine when the number isn't
14096 non-negative. */
14097 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14098 build_int_cst (TREE_TYPE (t), 0));
14099 if (CAN_HAVE_LOCATION_P (c))
14100 SET_EXPR_LOCATION (c, expr_loc);
14101 if (c == boolean_true_node)
14102 {
14103 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14104 t = integer_one_node;
14105 }
14106
14107 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14108
14109 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14110 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14111 OMP_CLAUSE_CHAIN (c) = list;
14112 list = c;
14113 }
14114
14115 return list;
14116 }
14117
14118 /* OpenMP 4.5:
14119 hint ( expression ) */
14120
14121 static tree
14122 c_parser_omp_clause_hint (c_parser *parser, tree list)
14123 {
14124 location_t hint_loc = c_parser_peek_token (parser)->location;
14125 matching_parens parens;
14126 if (parens.require_open (parser))
14127 {
14128 location_t expr_loc = c_parser_peek_token (parser)->location;
14129 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14130 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14131 tree c, t = expr.value;
14132 t = c_fully_fold (t, false, NULL);
14133 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14134 || TREE_CODE (t) != INTEGER_CST
14135 || tree_int_cst_sgn (t) == -1)
14136 {
14137 c_parser_error (parser, "expected constant integer expression "
14138 "with valid sync-hint value");
14139 return list;
14140 }
14141 parens.skip_until_found_close (parser);
14142 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14143
14144 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14145 OMP_CLAUSE_HINT_EXPR (c) = t;
14146 OMP_CLAUSE_CHAIN (c) = list;
14147 list = c;
14148 }
14149
14150 return list;
14151 }
14152
14153 /* OpenMP 5.1:
14154 filter ( integer-expression ) */
14155
14156 static tree
14157 c_parser_omp_clause_filter (c_parser *parser, tree list)
14158 {
14159 location_t hint_loc = c_parser_peek_token (parser)->location;
14160 matching_parens parens;
14161 if (parens.require_open (parser))
14162 {
14163 location_t expr_loc = c_parser_peek_token (parser)->location;
14164 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14165 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14166 tree c, t = expr.value;
14167 t = c_fully_fold (t, false, NULL);
14168 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14169 {
14170 c_parser_error (parser, "expected integer expression");
14171 return list;
14172 }
14173 parens.skip_until_found_close (parser);
14174 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14175
14176 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14177 OMP_CLAUSE_FILTER_EXPR (c) = t;
14178 OMP_CLAUSE_CHAIN (c) = list;
14179 list = c;
14180 }
14181
14182 return list;
14183 }
14184
14185 /* OpenMP 4.5:
14186 defaultmap ( tofrom : scalar )
14187
14188 OpenMP 5.0:
14189 defaultmap ( implicit-behavior [ : variable-category ] ) */
14190
14191 static tree
14192 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14193 {
14194 location_t loc = c_parser_peek_token (parser)->location;
14195 tree c;
14196 const char *p;
14197 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14198 enum omp_clause_defaultmap_kind category
14199 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14200
14201 matching_parens parens;
14202 if (!parens.require_open (parser))
14203 return list;
14204 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14205 p = "default";
14206 else if (!c_parser_next_token_is (parser, CPP_NAME))
14207 {
14208 invalid_behavior:
14209 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14210 "%<tofrom%>, %<firstprivate%>, %<none%> "
14211 "or %<default%>");
14212 goto out_err;
14213 }
14214 else
14215 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14216
14217 switch (p[0])
14218 {
14219 case 'a':
14220 if (strcmp ("alloc", p) == 0)
14221 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14222 else
14223 goto invalid_behavior;
14224 break;
14225
14226 case 'd':
14227 if (strcmp ("default", p) == 0)
14228 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14229 else
14230 goto invalid_behavior;
14231 break;
14232
14233 case 'f':
14234 if (strcmp ("firstprivate", p) == 0)
14235 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14236 else if (strcmp ("from", p) == 0)
14237 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14238 else
14239 goto invalid_behavior;
14240 break;
14241
14242 case 'n':
14243 if (strcmp ("none", p) == 0)
14244 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14245 else
14246 goto invalid_behavior;
14247 break;
14248
14249 case 't':
14250 if (strcmp ("tofrom", p) == 0)
14251 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14252 else if (strcmp ("to", p) == 0)
14253 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14254 else
14255 goto invalid_behavior;
14256 break;
14257
14258 default:
14259 goto invalid_behavior;
14260 }
14261 c_parser_consume_token (parser);
14262
14263 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14264 {
14265 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14266 goto out_err;
14267 if (!c_parser_next_token_is (parser, CPP_NAME))
14268 {
14269 invalid_category:
14270 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14271 "%<pointer%>");
14272 goto out_err;
14273 }
14274 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14275 switch (p[0])
14276 {
14277 case 'a':
14278 if (strcmp ("aggregate", p) == 0)
14279 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14280 else
14281 goto invalid_category;
14282 break;
14283
14284 case 'p':
14285 if (strcmp ("pointer", p) == 0)
14286 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14287 else
14288 goto invalid_category;
14289 break;
14290
14291 case 's':
14292 if (strcmp ("scalar", p) == 0)
14293 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14294 else
14295 goto invalid_category;
14296 break;
14297
14298 default:
14299 goto invalid_category;
14300 }
14301
14302 c_parser_consume_token (parser);
14303 }
14304 parens.skip_until_found_close (parser);
14305
14306 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14307 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14308 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14309 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14310 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14311 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14312 {
14313 enum omp_clause_defaultmap_kind cat = category;
14314 location_t loc = OMP_CLAUSE_LOCATION (c);
14315 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14316 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14317 p = NULL;
14318 switch (cat)
14319 {
14320 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14321 p = NULL;
14322 break;
14323 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14324 p = "aggregate";
14325 break;
14326 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14327 p = "pointer";
14328 break;
14329 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14330 p = "scalar";
14331 break;
14332 default:
14333 gcc_unreachable ();
14334 }
14335 if (p)
14336 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14337 p);
14338 else
14339 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14340 "category");
14341 break;
14342 }
14343
14344 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14345 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14346 OMP_CLAUSE_CHAIN (c) = list;
14347 return c;
14348
14349 out_err:
14350 parens.skip_until_found_close (parser);
14351 return list;
14352 }
14353
14354 /* OpenACC 2.0:
14355 use_device ( variable-list )
14356
14357 OpenMP 4.5:
14358 use_device_ptr ( variable-list ) */
14359
14360 static tree
14361 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14362 {
14363 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14364 list);
14365 }
14366
14367 /* OpenMP 5.0:
14368 use_device_addr ( variable-list ) */
14369
14370 static tree
14371 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14372 {
14373 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14374 list);
14375 }
14376
14377 /* OpenMP 5.1:
14378 has_device_addr ( variable-list ) */
14379
14380 static tree
14381 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
14382 {
14383 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
14384 list);
14385 }
14386
14387 /* OpenMP 4.5:
14388 is_device_ptr ( variable-list ) */
14389
14390 static tree
14391 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14392 {
14393 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14394 }
14395
14396 /* OpenACC:
14397 num_gangs ( expression )
14398 num_workers ( expression )
14399 vector_length ( expression ) */
14400
14401 static tree
14402 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14403 tree list)
14404 {
14405 location_t loc = c_parser_peek_token (parser)->location;
14406
14407 matching_parens parens;
14408 if (!parens.require_open (parser))
14409 return list;
14410
14411 location_t expr_loc = c_parser_peek_token (parser)->location;
14412 c_expr expr = c_parser_expression (parser);
14413 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14414 tree c, t = expr.value;
14415 t = c_fully_fold (t, false, NULL);
14416
14417 parens.skip_until_found_close (parser);
14418
14419 if (t == error_mark_node)
14420 return list;
14421 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14422 {
14423 error_at (expr_loc, "%qs expression must be integral",
14424 omp_clause_code_name[code]);
14425 return list;
14426 }
14427
14428 /* Attempt to statically determine when the number isn't positive. */
14429 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14430 build_int_cst (TREE_TYPE (t), 0));
14431 protected_set_expr_location (c, expr_loc);
14432 if (c == boolean_true_node)
14433 {
14434 warning_at (expr_loc, 0,
14435 "%qs value must be positive",
14436 omp_clause_code_name[code]);
14437 t = integer_one_node;
14438 }
14439
14440 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14441
14442 c = build_omp_clause (loc, code);
14443 OMP_CLAUSE_OPERAND (c, 0) = t;
14444 OMP_CLAUSE_CHAIN (c) = list;
14445 return c;
14446 }
14447
14448 /* OpenACC:
14449
14450 gang [( gang-arg-list )]
14451 worker [( [num:] int-expr )]
14452 vector [( [length:] int-expr )]
14453
14454 where gang-arg is one of:
14455
14456 [num:] int-expr
14457 static: size-expr
14458
14459 and size-expr may be:
14460
14461 *
14462 int-expr
14463 */
14464
14465 static tree
14466 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14467 omp_clause_code kind,
14468 const char *str, tree list)
14469 {
14470 const char *id = "num";
14471 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14472
14473 if (kind == OMP_CLAUSE_VECTOR)
14474 id = "length";
14475
14476 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14477 {
14478 c_parser_consume_token (parser);
14479
14480 do
14481 {
14482 c_token *next = c_parser_peek_token (parser);
14483 int idx = 0;
14484
14485 /* Gang static argument. */
14486 if (kind == OMP_CLAUSE_GANG
14487 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14488 {
14489 c_parser_consume_token (parser);
14490
14491 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14492 goto cleanup_error;
14493
14494 idx = 1;
14495 if (ops[idx] != NULL_TREE)
14496 {
14497 c_parser_error (parser, "too many %<static%> arguments");
14498 goto cleanup_error;
14499 }
14500
14501 /* Check for the '*' argument. */
14502 if (c_parser_next_token_is (parser, CPP_MULT)
14503 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14504 || c_parser_peek_2nd_token (parser)->type
14505 == CPP_CLOSE_PAREN))
14506 {
14507 c_parser_consume_token (parser);
14508 ops[idx] = integer_minus_one_node;
14509
14510 if (c_parser_next_token_is (parser, CPP_COMMA))
14511 {
14512 c_parser_consume_token (parser);
14513 continue;
14514 }
14515 else
14516 break;
14517 }
14518 }
14519 /* Worker num: argument and vector length: arguments. */
14520 else if (c_parser_next_token_is (parser, CPP_NAME)
14521 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14522 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14523 {
14524 c_parser_consume_token (parser); /* id */
14525 c_parser_consume_token (parser); /* ':' */
14526 }
14527
14528 /* Now collect the actual argument. */
14529 if (ops[idx] != NULL_TREE)
14530 {
14531 c_parser_error (parser, "unexpected argument");
14532 goto cleanup_error;
14533 }
14534
14535 location_t expr_loc = c_parser_peek_token (parser)->location;
14536 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14537 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14538 tree expr = cexpr.value;
14539 if (expr == error_mark_node)
14540 goto cleanup_error;
14541
14542 expr = c_fully_fold (expr, false, NULL);
14543
14544 /* Attempt to statically determine when the number isn't a
14545 positive integer. */
14546
14547 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14548 {
14549 c_parser_error (parser, "expected integer expression");
14550 return list;
14551 }
14552
14553 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14554 build_int_cst (TREE_TYPE (expr), 0));
14555 if (c == boolean_true_node)
14556 {
14557 warning_at (loc, 0,
14558 "%qs value must be positive", str);
14559 expr = integer_one_node;
14560 }
14561
14562 ops[idx] = expr;
14563
14564 if (kind == OMP_CLAUSE_GANG
14565 && c_parser_next_token_is (parser, CPP_COMMA))
14566 {
14567 c_parser_consume_token (parser);
14568 continue;
14569 }
14570 break;
14571 }
14572 while (1);
14573
14574 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14575 goto cleanup_error;
14576 }
14577
14578 check_no_duplicate_clause (list, kind, str);
14579
14580 c = build_omp_clause (loc, kind);
14581
14582 if (ops[1])
14583 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14584
14585 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14586 OMP_CLAUSE_CHAIN (c) = list;
14587
14588 return c;
14589
14590 cleanup_error:
14591 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14592 return list;
14593 }
14594
14595 /* OpenACC 2.5:
14596 auto
14597 finalize
14598 independent
14599 nohost
14600 seq */
14601
14602 static tree
14603 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14604 tree list)
14605 {
14606 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14607
14608 tree c = build_omp_clause (loc, code);
14609 OMP_CLAUSE_CHAIN (c) = list;
14610
14611 return c;
14612 }
14613
14614 /* OpenACC:
14615 async [( int-expr )] */
14616
14617 static tree
14618 c_parser_oacc_clause_async (c_parser *parser, tree list)
14619 {
14620 tree c, t;
14621 location_t loc = c_parser_peek_token (parser)->location;
14622
14623 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14624
14625 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14626 {
14627 c_parser_consume_token (parser);
14628
14629 t = c_parser_expr_no_commas (parser, NULL).value;
14630 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14631 c_parser_error (parser, "expected integer expression");
14632 else if (t == error_mark_node
14633 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14634 return list;
14635 }
14636 else
14637 t = c_fully_fold (t, false, NULL);
14638
14639 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14640
14641 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14642 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14643 OMP_CLAUSE_CHAIN (c) = list;
14644 list = c;
14645
14646 return list;
14647 }
14648
14649 /* OpenACC 2.0:
14650 tile ( size-expr-list ) */
14651
14652 static tree
14653 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14654 {
14655 tree c, expr = error_mark_node;
14656 location_t loc;
14657 tree tile = NULL_TREE;
14658
14659 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14660 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14661
14662 loc = c_parser_peek_token (parser)->location;
14663 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14664 return list;
14665
14666 do
14667 {
14668 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14669 return list;
14670
14671 if (c_parser_next_token_is (parser, CPP_MULT)
14672 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14673 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14674 {
14675 c_parser_consume_token (parser);
14676 expr = integer_zero_node;
14677 }
14678 else
14679 {
14680 location_t expr_loc = c_parser_peek_token (parser)->location;
14681 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14682 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14683 expr = cexpr.value;
14684
14685 if (expr == error_mark_node)
14686 {
14687 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14688 "expected %<)%>");
14689 return list;
14690 }
14691
14692 expr = c_fully_fold (expr, false, NULL);
14693
14694 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14695 || !tree_fits_shwi_p (expr)
14696 || tree_to_shwi (expr) <= 0)
14697 {
14698 error_at (expr_loc, "%<tile%> argument needs positive"
14699 " integral constant");
14700 expr = integer_zero_node;
14701 }
14702 }
14703
14704 tile = tree_cons (NULL_TREE, expr, tile);
14705 }
14706 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14707
14708 /* Consume the trailing ')'. */
14709 c_parser_consume_token (parser);
14710
14711 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14712 tile = nreverse (tile);
14713 OMP_CLAUSE_TILE_LIST (c) = tile;
14714 OMP_CLAUSE_CHAIN (c) = list;
14715 return c;
14716 }
14717
14718 /* OpenACC:
14719 wait [( int-expr-list )] */
14720
14721 static tree
14722 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14723 {
14724 location_t clause_loc = c_parser_peek_token (parser)->location;
14725
14726 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14727 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14728 else
14729 {
14730 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14731
14732 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14733 OMP_CLAUSE_CHAIN (c) = list;
14734 list = c;
14735 }
14736
14737 return list;
14738 }
14739
14740
14741 /* OpenMP 5.0:
14742 order ( concurrent )
14743
14744 OpenMP 5.1:
14745 order ( order-modifier : concurrent )
14746
14747 order-modifier:
14748 reproducible
14749 unconstrained */
14750
14751 static tree
14752 c_parser_omp_clause_order (c_parser *parser, tree list)
14753 {
14754 location_t loc = c_parser_peek_token (parser)->location;
14755 tree c;
14756 const char *p;
14757 bool unconstrained = false;
14758 bool reproducible = false;
14759
14760 matching_parens parens;
14761 if (!parens.require_open (parser))
14762 return list;
14763 if (c_parser_next_token_is (parser, CPP_NAME)
14764 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14765 {
14766 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14767 if (strcmp (p, "unconstrained") == 0)
14768 unconstrained = true;
14769 else if (strcmp (p, "reproducible") == 0)
14770 reproducible = true;
14771 else
14772 {
14773 c_parser_error (parser, "expected %<reproducible%> or "
14774 "%<unconstrained%>");
14775 goto out_err;
14776 }
14777 c_parser_consume_token (parser);
14778 c_parser_consume_token (parser);
14779 }
14780 if (!c_parser_next_token_is (parser, CPP_NAME))
14781 {
14782 c_parser_error (parser, "expected %<concurrent%>");
14783 goto out_err;
14784 }
14785 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14786 if (strcmp (p, "concurrent") != 0)
14787 {
14788 c_parser_error (parser, "expected %<concurrent%>");
14789 goto out_err;
14790 }
14791 c_parser_consume_token (parser);
14792 parens.skip_until_found_close (parser);
14793 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
14794 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14795 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
14796 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
14797 OMP_CLAUSE_CHAIN (c) = list;
14798 return c;
14799
14800 out_err:
14801 parens.skip_until_found_close (parser);
14802 return list;
14803 }
14804
14805
14806 /* OpenMP 5.0:
14807 bind ( teams | parallel | thread ) */
14808
14809 static tree
14810 c_parser_omp_clause_bind (c_parser *parser, tree list)
14811 {
14812 location_t loc = c_parser_peek_token (parser)->location;
14813 tree c;
14814 const char *p;
14815 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14816
14817 matching_parens parens;
14818 if (!parens.require_open (parser))
14819 return list;
14820 if (!c_parser_next_token_is (parser, CPP_NAME))
14821 {
14822 invalid:
14823 c_parser_error (parser,
14824 "expected %<teams%>, %<parallel%> or %<thread%>");
14825 parens.skip_until_found_close (parser);
14826 return list;
14827 }
14828 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14829 if (strcmp (p, "teams") == 0)
14830 kind = OMP_CLAUSE_BIND_TEAMS;
14831 else if (strcmp (p, "parallel") == 0)
14832 kind = OMP_CLAUSE_BIND_PARALLEL;
14833 else if (strcmp (p, "thread") != 0)
14834 goto invalid;
14835 c_parser_consume_token (parser);
14836 parens.skip_until_found_close (parser);
14837 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14838 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14839 OMP_CLAUSE_BIND_KIND (c) = kind;
14840 OMP_CLAUSE_CHAIN (c) = list;
14841 return c;
14842 }
14843
14844
14845 /* OpenMP 2.5:
14846 ordered
14847
14848 OpenMP 4.5:
14849 ordered ( constant-expression ) */
14850
14851 static tree
14852 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14853 {
14854 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14855
14856 tree c, num = NULL_TREE;
14857 HOST_WIDE_INT n;
14858 location_t loc = c_parser_peek_token (parser)->location;
14859 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14860 {
14861 matching_parens parens;
14862 parens.consume_open (parser);
14863 num = c_parser_expr_no_commas (parser, NULL).value;
14864 parens.skip_until_found_close (parser);
14865 }
14866 if (num == error_mark_node)
14867 return list;
14868 if (num)
14869 {
14870 mark_exp_read (num);
14871 num = c_fully_fold (num, false, NULL);
14872 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14873 || !tree_fits_shwi_p (num)
14874 || (n = tree_to_shwi (num)) <= 0
14875 || (int) n != n)
14876 {
14877 error_at (loc, "ordered argument needs positive "
14878 "constant integer expression");
14879 return list;
14880 }
14881 }
14882 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14883 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14884 OMP_CLAUSE_CHAIN (c) = list;
14885 return c;
14886 }
14887
14888 /* OpenMP 2.5:
14889 private ( variable-list ) */
14890
14891 static tree
14892 c_parser_omp_clause_private (c_parser *parser, tree list)
14893 {
14894 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14895 }
14896
14897 /* OpenMP 2.5:
14898 reduction ( reduction-operator : variable-list )
14899
14900 reduction-operator:
14901 One of: + * - & ^ | && ||
14902
14903 OpenMP 3.1:
14904
14905 reduction-operator:
14906 One of: + * - & ^ | && || max min
14907
14908 OpenMP 4.0:
14909
14910 reduction-operator:
14911 One of: + * - & ^ | && ||
14912 identifier
14913
14914 OpenMP 5.0:
14915 reduction ( reduction-modifier, reduction-operator : variable-list )
14916 in_reduction ( reduction-operator : variable-list )
14917 task_reduction ( reduction-operator : variable-list ) */
14918
14919 static tree
14920 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14921 bool is_omp, tree list)
14922 {
14923 location_t clause_loc = c_parser_peek_token (parser)->location;
14924 matching_parens parens;
14925 if (parens.require_open (parser))
14926 {
14927 bool task = false;
14928 bool inscan = false;
14929 enum tree_code code = ERROR_MARK;
14930 tree reduc_id = NULL_TREE;
14931
14932 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14933 {
14934 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14935 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14936 {
14937 c_parser_consume_token (parser);
14938 c_parser_consume_token (parser);
14939 }
14940 else if (c_parser_next_token_is (parser, CPP_NAME)
14941 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14942 {
14943 const char *p
14944 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14945 if (strcmp (p, "task") == 0)
14946 task = true;
14947 else if (strcmp (p, "inscan") == 0)
14948 inscan = true;
14949 if (task || inscan)
14950 {
14951 c_parser_consume_token (parser);
14952 c_parser_consume_token (parser);
14953 }
14954 }
14955 }
14956
14957 switch (c_parser_peek_token (parser)->type)
14958 {
14959 case CPP_PLUS:
14960 code = PLUS_EXPR;
14961 break;
14962 case CPP_MULT:
14963 code = MULT_EXPR;
14964 break;
14965 case CPP_MINUS:
14966 code = MINUS_EXPR;
14967 break;
14968 case CPP_AND:
14969 code = BIT_AND_EXPR;
14970 break;
14971 case CPP_XOR:
14972 code = BIT_XOR_EXPR;
14973 break;
14974 case CPP_OR:
14975 code = BIT_IOR_EXPR;
14976 break;
14977 case CPP_AND_AND:
14978 code = TRUTH_ANDIF_EXPR;
14979 break;
14980 case CPP_OR_OR:
14981 code = TRUTH_ORIF_EXPR;
14982 break;
14983 case CPP_NAME:
14984 {
14985 const char *p
14986 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14987 if (strcmp (p, "min") == 0)
14988 {
14989 code = MIN_EXPR;
14990 break;
14991 }
14992 if (strcmp (p, "max") == 0)
14993 {
14994 code = MAX_EXPR;
14995 break;
14996 }
14997 reduc_id = c_parser_peek_token (parser)->value;
14998 break;
14999 }
15000 default:
15001 c_parser_error (parser,
15002 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15003 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15004 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15005 return list;
15006 }
15007 c_parser_consume_token (parser);
15008 reduc_id = c_omp_reduction_id (code, reduc_id);
15009 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15010 {
15011 tree nl, c;
15012
15013 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
15014 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15015 {
15016 tree d = OMP_CLAUSE_DECL (c), type;
15017 if (TREE_CODE (d) != TREE_LIST)
15018 type = TREE_TYPE (d);
15019 else
15020 {
15021 int cnt = 0;
15022 tree t;
15023 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
15024 cnt++;
15025 type = TREE_TYPE (t);
15026 while (cnt > 0)
15027 {
15028 if (TREE_CODE (type) != POINTER_TYPE
15029 && TREE_CODE (type) != ARRAY_TYPE)
15030 break;
15031 type = TREE_TYPE (type);
15032 cnt--;
15033 }
15034 }
15035 while (TREE_CODE (type) == ARRAY_TYPE)
15036 type = TREE_TYPE (type);
15037 OMP_CLAUSE_REDUCTION_CODE (c) = code;
15038 if (task)
15039 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15040 else if (inscan)
15041 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15042 if (code == ERROR_MARK
15043 || !(INTEGRAL_TYPE_P (type)
15044 || TREE_CODE (type) == REAL_TYPE
15045 || TREE_CODE (type) == COMPLEX_TYPE))
15046 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15047 = c_omp_reduction_lookup (reduc_id,
15048 TYPE_MAIN_VARIANT (type));
15049 }
15050
15051 list = nl;
15052 }
15053 parens.skip_until_found_close (parser);
15054 }
15055 return list;
15056 }
15057
15058 /* OpenMP 2.5:
15059 schedule ( schedule-kind )
15060 schedule ( schedule-kind , expression )
15061
15062 schedule-kind:
15063 static | dynamic | guided | runtime | auto
15064
15065 OpenMP 4.5:
15066 schedule ( schedule-modifier : schedule-kind )
15067 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15068
15069 schedule-modifier:
15070 simd
15071 monotonic
15072 nonmonotonic */
15073
15074 static tree
15075 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15076 {
15077 tree c, t;
15078 location_t loc = c_parser_peek_token (parser)->location;
15079 int modifiers = 0, nmodifiers = 0;
15080
15081 matching_parens parens;
15082 if (!parens.require_open (parser))
15083 return list;
15084
15085 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15086
15087 location_t comma = UNKNOWN_LOCATION;
15088 while (c_parser_next_token_is (parser, CPP_NAME))
15089 {
15090 tree kind = c_parser_peek_token (parser)->value;
15091 const char *p = IDENTIFIER_POINTER (kind);
15092 if (strcmp ("simd", p) == 0)
15093 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15094 else if (strcmp ("monotonic", p) == 0)
15095 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15096 else if (strcmp ("nonmonotonic", p) == 0)
15097 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15098 else
15099 break;
15100 comma = UNKNOWN_LOCATION;
15101 c_parser_consume_token (parser);
15102 if (nmodifiers++ == 0
15103 && c_parser_next_token_is (parser, CPP_COMMA))
15104 {
15105 comma = c_parser_peek_token (parser)->location;
15106 c_parser_consume_token (parser);
15107 }
15108 else
15109 {
15110 c_parser_require (parser, CPP_COLON, "expected %<:%>");
15111 break;
15112 }
15113 }
15114 if (comma != UNKNOWN_LOCATION)
15115 error_at (comma, "expected %<:%>");
15116
15117 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15118 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15119 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15120 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15121 {
15122 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15123 "specified");
15124 modifiers = 0;
15125 }
15126
15127 if (c_parser_next_token_is (parser, CPP_NAME))
15128 {
15129 tree kind = c_parser_peek_token (parser)->value;
15130 const char *p = IDENTIFIER_POINTER (kind);
15131
15132 switch (p[0])
15133 {
15134 case 'd':
15135 if (strcmp ("dynamic", p) != 0)
15136 goto invalid_kind;
15137 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15138 break;
15139
15140 case 'g':
15141 if (strcmp ("guided", p) != 0)
15142 goto invalid_kind;
15143 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15144 break;
15145
15146 case 'r':
15147 if (strcmp ("runtime", p) != 0)
15148 goto invalid_kind;
15149 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15150 break;
15151
15152 default:
15153 goto invalid_kind;
15154 }
15155 }
15156 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15157 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15158 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15159 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15160 else
15161 goto invalid_kind;
15162
15163 c_parser_consume_token (parser);
15164 if (c_parser_next_token_is (parser, CPP_COMMA))
15165 {
15166 location_t here;
15167 c_parser_consume_token (parser);
15168
15169 here = c_parser_peek_token (parser)->location;
15170 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15171 expr = convert_lvalue_to_rvalue (here, expr, false, true);
15172 t = expr.value;
15173 t = c_fully_fold (t, false, NULL);
15174
15175 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15176 error_at (here, "schedule %<runtime%> does not take "
15177 "a %<chunk_size%> parameter");
15178 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15179 error_at (here,
15180 "schedule %<auto%> does not take "
15181 "a %<chunk_size%> parameter");
15182 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15183 {
15184 /* Attempt to statically determine when the number isn't
15185 positive. */
15186 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15187 build_int_cst (TREE_TYPE (t), 0));
15188 protected_set_expr_location (s, loc);
15189 if (s == boolean_true_node)
15190 {
15191 warning_at (loc, 0,
15192 "chunk size value must be positive");
15193 t = integer_one_node;
15194 }
15195 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15196 }
15197 else
15198 c_parser_error (parser, "expected integer expression");
15199
15200 parens.skip_until_found_close (parser);
15201 }
15202 else
15203 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15204 "expected %<,%> or %<)%>");
15205
15206 OMP_CLAUSE_SCHEDULE_KIND (c)
15207 = (enum omp_clause_schedule_kind)
15208 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15209
15210 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15211 OMP_CLAUSE_CHAIN (c) = list;
15212 return c;
15213
15214 invalid_kind:
15215 c_parser_error (parser, "invalid schedule kind");
15216 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15217 return list;
15218 }
15219
15220 /* OpenMP 2.5:
15221 shared ( variable-list ) */
15222
15223 static tree
15224 c_parser_omp_clause_shared (c_parser *parser, tree list)
15225 {
15226 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15227 }
15228
15229 /* OpenMP 3.0:
15230 untied */
15231
15232 static tree
15233 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15234 {
15235 tree c;
15236
15237 /* FIXME: Should we allow duplicates? */
15238 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15239
15240 c = build_omp_clause (c_parser_peek_token (parser)->location,
15241 OMP_CLAUSE_UNTIED);
15242 OMP_CLAUSE_CHAIN (c) = list;
15243
15244 return c;
15245 }
15246
15247 /* OpenMP 4.0:
15248 inbranch
15249 notinbranch */
15250
15251 static tree
15252 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15253 enum omp_clause_code code, tree list)
15254 {
15255 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15256
15257 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15258 OMP_CLAUSE_CHAIN (c) = list;
15259
15260 return c;
15261 }
15262
15263 /* OpenMP 4.0:
15264 parallel
15265 for
15266 sections
15267 taskgroup */
15268
15269 static tree
15270 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15271 enum omp_clause_code code, tree list)
15272 {
15273 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15274 OMP_CLAUSE_CHAIN (c) = list;
15275
15276 return c;
15277 }
15278
15279 /* OpenMP 4.5:
15280 nogroup */
15281
15282 static tree
15283 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15284 {
15285 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15286 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15287 OMP_CLAUSE_NOGROUP);
15288 OMP_CLAUSE_CHAIN (c) = list;
15289 return c;
15290 }
15291
15292 /* OpenMP 4.5:
15293 simd
15294 threads */
15295
15296 static tree
15297 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15298 enum omp_clause_code code, tree list)
15299 {
15300 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15301 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15302 OMP_CLAUSE_CHAIN (c) = list;
15303 return c;
15304 }
15305
15306 /* OpenMP 4.0:
15307 num_teams ( expression )
15308
15309 OpenMP 5.1:
15310 num_teams ( expression : expression ) */
15311
15312 static tree
15313 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15314 {
15315 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15316 matching_parens parens;
15317 if (parens.require_open (parser))
15318 {
15319 location_t upper_loc = c_parser_peek_token (parser)->location;
15320 location_t lower_loc = UNKNOWN_LOCATION;
15321 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15322 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15323 tree c, upper = expr.value, lower = NULL_TREE;
15324 upper = c_fully_fold (upper, false, NULL);
15325
15326 if (c_parser_next_token_is (parser, CPP_COLON))
15327 {
15328 c_parser_consume_token (parser);
15329 lower_loc = upper_loc;
15330 lower = upper;
15331 upper_loc = c_parser_peek_token (parser)->location;
15332 expr = c_parser_expr_no_commas (parser, NULL);
15333 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15334 upper = expr.value;
15335 upper = c_fully_fold (upper, false, NULL);
15336 }
15337
15338 parens.skip_until_found_close (parser);
15339
15340 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
15341 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
15342 {
15343 c_parser_error (parser, "expected integer expression");
15344 return list;
15345 }
15346
15347 /* Attempt to statically determine when the number isn't positive. */
15348 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
15349 build_int_cst (TREE_TYPE (upper), 0));
15350 protected_set_expr_location (c, upper_loc);
15351 if (c == boolean_true_node)
15352 {
15353 warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
15354 upper = integer_one_node;
15355 }
15356 if (lower)
15357 {
15358 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
15359 build_int_cst (TREE_TYPE (lower), 0));
15360 protected_set_expr_location (c, lower_loc);
15361 if (c == boolean_true_node)
15362 {
15363 warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
15364 lower = NULL_TREE;
15365 }
15366 else if (TREE_CODE (lower) == INTEGER_CST
15367 && TREE_CODE (upper) == INTEGER_CST
15368 && tree_int_cst_lt (upper, lower))
15369 {
15370 warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
15371 "than upper bound %qE", lower, upper);
15372 lower = NULL_TREE;
15373 }
15374 }
15375
15376 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15377
15378 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15379 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
15380 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
15381 OMP_CLAUSE_CHAIN (c) = list;
15382 list = c;
15383 }
15384
15385 return list;
15386 }
15387
15388 /* OpenMP 4.0:
15389 thread_limit ( expression ) */
15390
15391 static tree
15392 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15393 {
15394 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15395 matching_parens parens;
15396 if (parens.require_open (parser))
15397 {
15398 location_t expr_loc = c_parser_peek_token (parser)->location;
15399 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15400 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15401 tree c, t = expr.value;
15402 t = c_fully_fold (t, false, NULL);
15403
15404 parens.skip_until_found_close (parser);
15405
15406 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15407 {
15408 c_parser_error (parser, "expected integer expression");
15409 return list;
15410 }
15411
15412 /* Attempt to statically determine when the number isn't positive. */
15413 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15414 build_int_cst (TREE_TYPE (t), 0));
15415 protected_set_expr_location (c, expr_loc);
15416 if (c == boolean_true_node)
15417 {
15418 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15419 t = integer_one_node;
15420 }
15421
15422 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15423 "thread_limit");
15424
15425 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15426 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15427 OMP_CLAUSE_CHAIN (c) = list;
15428 list = c;
15429 }
15430
15431 return list;
15432 }
15433
15434 /* OpenMP 4.0:
15435 aligned ( variable-list )
15436 aligned ( variable-list : constant-expression ) */
15437
15438 static tree
15439 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15440 {
15441 location_t clause_loc = c_parser_peek_token (parser)->location;
15442 tree nl, c;
15443
15444 matching_parens parens;
15445 if (!parens.require_open (parser))
15446 return list;
15447
15448 nl = c_parser_omp_variable_list (parser, clause_loc,
15449 OMP_CLAUSE_ALIGNED, list);
15450
15451 if (c_parser_next_token_is (parser, CPP_COLON))
15452 {
15453 c_parser_consume_token (parser);
15454 location_t expr_loc = c_parser_peek_token (parser)->location;
15455 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15456 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15457 tree alignment = expr.value;
15458 alignment = c_fully_fold (alignment, false, NULL);
15459 if (TREE_CODE (alignment) != INTEGER_CST
15460 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15461 || tree_int_cst_sgn (alignment) != 1)
15462 {
15463 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15464 "be positive constant integer expression");
15465 alignment = NULL_TREE;
15466 }
15467
15468 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15469 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15470 }
15471
15472 parens.skip_until_found_close (parser);
15473 return nl;
15474 }
15475
15476 /* OpenMP 5.0:
15477 allocate ( variable-list )
15478 allocate ( expression : variable-list )
15479
15480 OpenMP 5.1:
15481 allocate ( allocator-modifier : variable-list )
15482 allocate ( allocator-modifier , allocator-modifier : variable-list )
15483
15484 allocator-modifier:
15485 allocator ( expression )
15486 align ( expression ) */
15487
15488 static tree
15489 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15490 {
15491 location_t clause_loc = c_parser_peek_token (parser)->location;
15492 tree nl, c;
15493 tree allocator = NULL_TREE;
15494 tree align = NULL_TREE;
15495
15496 matching_parens parens;
15497 if (!parens.require_open (parser))
15498 return list;
15499
15500 if ((c_parser_next_token_is_not (parser, CPP_NAME)
15501 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15502 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15503 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15504 {
15505 bool has_modifiers = false;
15506 tree orig_type = NULL_TREE;
15507 if (c_parser_next_token_is (parser, CPP_NAME)
15508 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15509 {
15510 unsigned int n = 3;
15511 const char *p
15512 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15513 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
15514 && c_parser_check_balanced_raw_token_sequence (parser, &n)
15515 && (c_parser_peek_nth_token_raw (parser, n)->type
15516 == CPP_CLOSE_PAREN))
15517 {
15518 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15519 == CPP_COLON)
15520 has_modifiers = true;
15521 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15522 == CPP_COMMA
15523 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
15524 == CPP_NAME)
15525 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
15526 == CPP_OPEN_PAREN))
15527 {
15528 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
15529 const char *q = IDENTIFIER_POINTER (tok->value);
15530 n += 4;
15531 if ((strcmp (q, "allocator") == 0
15532 || strcmp (q, "align") == 0)
15533 && c_parser_check_balanced_raw_token_sequence (parser,
15534 &n)
15535 && (c_parser_peek_nth_token_raw (parser, n)->type
15536 == CPP_CLOSE_PAREN)
15537 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15538 == CPP_COLON))
15539 has_modifiers = true;
15540 }
15541 }
15542 if (has_modifiers)
15543 {
15544 c_parser_consume_token (parser);
15545 matching_parens parens2;;
15546 parens2.require_open (parser);
15547 location_t expr_loc = c_parser_peek_token (parser)->location;
15548 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15549 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15550 if (strcmp (p, "allocator") == 0)
15551 {
15552 allocator = expr.value;
15553 allocator = c_fully_fold (allocator, false, NULL);
15554 orig_type = expr.original_type
15555 ? expr.original_type : TREE_TYPE (allocator);
15556 orig_type = TYPE_MAIN_VARIANT (orig_type);
15557 }
15558 else
15559 {
15560 align = expr.value;
15561 align = c_fully_fold (align, false, NULL);
15562 }
15563 parens2.skip_until_found_close (parser);
15564 if (c_parser_next_token_is (parser, CPP_COMMA))
15565 {
15566 c_parser_consume_token (parser);
15567 c_token *tok = c_parser_peek_token (parser);
15568 const char *q = "";
15569 if (c_parser_next_token_is (parser, CPP_NAME))
15570 q = IDENTIFIER_POINTER (tok->value);
15571 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
15572 {
15573 c_parser_error (parser, "expected %<allocator%> or "
15574 "%<align%>");
15575 parens.skip_until_found_close (parser);
15576 return list;
15577 }
15578 else if (strcmp (p, q) == 0)
15579 {
15580 error_at (tok->location, "duplicate %qs modifier", p);
15581 parens.skip_until_found_close (parser);
15582 return list;
15583 }
15584 c_parser_consume_token (parser);
15585 if (!parens2.require_open (parser))
15586 {
15587 parens.skip_until_found_close (parser);
15588 return list;
15589 }
15590 expr_loc = c_parser_peek_token (parser)->location;
15591 expr = c_parser_expr_no_commas (parser, NULL);
15592 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15593 true);
15594 if (strcmp (q, "allocator") == 0)
15595 {
15596 allocator = expr.value;
15597 allocator = c_fully_fold (allocator, false, NULL);
15598 orig_type = expr.original_type
15599 ? expr.original_type : TREE_TYPE (allocator);
15600 orig_type = TYPE_MAIN_VARIANT (orig_type);
15601 }
15602 else
15603 {
15604 align = expr.value;
15605 align = c_fully_fold (align, false, NULL);
15606 }
15607 parens2.skip_until_found_close (parser);
15608 }
15609 }
15610 }
15611 if (!has_modifiers)
15612 {
15613 location_t expr_loc = c_parser_peek_token (parser)->location;
15614 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15615 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15616 allocator = expr.value;
15617 allocator = c_fully_fold (allocator, false, NULL);
15618 orig_type = expr.original_type
15619 ? expr.original_type : TREE_TYPE (allocator);
15620 orig_type = TYPE_MAIN_VARIANT (orig_type);
15621 }
15622 if (allocator
15623 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15624 || TREE_CODE (orig_type) != ENUMERAL_TYPE
15625 || (TYPE_NAME (orig_type)
15626 != get_identifier ("omp_allocator_handle_t"))))
15627 {
15628 error_at (clause_loc, "%<allocate%> clause allocator expression "
15629 "has type %qT rather than "
15630 "%<omp_allocator_handle_t%>",
15631 TREE_TYPE (allocator));
15632 allocator = NULL_TREE;
15633 }
15634 if (align
15635 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
15636 || !tree_fits_uhwi_p (align)
15637 || !integer_pow2p (align)))
15638 {
15639 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
15640 "argument needs to be positive constant "
15641 "power of two integer expression");
15642 align = NULL_TREE;
15643 }
15644 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15645 {
15646 parens.skip_until_found_close (parser);
15647 return list;
15648 }
15649 }
15650
15651 nl = c_parser_omp_variable_list (parser, clause_loc,
15652 OMP_CLAUSE_ALLOCATE, list);
15653
15654 if (allocator || align)
15655 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15656 {
15657 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15658 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
15659 }
15660
15661 parens.skip_until_found_close (parser);
15662 return nl;
15663 }
15664
15665 /* OpenMP 4.0:
15666 linear ( variable-list )
15667 linear ( variable-list : expression )
15668
15669 OpenMP 4.5:
15670 linear ( modifier ( variable-list ) )
15671 linear ( modifier ( variable-list ) : expression )
15672
15673 modifier:
15674 val
15675
15676 OpenMP 5.2:
15677 linear ( variable-list : modifiers-list )
15678
15679 modifiers:
15680 val
15681 step ( expression ) */
15682
15683 static tree
15684 c_parser_omp_clause_linear (c_parser *parser, tree list)
15685 {
15686 location_t clause_loc = c_parser_peek_token (parser)->location;
15687 tree nl, c, step;
15688 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15689 bool old_linear_modifier = false;
15690
15691 matching_parens parens;
15692 if (!parens.require_open (parser))
15693 return list;
15694
15695 if (c_parser_next_token_is (parser, CPP_NAME))
15696 {
15697 c_token *tok = c_parser_peek_token (parser);
15698 const char *p = IDENTIFIER_POINTER (tok->value);
15699 if (strcmp ("val", p) == 0)
15700 kind = OMP_CLAUSE_LINEAR_VAL;
15701 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15702 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15703 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15704 {
15705 old_linear_modifier = true;
15706 c_parser_consume_token (parser);
15707 c_parser_consume_token (parser);
15708 }
15709 }
15710
15711 nl = c_parser_omp_variable_list (parser, clause_loc,
15712 OMP_CLAUSE_LINEAR, list);
15713
15714 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15715 parens.skip_until_found_close (parser);
15716
15717 if (c_parser_next_token_is (parser, CPP_COLON))
15718 {
15719 c_parser_consume_token (parser);
15720 location_t expr_loc = c_parser_peek_token (parser)->location;
15721 bool has_modifiers = false;
15722 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
15723 && c_parser_next_token_is (parser, CPP_NAME))
15724 {
15725 c_token *tok = c_parser_peek_token (parser);
15726 const char *p = IDENTIFIER_POINTER (tok->value);
15727 unsigned int pos = 0;
15728 if (strcmp ("val", p) == 0)
15729 pos = 2;
15730 else if (strcmp ("step", p) == 0
15731 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15732 {
15733 pos = 3;
15734 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
15735 && (c_parser_peek_nth_token_raw (parser, pos)->type
15736 == CPP_CLOSE_PAREN))
15737 ++pos;
15738 else
15739 pos = 0;
15740 }
15741 if (pos)
15742 {
15743 tok = c_parser_peek_nth_token_raw (parser, pos);
15744 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
15745 has_modifiers = true;
15746 }
15747 }
15748 if (has_modifiers)
15749 {
15750 step = NULL_TREE;
15751 while (c_parser_next_token_is (parser, CPP_NAME))
15752 {
15753 c_token *tok = c_parser_peek_token (parser);
15754 const char *p = IDENTIFIER_POINTER (tok->value);
15755 if (strcmp ("val", p) == 0)
15756 {
15757 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15758 error_at (tok->location, "multiple linear modifiers");
15759 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15760 c_parser_consume_token (parser);
15761 }
15762 else if (strcmp ("step", p) == 0)
15763 {
15764 c_parser_consume_token (parser);
15765 matching_parens parens2;
15766 if (parens2.require_open (parser))
15767 {
15768 if (step)
15769 error_at (tok->location,
15770 "multiple %<step%> modifiers");
15771 expr_loc = c_parser_peek_token (parser)->location;
15772 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15773 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15774 true);
15775 step = c_fully_fold (expr.value, false, NULL);
15776 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15777 {
15778 error_at (clause_loc, "%<linear%> clause step "
15779 "expression must be integral");
15780 step = integer_one_node;
15781 }
15782 parens2.skip_until_found_close (parser);
15783 }
15784 else
15785 break;
15786 }
15787 else
15788 break;
15789 if (c_parser_next_token_is (parser, CPP_COMMA))
15790 {
15791 c_parser_consume_token (parser);
15792 continue;
15793 }
15794 break;
15795 }
15796 if (!step)
15797 step = integer_one_node;
15798 }
15799 else
15800 {
15801 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15802 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15803 step = c_fully_fold (expr.value, false, NULL);
15804 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15805 {
15806 error_at (clause_loc, "%<linear%> clause step expression must "
15807 "be integral");
15808 step = integer_one_node;
15809 }
15810 }
15811
15812 }
15813 else
15814 step = integer_one_node;
15815
15816 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15817 {
15818 OMP_CLAUSE_LINEAR_STEP (c) = step;
15819 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15820 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
15821 }
15822
15823 parens.skip_until_found_close (parser);
15824 return nl;
15825 }
15826
15827 /* OpenMP 5.0:
15828 nontemporal ( variable-list ) */
15829
15830 static tree
15831 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15832 {
15833 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15834 }
15835
15836 /* OpenMP 4.0:
15837 safelen ( constant-expression ) */
15838
15839 static tree
15840 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15841 {
15842 location_t clause_loc = c_parser_peek_token (parser)->location;
15843 tree c, t;
15844
15845 matching_parens parens;
15846 if (!parens.require_open (parser))
15847 return list;
15848
15849 location_t expr_loc = c_parser_peek_token (parser)->location;
15850 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15851 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15852 t = expr.value;
15853 t = c_fully_fold (t, false, NULL);
15854 if (TREE_CODE (t) != INTEGER_CST
15855 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15856 || tree_int_cst_sgn (t) != 1)
15857 {
15858 error_at (clause_loc, "%<safelen%> clause expression must "
15859 "be positive constant integer expression");
15860 t = NULL_TREE;
15861 }
15862
15863 parens.skip_until_found_close (parser);
15864 if (t == NULL_TREE || t == error_mark_node)
15865 return list;
15866
15867 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15868
15869 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15870 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15871 OMP_CLAUSE_CHAIN (c) = list;
15872 return c;
15873 }
15874
15875 /* OpenMP 4.0:
15876 simdlen ( constant-expression ) */
15877
15878 static tree
15879 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15880 {
15881 location_t clause_loc = c_parser_peek_token (parser)->location;
15882 tree c, t;
15883
15884 matching_parens parens;
15885 if (!parens.require_open (parser))
15886 return list;
15887
15888 location_t expr_loc = c_parser_peek_token (parser)->location;
15889 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15890 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15891 t = expr.value;
15892 t = c_fully_fold (t, false, NULL);
15893 if (TREE_CODE (t) != INTEGER_CST
15894 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15895 || tree_int_cst_sgn (t) != 1)
15896 {
15897 error_at (clause_loc, "%<simdlen%> clause expression must "
15898 "be positive constant integer expression");
15899 t = NULL_TREE;
15900 }
15901
15902 parens.skip_until_found_close (parser);
15903 if (t == NULL_TREE || t == error_mark_node)
15904 return list;
15905
15906 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15907
15908 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15909 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15910 OMP_CLAUSE_CHAIN (c) = list;
15911 return c;
15912 }
15913
15914 /* OpenMP 4.5:
15915 vec:
15916 identifier [+/- integer]
15917 vec , identifier [+/- integer]
15918 */
15919
15920 static tree
15921 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15922 tree list)
15923 {
15924 tree vec = NULL;
15925 if (c_parser_next_token_is_not (parser, CPP_NAME)
15926 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15927 {
15928 c_parser_error (parser, "expected identifier");
15929 return list;
15930 }
15931
15932 while (c_parser_next_token_is (parser, CPP_NAME)
15933 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15934 {
15935 tree t = lookup_name (c_parser_peek_token (parser)->value);
15936 tree addend = NULL;
15937
15938 if (t == NULL_TREE)
15939 {
15940 undeclared_variable (c_parser_peek_token (parser)->location,
15941 c_parser_peek_token (parser)->value);
15942 t = error_mark_node;
15943 }
15944
15945 c_parser_consume_token (parser);
15946
15947 bool neg = false;
15948 if (c_parser_next_token_is (parser, CPP_MINUS))
15949 neg = true;
15950 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15951 {
15952 addend = integer_zero_node;
15953 neg = false;
15954 goto add_to_vector;
15955 }
15956 c_parser_consume_token (parser);
15957
15958 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15959 {
15960 c_parser_error (parser, "expected integer");
15961 return list;
15962 }
15963
15964 addend = c_parser_peek_token (parser)->value;
15965 if (TREE_CODE (addend) != INTEGER_CST)
15966 {
15967 c_parser_error (parser, "expected integer");
15968 return list;
15969 }
15970 c_parser_consume_token (parser);
15971
15972 add_to_vector:
15973 if (t != error_mark_node)
15974 {
15975 vec = tree_cons (addend, t, vec);
15976 if (neg)
15977 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15978 }
15979
15980 if (c_parser_next_token_is_not (parser, CPP_COMMA)
15981 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
15982 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
15983 break;
15984
15985 c_parser_consume_token (parser);
15986 }
15987
15988 if (vec == NULL_TREE)
15989 return list;
15990
15991 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15992 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15993 OMP_CLAUSE_DECL (u) = nreverse (vec);
15994 OMP_CLAUSE_CHAIN (u) = list;
15995 return u;
15996 }
15997
15998 /* OpenMP 5.0:
15999 iterators ( iterators-definition )
16000
16001 iterators-definition:
16002 iterator-specifier
16003 iterator-specifier , iterators-definition
16004
16005 iterator-specifier:
16006 identifier = range-specification
16007 iterator-type identifier = range-specification
16008
16009 range-specification:
16010 begin : end
16011 begin : end : step */
16012
16013 static tree
16014 c_parser_omp_iterators (c_parser *parser)
16015 {
16016 tree ret = NULL_TREE, *last = &ret;
16017 c_parser_consume_token (parser);
16018
16019 push_scope ();
16020
16021 matching_parens parens;
16022 if (!parens.require_open (parser))
16023 return error_mark_node;
16024
16025 do
16026 {
16027 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
16028 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
16029 {
16030 struct c_type_name *type = c_parser_type_name (parser);
16031 if (type != NULL)
16032 iter_type = groktypename (type, &type_expr, NULL);
16033 }
16034 if (iter_type == NULL_TREE)
16035 iter_type = integer_type_node;
16036
16037 location_t loc = c_parser_peek_token (parser)->location;
16038 if (!c_parser_next_token_is (parser, CPP_NAME))
16039 {
16040 c_parser_error (parser, "expected identifier");
16041 break;
16042 }
16043
16044 tree id = c_parser_peek_token (parser)->value;
16045 c_parser_consume_token (parser);
16046
16047 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16048 break;
16049
16050 location_t eloc = c_parser_peek_token (parser)->location;
16051 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16052 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16053 tree begin = expr.value;
16054
16055 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16056 break;
16057
16058 eloc = c_parser_peek_token (parser)->location;
16059 expr = c_parser_expr_no_commas (parser, NULL);
16060 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16061 tree end = expr.value;
16062
16063 tree step = integer_one_node;
16064 if (c_parser_next_token_is (parser, CPP_COLON))
16065 {
16066 c_parser_consume_token (parser);
16067 eloc = c_parser_peek_token (parser)->location;
16068 expr = c_parser_expr_no_commas (parser, NULL);
16069 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16070 step = expr.value;
16071 }
16072
16073 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
16074 DECL_ARTIFICIAL (iter_var) = 1;
16075 DECL_CONTEXT (iter_var) = current_function_decl;
16076 pushdecl (iter_var);
16077
16078 *last = make_tree_vec (6);
16079 TREE_VEC_ELT (*last, 0) = iter_var;
16080 TREE_VEC_ELT (*last, 1) = begin;
16081 TREE_VEC_ELT (*last, 2) = end;
16082 TREE_VEC_ELT (*last, 3) = step;
16083 last = &TREE_CHAIN (*last);
16084
16085 if (c_parser_next_token_is (parser, CPP_COMMA))
16086 {
16087 c_parser_consume_token (parser);
16088 continue;
16089 }
16090 break;
16091 }
16092 while (1);
16093
16094 parens.skip_until_found_close (parser);
16095 return ret ? ret : error_mark_node;
16096 }
16097
16098 /* OpenMP 5.0:
16099 affinity ( [aff-modifier :] variable-list )
16100 aff-modifier:
16101 iterator ( iterators-definition ) */
16102
16103 static tree
16104 c_parser_omp_clause_affinity (c_parser *parser, tree list)
16105 {
16106 location_t clause_loc = c_parser_peek_token (parser)->location;
16107 tree nl, iterators = NULL_TREE;
16108
16109 matching_parens parens;
16110 if (!parens.require_open (parser))
16111 return list;
16112
16113 if (c_parser_next_token_is (parser, CPP_NAME))
16114 {
16115 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16116 bool parse_iter = ((strcmp ("iterator", p) == 0)
16117 && (c_parser_peek_2nd_token (parser)->type
16118 == CPP_OPEN_PAREN));
16119 if (parse_iter)
16120 {
16121 unsigned n = 3;
16122 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
16123 && (c_parser_peek_nth_token_raw (parser, n)->type
16124 == CPP_CLOSE_PAREN)
16125 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
16126 == CPP_COLON));
16127 }
16128 if (parse_iter)
16129 {
16130 iterators = c_parser_omp_iterators (parser);
16131 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16132 {
16133 if (iterators)
16134 pop_scope ();
16135 parens.skip_until_found_close (parser);
16136 return list;
16137 }
16138 }
16139 }
16140 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16141 list);
16142 if (iterators)
16143 {
16144 tree block = pop_scope ();
16145 if (iterators != error_mark_node)
16146 {
16147 TREE_VEC_ELT (iterators, 5) = block;
16148 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16149 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16150 OMP_CLAUSE_DECL (c));
16151 }
16152 }
16153
16154 parens.skip_until_found_close (parser);
16155 return nl;
16156 }
16157
16158
16159 /* OpenMP 4.0:
16160 depend ( depend-kind: variable-list )
16161
16162 depend-kind:
16163 in | out | inout
16164
16165 OpenMP 4.5:
16166 depend ( source )
16167
16168 depend ( sink : vec )
16169
16170 OpenMP 5.0:
16171 depend ( depend-modifier , depend-kind: variable-list )
16172
16173 depend-kind:
16174 in | out | inout | mutexinoutset | depobj | inoutset
16175
16176 depend-modifier:
16177 iterator ( iterators-definition ) */
16178
16179 static tree
16180 c_parser_omp_clause_depend (c_parser *parser, tree list)
16181 {
16182 location_t clause_loc = c_parser_peek_token (parser)->location;
16183 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16184 tree nl, c, iterators = NULL_TREE;
16185
16186 matching_parens parens;
16187 if (!parens.require_open (parser))
16188 return list;
16189
16190 do
16191 {
16192 if (c_parser_next_token_is_not (parser, CPP_NAME))
16193 goto invalid_kind;
16194
16195 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16196 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16197 {
16198 iterators = c_parser_omp_iterators (parser);
16199 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16200 continue;
16201 }
16202 if (strcmp ("in", p) == 0)
16203 kind = OMP_CLAUSE_DEPEND_IN;
16204 else if (strcmp ("inout", p) == 0)
16205 kind = OMP_CLAUSE_DEPEND_INOUT;
16206 else if (strcmp ("inoutset", p) == 0)
16207 kind = OMP_CLAUSE_DEPEND_INOUTSET;
16208 else if (strcmp ("mutexinoutset", p) == 0)
16209 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16210 else if (strcmp ("out", p) == 0)
16211 kind = OMP_CLAUSE_DEPEND_OUT;
16212 else if (strcmp ("depobj", p) == 0)
16213 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16214 else if (strcmp ("sink", p) == 0)
16215 kind = OMP_CLAUSE_DEPEND_SINK;
16216 else if (strcmp ("source", p) == 0)
16217 kind = OMP_CLAUSE_DEPEND_SOURCE;
16218 else
16219 goto invalid_kind;
16220 break;
16221 }
16222 while (1);
16223
16224 c_parser_consume_token (parser);
16225
16226 if (iterators
16227 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
16228 {
16229 pop_scope ();
16230 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16231 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
16232 iterators = NULL_TREE;
16233 }
16234
16235 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
16236 {
16237 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
16238 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16239 OMP_CLAUSE_DECL (c) = NULL_TREE;
16240 OMP_CLAUSE_CHAIN (c) = list;
16241 parens.skip_until_found_close (parser);
16242 return c;
16243 }
16244
16245 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16246 goto resync_fail;
16247
16248 if (kind == OMP_CLAUSE_DEPEND_SINK)
16249 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
16250 else
16251 {
16252 nl = c_parser_omp_variable_list (parser, clause_loc,
16253 OMP_CLAUSE_DEPEND, list);
16254
16255 if (iterators)
16256 {
16257 tree block = pop_scope ();
16258 if (iterators == error_mark_node)
16259 iterators = NULL_TREE;
16260 else
16261 TREE_VEC_ELT (iterators, 5) = block;
16262 }
16263
16264 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16265 {
16266 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16267 if (iterators)
16268 OMP_CLAUSE_DECL (c)
16269 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16270 }
16271 }
16272
16273 parens.skip_until_found_close (parser);
16274 return nl;
16275
16276 invalid_kind:
16277 c_parser_error (parser, "invalid depend kind");
16278 resync_fail:
16279 parens.skip_until_found_close (parser);
16280 if (iterators)
16281 pop_scope ();
16282 return list;
16283 }
16284
16285 /* OpenMP 4.0:
16286 map ( map-kind: variable-list )
16287 map ( variable-list )
16288
16289 map-kind:
16290 alloc | to | from | tofrom
16291
16292 OpenMP 4.5:
16293 map-kind:
16294 alloc | to | from | tofrom | release | delete
16295
16296 map ( always [,] map-kind: variable-list )
16297
16298 OpenMP 5.0:
16299 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16300
16301 map-type-modifier:
16302 always | close */
16303
16304 static tree
16305 c_parser_omp_clause_map (c_parser *parser, tree list)
16306 {
16307 location_t clause_loc = c_parser_peek_token (parser)->location;
16308 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
16309 tree nl, c;
16310
16311 matching_parens parens;
16312 if (!parens.require_open (parser))
16313 return list;
16314
16315 int pos = 1;
16316 int map_kind_pos = 0;
16317 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
16318 {
16319 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
16320 {
16321 map_kind_pos = pos;
16322 break;
16323 }
16324
16325 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
16326 pos++;
16327 pos++;
16328 }
16329
16330 int always_modifier = 0;
16331 int close_modifier = 0;
16332 for (int pos = 1; pos < map_kind_pos; ++pos)
16333 {
16334 c_token *tok = c_parser_peek_token (parser);
16335
16336 if (tok->type == CPP_COMMA)
16337 {
16338 c_parser_consume_token (parser);
16339 continue;
16340 }
16341
16342 const char *p = IDENTIFIER_POINTER (tok->value);
16343 if (strcmp ("always", p) == 0)
16344 {
16345 if (always_modifier)
16346 {
16347 c_parser_error (parser, "too many %<always%> modifiers");
16348 parens.skip_until_found_close (parser);
16349 return list;
16350 }
16351 always_modifier++;
16352 }
16353 else if (strcmp ("close", p) == 0)
16354 {
16355 if (close_modifier)
16356 {
16357 c_parser_error (parser, "too many %<close%> modifiers");
16358 parens.skip_until_found_close (parser);
16359 return list;
16360 }
16361 close_modifier++;
16362 }
16363 else
16364 {
16365 c_parser_error (parser, "%<#pragma omp target%> with "
16366 "modifier other than %<always%> or "
16367 "%<close%> on %<map%> clause");
16368 parens.skip_until_found_close (parser);
16369 return list;
16370 }
16371
16372 c_parser_consume_token (parser);
16373 }
16374
16375 if (c_parser_next_token_is (parser, CPP_NAME)
16376 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16377 {
16378 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16379 if (strcmp ("alloc", p) == 0)
16380 kind = GOMP_MAP_ALLOC;
16381 else if (strcmp ("to", p) == 0)
16382 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
16383 else if (strcmp ("from", p) == 0)
16384 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
16385 else if (strcmp ("tofrom", p) == 0)
16386 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
16387 else if (strcmp ("release", p) == 0)
16388 kind = GOMP_MAP_RELEASE;
16389 else if (strcmp ("delete", p) == 0)
16390 kind = GOMP_MAP_DELETE;
16391 else
16392 {
16393 c_parser_error (parser, "invalid map kind");
16394 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16395 "expected %<)%>");
16396 return list;
16397 }
16398 c_parser_consume_token (parser);
16399 c_parser_consume_token (parser);
16400 }
16401
16402 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
16403 true);
16404
16405 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16406 OMP_CLAUSE_SET_MAP_KIND (c, kind);
16407
16408 parens.skip_until_found_close (parser);
16409 return nl;
16410 }
16411
16412 /* OpenMP 4.0:
16413 device ( expression )
16414
16415 OpenMP 5.0:
16416 device ( [device-modifier :] integer-expression )
16417
16418 device-modifier:
16419 ancestor | device_num */
16420
16421 static tree
16422 c_parser_omp_clause_device (c_parser *parser, tree list)
16423 {
16424 location_t clause_loc = c_parser_peek_token (parser)->location;
16425 location_t expr_loc;
16426 c_expr expr;
16427 tree c, t;
16428 bool ancestor = false;
16429
16430 matching_parens parens;
16431 if (!parens.require_open (parser))
16432 return list;
16433
16434 if (c_parser_next_token_is (parser, CPP_NAME)
16435 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16436 {
16437 c_token *tok = c_parser_peek_token (parser);
16438 const char *p = IDENTIFIER_POINTER (tok->value);
16439 if (strcmp ("ancestor", p) == 0)
16440 {
16441 /* A requires directive with the reverse_offload clause must be
16442 specified. */
16443 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
16444 {
16445 error_at (tok->location, "%<ancestor%> device modifier not "
16446 "preceded by %<requires%> directive "
16447 "with %<reverse_offload%> clause");
16448 parens.skip_until_found_close (parser);
16449 return list;
16450 }
16451 ancestor = true;
16452 }
16453 else if (strcmp ("device_num", p) == 0)
16454 ;
16455 else
16456 {
16457 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
16458 parens.skip_until_found_close (parser);
16459 return list;
16460 }
16461 c_parser_consume_token (parser);
16462 c_parser_consume_token (parser);
16463 }
16464
16465 expr_loc = c_parser_peek_token (parser)->location;
16466 expr = c_parser_expr_no_commas (parser, NULL);
16467 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16468 t = expr.value;
16469 t = c_fully_fold (t, false, NULL);
16470
16471 parens.skip_until_found_close (parser);
16472
16473 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16474 {
16475 c_parser_error (parser, "expected integer expression");
16476 return list;
16477 }
16478 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
16479 {
16480 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
16481 "%<1%>");
16482 return list;
16483 }
16484
16485 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
16486
16487 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
16488
16489 OMP_CLAUSE_DEVICE_ID (c) = t;
16490 OMP_CLAUSE_CHAIN (c) = list;
16491 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
16492
16493 list = c;
16494 return list;
16495 }
16496
16497 /* OpenMP 4.0:
16498 dist_schedule ( static )
16499 dist_schedule ( static , expression ) */
16500
16501 static tree
16502 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
16503 {
16504 tree c, t = NULL_TREE;
16505 location_t loc = c_parser_peek_token (parser)->location;
16506
16507 matching_parens parens;
16508 if (!parens.require_open (parser))
16509 return list;
16510
16511 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
16512 {
16513 c_parser_error (parser, "invalid dist_schedule kind");
16514 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16515 "expected %<)%>");
16516 return list;
16517 }
16518
16519 c_parser_consume_token (parser);
16520 if (c_parser_next_token_is (parser, CPP_COMMA))
16521 {
16522 c_parser_consume_token (parser);
16523
16524 location_t expr_loc = c_parser_peek_token (parser)->location;
16525 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16526 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16527 t = expr.value;
16528 t = c_fully_fold (t, false, NULL);
16529 parens.skip_until_found_close (parser);
16530 }
16531 else
16532 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16533 "expected %<,%> or %<)%>");
16534
16535 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16536 "dist_schedule"); */
16537 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
16538 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
16539 if (t == error_mark_node)
16540 return list;
16541
16542 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
16543 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
16544 OMP_CLAUSE_CHAIN (c) = list;
16545 return c;
16546 }
16547
16548 /* OpenMP 4.0:
16549 proc_bind ( proc-bind-kind )
16550
16551 proc-bind-kind:
16552 primary | master | close | spread
16553 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16554
16555 static tree
16556 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16557 {
16558 location_t clause_loc = c_parser_peek_token (parser)->location;
16559 enum omp_clause_proc_bind_kind kind;
16560 tree c;
16561
16562 matching_parens parens;
16563 if (!parens.require_open (parser))
16564 return list;
16565
16566 if (c_parser_next_token_is (parser, CPP_NAME))
16567 {
16568 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16569 if (strcmp ("primary", p) == 0)
16570 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16571 else if (strcmp ("master", p) == 0)
16572 kind = OMP_CLAUSE_PROC_BIND_MASTER;
16573 else if (strcmp ("close", p) == 0)
16574 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16575 else if (strcmp ("spread", p) == 0)
16576 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16577 else
16578 goto invalid_kind;
16579 }
16580 else
16581 goto invalid_kind;
16582
16583 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16584 c_parser_consume_token (parser);
16585 parens.skip_until_found_close (parser);
16586 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16587 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16588 OMP_CLAUSE_CHAIN (c) = list;
16589 return c;
16590
16591 invalid_kind:
16592 c_parser_error (parser, "invalid proc_bind kind");
16593 parens.skip_until_found_close (parser);
16594 return list;
16595 }
16596
16597 /* OpenMP 5.0:
16598 device_type ( host | nohost | any ) */
16599
16600 static tree
16601 c_parser_omp_clause_device_type (c_parser *parser, tree list)
16602 {
16603 location_t clause_loc = c_parser_peek_token (parser)->location;
16604 enum omp_clause_device_type_kind kind;
16605 tree c;
16606
16607 matching_parens parens;
16608 if (!parens.require_open (parser))
16609 return list;
16610
16611 if (c_parser_next_token_is (parser, CPP_NAME))
16612 {
16613 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16614 if (strcmp ("host", p) == 0)
16615 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
16616 else if (strcmp ("nohost", p) == 0)
16617 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
16618 else if (strcmp ("any", p) == 0)
16619 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
16620 else
16621 goto invalid_kind;
16622 }
16623 else
16624 goto invalid_kind;
16625
16626 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16627 "device_type"); */
16628 c_parser_consume_token (parser);
16629 parens.skip_until_found_close (parser);
16630 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
16631 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
16632 OMP_CLAUSE_CHAIN (c) = list;
16633 return c;
16634
16635 invalid_kind:
16636 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
16637 parens.skip_until_found_close (parser);
16638 return list;
16639 }
16640
16641 /* OpenMP 4.0:
16642 to ( variable-list ) */
16643
16644 static tree
16645 c_parser_omp_clause_to (c_parser *parser, tree list)
16646 {
16647 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
16648 }
16649
16650 /* OpenMP 4.0:
16651 from ( variable-list ) */
16652
16653 static tree
16654 c_parser_omp_clause_from (c_parser *parser, tree list)
16655 {
16656 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
16657 }
16658
16659 /* OpenMP 4.0:
16660 uniform ( variable-list ) */
16661
16662 static tree
16663 c_parser_omp_clause_uniform (c_parser *parser, tree list)
16664 {
16665 /* The clauses location. */
16666 location_t loc = c_parser_peek_token (parser)->location;
16667
16668 matching_parens parens;
16669 if (parens.require_open (parser))
16670 {
16671 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
16672 list);
16673 parens.skip_until_found_close (parser);
16674 }
16675 return list;
16676 }
16677
16678 /* OpenMP 5.0:
16679 detach ( event-handle ) */
16680
16681 static tree
16682 c_parser_omp_clause_detach (c_parser *parser, tree list)
16683 {
16684 matching_parens parens;
16685 location_t clause_loc = c_parser_peek_token (parser)->location;
16686
16687 if (!parens.require_open (parser))
16688 return list;
16689
16690 if (c_parser_next_token_is_not (parser, CPP_NAME)
16691 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16692 {
16693 c_parser_error (parser, "expected identifier");
16694 parens.skip_until_found_close (parser);
16695 return list;
16696 }
16697
16698 tree t = lookup_name (c_parser_peek_token (parser)->value);
16699 if (t == NULL_TREE)
16700 {
16701 undeclared_variable (c_parser_peek_token (parser)->location,
16702 c_parser_peek_token (parser)->value);
16703 parens.skip_until_found_close (parser);
16704 return list;
16705 }
16706 c_parser_consume_token (parser);
16707
16708 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16709 if (!INTEGRAL_TYPE_P (type)
16710 || TREE_CODE (type) != ENUMERAL_TYPE
16711 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16712 {
16713 error_at (clause_loc, "%<detach%> clause event handle "
16714 "has type %qT rather than "
16715 "%<omp_event_handle_t%>",
16716 type);
16717 parens.skip_until_found_close (parser);
16718 return list;
16719 }
16720
16721 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16722 OMP_CLAUSE_DECL (u) = t;
16723 OMP_CLAUSE_CHAIN (u) = list;
16724 parens.skip_until_found_close (parser);
16725 return u;
16726 }
16727
16728 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16729 is a bitmask in MASK. Return the list of clauses found. */
16730
16731 static tree
16732 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16733 const char *where, bool finish_p = true)
16734 {
16735 tree clauses = NULL;
16736 bool first = true;
16737
16738 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16739 {
16740 location_t here;
16741 pragma_omp_clause c_kind;
16742 const char *c_name;
16743 tree prev = clauses;
16744
16745 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16746 c_parser_consume_token (parser);
16747
16748 here = c_parser_peek_token (parser)->location;
16749 c_kind = c_parser_omp_clause_name (parser);
16750
16751 switch (c_kind)
16752 {
16753 case PRAGMA_OACC_CLAUSE_ASYNC:
16754 clauses = c_parser_oacc_clause_async (parser, clauses);
16755 c_name = "async";
16756 break;
16757 case PRAGMA_OACC_CLAUSE_AUTO:
16758 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16759 clauses);
16760 c_name = "auto";
16761 break;
16762 case PRAGMA_OACC_CLAUSE_ATTACH:
16763 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16764 c_name = "attach";
16765 break;
16766 case PRAGMA_OACC_CLAUSE_COLLAPSE:
16767 clauses = c_parser_omp_clause_collapse (parser, clauses);
16768 c_name = "collapse";
16769 break;
16770 case PRAGMA_OACC_CLAUSE_COPY:
16771 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16772 c_name = "copy";
16773 break;
16774 case PRAGMA_OACC_CLAUSE_COPYIN:
16775 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16776 c_name = "copyin";
16777 break;
16778 case PRAGMA_OACC_CLAUSE_COPYOUT:
16779 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16780 c_name = "copyout";
16781 break;
16782 case PRAGMA_OACC_CLAUSE_CREATE:
16783 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16784 c_name = "create";
16785 break;
16786 case PRAGMA_OACC_CLAUSE_DELETE:
16787 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16788 c_name = "delete";
16789 break;
16790 case PRAGMA_OMP_CLAUSE_DEFAULT:
16791 clauses = c_parser_omp_clause_default (parser, clauses, true);
16792 c_name = "default";
16793 break;
16794 case PRAGMA_OACC_CLAUSE_DETACH:
16795 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16796 c_name = "detach";
16797 break;
16798 case PRAGMA_OACC_CLAUSE_DEVICE:
16799 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16800 c_name = "device";
16801 break;
16802 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16803 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16804 c_name = "deviceptr";
16805 break;
16806 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16807 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16808 c_name = "device_resident";
16809 break;
16810 case PRAGMA_OACC_CLAUSE_FINALIZE:
16811 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16812 clauses);
16813 c_name = "finalize";
16814 break;
16815 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16816 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16817 c_name = "firstprivate";
16818 break;
16819 case PRAGMA_OACC_CLAUSE_GANG:
16820 c_name = "gang";
16821 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16822 c_name, clauses);
16823 break;
16824 case PRAGMA_OACC_CLAUSE_HOST:
16825 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16826 c_name = "host";
16827 break;
16828 case PRAGMA_OACC_CLAUSE_IF:
16829 clauses = c_parser_omp_clause_if (parser, clauses, false);
16830 c_name = "if";
16831 break;
16832 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16833 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16834 clauses);
16835 c_name = "if_present";
16836 break;
16837 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16838 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16839 clauses);
16840 c_name = "independent";
16841 break;
16842 case PRAGMA_OACC_CLAUSE_LINK:
16843 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16844 c_name = "link";
16845 break;
16846 case PRAGMA_OACC_CLAUSE_NO_CREATE:
16847 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16848 c_name = "no_create";
16849 break;
16850 case PRAGMA_OACC_CLAUSE_NOHOST:
16851 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
16852 clauses);
16853 c_name = "nohost";
16854 break;
16855 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16856 clauses = c_parser_oacc_single_int_clause (parser,
16857 OMP_CLAUSE_NUM_GANGS,
16858 clauses);
16859 c_name = "num_gangs";
16860 break;
16861 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16862 clauses = c_parser_oacc_single_int_clause (parser,
16863 OMP_CLAUSE_NUM_WORKERS,
16864 clauses);
16865 c_name = "num_workers";
16866 break;
16867 case PRAGMA_OACC_CLAUSE_PRESENT:
16868 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16869 c_name = "present";
16870 break;
16871 case PRAGMA_OACC_CLAUSE_PRIVATE:
16872 clauses = c_parser_omp_clause_private (parser, clauses);
16873 c_name = "private";
16874 break;
16875 case PRAGMA_OACC_CLAUSE_REDUCTION:
16876 clauses
16877 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16878 false, clauses);
16879 c_name = "reduction";
16880 break;
16881 case PRAGMA_OACC_CLAUSE_SEQ:
16882 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16883 clauses);
16884 c_name = "seq";
16885 break;
16886 case PRAGMA_OACC_CLAUSE_TILE:
16887 clauses = c_parser_oacc_clause_tile (parser, clauses);
16888 c_name = "tile";
16889 break;
16890 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16891 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16892 c_name = "use_device";
16893 break;
16894 case PRAGMA_OACC_CLAUSE_VECTOR:
16895 c_name = "vector";
16896 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16897 c_name, clauses);
16898 break;
16899 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16900 clauses = c_parser_oacc_single_int_clause (parser,
16901 OMP_CLAUSE_VECTOR_LENGTH,
16902 clauses);
16903 c_name = "vector_length";
16904 break;
16905 case PRAGMA_OACC_CLAUSE_WAIT:
16906 clauses = c_parser_oacc_clause_wait (parser, clauses);
16907 c_name = "wait";
16908 break;
16909 case PRAGMA_OACC_CLAUSE_WORKER:
16910 c_name = "worker";
16911 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16912 c_name, clauses);
16913 break;
16914 default:
16915 c_parser_error (parser, "expected %<#pragma acc%> clause");
16916 goto saw_error;
16917 }
16918
16919 first = false;
16920
16921 if (((mask >> c_kind) & 1) == 0)
16922 {
16923 /* Remove the invalid clause(s) from the list to avoid
16924 confusing the rest of the compiler. */
16925 clauses = prev;
16926 error_at (here, "%qs is not valid for %qs", c_name, where);
16927 }
16928 }
16929
16930 saw_error:
16931 c_parser_skip_to_pragma_eol (parser);
16932
16933 if (finish_p)
16934 return c_finish_omp_clauses (clauses, C_ORT_ACC);
16935
16936 return clauses;
16937 }
16938
16939 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16940 is a bitmask in MASK. Return the list of clauses found.
16941 FINISH_P set if c_finish_omp_clauses should be called.
16942 NESTED non-zero if clauses should be terminated by closing paren instead
16943 of end of pragma. If it is 2, additionally commas are required in between
16944 the clauses. */
16945
16946 static tree
16947 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16948 const char *where, bool finish_p = true,
16949 int nested = 0)
16950 {
16951 tree clauses = NULL;
16952 bool first = true;
16953
16954 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16955 {
16956 location_t here;
16957 pragma_omp_clause c_kind;
16958 const char *c_name;
16959 tree prev = clauses;
16960
16961 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16962 break;
16963
16964 if (!first)
16965 {
16966 if (c_parser_next_token_is (parser, CPP_COMMA))
16967 c_parser_consume_token (parser);
16968 else if (nested == 2)
16969 error_at (c_parser_peek_token (parser)->location,
16970 "clauses in %<simd%> trait should be separated "
16971 "by %<,%>");
16972 }
16973
16974 here = c_parser_peek_token (parser)->location;
16975 c_kind = c_parser_omp_clause_name (parser);
16976
16977 switch (c_kind)
16978 {
16979 case PRAGMA_OMP_CLAUSE_BIND:
16980 clauses = c_parser_omp_clause_bind (parser, clauses);
16981 c_name = "bind";
16982 break;
16983 case PRAGMA_OMP_CLAUSE_COLLAPSE:
16984 clauses = c_parser_omp_clause_collapse (parser, clauses);
16985 c_name = "collapse";
16986 break;
16987 case PRAGMA_OMP_CLAUSE_COPYIN:
16988 clauses = c_parser_omp_clause_copyin (parser, clauses);
16989 c_name = "copyin";
16990 break;
16991 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16992 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16993 c_name = "copyprivate";
16994 break;
16995 case PRAGMA_OMP_CLAUSE_DEFAULT:
16996 clauses = c_parser_omp_clause_default (parser, clauses, false);
16997 c_name = "default";
16998 break;
16999 case PRAGMA_OMP_CLAUSE_DETACH:
17000 clauses = c_parser_omp_clause_detach (parser, clauses);
17001 c_name = "detach";
17002 break;
17003 case PRAGMA_OMP_CLAUSE_FILTER:
17004 clauses = c_parser_omp_clause_filter (parser, clauses);
17005 c_name = "filter";
17006 break;
17007 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
17008 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
17009 c_name = "firstprivate";
17010 break;
17011 case PRAGMA_OMP_CLAUSE_FINAL:
17012 clauses = c_parser_omp_clause_final (parser, clauses);
17013 c_name = "final";
17014 break;
17015 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
17016 clauses = c_parser_omp_clause_grainsize (parser, clauses);
17017 c_name = "grainsize";
17018 break;
17019 case PRAGMA_OMP_CLAUSE_HINT:
17020 clauses = c_parser_omp_clause_hint (parser, clauses);
17021 c_name = "hint";
17022 break;
17023 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
17024 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
17025 c_name = "defaultmap";
17026 break;
17027 case PRAGMA_OMP_CLAUSE_IF:
17028 clauses = c_parser_omp_clause_if (parser, clauses, true);
17029 c_name = "if";
17030 break;
17031 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
17032 clauses
17033 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
17034 true, clauses);
17035 c_name = "in_reduction";
17036 break;
17037 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
17038 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
17039 c_name = "lastprivate";
17040 break;
17041 case PRAGMA_OMP_CLAUSE_MERGEABLE:
17042 clauses = c_parser_omp_clause_mergeable (parser, clauses);
17043 c_name = "mergeable";
17044 break;
17045 case PRAGMA_OMP_CLAUSE_NOWAIT:
17046 clauses = c_parser_omp_clause_nowait (parser, clauses);
17047 c_name = "nowait";
17048 break;
17049 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
17050 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
17051 c_name = "num_tasks";
17052 break;
17053 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
17054 clauses = c_parser_omp_clause_num_threads (parser, clauses);
17055 c_name = "num_threads";
17056 break;
17057 case PRAGMA_OMP_CLAUSE_ORDER:
17058 clauses = c_parser_omp_clause_order (parser, clauses);
17059 c_name = "order";
17060 break;
17061 case PRAGMA_OMP_CLAUSE_ORDERED:
17062 clauses = c_parser_omp_clause_ordered (parser, clauses);
17063 c_name = "ordered";
17064 break;
17065 case PRAGMA_OMP_CLAUSE_PRIORITY:
17066 clauses = c_parser_omp_clause_priority (parser, clauses);
17067 c_name = "priority";
17068 break;
17069 case PRAGMA_OMP_CLAUSE_PRIVATE:
17070 clauses = c_parser_omp_clause_private (parser, clauses);
17071 c_name = "private";
17072 break;
17073 case PRAGMA_OMP_CLAUSE_REDUCTION:
17074 clauses
17075 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17076 true, clauses);
17077 c_name = "reduction";
17078 break;
17079 case PRAGMA_OMP_CLAUSE_SCHEDULE:
17080 clauses = c_parser_omp_clause_schedule (parser, clauses);
17081 c_name = "schedule";
17082 break;
17083 case PRAGMA_OMP_CLAUSE_SHARED:
17084 clauses = c_parser_omp_clause_shared (parser, clauses);
17085 c_name = "shared";
17086 break;
17087 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
17088 clauses
17089 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
17090 true, clauses);
17091 c_name = "task_reduction";
17092 break;
17093 case PRAGMA_OMP_CLAUSE_UNTIED:
17094 clauses = c_parser_omp_clause_untied (parser, clauses);
17095 c_name = "untied";
17096 break;
17097 case PRAGMA_OMP_CLAUSE_INBRANCH:
17098 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
17099 clauses);
17100 c_name = "inbranch";
17101 break;
17102 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
17103 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
17104 c_name = "nontemporal";
17105 break;
17106 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
17107 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
17108 clauses);
17109 c_name = "notinbranch";
17110 break;
17111 case PRAGMA_OMP_CLAUSE_PARALLEL:
17112 clauses
17113 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
17114 clauses);
17115 c_name = "parallel";
17116 if (!first)
17117 {
17118 clause_not_first:
17119 error_at (here, "%qs must be the first clause of %qs",
17120 c_name, where);
17121 clauses = prev;
17122 }
17123 break;
17124 case PRAGMA_OMP_CLAUSE_FOR:
17125 clauses
17126 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
17127 clauses);
17128 c_name = "for";
17129 if (!first)
17130 goto clause_not_first;
17131 break;
17132 case PRAGMA_OMP_CLAUSE_SECTIONS:
17133 clauses
17134 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17135 clauses);
17136 c_name = "sections";
17137 if (!first)
17138 goto clause_not_first;
17139 break;
17140 case PRAGMA_OMP_CLAUSE_TASKGROUP:
17141 clauses
17142 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17143 clauses);
17144 c_name = "taskgroup";
17145 if (!first)
17146 goto clause_not_first;
17147 break;
17148 case PRAGMA_OMP_CLAUSE_LINK:
17149 clauses
17150 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17151 c_name = "link";
17152 break;
17153 case PRAGMA_OMP_CLAUSE_TO:
17154 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17155 {
17156 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17157 clauses);
17158 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
17159 OMP_CLAUSE_ENTER_TO (c) = 1;
17160 clauses = nl;
17161 }
17162 else
17163 clauses = c_parser_omp_clause_to (parser, clauses);
17164 c_name = "to";
17165 break;
17166 case PRAGMA_OMP_CLAUSE_FROM:
17167 clauses = c_parser_omp_clause_from (parser, clauses);
17168 c_name = "from";
17169 break;
17170 case PRAGMA_OMP_CLAUSE_UNIFORM:
17171 clauses = c_parser_omp_clause_uniform (parser, clauses);
17172 c_name = "uniform";
17173 break;
17174 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17175 clauses = c_parser_omp_clause_num_teams (parser, clauses);
17176 c_name = "num_teams";
17177 break;
17178 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17179 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17180 c_name = "thread_limit";
17181 break;
17182 case PRAGMA_OMP_CLAUSE_ALIGNED:
17183 clauses = c_parser_omp_clause_aligned (parser, clauses);
17184 c_name = "aligned";
17185 break;
17186 case PRAGMA_OMP_CLAUSE_ALLOCATE:
17187 clauses = c_parser_omp_clause_allocate (parser, clauses);
17188 c_name = "allocate";
17189 break;
17190 case PRAGMA_OMP_CLAUSE_LINEAR:
17191 clauses = c_parser_omp_clause_linear (parser, clauses);
17192 c_name = "linear";
17193 break;
17194 case PRAGMA_OMP_CLAUSE_AFFINITY:
17195 clauses = c_parser_omp_clause_affinity (parser, clauses);
17196 c_name = "affinity";
17197 break;
17198 case PRAGMA_OMP_CLAUSE_DEPEND:
17199 clauses = c_parser_omp_clause_depend (parser, clauses);
17200 c_name = "depend";
17201 break;
17202 case PRAGMA_OMP_CLAUSE_MAP:
17203 clauses = c_parser_omp_clause_map (parser, clauses);
17204 c_name = "map";
17205 break;
17206 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17207 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17208 c_name = "use_device_ptr";
17209 break;
17210 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17211 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17212 c_name = "use_device_addr";
17213 break;
17214 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17215 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17216 c_name = "has_device_addr";
17217 break;
17218 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17219 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17220 c_name = "is_device_ptr";
17221 break;
17222 case PRAGMA_OMP_CLAUSE_DEVICE:
17223 clauses = c_parser_omp_clause_device (parser, clauses);
17224 c_name = "device";
17225 break;
17226 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
17227 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
17228 c_name = "dist_schedule";
17229 break;
17230 case PRAGMA_OMP_CLAUSE_PROC_BIND:
17231 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
17232 c_name = "proc_bind";
17233 break;
17234 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
17235 clauses = c_parser_omp_clause_device_type (parser, clauses);
17236 c_name = "device_type";
17237 break;
17238 case PRAGMA_OMP_CLAUSE_SAFELEN:
17239 clauses = c_parser_omp_clause_safelen (parser, clauses);
17240 c_name = "safelen";
17241 break;
17242 case PRAGMA_OMP_CLAUSE_SIMDLEN:
17243 clauses = c_parser_omp_clause_simdlen (parser, clauses);
17244 c_name = "simdlen";
17245 break;
17246 case PRAGMA_OMP_CLAUSE_NOGROUP:
17247 clauses = c_parser_omp_clause_nogroup (parser, clauses);
17248 c_name = "nogroup";
17249 break;
17250 case PRAGMA_OMP_CLAUSE_THREADS:
17251 clauses
17252 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
17253 clauses);
17254 c_name = "threads";
17255 break;
17256 case PRAGMA_OMP_CLAUSE_SIMD:
17257 clauses
17258 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
17259 clauses);
17260 c_name = "simd";
17261 break;
17262 case PRAGMA_OMP_CLAUSE_ENTER:
17263 clauses
17264 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17265 clauses);
17266 c_name = "enter";
17267 break;
17268 default:
17269 c_parser_error (parser, "expected %<#pragma omp%> clause");
17270 goto saw_error;
17271 }
17272
17273 first = false;
17274
17275 if (((mask >> c_kind) & 1) == 0)
17276 {
17277 /* Remove the invalid clause(s) from the list to avoid
17278 confusing the rest of the compiler. */
17279 clauses = prev;
17280 error_at (here, "%qs is not valid for %qs", c_name, where);
17281 }
17282 }
17283
17284 saw_error:
17285 if (!nested)
17286 c_parser_skip_to_pragma_eol (parser);
17287
17288 if (finish_p)
17289 {
17290 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
17291 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
17292 return c_finish_omp_clauses (clauses, C_ORT_OMP);
17293 }
17294
17295 return clauses;
17296 }
17297
17298 /* OpenACC 2.0, OpenMP 2.5:
17299 structured-block:
17300 statement
17301
17302 In practice, we're also interested in adding the statement to an
17303 outer node. So it is convenient if we work around the fact that
17304 c_parser_statement calls add_stmt. */
17305
17306 static tree
17307 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
17308 {
17309 tree stmt = push_stmt_list ();
17310 c_parser_statement (parser, if_p);
17311 return pop_stmt_list (stmt);
17312 }
17313
17314 /* OpenACC 2.0:
17315 # pragma acc cache (variable-list) new-line
17316
17317 LOC is the location of the #pragma token.
17318 */
17319
17320 static tree
17321 c_parser_oacc_cache (location_t loc, c_parser *parser)
17322 {
17323 tree stmt, clauses;
17324
17325 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
17326 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17327
17328 c_parser_skip_to_pragma_eol (parser);
17329
17330 stmt = make_node (OACC_CACHE);
17331 TREE_TYPE (stmt) = void_type_node;
17332 OACC_CACHE_CLAUSES (stmt) = clauses;
17333 SET_EXPR_LOCATION (stmt, loc);
17334 add_stmt (stmt);
17335
17336 return stmt;
17337 }
17338
17339 /* OpenACC 2.0:
17340 # pragma acc data oacc-data-clause[optseq] new-line
17341 structured-block
17342
17343 LOC is the location of the #pragma token.
17344 */
17345
17346 #define OACC_DATA_CLAUSE_MASK \
17347 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17348 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17356
17357 static tree
17358 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
17359 {
17360 tree stmt, clauses, block;
17361
17362 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
17363 "#pragma acc data");
17364
17365 block = c_begin_omp_parallel ();
17366 add_stmt (c_parser_omp_structured_block (parser, if_p));
17367
17368 stmt = c_finish_oacc_data (loc, clauses, block);
17369
17370 return stmt;
17371 }
17372
17373 /* OpenACC 2.0:
17374 # pragma acc declare oacc-data-clause[optseq] new-line
17375 */
17376
17377 #define OACC_DECLARE_CLAUSE_MASK \
17378 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17381 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17383 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17384 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17386
17387 static void
17388 c_parser_oacc_declare (c_parser *parser)
17389 {
17390 location_t pragma_loc = c_parser_peek_token (parser)->location;
17391 tree clauses, stmt, t, decl;
17392
17393 bool error = false;
17394
17395 c_parser_consume_pragma (parser);
17396
17397 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
17398 "#pragma acc declare");
17399 if (!clauses)
17400 {
17401 error_at (pragma_loc,
17402 "no valid clauses specified in %<#pragma acc declare%>");
17403 return;
17404 }
17405
17406 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
17407 {
17408 location_t loc = OMP_CLAUSE_LOCATION (t);
17409 decl = OMP_CLAUSE_DECL (t);
17410 if (!DECL_P (decl))
17411 {
17412 error_at (loc, "array section in %<#pragma acc declare%>");
17413 error = true;
17414 continue;
17415 }
17416
17417 switch (OMP_CLAUSE_MAP_KIND (t))
17418 {
17419 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17420 case GOMP_MAP_ALLOC:
17421 case GOMP_MAP_TO:
17422 case GOMP_MAP_FORCE_DEVICEPTR:
17423 case GOMP_MAP_DEVICE_RESIDENT:
17424 break;
17425
17426 case GOMP_MAP_LINK:
17427 if (!global_bindings_p ()
17428 && (TREE_STATIC (decl)
17429 || !DECL_EXTERNAL (decl)))
17430 {
17431 error_at (loc,
17432 "%qD must be a global variable in "
17433 "%<#pragma acc declare link%>",
17434 decl);
17435 error = true;
17436 continue;
17437 }
17438 break;
17439
17440 default:
17441 if (global_bindings_p ())
17442 {
17443 error_at (loc, "invalid OpenACC clause at file scope");
17444 error = true;
17445 continue;
17446 }
17447 if (DECL_EXTERNAL (decl))
17448 {
17449 error_at (loc,
17450 "invalid use of %<extern%> variable %qD "
17451 "in %<#pragma acc declare%>", decl);
17452 error = true;
17453 continue;
17454 }
17455 else if (TREE_PUBLIC (decl))
17456 {
17457 error_at (loc,
17458 "invalid use of %<global%> variable %qD "
17459 "in %<#pragma acc declare%>", decl);
17460 error = true;
17461 continue;
17462 }
17463 break;
17464 }
17465
17466 if (!c_check_in_current_scope (decl))
17467 {
17468 error_at (loc,
17469 "%qD must be a variable declared in the same scope as "
17470 "%<#pragma acc declare%>", decl);
17471 error = true;
17472 continue;
17473 }
17474
17475 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
17476 || lookup_attribute ("omp declare target link",
17477 DECL_ATTRIBUTES (decl)))
17478 {
17479 error_at (loc, "variable %qD used more than once with "
17480 "%<#pragma acc declare%>", decl);
17481 error = true;
17482 continue;
17483 }
17484
17485 if (!error)
17486 {
17487 tree id;
17488
17489 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
17490 id = get_identifier ("omp declare target link");
17491 else
17492 id = get_identifier ("omp declare target");
17493
17494 DECL_ATTRIBUTES (decl)
17495 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
17496
17497 if (global_bindings_p ())
17498 {
17499 symtab_node *node = symtab_node::get (decl);
17500 if (node != NULL)
17501 {
17502 node->offloadable = 1;
17503 if (ENABLE_OFFLOADING)
17504 {
17505 g->have_offload = true;
17506 if (is_a <varpool_node *> (node))
17507 vec_safe_push (offload_vars, decl);
17508 }
17509 }
17510 }
17511 }
17512 }
17513
17514 if (error || global_bindings_p ())
17515 return;
17516
17517 stmt = make_node (OACC_DECLARE);
17518 TREE_TYPE (stmt) = void_type_node;
17519 OACC_DECLARE_CLAUSES (stmt) = clauses;
17520 SET_EXPR_LOCATION (stmt, pragma_loc);
17521
17522 add_stmt (stmt);
17523
17524 return;
17525 }
17526
17527 /* OpenACC 2.0:
17528 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17529
17530 or
17531
17532 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17533
17534
17535 LOC is the location of the #pragma token.
17536 */
17537
17538 #define OACC_ENTER_DATA_CLAUSE_MASK \
17539 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17545
17546 #define OACC_EXIT_DATA_CLAUSE_MASK \
17547 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17554
17555 static void
17556 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
17557 {
17558 location_t loc = c_parser_peek_token (parser)->location;
17559 tree clauses, stmt;
17560 const char *p = "";
17561
17562 c_parser_consume_pragma (parser);
17563
17564 if (c_parser_next_token_is (parser, CPP_NAME))
17565 {
17566 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17567 c_parser_consume_token (parser);
17568 }
17569
17570 if (strcmp (p, "data") != 0)
17571 {
17572 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17573 enter ? "enter" : "exit");
17574 parser->error = true;
17575 c_parser_skip_to_pragma_eol (parser);
17576 return;
17577 }
17578
17579 if (enter)
17580 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17581 "#pragma acc enter data");
17582 else
17583 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17584 "#pragma acc exit data");
17585
17586 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17587 {
17588 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17589 enter ? "enter" : "exit");
17590 return;
17591 }
17592
17593 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
17594 TREE_TYPE (stmt) = void_type_node;
17595 OMP_STANDALONE_CLAUSES (stmt) = clauses;
17596 SET_EXPR_LOCATION (stmt, loc);
17597 add_stmt (stmt);
17598 }
17599
17600
17601 /* OpenACC 2.0:
17602 # pragma acc host_data oacc-data-clause[optseq] new-line
17603 structured-block
17604 */
17605
17606 #define OACC_HOST_DATA_CLAUSE_MASK \
17607 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17608 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17610
17611 static tree
17612 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
17613 {
17614 tree stmt, clauses, block;
17615
17616 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
17617 "#pragma acc host_data");
17618
17619 block = c_begin_omp_parallel ();
17620 add_stmt (c_parser_omp_structured_block (parser, if_p));
17621 stmt = c_finish_oacc_host_data (loc, clauses, block);
17622 return stmt;
17623 }
17624
17625
17626 /* OpenACC 2.0:
17627
17628 # pragma acc loop oacc-loop-clause[optseq] new-line
17629 structured-block
17630
17631 LOC is the location of the #pragma token.
17632 */
17633
17634 #define OACC_LOOP_CLAUSE_MASK \
17635 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17645 static tree
17646 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
17647 omp_clause_mask mask, tree *cclauses, bool *if_p)
17648 {
17649 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
17650
17651 strcat (p_name, " loop");
17652 mask |= OACC_LOOP_CLAUSE_MASK;
17653
17654 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
17655 cclauses == NULL);
17656 if (cclauses)
17657 {
17658 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
17659 if (*cclauses)
17660 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
17661 if (clauses)
17662 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17663 }
17664
17665 tree block = c_begin_compound_stmt (true);
17666 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
17667 if_p);
17668 block = c_end_compound_stmt (loc, block, true);
17669 add_stmt (block);
17670
17671 return stmt;
17672 }
17673
17674 /* OpenACC 2.0:
17675 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17676 structured-block
17677
17678 or
17679
17680 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17681 structured-block
17682
17683 OpenACC 2.6:
17684
17685 # pragma acc serial oacc-serial-clause[optseq] new-line
17686 structured-block
17687
17688 LOC is the location of the #pragma token.
17689 */
17690
17691 #define OACC_KERNELS_CLAUSE_MASK \
17692 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17693 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17694 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17695 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17696 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17697 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17698 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17699 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17705 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17706 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17707
17708 #define OACC_PARALLEL_CLAUSE_MASK \
17709 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17715 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17727
17728 #define OACC_SERIAL_CLAUSE_MASK \
17729 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17730 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17731 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17732 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17744
17745 static tree
17746 c_parser_oacc_compute (location_t loc, c_parser *parser,
17747 enum pragma_kind p_kind, char *p_name, bool *if_p)
17748 {
17749 omp_clause_mask mask;
17750 enum tree_code code;
17751 switch (p_kind)
17752 {
17753 case PRAGMA_OACC_KERNELS:
17754 strcat (p_name, " kernels");
17755 mask = OACC_KERNELS_CLAUSE_MASK;
17756 code = OACC_KERNELS;
17757 break;
17758 case PRAGMA_OACC_PARALLEL:
17759 strcat (p_name, " parallel");
17760 mask = OACC_PARALLEL_CLAUSE_MASK;
17761 code = OACC_PARALLEL;
17762 break;
17763 case PRAGMA_OACC_SERIAL:
17764 strcat (p_name, " serial");
17765 mask = OACC_SERIAL_CLAUSE_MASK;
17766 code = OACC_SERIAL;
17767 break;
17768 default:
17769 gcc_unreachable ();
17770 }
17771
17772 if (c_parser_next_token_is (parser, CPP_NAME))
17773 {
17774 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17775 if (strcmp (p, "loop") == 0)
17776 {
17777 c_parser_consume_token (parser);
17778 tree block = c_begin_omp_parallel ();
17779 tree clauses;
17780 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17781 return c_finish_omp_construct (loc, code, block, clauses);
17782 }
17783 }
17784
17785 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17786
17787 tree block = c_begin_omp_parallel ();
17788 add_stmt (c_parser_omp_structured_block (parser, if_p));
17789
17790 return c_finish_omp_construct (loc, code, block, clauses);
17791 }
17792
17793 /* OpenACC 2.0:
17794 # pragma acc routine oacc-routine-clause[optseq] new-line
17795 function-definition
17796
17797 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17798 */
17799
17800 #define OACC_ROUTINE_CLAUSE_MASK \
17801 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17806
17807 /* Parse an OpenACC routine directive. For named directives, we apply
17808 immediately to the named function. For unnamed ones we then parse
17809 a declaration or definition, which must be for a function. */
17810
17811 static void
17812 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17813 {
17814 gcc_checking_assert (context == pragma_external);
17815
17816 oacc_routine_data data;
17817 data.error_seen = false;
17818 data.fndecl_seen = false;
17819 data.loc = c_parser_peek_token (parser)->location;
17820
17821 c_parser_consume_pragma (parser);
17822
17823 /* Look for optional '( name )'. */
17824 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17825 {
17826 c_parser_consume_token (parser); /* '(' */
17827
17828 tree decl = NULL_TREE;
17829 c_token *name_token = c_parser_peek_token (parser);
17830 location_t name_loc = name_token->location;
17831 if (name_token->type == CPP_NAME
17832 && (name_token->id_kind == C_ID_ID
17833 || name_token->id_kind == C_ID_TYPENAME))
17834 {
17835 decl = lookup_name (name_token->value);
17836 if (!decl)
17837 error_at (name_loc,
17838 "%qE has not been declared", name_token->value);
17839 c_parser_consume_token (parser);
17840 }
17841 else
17842 c_parser_error (parser, "expected function name");
17843
17844 if (!decl
17845 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17846 {
17847 c_parser_skip_to_pragma_eol (parser, false);
17848 return;
17849 }
17850
17851 data.clauses
17852 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17853 "#pragma acc routine");
17854 /* The clauses are in reverse order; fix that to make later diagnostic
17855 emission easier. */
17856 data.clauses = nreverse (data.clauses);
17857
17858 if (TREE_CODE (decl) != FUNCTION_DECL)
17859 {
17860 error_at (name_loc, "%qD does not refer to a function", decl);
17861 return;
17862 }
17863
17864 c_finish_oacc_routine (&data, decl, false);
17865 }
17866 else /* No optional '( name )'. */
17867 {
17868 data.clauses
17869 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17870 "#pragma acc routine");
17871 /* The clauses are in reverse order; fix that to make later diagnostic
17872 emission easier. */
17873 data.clauses = nreverse (data.clauses);
17874
17875 /* Emit a helpful diagnostic if there's another pragma following this
17876 one. Also don't allow a static assertion declaration, as in the
17877 following we'll just parse a *single* "declaration or function
17878 definition", and the static assertion counts an one. */
17879 if (c_parser_next_token_is (parser, CPP_PRAGMA)
17880 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17881 {
17882 error_at (data.loc,
17883 "%<#pragma acc routine%> not immediately followed by"
17884 " function declaration or definition");
17885 /* ..., and then just keep going. */
17886 return;
17887 }
17888
17889 /* We only have to consider the pragma_external case here. */
17890 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17891 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17892 {
17893 int ext = disable_extension_diagnostics ();
17894 do
17895 c_parser_consume_token (parser);
17896 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17897 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17898 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17899 NULL, NULL, false, NULL, &data);
17900 restore_extension_diagnostics (ext);
17901 }
17902 else
17903 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17904 NULL, NULL, false, NULL, &data);
17905 }
17906 }
17907
17908 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17909 IS_DEFN is true if we're applying it to the definition. */
17910
17911 static void
17912 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17913 bool is_defn)
17914 {
17915 /* Keep going if we're in error reporting mode. */
17916 if (data->error_seen
17917 || fndecl == error_mark_node)
17918 return;
17919
17920 if (data->fndecl_seen)
17921 {
17922 error_at (data->loc,
17923 "%<#pragma acc routine%> not immediately followed by"
17924 " a single function declaration or definition");
17925 data->error_seen = true;
17926 return;
17927 }
17928 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17929 {
17930 error_at (data->loc,
17931 "%<#pragma acc routine%> not immediately followed by"
17932 " function declaration or definition");
17933 data->error_seen = true;
17934 return;
17935 }
17936
17937 int compatible
17938 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17939 "#pragma acc routine");
17940 if (compatible < 0)
17941 {
17942 data->error_seen = true;
17943 return;
17944 }
17945 if (compatible > 0)
17946 {
17947 }
17948 else
17949 {
17950 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17951 {
17952 error_at (data->loc,
17953 TREE_USED (fndecl)
17954 ? G_("%<#pragma acc routine%> must be applied before use")
17955 : G_("%<#pragma acc routine%> must be applied before"
17956 " definition"));
17957 data->error_seen = true;
17958 return;
17959 }
17960
17961 /* Set the routine's level of parallelism. */
17962 tree dims = oacc_build_routine_dims (data->clauses);
17963 oacc_replace_fn_attrib (fndecl, dims);
17964
17965 /* Add an "omp declare target" attribute. */
17966 DECL_ATTRIBUTES (fndecl)
17967 = tree_cons (get_identifier ("omp declare target"),
17968 data->clauses, DECL_ATTRIBUTES (fndecl));
17969 }
17970
17971 /* Remember that we've used this "#pragma acc routine". */
17972 data->fndecl_seen = true;
17973 }
17974
17975 /* OpenACC 2.0:
17976 # pragma acc update oacc-update-clause[optseq] new-line
17977 */
17978
17979 #define OACC_UPDATE_CLAUSE_MASK \
17980 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17986
17987 static void
17988 c_parser_oacc_update (c_parser *parser)
17989 {
17990 location_t loc = c_parser_peek_token (parser)->location;
17991
17992 c_parser_consume_pragma (parser);
17993
17994 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17995 "#pragma acc update");
17996 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17997 {
17998 error_at (loc,
17999 "%<#pragma acc update%> must contain at least one "
18000 "%<device%> or %<host%> or %<self%> clause");
18001 return;
18002 }
18003
18004 if (parser->error)
18005 return;
18006
18007 tree stmt = make_node (OACC_UPDATE);
18008 TREE_TYPE (stmt) = void_type_node;
18009 OACC_UPDATE_CLAUSES (stmt) = clauses;
18010 SET_EXPR_LOCATION (stmt, loc);
18011 add_stmt (stmt);
18012 }
18013
18014 /* OpenACC 2.0:
18015 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18016
18017 LOC is the location of the #pragma token.
18018 */
18019
18020 #define OACC_WAIT_CLAUSE_MASK \
18021 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18022
18023 static tree
18024 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
18025 {
18026 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
18027
18028 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
18029 list = c_parser_oacc_wait_list (parser, loc, list);
18030
18031 strcpy (p_name, " wait");
18032 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
18033 stmt = c_finish_oacc_wait (loc, list, clauses);
18034 add_stmt (stmt);
18035
18036 return stmt;
18037 }
18038
18039 /* OpenMP 5.0:
18040 # pragma omp allocate (list) [allocator(allocator)] */
18041
18042 static void
18043 c_parser_omp_allocate (location_t loc, c_parser *parser)
18044 {
18045 tree allocator = NULL_TREE;
18046 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
18047 if (c_parser_next_token_is (parser, CPP_NAME))
18048 {
18049 matching_parens parens;
18050 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18051 c_parser_consume_token (parser);
18052 if (strcmp ("allocator", p) != 0)
18053 error_at (c_parser_peek_token (parser)->location,
18054 "expected %<allocator%>");
18055 else if (parens.require_open (parser))
18056 {
18057 location_t expr_loc = c_parser_peek_token (parser)->location;
18058 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18059 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18060 allocator = expr.value;
18061 allocator = c_fully_fold (allocator, false, NULL);
18062 tree orig_type
18063 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
18064 orig_type = TYPE_MAIN_VARIANT (orig_type);
18065 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
18066 || TREE_CODE (orig_type) != ENUMERAL_TYPE
18067 || TYPE_NAME (orig_type)
18068 != get_identifier ("omp_allocator_handle_t"))
18069 {
18070 error_at (expr_loc, "%<allocator%> clause allocator expression "
18071 "has type %qT rather than "
18072 "%<omp_allocator_handle_t%>",
18073 TREE_TYPE (allocator));
18074 allocator = NULL_TREE;
18075 }
18076 parens.skip_until_found_close (parser);
18077 }
18078 }
18079 c_parser_skip_to_pragma_eol (parser);
18080
18081 if (allocator)
18082 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
18083 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18084
18085 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
18086 }
18087
18088 /* OpenMP 2.5:
18089 # pragma omp atomic new-line
18090 expression-stmt
18091
18092 expression-stmt:
18093 x binop= expr | x++ | ++x | x-- | --x
18094 binop:
18095 +, *, -, /, &, ^, |, <<, >>
18096
18097 where x is an lvalue expression with scalar type.
18098
18099 OpenMP 3.1:
18100 # pragma omp atomic new-line
18101 update-stmt
18102
18103 # pragma omp atomic read new-line
18104 read-stmt
18105
18106 # pragma omp atomic write new-line
18107 write-stmt
18108
18109 # pragma omp atomic update new-line
18110 update-stmt
18111
18112 # pragma omp atomic capture new-line
18113 capture-stmt
18114
18115 # pragma omp atomic capture new-line
18116 capture-block
18117
18118 read-stmt:
18119 v = x
18120 write-stmt:
18121 x = expr
18122 update-stmt:
18123 expression-stmt | x = x binop expr
18124 capture-stmt:
18125 v = expression-stmt
18126 capture-block:
18127 { v = x; update-stmt; } | { update-stmt; v = x; }
18128
18129 OpenMP 4.0:
18130 update-stmt:
18131 expression-stmt | x = x binop expr | x = expr binop x
18132 capture-stmt:
18133 v = update-stmt
18134 capture-block:
18135 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18136
18137 OpenMP 5.1:
18138 # pragma omp atomic compare new-line
18139 conditional-update-atomic
18140
18141 # pragma omp atomic compare capture new-line
18142 conditional-update-capture-atomic
18143
18144 conditional-update-atomic:
18145 cond-expr-stmt | cond-update-stmt
18146 cond-expr-stmt:
18147 x = expr ordop x ? expr : x;
18148 x = x ordop expr ? expr : x;
18149 x = x == e ? d : x;
18150 cond-update-stmt:
18151 if (expr ordop x) { x = expr; }
18152 if (x ordop expr) { x = expr; }
18153 if (x == e) { x = d; }
18154 ordop:
18155 <, >
18156 conditional-update-capture-atomic:
18157 v = cond-expr-stmt
18158 { v = x; cond-expr-stmt }
18159 { cond-expr-stmt v = x; }
18160 { v = x; cond-update-stmt }
18161 { cond-update-stmt v = x; }
18162 if (x == e) { x = d; } else { v = x; }
18163 { r = x == e; if (r) { x = d; } }
18164 { r = x == e; if (r) { x = d; } else { v = x; } }
18165
18166 where x, r and v are lvalue expressions with scalar type,
18167 expr, e and d are expressions with scalar type and e might be
18168 the same as v.
18169
18170 LOC is the location of the #pragma token. */
18171
18172 static void
18173 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18174 {
18175 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18176 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18177 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
18178 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
18179 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
18180 struct c_expr expr;
18181 location_t eloc;
18182 bool structured_block = false;
18183 bool swapped = false;
18184 bool non_lvalue_p;
18185 bool first = true;
18186 tree clauses = NULL_TREE;
18187 bool capture = false;
18188 bool compare = false;
18189 bool weak = false;
18190 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18191 bool no_semicolon = false;
18192 bool extra_scope = false;
18193
18194 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18195 {
18196 if (!first
18197 && c_parser_next_token_is (parser, CPP_COMMA)
18198 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18199 c_parser_consume_token (parser);
18200
18201 first = false;
18202
18203 if (c_parser_next_token_is (parser, CPP_NAME))
18204 {
18205 const char *p
18206 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18207 location_t cloc = c_parser_peek_token (parser)->location;
18208 enum tree_code new_code = ERROR_MARK;
18209 enum omp_memory_order new_memory_order
18210 = OMP_MEMORY_ORDER_UNSPECIFIED;
18211 bool new_capture = false;
18212 bool new_compare = false;
18213 bool new_weak = false;
18214 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18215
18216 if (!strcmp (p, "read"))
18217 new_code = OMP_ATOMIC_READ;
18218 else if (!strcmp (p, "write"))
18219 new_code = NOP_EXPR;
18220 else if (!strcmp (p, "update"))
18221 new_code = OMP_ATOMIC;
18222 else if (openacc && !strcmp (p, "capture"))
18223 new_code = OMP_ATOMIC_CAPTURE_NEW;
18224 else if (openacc)
18225 {
18226 p = NULL;
18227 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18228 "or %<capture%> clause");
18229 }
18230 else if (!strcmp (p, "capture"))
18231 new_capture = true;
18232 else if (!strcmp (p, "compare"))
18233 new_compare = true;
18234 else if (!strcmp (p, "weak"))
18235 new_weak = true;
18236 else if (!strcmp (p, "fail"))
18237 {
18238 matching_parens parens;
18239
18240 c_parser_consume_token (parser);
18241 if (!parens.require_open (parser))
18242 continue;
18243
18244 if (c_parser_next_token_is (parser, CPP_NAME))
18245 {
18246 const char *q
18247 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18248
18249 if (!strcmp (q, "seq_cst"))
18250 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
18251 else if (!strcmp (q, "acquire"))
18252 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
18253 else if (!strcmp (q, "relaxed"))
18254 new_fail = OMP_MEMORY_ORDER_RELAXED;
18255 }
18256
18257 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18258 {
18259 c_parser_consume_token (parser);
18260 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18261 error_at (cloc, "too many %qs clauses", "fail");
18262 else
18263 fail = new_fail;
18264 }
18265 else
18266 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
18267 "or %<relaxed%>");
18268 parens.skip_until_found_close (parser);
18269 continue;
18270 }
18271 else if (!strcmp (p, "seq_cst"))
18272 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18273 else if (!strcmp (p, "acq_rel"))
18274 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18275 else if (!strcmp (p, "release"))
18276 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
18277 else if (!strcmp (p, "acquire"))
18278 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18279 else if (!strcmp (p, "relaxed"))
18280 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
18281 else if (!strcmp (p, "hint"))
18282 {
18283 c_parser_consume_token (parser);
18284 clauses = c_parser_omp_clause_hint (parser, clauses);
18285 continue;
18286 }
18287 else
18288 {
18289 p = NULL;
18290 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18291 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18292 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18293 "%<relaxed%> or %<hint%> clause");
18294 }
18295 if (p)
18296 {
18297 if (new_code != ERROR_MARK)
18298 {
18299 /* OpenACC permits 'update capture'. */
18300 if (openacc
18301 && code == OMP_ATOMIC
18302 && new_code == OMP_ATOMIC_CAPTURE_NEW)
18303 code = new_code;
18304 else if (code != ERROR_MARK)
18305 error_at (cloc, "too many atomic clauses");
18306 else
18307 code = new_code;
18308 }
18309 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18310 {
18311 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18312 error_at (cloc, "too many memory order clauses");
18313 else
18314 memory_order = new_memory_order;
18315 }
18316 else if (new_capture)
18317 {
18318 if (capture)
18319 error_at (cloc, "too many %qs clauses", "capture");
18320 else
18321 capture = true;
18322 }
18323 else if (new_compare)
18324 {
18325 if (compare)
18326 error_at (cloc, "too many %qs clauses", "compare");
18327 else
18328 compare = true;
18329 }
18330 else if (new_weak)
18331 {
18332 if (weak)
18333 error_at (cloc, "too many %qs clauses", "weak");
18334 else
18335 weak = true;
18336 }
18337 c_parser_consume_token (parser);
18338 continue;
18339 }
18340 }
18341 break;
18342 }
18343 c_parser_skip_to_pragma_eol (parser);
18344
18345 if (code == ERROR_MARK)
18346 code = OMP_ATOMIC;
18347 if (capture)
18348 {
18349 if (code != OMP_ATOMIC)
18350 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18351 "clauses", "capture");
18352 else
18353 code = OMP_ATOMIC_CAPTURE_NEW;
18354 }
18355 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
18356 {
18357 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18358 "clauses", "compare");
18359 compare = false;
18360 }
18361 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
18362 {
18363 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
18364 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18365 }
18366 if (weak && !compare)
18367 {
18368 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
18369 weak = false;
18370 }
18371 if (openacc)
18372 memory_order = OMP_MEMORY_ORDER_RELAXED;
18373 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
18374 {
18375 omp_requires_mask
18376 = (enum omp_requires) (omp_requires_mask
18377 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
18378 switch ((enum omp_memory_order)
18379 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
18380 {
18381 case OMP_MEMORY_ORDER_UNSPECIFIED:
18382 case OMP_MEMORY_ORDER_RELAXED:
18383 memory_order = OMP_MEMORY_ORDER_RELAXED;
18384 break;
18385 case OMP_MEMORY_ORDER_SEQ_CST:
18386 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18387 break;
18388 case OMP_MEMORY_ORDER_ACQ_REL:
18389 switch (code)
18390 {
18391 case OMP_ATOMIC_READ:
18392 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18393 break;
18394 case NOP_EXPR: /* atomic write */
18395 memory_order = OMP_MEMORY_ORDER_RELEASE;
18396 break;
18397 default:
18398 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18399 break;
18400 }
18401 break;
18402 default:
18403 gcc_unreachable ();
18404 }
18405 }
18406 else
18407 switch (code)
18408 {
18409 case OMP_ATOMIC_READ:
18410 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
18411 {
18412 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
18413 "%<release%> clause");
18414 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18415 }
18416 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18417 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18418 break;
18419 case NOP_EXPR: /* atomic write */
18420 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
18421 {
18422 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
18423 "%<acquire%> clause");
18424 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18425 }
18426 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18427 memory_order = OMP_MEMORY_ORDER_RELEASE;
18428 break;
18429 default:
18430 break;
18431 }
18432 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18433 memory_order
18434 = (enum omp_memory_order) (memory_order
18435 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
18436
18437 switch (code)
18438 {
18439 case OMP_ATOMIC_READ:
18440 case NOP_EXPR: /* atomic write */
18441 v = c_parser_cast_expression (parser, NULL).value;
18442 non_lvalue_p = !lvalue_p (v);
18443 v = c_fully_fold (v, false, NULL, true);
18444 if (v == error_mark_node)
18445 goto saw_error;
18446 if (non_lvalue_p)
18447 v = non_lvalue (v);
18448 loc = c_parser_peek_token (parser)->location;
18449 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18450 goto saw_error;
18451 if (code == NOP_EXPR)
18452 {
18453 lhs = c_parser_expression (parser).value;
18454 lhs = c_fully_fold (lhs, false, NULL);
18455 if (lhs == error_mark_node)
18456 goto saw_error;
18457 }
18458 else
18459 {
18460 lhs = c_parser_cast_expression (parser, NULL).value;
18461 non_lvalue_p = !lvalue_p (lhs);
18462 lhs = c_fully_fold (lhs, false, NULL, true);
18463 if (lhs == error_mark_node)
18464 goto saw_error;
18465 if (non_lvalue_p)
18466 lhs = non_lvalue (lhs);
18467 }
18468 if (code == NOP_EXPR)
18469 {
18470 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18471 opcode. */
18472 code = OMP_ATOMIC;
18473 rhs = lhs;
18474 lhs = v;
18475 v = NULL_TREE;
18476 }
18477 goto done;
18478 case OMP_ATOMIC_CAPTURE_NEW:
18479 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18480 {
18481 c_parser_consume_token (parser);
18482 structured_block = true;
18483 }
18484 else if (compare
18485 && c_parser_next_token_is_keyword (parser, RID_IF))
18486 break;
18487 else
18488 {
18489 v = c_parser_cast_expression (parser, NULL).value;
18490 non_lvalue_p = !lvalue_p (v);
18491 v = c_fully_fold (v, false, NULL, true);
18492 if (v == error_mark_node)
18493 goto saw_error;
18494 if (non_lvalue_p)
18495 v = non_lvalue (v);
18496 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18497 goto saw_error;
18498 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18499 {
18500 eloc = c_parser_peek_token (parser)->location;
18501 error_at (eloc, "expected expression");
18502 goto saw_error;
18503 }
18504 }
18505 break;
18506 default:
18507 break;
18508 }
18509
18510 /* For structured_block case we don't know yet whether
18511 old or new x should be captured. */
18512 restart:
18513 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18514 {
18515 c_parser_consume_token (parser);
18516
18517 matching_parens parens;
18518 if (!parens.require_open (parser))
18519 goto saw_error;
18520 eloc = c_parser_peek_token (parser)->location;
18521 c_expr cmp_expr;
18522 if (r)
18523 {
18524 cmp_expr = c_parser_cast_expression (parser, NULL);
18525 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
18526 }
18527 else
18528 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
18529 parens.skip_until_found_close (parser);
18530 if (cmp_expr.value == error_mark_node)
18531 goto saw_error;
18532 if (r)
18533 {
18534 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
18535 goto bad_if;
18536 cmp_expr.value = rhs1;
18537 rhs1 = NULL_TREE;
18538 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
18539 }
18540 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18541 ;
18542 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18543 {
18544 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18545 "expected %<==%> comparison in %<if%> condition");
18546 goto saw_error;
18547 }
18548 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
18549 && TREE_CODE (cmp_expr.value) != LT_EXPR)
18550 {
18551 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18552 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18553 "condition");
18554 goto saw_error;
18555 }
18556 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18557 goto saw_error;
18558
18559 extra_scope = true;
18560 eloc = c_parser_peek_token (parser)->location;
18561 expr = c_parser_cast_expression (parser, NULL);
18562 lhs = expr.value;
18563 expr = default_function_array_conversion (eloc, expr);
18564 unfolded_lhs = expr.value;
18565 lhs = c_fully_fold (lhs, false, NULL, true);
18566 orig_lhs = lhs;
18567 if (lhs == error_mark_node)
18568 goto saw_error;
18569 if (!lvalue_p (unfolded_lhs))
18570 lhs = non_lvalue (lhs);
18571 if (!c_parser_next_token_is (parser, CPP_EQ))
18572 {
18573 c_parser_error (parser, "expected %<=%>");
18574 goto saw_error;
18575 }
18576 c_parser_consume_token (parser);
18577 eloc = c_parser_peek_token (parser)->location;
18578 expr = c_parser_expr_no_commas (parser, NULL);
18579 rhs1 = expr.value;
18580
18581 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18582 goto saw_error;
18583
18584 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18585 goto saw_error;
18586
18587 extra_scope = false;
18588 no_semicolon = true;
18589
18590 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
18591 {
18592 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18593 {
18594 opcode = COND_EXPR;
18595 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18596 false, NULL, true);
18597 rhs1 = c_fully_fold (rhs1, false, NULL, true);
18598 }
18599 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
18600 {
18601 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18602 ? MIN_EXPR : MAX_EXPR);
18603 rhs = c_fully_fold (rhs1, false, NULL, true);
18604 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
18605 false, NULL, true);
18606 }
18607 else
18608 goto bad_if;
18609 }
18610 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18611 goto bad_if;
18612 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
18613 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
18614 {
18615 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18616 ? MAX_EXPR : MIN_EXPR);
18617 rhs = c_fully_fold (rhs1, false, NULL, true);
18618 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18619 false, NULL, true);
18620 }
18621 else
18622 {
18623 bad_if:
18624 c_parser_error (parser,
18625 "invalid form of %<#pragma omp atomic compare%>");
18626 goto saw_error;
18627 }
18628
18629 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
18630 {
18631 if (code != OMP_ATOMIC_CAPTURE_NEW
18632 || (structured_block && r == NULL_TREE)
18633 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
18634 {
18635 eloc = c_parser_peek_token (parser)->location;
18636 error_at (eloc, "unexpected %<else%>");
18637 goto saw_error;
18638 }
18639
18640 c_parser_consume_token (parser);
18641
18642 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18643 goto saw_error;
18644
18645 extra_scope = true;
18646 v = c_parser_cast_expression (parser, NULL).value;
18647 non_lvalue_p = !lvalue_p (v);
18648 v = c_fully_fold (v, false, NULL, true);
18649 if (v == error_mark_node)
18650 goto saw_error;
18651 if (non_lvalue_p)
18652 v = non_lvalue (v);
18653 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18654 goto saw_error;
18655
18656 expr = c_parser_expr_no_commas (parser, NULL);
18657
18658 if (!c_tree_equal (expr.value, unfolded_lhs))
18659 goto bad_if;
18660
18661 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18662 goto saw_error;
18663
18664 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18665 goto saw_error;
18666
18667 extra_scope = false;
18668 code = OMP_ATOMIC_CAPTURE_OLD;
18669 if (r == NULL_TREE)
18670 /* Signal to c_finish_omp_atomic that in
18671 if (x == e) { x = d; } else { v = x; }
18672 case the store to v should be conditional. */
18673 r = void_list_node;
18674 }
18675 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18676 {
18677 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
18678 goto saw_error;
18679 }
18680 else if (code == OMP_ATOMIC_CAPTURE_NEW
18681 && r != NULL_TREE
18682 && v == NULL_TREE)
18683 code = OMP_ATOMIC;
18684 goto stmt_done;
18685 }
18686 eloc = c_parser_peek_token (parser)->location;
18687 expr = c_parser_cast_expression (parser, NULL);
18688 lhs = expr.value;
18689 expr = default_function_array_conversion (eloc, expr);
18690 unfolded_lhs = expr.value;
18691 lhs = c_fully_fold (lhs, false, NULL, true);
18692 orig_lhs = lhs;
18693 switch (TREE_CODE (lhs))
18694 {
18695 invalid_compare:
18696 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
18697 /* FALLTHRU */
18698 case ERROR_MARK:
18699 saw_error:
18700 c_parser_skip_to_end_of_block_or_statement (parser);
18701 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18702 c_parser_consume_token (parser);
18703 if (structured_block)
18704 {
18705 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18706 c_parser_consume_token (parser);
18707 else if (code == OMP_ATOMIC_CAPTURE_NEW)
18708 {
18709 c_parser_skip_to_end_of_block_or_statement (parser);
18710 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18711 c_parser_consume_token (parser);
18712 }
18713 }
18714 return;
18715
18716 case POSTINCREMENT_EXPR:
18717 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18718 code = OMP_ATOMIC_CAPTURE_OLD;
18719 /* FALLTHROUGH */
18720 case PREINCREMENT_EXPR:
18721 lhs = TREE_OPERAND (lhs, 0);
18722 unfolded_lhs = NULL_TREE;
18723 opcode = PLUS_EXPR;
18724 rhs = integer_one_node;
18725 if (compare)
18726 goto invalid_compare;
18727 break;
18728
18729 case POSTDECREMENT_EXPR:
18730 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18731 code = OMP_ATOMIC_CAPTURE_OLD;
18732 /* FALLTHROUGH */
18733 case PREDECREMENT_EXPR:
18734 lhs = TREE_OPERAND (lhs, 0);
18735 unfolded_lhs = NULL_TREE;
18736 opcode = MINUS_EXPR;
18737 rhs = integer_one_node;
18738 if (compare)
18739 goto invalid_compare;
18740 break;
18741
18742 case COMPOUND_EXPR:
18743 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
18744 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
18745 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
18746 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
18747 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18748 (TREE_OPERAND (lhs, 1), 0), 0)))
18749 == BOOLEAN_TYPE)
18750 /* Undo effects of boolean_increment for post {in,de}crement. */
18751 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
18752 /* FALLTHRU */
18753 case MODIFY_EXPR:
18754 if (TREE_CODE (lhs) == MODIFY_EXPR
18755 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
18756 {
18757 /* Undo effects of boolean_increment. */
18758 if (integer_onep (TREE_OPERAND (lhs, 1)))
18759 {
18760 /* This is pre or post increment. */
18761 rhs = TREE_OPERAND (lhs, 1);
18762 lhs = TREE_OPERAND (lhs, 0);
18763 unfolded_lhs = NULL_TREE;
18764 opcode = NOP_EXPR;
18765 if (code == OMP_ATOMIC_CAPTURE_NEW
18766 && !structured_block
18767 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18768 code = OMP_ATOMIC_CAPTURE_OLD;
18769 if (compare)
18770 goto invalid_compare;
18771 break;
18772 }
18773 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
18774 && TREE_OPERAND (lhs, 0)
18775 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
18776 {
18777 /* This is pre or post decrement. */
18778 rhs = TREE_OPERAND (lhs, 1);
18779 lhs = TREE_OPERAND (lhs, 0);
18780 unfolded_lhs = NULL_TREE;
18781 opcode = NOP_EXPR;
18782 if (code == OMP_ATOMIC_CAPTURE_NEW
18783 && !structured_block
18784 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18785 code = OMP_ATOMIC_CAPTURE_OLD;
18786 if (compare)
18787 goto invalid_compare;
18788 break;
18789 }
18790 }
18791 /* FALLTHRU */
18792 default:
18793 if (!lvalue_p (unfolded_lhs))
18794 lhs = non_lvalue (lhs);
18795 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
18796 {
18797 c_parser_error (parser, "expected %<=%>");
18798 goto saw_error;
18799 }
18800 switch (c_parser_peek_token (parser)->type)
18801 {
18802 case CPP_MULT_EQ:
18803 opcode = MULT_EXPR;
18804 break;
18805 case CPP_DIV_EQ:
18806 opcode = TRUNC_DIV_EXPR;
18807 break;
18808 case CPP_PLUS_EQ:
18809 opcode = PLUS_EXPR;
18810 break;
18811 case CPP_MINUS_EQ:
18812 opcode = MINUS_EXPR;
18813 break;
18814 case CPP_LSHIFT_EQ:
18815 opcode = LSHIFT_EXPR;
18816 break;
18817 case CPP_RSHIFT_EQ:
18818 opcode = RSHIFT_EXPR;
18819 break;
18820 case CPP_AND_EQ:
18821 opcode = BIT_AND_EXPR;
18822 break;
18823 case CPP_OR_EQ:
18824 opcode = BIT_IOR_EXPR;
18825 break;
18826 case CPP_XOR_EQ:
18827 opcode = BIT_XOR_EXPR;
18828 break;
18829 case CPP_EQ:
18830 c_parser_consume_token (parser);
18831 eloc = c_parser_peek_token (parser)->location;
18832 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
18833 rhs1 = expr.value;
18834 switch (TREE_CODE (rhs1))
18835 {
18836 case MULT_EXPR:
18837 case TRUNC_DIV_EXPR:
18838 case RDIV_EXPR:
18839 case PLUS_EXPR:
18840 case MINUS_EXPR:
18841 case LSHIFT_EXPR:
18842 case RSHIFT_EXPR:
18843 case BIT_AND_EXPR:
18844 case BIT_IOR_EXPR:
18845 case BIT_XOR_EXPR:
18846 if (compare)
18847 break;
18848 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
18849 {
18850 opcode = TREE_CODE (rhs1);
18851 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18852 true);
18853 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18854 true);
18855 goto stmt_done;
18856 }
18857 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
18858 {
18859 opcode = TREE_CODE (rhs1);
18860 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18861 true);
18862 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18863 true);
18864 swapped = !commutative_tree_code (opcode);
18865 goto stmt_done;
18866 }
18867 break;
18868 case COND_EXPR:
18869 if (!compare)
18870 break;
18871 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
18872 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
18873 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
18874 break;
18875 if (!TREE_OPERAND (rhs1, 1))
18876 break;
18877 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
18878 break;
18879 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18880 unfolded_lhs))
18881 {
18882 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18883 {
18884 opcode = COND_EXPR;
18885 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18886 0), 1),
18887 false, NULL, true);
18888 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
18889 NULL, true);
18890 goto stmt_done;
18891 }
18892 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18893 TREE_OPERAND (rhs1, 1)))
18894 {
18895 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18896 ? MIN_EXPR : MAX_EXPR);
18897 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18898 true);
18899 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18900 0), 0),
18901 false, NULL, true);
18902 goto stmt_done;
18903 }
18904 }
18905 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18906 break;
18907 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18908 unfolded_lhs))
18909 {
18910 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18911 TREE_OPERAND (rhs1, 1)))
18912 {
18913 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18914 ? MAX_EXPR : MIN_EXPR);
18915 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18916 true);
18917 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18918 0), 1),
18919 false, NULL, true);
18920 goto stmt_done;
18921 }
18922 }
18923 break;
18924 case EQ_EXPR:
18925 if (!compare
18926 || code != OMP_ATOMIC_CAPTURE_NEW
18927 || !structured_block
18928 || v
18929 || r)
18930 break;
18931 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
18932 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
18933 {
18934 r = lhs;
18935 lhs = NULL_TREE;
18936 c_parser_consume_token (parser);
18937 goto restart;
18938 }
18939 break;
18940 case ERROR_MARK:
18941 goto saw_error;
18942 default:
18943 break;
18944 }
18945 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
18946 {
18947 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18948 {
18949 code = OMP_ATOMIC_CAPTURE_OLD;
18950 v = lhs;
18951 lhs = NULL_TREE;
18952 expr = default_function_array_read_conversion (eloc, expr);
18953 unfolded_lhs1 = expr.value;
18954 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
18955 rhs1 = NULL_TREE;
18956 c_parser_consume_token (parser);
18957 goto restart;
18958 }
18959 if (structured_block && !compare)
18960 {
18961 opcode = NOP_EXPR;
18962 expr = default_function_array_read_conversion (eloc, expr);
18963 rhs = c_fully_fold (expr.value, false, NULL, true);
18964 rhs1 = NULL_TREE;
18965 goto stmt_done;
18966 }
18967 }
18968 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
18969 goto saw_error;
18970 default:
18971 c_parser_error (parser,
18972 "invalid operator for %<#pragma omp atomic%>");
18973 goto saw_error;
18974 }
18975
18976 /* Arrange to pass the location of the assignment operator to
18977 c_finish_omp_atomic. */
18978 loc = c_parser_peek_token (parser)->location;
18979 c_parser_consume_token (parser);
18980 eloc = c_parser_peek_token (parser)->location;
18981 expr = c_parser_expression (parser);
18982 expr = default_function_array_read_conversion (eloc, expr);
18983 rhs = expr.value;
18984 rhs = c_fully_fold (rhs, false, NULL, true);
18985 break;
18986 }
18987 stmt_done:
18988 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
18989 {
18990 if (!no_semicolon
18991 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18992 goto saw_error;
18993 no_semicolon = false;
18994 v = c_parser_cast_expression (parser, NULL).value;
18995 non_lvalue_p = !lvalue_p (v);
18996 v = c_fully_fold (v, false, NULL, true);
18997 if (v == error_mark_node)
18998 goto saw_error;
18999 if (non_lvalue_p)
19000 v = non_lvalue (v);
19001 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19002 goto saw_error;
19003 eloc = c_parser_peek_token (parser)->location;
19004 expr = c_parser_cast_expression (parser, NULL);
19005 lhs1 = expr.value;
19006 expr = default_function_array_read_conversion (eloc, expr);
19007 unfolded_lhs1 = expr.value;
19008 lhs1 = c_fully_fold (lhs1, false, NULL, true);
19009 if (lhs1 == error_mark_node)
19010 goto saw_error;
19011 if (!lvalue_p (unfolded_lhs1))
19012 lhs1 = non_lvalue (lhs1);
19013 }
19014 if (structured_block)
19015 {
19016 if (!no_semicolon)
19017 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19018 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
19019 }
19020 done:
19021 if (weak && opcode != COND_EXPR)
19022 {
19023 error_at (loc, "%<weak%> clause requires atomic equality comparison");
19024 weak = false;
19025 }
19026 if (unfolded_lhs && unfolded_lhs1
19027 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
19028 {
19029 error ("%<#pragma omp atomic capture%> uses two different "
19030 "expressions for memory");
19031 stmt = error_mark_node;
19032 }
19033 else
19034 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
19035 swapped, memory_order, weak);
19036 if (stmt != error_mark_node)
19037 add_stmt (stmt);
19038
19039 if (!structured_block && !no_semicolon)
19040 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19041 }
19042
19043
19044 /* OpenMP 2.5:
19045 # pragma omp barrier new-line
19046 */
19047
19048 static void
19049 c_parser_omp_barrier (c_parser *parser)
19050 {
19051 location_t loc = c_parser_peek_token (parser)->location;
19052 c_parser_consume_pragma (parser);
19053 c_parser_skip_to_pragma_eol (parser);
19054
19055 c_finish_omp_barrier (loc);
19056 }
19057
19058 /* OpenMP 2.5:
19059 # pragma omp critical [(name)] new-line
19060 structured-block
19061
19062 OpenMP 4.5:
19063 # pragma omp critical [(name) [hint(expression)]] new-line
19064
19065 LOC is the location of the #pragma itself. */
19066
19067 #define OMP_CRITICAL_CLAUSE_MASK \
19068 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19069
19070 static tree
19071 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
19072 {
19073 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
19074
19075 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19076 {
19077 c_parser_consume_token (parser);
19078 if (c_parser_next_token_is (parser, CPP_NAME))
19079 {
19080 name = c_parser_peek_token (parser)->value;
19081 c_parser_consume_token (parser);
19082 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
19083 }
19084 else
19085 c_parser_error (parser, "expected identifier");
19086
19087 if (c_parser_next_token_is (parser, CPP_COMMA)
19088 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
19089 c_parser_consume_token (parser);
19090 }
19091 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
19092 "#pragma omp critical");
19093 stmt = c_parser_omp_structured_block (parser, if_p);
19094 return c_finish_omp_critical (loc, stmt, name, clauses);
19095 }
19096
19097 /* OpenMP 5.0:
19098 # pragma omp depobj ( depobj ) depobj-clause new-line
19099
19100 depobj-clause:
19101 depend (dependence-type : locator)
19102 destroy
19103 update (dependence-type)
19104
19105 dependence-type:
19106 in
19107 out
19108 inout
19109 mutexinout */
19110
19111 static void
19112 c_parser_omp_depobj (c_parser *parser)
19113 {
19114 location_t loc = c_parser_peek_token (parser)->location;
19115 c_parser_consume_pragma (parser);
19116 matching_parens parens;
19117 if (!parens.require_open (parser))
19118 {
19119 c_parser_skip_to_pragma_eol (parser);
19120 return;
19121 }
19122
19123 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
19124 if (depobj != error_mark_node)
19125 {
19126 if (!lvalue_p (depobj))
19127 {
19128 error_at (EXPR_LOC_OR_LOC (depobj, loc),
19129 "%<depobj%> expression is not lvalue expression");
19130 depobj = error_mark_node;
19131 }
19132 else
19133 {
19134 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
19135 depobj, false);
19136 if (addr == error_mark_node)
19137 depobj = error_mark_node;
19138 else
19139 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
19140 addr, RO_UNARY_STAR);
19141 }
19142 }
19143
19144 parens.skip_until_found_close (parser);
19145 tree clause = NULL_TREE;
19146 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
19147 location_t c_loc = c_parser_peek_token (parser)->location;
19148 if (c_parser_next_token_is (parser, CPP_NAME))
19149 {
19150 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19151
19152 c_parser_consume_token (parser);
19153 if (!strcmp ("depend", p))
19154 {
19155 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19156 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19157 if (!clause)
19158 clause = error_mark_node;
19159 }
19160 else if (!strcmp ("destroy", p))
19161 kind = OMP_CLAUSE_DEPEND_LAST;
19162 else if (!strcmp ("update", p))
19163 {
19164 matching_parens c_parens;
19165 if (c_parens.require_open (parser))
19166 {
19167 location_t c2_loc = c_parser_peek_token (parser)->location;
19168 if (c_parser_next_token_is (parser, CPP_NAME))
19169 {
19170 const char *p2
19171 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19172
19173 c_parser_consume_token (parser);
19174 if (!strcmp ("in", p2))
19175 kind = OMP_CLAUSE_DEPEND_IN;
19176 else if (!strcmp ("out", p2))
19177 kind = OMP_CLAUSE_DEPEND_OUT;
19178 else if (!strcmp ("inout", p2))
19179 kind = OMP_CLAUSE_DEPEND_INOUT;
19180 else if (!strcmp ("mutexinoutset", p2))
19181 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
19182 else if (!strcmp ("inoutset", p2))
19183 kind = OMP_CLAUSE_DEPEND_INOUTSET;
19184 }
19185 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
19186 {
19187 clause = error_mark_node;
19188 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
19189 "%<mutexinoutset%> or %<inoutset%>");
19190 }
19191 c_parens.skip_until_found_close (parser);
19192 }
19193 else
19194 clause = error_mark_node;
19195 }
19196 }
19197 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
19198 {
19199 clause = error_mark_node;
19200 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
19201 }
19202 c_parser_skip_to_pragma_eol (parser);
19203
19204 c_finish_omp_depobj (loc, depobj, kind, clause);
19205 }
19206
19207
19208 /* OpenMP 2.5:
19209 # pragma omp flush flush-vars[opt] new-line
19210
19211 flush-vars:
19212 ( variable-list )
19213
19214 OpenMP 5.0:
19215 # pragma omp flush memory-order-clause new-line */
19216
19217 static void
19218 c_parser_omp_flush (c_parser *parser)
19219 {
19220 location_t loc = c_parser_peek_token (parser)->location;
19221 c_parser_consume_pragma (parser);
19222 enum memmodel mo = MEMMODEL_LAST;
19223 if (c_parser_next_token_is (parser, CPP_NAME))
19224 {
19225 const char *p
19226 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19227
19228 if (!strcmp (p, "seq_cst"))
19229 mo = MEMMODEL_SEQ_CST;
19230 else if (!strcmp (p, "acq_rel"))
19231 mo = MEMMODEL_ACQ_REL;
19232 else if (!strcmp (p, "release"))
19233 mo = MEMMODEL_RELEASE;
19234 else if (!strcmp (p, "acquire"))
19235 mo = MEMMODEL_ACQUIRE;
19236 else
19237 error_at (c_parser_peek_token (parser)->location,
19238 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19239 "%<acquire%>");
19240 c_parser_consume_token (parser);
19241 }
19242 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19243 {
19244 if (mo != MEMMODEL_LAST)
19245 error_at (c_parser_peek_token (parser)->location,
19246 "%<flush%> list specified together with memory order "
19247 "clause");
19248 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
19249 }
19250 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19251 c_parser_error (parser, "expected %<(%> or end of line");
19252 c_parser_skip_to_pragma_eol (parser);
19253
19254 c_finish_omp_flush (loc, mo);
19255 }
19256
19257 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19258 separating directive. */
19259
19260 static tree
19261 c_parser_omp_structured_block_sequence (c_parser *parser,
19262 enum pragma_kind kind)
19263 {
19264 tree stmt = push_stmt_list ();
19265 c_parser_statement (parser, NULL);
19266 do
19267 {
19268 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19269 break;
19270 if (c_parser_next_token_is (parser, CPP_EOF))
19271 break;
19272
19273 if (kind != PRAGMA_NONE
19274 && c_parser_peek_token (parser)->pragma_kind == kind)
19275 break;
19276 c_parser_statement (parser, NULL);
19277 }
19278 while (1);
19279 return pop_stmt_list (stmt);
19280 }
19281
19282 /* OpenMP 5.0:
19283
19284 scan-loop-body:
19285 { structured-block scan-directive structured-block } */
19286
19287 static void
19288 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
19289 {
19290 tree substmt;
19291 location_t loc;
19292 tree clauses = NULL_TREE;
19293
19294 loc = c_parser_peek_token (parser)->location;
19295 if (!open_brace_parsed
19296 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19297 {
19298 /* Avoid skipping until the end of the block. */
19299 parser->error = false;
19300 return;
19301 }
19302
19303 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
19304 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
19305 SET_EXPR_LOCATION (substmt, loc);
19306 add_stmt (substmt);
19307
19308 loc = c_parser_peek_token (parser)->location;
19309 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
19310 {
19311 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
19312
19313 c_parser_consume_pragma (parser);
19314
19315 if (c_parser_next_token_is (parser, CPP_NAME))
19316 {
19317 const char *p
19318 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19319 if (strcmp (p, "inclusive") == 0)
19320 clause = OMP_CLAUSE_INCLUSIVE;
19321 else if (strcmp (p, "exclusive") == 0)
19322 clause = OMP_CLAUSE_EXCLUSIVE;
19323 }
19324 if (clause != OMP_CLAUSE_ERROR)
19325 {
19326 c_parser_consume_token (parser);
19327 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
19328 }
19329 else
19330 c_parser_error (parser, "expected %<inclusive%> or "
19331 "%<exclusive%> clause");
19332 c_parser_skip_to_pragma_eol (parser);
19333 }
19334 else
19335 error ("expected %<#pragma omp scan%>");
19336
19337 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19338 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
19339 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
19340 SET_EXPR_LOCATION (substmt, loc);
19341 add_stmt (substmt);
19342
19343 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19344 "expected %<}%>");
19345 }
19346
19347 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19348 The real trick here is to determine the loop control variable early
19349 so that we can push a new decl if necessary to make it private.
19350 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19351 respectively. */
19352
19353 static tree
19354 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
19355 tree clauses, tree *cclauses, bool *if_p)
19356 {
19357 tree decl, cond, incr, body, init, stmt, cl;
19358 unsigned char save_in_statement;
19359 tree declv, condv, incrv, initv, ret = NULL_TREE;
19360 tree pre_body = NULL_TREE, this_pre_body;
19361 tree ordered_cl = NULL_TREE;
19362 bool fail = false, open_brace_parsed = false;
19363 int i, collapse = 1, ordered = 0, count, nbraces = 0;
19364 location_t for_loc;
19365 bool tiling = false;
19366 bool inscan = false;
19367 vec<tree, va_gc> *for_block = make_tree_vector ();
19368
19369 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
19370 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
19371 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
19372 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
19373 {
19374 tiling = true;
19375 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
19376 }
19377 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
19378 && OMP_CLAUSE_ORDERED_EXPR (cl))
19379 {
19380 ordered_cl = cl;
19381 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
19382 }
19383 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
19384 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
19385 && (code == OMP_SIMD || code == OMP_FOR))
19386 inscan = true;
19387
19388 if (ordered && ordered < collapse)
19389 {
19390 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
19391 "%<ordered%> clause parameter is less than %<collapse%>");
19392 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
19393 = build_int_cst (NULL_TREE, collapse);
19394 ordered = collapse;
19395 }
19396 if (ordered)
19397 {
19398 for (tree *pc = &clauses; *pc; )
19399 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
19400 {
19401 error_at (OMP_CLAUSE_LOCATION (*pc),
19402 "%<linear%> clause may not be specified together "
19403 "with %<ordered%> clause with a parameter");
19404 *pc = OMP_CLAUSE_CHAIN (*pc);
19405 }
19406 else
19407 pc = &OMP_CLAUSE_CHAIN (*pc);
19408 }
19409
19410 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
19411 count = ordered ? ordered : collapse;
19412
19413 declv = make_tree_vec (count);
19414 initv = make_tree_vec (count);
19415 condv = make_tree_vec (count);
19416 incrv = make_tree_vec (count);
19417
19418 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
19419 {
19420 c_parser_error (parser, "for statement expected");
19421 return NULL;
19422 }
19423 for_loc = c_parser_peek_token (parser)->location;
19424 c_parser_consume_token (parser);
19425
19426 /* Forbid break/continue in the loop initializer, condition, and
19427 increment expressions. */
19428 save_in_statement = in_statement;
19429 in_statement = IN_OMP_BLOCK;
19430
19431 for (i = 0; i < count; i++)
19432 {
19433 int bracecount = 0;
19434
19435 matching_parens parens;
19436 if (!parens.require_open (parser))
19437 goto pop_scopes;
19438
19439 /* Parse the initialization declaration or expression. */
19440 if (c_parser_next_tokens_start_declaration (parser))
19441 {
19442 if (i > 0)
19443 vec_safe_push (for_block, c_begin_compound_stmt (true));
19444 this_pre_body = push_stmt_list ();
19445 c_in_omp_for = true;
19446 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
19447 c_in_omp_for = false;
19448 if (this_pre_body)
19449 {
19450 this_pre_body = pop_stmt_list (this_pre_body);
19451 if (pre_body)
19452 {
19453 tree t = pre_body;
19454 pre_body = push_stmt_list ();
19455 add_stmt (t);
19456 add_stmt (this_pre_body);
19457 pre_body = pop_stmt_list (pre_body);
19458 }
19459 else
19460 pre_body = this_pre_body;
19461 }
19462 decl = check_for_loop_decls (for_loc, flag_isoc99);
19463 if (decl == NULL)
19464 goto error_init;
19465 if (DECL_INITIAL (decl) == error_mark_node)
19466 decl = error_mark_node;
19467 init = decl;
19468 }
19469 else if (c_parser_next_token_is (parser, CPP_NAME)
19470 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
19471 {
19472 struct c_expr decl_exp;
19473 struct c_expr init_exp;
19474 location_t init_loc;
19475
19476 decl_exp = c_parser_postfix_expression (parser);
19477 decl = decl_exp.value;
19478
19479 c_parser_require (parser, CPP_EQ, "expected %<=%>");
19480
19481 init_loc = c_parser_peek_token (parser)->location;
19482 init_exp = c_parser_expr_no_commas (parser, NULL);
19483 init_exp = default_function_array_read_conversion (init_loc,
19484 init_exp);
19485 c_in_omp_for = true;
19486 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
19487 NOP_EXPR, init_loc, init_exp.value,
19488 init_exp.original_type);
19489 c_in_omp_for = false;
19490 init = c_process_expr_stmt (init_loc, init);
19491
19492 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19493 }
19494 else
19495 {
19496 error_init:
19497 c_parser_error (parser,
19498 "expected iteration declaration or initialization");
19499 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19500 "expected %<)%>");
19501 fail = true;
19502 goto parse_next;
19503 }
19504
19505 /* Parse the loop condition. */
19506 cond = NULL_TREE;
19507 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
19508 {
19509 location_t cond_loc = c_parser_peek_token (parser)->location;
19510 c_in_omp_for = true;
19511 struct c_expr cond_expr
19512 = c_parser_binary_expression (parser, NULL, NULL_TREE);
19513 c_in_omp_for = false;
19514
19515 cond = cond_expr.value;
19516 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
19517 switch (cond_expr.original_code)
19518 {
19519 case GT_EXPR:
19520 case GE_EXPR:
19521 case LT_EXPR:
19522 case LE_EXPR:
19523 break;
19524 case NE_EXPR:
19525 if (code != OACC_LOOP)
19526 break;
19527 /* FALLTHRU. */
19528 default:
19529 /* Can't be cond = error_mark_node, because we want to preserve
19530 the location until c_finish_omp_for. */
19531 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
19532 break;
19533 }
19534 protected_set_expr_location (cond, cond_loc);
19535 }
19536 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19537
19538 /* Parse the increment expression. */
19539 incr = NULL_TREE;
19540 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
19541 {
19542 location_t incr_loc = c_parser_peek_token (parser)->location;
19543
19544 incr = c_process_expr_stmt (incr_loc,
19545 c_parser_expression (parser).value);
19546 }
19547 parens.skip_until_found_close (parser);
19548
19549 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
19550 fail = true;
19551 else
19552 {
19553 TREE_VEC_ELT (declv, i) = decl;
19554 TREE_VEC_ELT (initv, i) = init;
19555 TREE_VEC_ELT (condv, i) = cond;
19556 TREE_VEC_ELT (incrv, i) = incr;
19557 }
19558
19559 parse_next:
19560 if (i == count - 1)
19561 break;
19562
19563 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19564 in between the collapsed for loops to be still considered perfectly
19565 nested. Hopefully the final version clarifies this.
19566 For now handle (multiple) {'s and empty statements. */
19567 do
19568 {
19569 if (c_parser_next_token_is_keyword (parser, RID_FOR))
19570 {
19571 c_parser_consume_token (parser);
19572 break;
19573 }
19574 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19575 {
19576 c_parser_consume_token (parser);
19577 bracecount++;
19578 }
19579 else if (bracecount
19580 && c_parser_next_token_is (parser, CPP_SEMICOLON))
19581 c_parser_consume_token (parser);
19582 else
19583 {
19584 c_parser_error (parser, "not enough perfectly nested loops");
19585 if (bracecount)
19586 {
19587 open_brace_parsed = true;
19588 bracecount--;
19589 }
19590 fail = true;
19591 count = 0;
19592 break;
19593 }
19594 }
19595 while (1);
19596
19597 nbraces += bracecount;
19598 }
19599
19600 if (nbraces)
19601 if_p = NULL;
19602
19603 in_statement = IN_OMP_FOR;
19604 body = push_stmt_list ();
19605
19606 if (inscan)
19607 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
19608 else if (open_brace_parsed)
19609 {
19610 location_t here = c_parser_peek_token (parser)->location;
19611 stmt = c_begin_compound_stmt (true);
19612 c_parser_compound_statement_nostart (parser);
19613 add_stmt (c_end_compound_stmt (here, stmt, true));
19614 }
19615 else
19616 add_stmt (c_parser_c99_block_statement (parser, if_p));
19617
19618 body = pop_stmt_list (body);
19619 in_statement = save_in_statement;
19620
19621 while (nbraces)
19622 {
19623 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19624 {
19625 c_parser_consume_token (parser);
19626 nbraces--;
19627 }
19628 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
19629 c_parser_consume_token (parser);
19630 else
19631 {
19632 c_parser_error (parser, "collapsed loops not perfectly nested");
19633 while (nbraces)
19634 {
19635 location_t here = c_parser_peek_token (parser)->location;
19636 stmt = c_begin_compound_stmt (true);
19637 add_stmt (body);
19638 c_parser_compound_statement_nostart (parser);
19639 body = c_end_compound_stmt (here, stmt, true);
19640 nbraces--;
19641 }
19642 goto pop_scopes;
19643 }
19644 }
19645
19646 /* Only bother calling c_finish_omp_for if we haven't already generated
19647 an error from the initialization parsing. */
19648 if (!fail)
19649 {
19650 c_in_omp_for = true;
19651 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
19652 incrv, body, pre_body, true);
19653 c_in_omp_for = false;
19654
19655 /* Check for iterators appearing in lb, b or incr expressions. */
19656 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
19657 stmt = NULL_TREE;
19658
19659 if (stmt)
19660 {
19661 add_stmt (stmt);
19662
19663 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
19664 {
19665 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
19666 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
19667 tree decl = TREE_OPERAND (init, 0);
19668 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
19669 gcc_assert (COMPARISON_CLASS_P (cond));
19670 gcc_assert (TREE_OPERAND (cond, 0) == decl);
19671
19672 tree op0 = TREE_OPERAND (init, 1);
19673 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19674 || TREE_CODE (op0) != TREE_VEC)
19675 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
19676 else
19677 {
19678 TREE_VEC_ELT (op0, 1)
19679 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
19680 TREE_VEC_ELT (op0, 2)
19681 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
19682 }
19683
19684 tree op1 = TREE_OPERAND (cond, 1);
19685 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19686 || TREE_CODE (op1) != TREE_VEC)
19687 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
19688 else
19689 {
19690 TREE_VEC_ELT (op1, 1)
19691 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
19692 TREE_VEC_ELT (op1, 2)
19693 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
19694 }
19695 }
19696
19697 if (cclauses != NULL
19698 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
19699 {
19700 tree *c;
19701 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
19702 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
19703 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
19704 c = &OMP_CLAUSE_CHAIN (*c);
19705 else
19706 {
19707 for (i = 0; i < count; i++)
19708 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
19709 break;
19710 if (i == count)
19711 c = &OMP_CLAUSE_CHAIN (*c);
19712 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
19713 {
19714 error_at (loc,
19715 "iteration variable %qD should not be firstprivate",
19716 OMP_CLAUSE_DECL (*c));
19717 *c = OMP_CLAUSE_CHAIN (*c);
19718 }
19719 else
19720 {
19721 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19722 tree l = *c;
19723 *c = OMP_CLAUSE_CHAIN (*c);
19724 if (code == OMP_SIMD)
19725 {
19726 OMP_CLAUSE_CHAIN (l)
19727 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19728 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
19729 }
19730 else
19731 {
19732 OMP_CLAUSE_CHAIN (l) = clauses;
19733 clauses = l;
19734 }
19735 }
19736 }
19737 }
19738 OMP_FOR_CLAUSES (stmt) = clauses;
19739 }
19740 ret = stmt;
19741 }
19742 pop_scopes:
19743 while (!for_block->is_empty ())
19744 {
19745 /* FIXME diagnostics: LOC below should be the actual location of
19746 this particular for block. We need to build a list of
19747 locations to go along with FOR_BLOCK. */
19748 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
19749 add_stmt (stmt);
19750 }
19751 release_tree_vector (for_block);
19752 return ret;
19753 }
19754
19755 /* Helper function for OpenMP parsing, split clauses and call
19756 finish_omp_clauses on each of the set of clauses afterwards. */
19757
19758 static void
19759 omp_split_clauses (location_t loc, enum tree_code code,
19760 omp_clause_mask mask, tree clauses, tree *cclauses)
19761 {
19762 int i;
19763 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
19764 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
19765 if (cclauses[i])
19766 cclauses[i] = c_finish_omp_clauses (cclauses[i],
19767 i == C_OMP_CLAUSE_SPLIT_TARGET
19768 ? C_ORT_OMP_TARGET : C_ORT_OMP);
19769 }
19770
19771 /* OpenMP 5.0:
19772 #pragma omp loop loop-clause[optseq] new-line
19773 for-loop
19774
19775 LOC is the location of the #pragma token.
19776 */
19777
19778 #define OMP_LOOP_CLAUSE_MASK \
19779 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19780 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19781 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19782 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19785
19786 static tree
19787 c_parser_omp_loop (location_t loc, c_parser *parser,
19788 char *p_name, omp_clause_mask mask, tree *cclauses,
19789 bool *if_p)
19790 {
19791 tree block, clauses, ret;
19792
19793 strcat (p_name, " loop");
19794 mask |= OMP_LOOP_CLAUSE_MASK;
19795
19796 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19797 if (cclauses)
19798 {
19799 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
19800 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
19801 }
19802
19803 block = c_begin_compound_stmt (true);
19804 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
19805 block = c_end_compound_stmt (loc, block, true);
19806 add_stmt (block);
19807
19808 return ret;
19809 }
19810
19811 /* OpenMP 4.0:
19812 #pragma omp simd simd-clause[optseq] new-line
19813 for-loop
19814
19815 LOC is the location of the #pragma token.
19816 */
19817
19818 #define OMP_SIMD_CLAUSE_MASK \
19819 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19820 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19830
19831 static tree
19832 c_parser_omp_simd (location_t loc, c_parser *parser,
19833 char *p_name, omp_clause_mask mask, tree *cclauses,
19834 bool *if_p)
19835 {
19836 tree block, clauses, ret;
19837
19838 strcat (p_name, " simd");
19839 mask |= OMP_SIMD_CLAUSE_MASK;
19840
19841 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19842 if (cclauses)
19843 {
19844 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
19845 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
19846 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
19847 OMP_CLAUSE_ORDERED);
19848 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
19849 {
19850 error_at (OMP_CLAUSE_LOCATION (c),
19851 "%<ordered%> clause with parameter may not be specified "
19852 "on %qs construct", p_name);
19853 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
19854 }
19855 }
19856
19857 block = c_begin_compound_stmt (true);
19858 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
19859 block = c_end_compound_stmt (loc, block, true);
19860 add_stmt (block);
19861
19862 return ret;
19863 }
19864
19865 /* OpenMP 2.5:
19866 #pragma omp for for-clause[optseq] new-line
19867 for-loop
19868
19869 OpenMP 4.0:
19870 #pragma omp for simd for-simd-clause[optseq] new-line
19871 for-loop
19872
19873 LOC is the location of the #pragma token.
19874 */
19875
19876 #define OMP_FOR_CLAUSE_MASK \
19877 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
19883 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
19884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19888
19889 static tree
19890 c_parser_omp_for (location_t loc, c_parser *parser,
19891 char *p_name, omp_clause_mask mask, tree *cclauses,
19892 bool *if_p)
19893 {
19894 tree block, clauses, ret;
19895
19896 strcat (p_name, " for");
19897 mask |= OMP_FOR_CLAUSE_MASK;
19898 /* parallel for{, simd} disallows nowait clause, but for
19899 target {teams distribute ,}parallel for{, simd} it should be accepted. */
19900 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
19901 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
19902 /* Composite distribute parallel for{, simd} disallows ordered clause. */
19903 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19904 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
19905
19906 if (c_parser_next_token_is (parser, CPP_NAME))
19907 {
19908 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19909
19910 if (strcmp (p, "simd") == 0)
19911 {
19912 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19913 if (cclauses == NULL)
19914 cclauses = cclauses_buf;
19915
19916 c_parser_consume_token (parser);
19917 if (!flag_openmp) /* flag_openmp_simd */
19918 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19919 if_p);
19920 block = c_begin_compound_stmt (true);
19921 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
19922 block = c_end_compound_stmt (loc, block, true);
19923 if (ret == NULL_TREE)
19924 return ret;
19925 ret = make_node (OMP_FOR);
19926 TREE_TYPE (ret) = void_type_node;
19927 OMP_FOR_BODY (ret) = block;
19928 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19929 SET_EXPR_LOCATION (ret, loc);
19930 add_stmt (ret);
19931 return ret;
19932 }
19933 }
19934 if (!flag_openmp) /* flag_openmp_simd */
19935 {
19936 c_parser_skip_to_pragma_eol (parser, false);
19937 return NULL_TREE;
19938 }
19939
19940 /* Composite distribute parallel for disallows linear clause. */
19941 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19942 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
19943
19944 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19945 if (cclauses)
19946 {
19947 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
19948 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19949 }
19950
19951 block = c_begin_compound_stmt (true);
19952 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
19953 block = c_end_compound_stmt (loc, block, true);
19954 add_stmt (block);
19955
19956 return ret;
19957 }
19958
19959 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
19960 omp_clause_mask, tree *, bool *);
19961
19962 /* OpenMP 2.5:
19963 # pragma omp master new-line
19964 structured-block
19965
19966 LOC is the location of the #pragma token.
19967 */
19968
19969 static tree
19970 c_parser_omp_master (location_t loc, c_parser *parser,
19971 char *p_name, omp_clause_mask mask, tree *cclauses,
19972 bool *if_p)
19973 {
19974 tree block, clauses, ret;
19975
19976 strcat (p_name, " master");
19977
19978 if (c_parser_next_token_is (parser, CPP_NAME))
19979 {
19980 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19981
19982 if (strcmp (p, "taskloop") == 0)
19983 {
19984 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19985 if (cclauses == NULL)
19986 cclauses = cclauses_buf;
19987
19988 c_parser_consume_token (parser);
19989 if (!flag_openmp) /* flag_openmp_simd */
19990 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19991 if_p);
19992 block = c_begin_compound_stmt (true);
19993 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19994 if_p);
19995 block = c_end_compound_stmt (loc, block, true);
19996 if (ret == NULL_TREE)
19997 return ret;
19998 ret = c_finish_omp_master (loc, block);
19999 OMP_MASTER_COMBINED (ret) = 1;
20000 return ret;
20001 }
20002 }
20003 if (!flag_openmp) /* flag_openmp_simd */
20004 {
20005 c_parser_skip_to_pragma_eol (parser, false);
20006 return NULL_TREE;
20007 }
20008
20009 if (cclauses)
20010 {
20011 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
20012 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
20013 }
20014 else
20015 c_parser_skip_to_pragma_eol (parser);
20016
20017 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
20018 if_p));
20019 }
20020
20021 /* OpenMP 5.1:
20022 # pragma omp masked masked-clauses new-line
20023 structured-block
20024
20025 LOC is the location of the #pragma token.
20026 */
20027
20028 #define OMP_MASKED_CLAUSE_MASK \
20029 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20030
20031 static tree
20032 c_parser_omp_masked (location_t loc, c_parser *parser,
20033 char *p_name, omp_clause_mask mask, tree *cclauses,
20034 bool *if_p)
20035 {
20036 tree block, clauses, ret;
20037
20038 strcat (p_name, " masked");
20039 mask |= OMP_MASKED_CLAUSE_MASK;
20040
20041 if (c_parser_next_token_is (parser, CPP_NAME))
20042 {
20043 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20044
20045 if (strcmp (p, "taskloop") == 0)
20046 {
20047 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20048 if (cclauses == NULL)
20049 cclauses = cclauses_buf;
20050
20051 c_parser_consume_token (parser);
20052 if (!flag_openmp) /* flag_openmp_simd */
20053 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20054 if_p);
20055 block = c_begin_compound_stmt (true);
20056 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20057 if_p);
20058 block = c_end_compound_stmt (loc, block, true);
20059 if (ret == NULL_TREE)
20060 return ret;
20061 ret = c_finish_omp_masked (loc, block,
20062 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
20063 OMP_MASKED_COMBINED (ret) = 1;
20064 return ret;
20065 }
20066 }
20067 if (!flag_openmp) /* flag_openmp_simd */
20068 {
20069 c_parser_skip_to_pragma_eol (parser, false);
20070 return NULL_TREE;
20071 }
20072
20073 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20074 if (cclauses)
20075 {
20076 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
20077 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
20078 }
20079
20080 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
20081 if_p),
20082 clauses);
20083 }
20084
20085 /* OpenMP 2.5:
20086 # pragma omp ordered new-line
20087 structured-block
20088
20089 OpenMP 4.5:
20090 # pragma omp ordered ordered-clauses new-line
20091 structured-block
20092
20093 # pragma omp ordered depend-clauses new-line */
20094
20095 #define OMP_ORDERED_CLAUSE_MASK \
20096 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20098
20099 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20100 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20101
20102 static bool
20103 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
20104 bool *if_p)
20105 {
20106 location_t loc = c_parser_peek_token (parser)->location;
20107 c_parser_consume_pragma (parser);
20108
20109 if (context != pragma_stmt && context != pragma_compound)
20110 {
20111 c_parser_error (parser, "expected declaration specifiers");
20112 c_parser_skip_to_pragma_eol (parser, false);
20113 return false;
20114 }
20115
20116 if (c_parser_next_token_is (parser, CPP_NAME))
20117 {
20118 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20119
20120 if (!strcmp ("depend", p))
20121 {
20122 if (!flag_openmp) /* flag_openmp_simd */
20123 {
20124 c_parser_skip_to_pragma_eol (parser, false);
20125 return false;
20126 }
20127 if (context == pragma_stmt)
20128 {
20129 error_at (loc,
20130 "%<#pragma omp ordered%> with %<depend%> clause may "
20131 "only be used in compound statements");
20132 c_parser_skip_to_pragma_eol (parser, false);
20133 return true;
20134 }
20135
20136 tree clauses
20137 = c_parser_omp_all_clauses (parser,
20138 OMP_ORDERED_DEPEND_CLAUSE_MASK,
20139 "#pragma omp ordered");
20140 c_finish_omp_ordered (loc, clauses, NULL_TREE);
20141 return false;
20142 }
20143 }
20144
20145 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20146 "#pragma omp ordered");
20147
20148 if (!flag_openmp /* flag_openmp_simd */
20149 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20150 return false;
20151
20152 c_finish_omp_ordered (loc, clauses,
20153 c_parser_omp_structured_block (parser, if_p));
20154 return true;
20155 }
20156
20157 /* OpenMP 2.5:
20158
20159 section-scope:
20160 { section-sequence }
20161
20162 section-sequence:
20163 section-directive[opt] structured-block
20164 section-sequence section-directive structured-block
20165
20166 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20167
20168 SECTIONS_LOC is the location of the #pragma omp sections. */
20169
20170 static tree
20171 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20172 {
20173 tree stmt, substmt;
20174 bool error_suppress = false;
20175 location_t loc;
20176
20177 loc = c_parser_peek_token (parser)->location;
20178 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20179 {
20180 /* Avoid skipping until the end of the block. */
20181 parser->error = false;
20182 return NULL_TREE;
20183 }
20184
20185 stmt = push_stmt_list ();
20186
20187 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
20188 {
20189 substmt = c_parser_omp_structured_block_sequence (parser,
20190 PRAGMA_OMP_SECTION);
20191 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20192 SET_EXPR_LOCATION (substmt, loc);
20193 add_stmt (substmt);
20194 }
20195
20196 while (1)
20197 {
20198 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20199 break;
20200 if (c_parser_next_token_is (parser, CPP_EOF))
20201 break;
20202
20203 loc = c_parser_peek_token (parser)->location;
20204 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
20205 {
20206 c_parser_consume_pragma (parser);
20207 c_parser_skip_to_pragma_eol (parser);
20208 error_suppress = false;
20209 }
20210 else if (!error_suppress)
20211 {
20212 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
20213 error_suppress = true;
20214 }
20215
20216 substmt = c_parser_omp_structured_block_sequence (parser,
20217 PRAGMA_OMP_SECTION);
20218 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20219 SET_EXPR_LOCATION (substmt, loc);
20220 add_stmt (substmt);
20221 }
20222 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20223 "expected %<#pragma omp section%> or %<}%>");
20224
20225 substmt = pop_stmt_list (stmt);
20226
20227 stmt = make_node (OMP_SECTIONS);
20228 SET_EXPR_LOCATION (stmt, sections_loc);
20229 TREE_TYPE (stmt) = void_type_node;
20230 OMP_SECTIONS_BODY (stmt) = substmt;
20231
20232 return add_stmt (stmt);
20233 }
20234
20235 /* OpenMP 2.5:
20236 # pragma omp sections sections-clause[optseq] newline
20237 sections-scope
20238
20239 LOC is the location of the #pragma token.
20240 */
20241
20242 #define OMP_SECTIONS_CLAUSE_MASK \
20243 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20249
20250 static tree
20251 c_parser_omp_sections (location_t loc, c_parser *parser,
20252 char *p_name, omp_clause_mask mask, tree *cclauses)
20253 {
20254 tree block, clauses, ret;
20255
20256 strcat (p_name, " sections");
20257 mask |= OMP_SECTIONS_CLAUSE_MASK;
20258 if (cclauses)
20259 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20260
20261 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20262 if (cclauses)
20263 {
20264 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
20265 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
20266 }
20267
20268 block = c_begin_compound_stmt (true);
20269 ret = c_parser_omp_sections_scope (loc, parser);
20270 if (ret)
20271 OMP_SECTIONS_CLAUSES (ret) = clauses;
20272 block = c_end_compound_stmt (loc, block, true);
20273 add_stmt (block);
20274
20275 return ret;
20276 }
20277
20278 /* OpenMP 2.5:
20279 # pragma omp parallel parallel-clause[optseq] new-line
20280 structured-block
20281 # pragma omp parallel for parallel-for-clause[optseq] new-line
20282 structured-block
20283 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20284 structured-block
20285
20286 OpenMP 4.0:
20287 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20288 structured-block
20289
20290 LOC is the location of the #pragma token.
20291 */
20292
20293 #define OMP_PARALLEL_CLAUSE_MASK \
20294 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20295 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20296 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20297 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20298 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20299 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20300 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20301 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20304
20305 static tree
20306 c_parser_omp_parallel (location_t loc, c_parser *parser,
20307 char *p_name, omp_clause_mask mask, tree *cclauses,
20308 bool *if_p)
20309 {
20310 tree stmt, clauses, block;
20311
20312 strcat (p_name, " parallel");
20313 mask |= OMP_PARALLEL_CLAUSE_MASK;
20314 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20315 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
20316 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
20317 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
20318
20319 if (c_parser_next_token_is_keyword (parser, RID_FOR))
20320 {
20321 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20322 if (cclauses == NULL)
20323 cclauses = cclauses_buf;
20324
20325 c_parser_consume_token (parser);
20326 if (!flag_openmp) /* flag_openmp_simd */
20327 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20328 block = c_begin_omp_parallel ();
20329 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20330 stmt
20331 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20332 block);
20333 if (ret == NULL_TREE)
20334 return ret;
20335 OMP_PARALLEL_COMBINED (stmt) = 1;
20336 return stmt;
20337 }
20338 /* When combined with distribute, parallel has to be followed by for.
20339 #pragma omp target parallel is allowed though. */
20340 else if (cclauses
20341 && (mask & (OMP_CLAUSE_MASK_1
20342 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20343 {
20344 error_at (loc, "expected %<for%> after %qs", p_name);
20345 c_parser_skip_to_pragma_eol (parser);
20346 return NULL_TREE;
20347 }
20348 else if (c_parser_next_token_is (parser, CPP_NAME))
20349 {
20350 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20351 if (cclauses == NULL && strcmp (p, "masked") == 0)
20352 {
20353 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20354 cclauses = cclauses_buf;
20355
20356 c_parser_consume_token (parser);
20357 if (!flag_openmp) /* flag_openmp_simd */
20358 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20359 if_p);
20360 block = c_begin_omp_parallel ();
20361 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20362 if_p);
20363 stmt = c_finish_omp_parallel (loc,
20364 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20365 block);
20366 if (ret == NULL)
20367 return ret;
20368 /* masked does have just filter clause, but during gimplification
20369 isn't represented by a gimplification omp context, so for
20370 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20371 so that
20372 #pragma omp parallel masked
20373 #pragma omp taskloop simd lastprivate (x)
20374 isn't confused with
20375 #pragma omp parallel masked taskloop simd lastprivate (x) */
20376 if (OMP_MASKED_COMBINED (ret))
20377 OMP_PARALLEL_COMBINED (stmt) = 1;
20378 return stmt;
20379 }
20380 else if (cclauses == NULL && strcmp (p, "master") == 0)
20381 {
20382 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20383 cclauses = cclauses_buf;
20384
20385 c_parser_consume_token (parser);
20386 if (!flag_openmp) /* flag_openmp_simd */
20387 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20388 if_p);
20389 block = c_begin_omp_parallel ();
20390 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20391 if_p);
20392 stmt = c_finish_omp_parallel (loc,
20393 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20394 block);
20395 if (ret == NULL)
20396 return ret;
20397 /* master doesn't have any clauses and during gimplification
20398 isn't represented by a gimplification omp context, so for
20399 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20400 so that
20401 #pragma omp parallel master
20402 #pragma omp taskloop simd lastprivate (x)
20403 isn't confused with
20404 #pragma omp parallel master taskloop simd lastprivate (x) */
20405 if (OMP_MASTER_COMBINED (ret))
20406 OMP_PARALLEL_COMBINED (stmt) = 1;
20407 return stmt;
20408 }
20409 else if (strcmp (p, "loop") == 0)
20410 {
20411 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20412 if (cclauses == NULL)
20413 cclauses = cclauses_buf;
20414
20415 c_parser_consume_token (parser);
20416 if (!flag_openmp) /* flag_openmp_simd */
20417 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20418 if_p);
20419 block = c_begin_omp_parallel ();
20420 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20421 if_p);
20422 stmt
20423 = c_finish_omp_parallel (loc,
20424 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20425 block);
20426 if (ret == NULL_TREE)
20427 return ret;
20428 OMP_PARALLEL_COMBINED (stmt) = 1;
20429 return stmt;
20430 }
20431 else if (!flag_openmp) /* flag_openmp_simd */
20432 {
20433 c_parser_skip_to_pragma_eol (parser, false);
20434 return NULL_TREE;
20435 }
20436 else if (cclauses == NULL && strcmp (p, "sections") == 0)
20437 {
20438 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20439 cclauses = cclauses_buf;
20440
20441 c_parser_consume_token (parser);
20442 block = c_begin_omp_parallel ();
20443 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
20444 stmt = c_finish_omp_parallel (loc,
20445 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20446 block);
20447 OMP_PARALLEL_COMBINED (stmt) = 1;
20448 return stmt;
20449 }
20450 }
20451 else if (!flag_openmp) /* flag_openmp_simd */
20452 {
20453 c_parser_skip_to_pragma_eol (parser, false);
20454 return NULL_TREE;
20455 }
20456
20457 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20458 if (cclauses)
20459 {
20460 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
20461 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
20462 }
20463
20464 block = c_begin_omp_parallel ();
20465 c_parser_statement (parser, if_p);
20466 stmt = c_finish_omp_parallel (loc, clauses, block);
20467
20468 return stmt;
20469 }
20470
20471 /* OpenMP 2.5:
20472 # pragma omp single single-clause[optseq] new-line
20473 structured-block
20474
20475 LOC is the location of the #pragma.
20476 */
20477
20478 #define OMP_SINGLE_CLAUSE_MASK \
20479 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20484
20485 static tree
20486 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
20487 {
20488 tree stmt = make_node (OMP_SINGLE);
20489 SET_EXPR_LOCATION (stmt, loc);
20490 TREE_TYPE (stmt) = void_type_node;
20491
20492 OMP_SINGLE_CLAUSES (stmt)
20493 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
20494 "#pragma omp single");
20495 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20496
20497 return add_stmt (stmt);
20498 }
20499
20500 /* OpenMP 5.1:
20501 # pragma omp scope scope-clause[optseq] new-line
20502 structured-block
20503
20504 LOC is the location of the #pragma.
20505 */
20506
20507 #define OMP_SCOPE_CLAUSE_MASK \
20508 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20513
20514 static tree
20515 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
20516 {
20517 tree stmt = make_node (OMP_SCOPE);
20518 SET_EXPR_LOCATION (stmt, loc);
20519 TREE_TYPE (stmt) = void_type_node;
20520
20521 OMP_SCOPE_CLAUSES (stmt)
20522 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
20523 "#pragma omp scope");
20524 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20525
20526 return add_stmt (stmt);
20527 }
20528
20529 /* OpenMP 3.0:
20530 # pragma omp task task-clause[optseq] new-line
20531
20532 LOC is the location of the #pragma.
20533 */
20534
20535 #define OMP_TASK_CLAUSE_MASK \
20536 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20550
20551 static tree
20552 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
20553 {
20554 tree clauses, block;
20555
20556 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
20557 "#pragma omp task");
20558
20559 block = c_begin_omp_task ();
20560 c_parser_statement (parser, if_p);
20561 return c_finish_omp_task (loc, clauses, block);
20562 }
20563
20564 /* OpenMP 3.0:
20565 # pragma omp taskwait new-line
20566
20567 OpenMP 5.0:
20568 # pragma omp taskwait taskwait-clause[optseq] new-line
20569 */
20570
20571 #define OMP_TASKWAIT_CLAUSE_MASK \
20572 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20574
20575 static void
20576 c_parser_omp_taskwait (c_parser *parser)
20577 {
20578 location_t loc = c_parser_peek_token (parser)->location;
20579 c_parser_consume_pragma (parser);
20580
20581 tree clauses
20582 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
20583 "#pragma omp taskwait");
20584
20585 if (clauses)
20586 {
20587 tree stmt = make_node (OMP_TASK);
20588 TREE_TYPE (stmt) = void_node;
20589 OMP_TASK_CLAUSES (stmt) = clauses;
20590 OMP_TASK_BODY (stmt) = NULL_TREE;
20591 SET_EXPR_LOCATION (stmt, loc);
20592 add_stmt (stmt);
20593 }
20594 else
20595 c_finish_omp_taskwait (loc);
20596 }
20597
20598 /* OpenMP 3.1:
20599 # pragma omp taskyield new-line
20600 */
20601
20602 static void
20603 c_parser_omp_taskyield (c_parser *parser)
20604 {
20605 location_t loc = c_parser_peek_token (parser)->location;
20606 c_parser_consume_pragma (parser);
20607 c_parser_skip_to_pragma_eol (parser);
20608
20609 c_finish_omp_taskyield (loc);
20610 }
20611
20612 /* OpenMP 4.0:
20613 # pragma omp taskgroup new-line
20614
20615 OpenMP 5.0:
20616 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20617 */
20618
20619 #define OMP_TASKGROUP_CLAUSE_MASK \
20620 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20621 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20622
20623 static tree
20624 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
20625 {
20626 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
20627 "#pragma omp taskgroup");
20628
20629 tree body = c_parser_omp_structured_block (parser, if_p);
20630 return c_finish_omp_taskgroup (loc, body, clauses);
20631 }
20632
20633 /* OpenMP 4.0:
20634 # pragma omp cancel cancel-clause[optseq] new-line
20635
20636 LOC is the location of the #pragma.
20637 */
20638
20639 #define OMP_CANCEL_CLAUSE_MASK \
20640 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20645
20646 static void
20647 c_parser_omp_cancel (c_parser *parser)
20648 {
20649 location_t loc = c_parser_peek_token (parser)->location;
20650
20651 c_parser_consume_pragma (parser);
20652 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
20653 "#pragma omp cancel");
20654
20655 c_finish_omp_cancel (loc, clauses);
20656 }
20657
20658 /* OpenMP 4.0:
20659 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20660
20661 LOC is the location of the #pragma.
20662 */
20663
20664 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20665 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20666 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20668 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20669
20670 static bool
20671 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
20672 {
20673 location_t loc = c_parser_peek_token (parser)->location;
20674 tree clauses;
20675 bool point_seen = false;
20676
20677 c_parser_consume_pragma (parser);
20678 if (c_parser_next_token_is (parser, CPP_NAME))
20679 {
20680 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20681 if (strcmp (p, "point") == 0)
20682 {
20683 c_parser_consume_token (parser);
20684 point_seen = true;
20685 }
20686 }
20687 if (!point_seen)
20688 {
20689 c_parser_error (parser, "expected %<point%>");
20690 c_parser_skip_to_pragma_eol (parser);
20691 return false;
20692 }
20693
20694 if (context != pragma_compound)
20695 {
20696 if (context == pragma_stmt)
20697 error_at (loc,
20698 "%<#pragma %s%> may only be used in compound statements",
20699 "omp cancellation point");
20700 else
20701 c_parser_error (parser, "expected declaration specifiers");
20702 c_parser_skip_to_pragma_eol (parser, false);
20703 return true;
20704 }
20705
20706 clauses
20707 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
20708 "#pragma omp cancellation point");
20709
20710 c_finish_omp_cancellation_point (loc, clauses);
20711 return true;
20712 }
20713
20714 /* OpenMP 4.0:
20715 #pragma omp distribute distribute-clause[optseq] new-line
20716 for-loop */
20717
20718 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20719 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20726
20727 static tree
20728 c_parser_omp_distribute (location_t loc, c_parser *parser,
20729 char *p_name, omp_clause_mask mask, tree *cclauses,
20730 bool *if_p)
20731 {
20732 tree clauses, block, ret;
20733
20734 strcat (p_name, " distribute");
20735 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
20736
20737 if (c_parser_next_token_is (parser, CPP_NAME))
20738 {
20739 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20740 bool simd = false;
20741 bool parallel = false;
20742
20743 if (strcmp (p, "simd") == 0)
20744 simd = true;
20745 else
20746 parallel = strcmp (p, "parallel") == 0;
20747 if (parallel || simd)
20748 {
20749 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20750 if (cclauses == NULL)
20751 cclauses = cclauses_buf;
20752 c_parser_consume_token (parser);
20753 if (!flag_openmp) /* flag_openmp_simd */
20754 {
20755 if (simd)
20756 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20757 if_p);
20758 else
20759 return c_parser_omp_parallel (loc, parser, p_name, mask,
20760 cclauses, if_p);
20761 }
20762 block = c_begin_compound_stmt (true);
20763 if (simd)
20764 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20765 if_p);
20766 else
20767 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
20768 if_p);
20769 block = c_end_compound_stmt (loc, block, true);
20770 if (ret == NULL)
20771 return ret;
20772 ret = make_node (OMP_DISTRIBUTE);
20773 TREE_TYPE (ret) = void_type_node;
20774 OMP_FOR_BODY (ret) = block;
20775 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20776 SET_EXPR_LOCATION (ret, loc);
20777 add_stmt (ret);
20778 return ret;
20779 }
20780 }
20781 if (!flag_openmp) /* flag_openmp_simd */
20782 {
20783 c_parser_skip_to_pragma_eol (parser, false);
20784 return NULL_TREE;
20785 }
20786
20787 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20788 if (cclauses)
20789 {
20790 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
20791 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20792 }
20793
20794 block = c_begin_compound_stmt (true);
20795 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
20796 if_p);
20797 block = c_end_compound_stmt (loc, block, true);
20798 add_stmt (block);
20799
20800 return ret;
20801 }
20802
20803 /* OpenMP 4.0:
20804 # pragma omp teams teams-clause[optseq] new-line
20805 structured-block */
20806
20807 #define OMP_TEAMS_CLAUSE_MASK \
20808 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20816
20817 static tree
20818 c_parser_omp_teams (location_t loc, c_parser *parser,
20819 char *p_name, omp_clause_mask mask, tree *cclauses,
20820 bool *if_p)
20821 {
20822 tree clauses, block, ret;
20823
20824 strcat (p_name, " teams");
20825 mask |= OMP_TEAMS_CLAUSE_MASK;
20826
20827 if (c_parser_next_token_is (parser, CPP_NAME))
20828 {
20829 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20830 if (strcmp (p, "distribute") == 0)
20831 {
20832 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20833 if (cclauses == NULL)
20834 cclauses = cclauses_buf;
20835
20836 c_parser_consume_token (parser);
20837 if (!flag_openmp) /* flag_openmp_simd */
20838 return c_parser_omp_distribute (loc, parser, p_name, mask,
20839 cclauses, if_p);
20840 block = c_begin_omp_parallel ();
20841 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
20842 if_p);
20843 block = c_end_compound_stmt (loc, block, true);
20844 if (ret == NULL)
20845 return ret;
20846 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20847 ret = make_node (OMP_TEAMS);
20848 TREE_TYPE (ret) = void_type_node;
20849 OMP_TEAMS_CLAUSES (ret) = clauses;
20850 OMP_TEAMS_BODY (ret) = block;
20851 OMP_TEAMS_COMBINED (ret) = 1;
20852 SET_EXPR_LOCATION (ret, loc);
20853 return add_stmt (ret);
20854 }
20855 else if (strcmp (p, "loop") == 0)
20856 {
20857 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20858 if (cclauses == NULL)
20859 cclauses = cclauses_buf;
20860
20861 c_parser_consume_token (parser);
20862 if (!flag_openmp) /* flag_openmp_simd */
20863 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20864 if_p);
20865 block = c_begin_omp_parallel ();
20866 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
20867 block = c_end_compound_stmt (loc, block, true);
20868 if (ret == NULL)
20869 return ret;
20870 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20871 ret = make_node (OMP_TEAMS);
20872 TREE_TYPE (ret) = void_type_node;
20873 OMP_TEAMS_CLAUSES (ret) = clauses;
20874 OMP_TEAMS_BODY (ret) = block;
20875 OMP_TEAMS_COMBINED (ret) = 1;
20876 SET_EXPR_LOCATION (ret, loc);
20877 return add_stmt (ret);
20878 }
20879 }
20880 if (!flag_openmp) /* flag_openmp_simd */
20881 {
20882 c_parser_skip_to_pragma_eol (parser, false);
20883 return NULL_TREE;
20884 }
20885
20886 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20887 if (cclauses)
20888 {
20889 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
20890 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20891 }
20892
20893 tree stmt = make_node (OMP_TEAMS);
20894 TREE_TYPE (stmt) = void_type_node;
20895 OMP_TEAMS_CLAUSES (stmt) = clauses;
20896 block = c_begin_omp_parallel ();
20897 add_stmt (c_parser_omp_structured_block (parser, if_p));
20898 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20899 SET_EXPR_LOCATION (stmt, loc);
20900
20901 return add_stmt (stmt);
20902 }
20903
20904 /* OpenMP 4.0:
20905 # pragma omp target data target-data-clause[optseq] new-line
20906 structured-block */
20907
20908 #define OMP_TARGET_DATA_CLAUSE_MASK \
20909 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20914
20915 static tree
20916 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
20917 {
20918 if (flag_openmp)
20919 omp_requires_mask
20920 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
20921
20922 tree clauses
20923 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
20924 "#pragma omp target data");
20925 c_omp_adjust_map_clauses (clauses, false);
20926 int map_seen = 0;
20927 for (tree *pc = &clauses; *pc;)
20928 {
20929 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20930 switch (OMP_CLAUSE_MAP_KIND (*pc))
20931 {
20932 case GOMP_MAP_TO:
20933 case GOMP_MAP_ALWAYS_TO:
20934 case GOMP_MAP_FROM:
20935 case GOMP_MAP_ALWAYS_FROM:
20936 case GOMP_MAP_TOFROM:
20937 case GOMP_MAP_ALWAYS_TOFROM:
20938 case GOMP_MAP_ALLOC:
20939 map_seen = 3;
20940 break;
20941 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20942 case GOMP_MAP_ALWAYS_POINTER:
20943 case GOMP_MAP_ATTACH_DETACH:
20944 break;
20945 default:
20946 map_seen |= 1;
20947 error_at (OMP_CLAUSE_LOCATION (*pc),
20948 "%<#pragma omp target data%> with map-type other "
20949 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20950 "on %<map%> clause");
20951 *pc = OMP_CLAUSE_CHAIN (*pc);
20952 continue;
20953 }
20954 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
20955 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
20956 map_seen = 3;
20957 pc = &OMP_CLAUSE_CHAIN (*pc);
20958 }
20959
20960 if (map_seen != 3)
20961 {
20962 if (map_seen == 0)
20963 error_at (loc,
20964 "%<#pragma omp target data%> must contain at least "
20965 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
20966 "clause");
20967 return NULL_TREE;
20968 }
20969
20970 tree stmt = make_node (OMP_TARGET_DATA);
20971 TREE_TYPE (stmt) = void_type_node;
20972 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
20973 keep_next_level ();
20974 tree block = c_begin_compound_stmt (true);
20975 add_stmt (c_parser_omp_structured_block (parser, if_p));
20976 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20977
20978 SET_EXPR_LOCATION (stmt, loc);
20979 return add_stmt (stmt);
20980 }
20981
20982 /* OpenMP 4.0:
20983 # pragma omp target update target-update-clause[optseq] new-line */
20984
20985 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
20986 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
20987 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20992
20993 static bool
20994 c_parser_omp_target_update (location_t loc, c_parser *parser,
20995 enum pragma_context context)
20996 {
20997 if (context == pragma_stmt)
20998 {
20999 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21000 "omp target update");
21001 c_parser_skip_to_pragma_eol (parser, false);
21002 return true;
21003 }
21004
21005 tree clauses
21006 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
21007 "#pragma omp target update");
21008 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
21009 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
21010 {
21011 error_at (loc,
21012 "%<#pragma omp target update%> must contain at least one "
21013 "%<from%> or %<to%> clauses");
21014 return false;
21015 }
21016
21017 if (flag_openmp)
21018 omp_requires_mask
21019 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21020
21021 tree stmt = make_node (OMP_TARGET_UPDATE);
21022 TREE_TYPE (stmt) = void_type_node;
21023 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
21024 SET_EXPR_LOCATION (stmt, loc);
21025 add_stmt (stmt);
21026 return false;
21027 }
21028
21029 /* OpenMP 4.5:
21030 # pragma omp target enter data target-data-clause[optseq] new-line */
21031
21032 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21033 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21034 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21035 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21036 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21037 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21038
21039 static bool
21040 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
21041 enum pragma_context context)
21042 {
21043 bool data_seen = false;
21044 if (c_parser_next_token_is (parser, CPP_NAME))
21045 {
21046 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21047 if (strcmp (p, "data") == 0)
21048 {
21049 c_parser_consume_token (parser);
21050 data_seen = true;
21051 }
21052 }
21053 if (!data_seen)
21054 {
21055 c_parser_error (parser, "expected %<data%>");
21056 c_parser_skip_to_pragma_eol (parser);
21057 return false;
21058 }
21059
21060 if (context == pragma_stmt)
21061 {
21062 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21063 "omp target enter data");
21064 c_parser_skip_to_pragma_eol (parser, false);
21065 return true;
21066 }
21067
21068 if (flag_openmp)
21069 omp_requires_mask
21070 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21071
21072 tree clauses
21073 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
21074 "#pragma omp target enter data");
21075 c_omp_adjust_map_clauses (clauses, false);
21076 int map_seen = 0;
21077 for (tree *pc = &clauses; *pc;)
21078 {
21079 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21080 switch (OMP_CLAUSE_MAP_KIND (*pc))
21081 {
21082 case GOMP_MAP_TO:
21083 case GOMP_MAP_ALWAYS_TO:
21084 case GOMP_MAP_ALLOC:
21085 map_seen = 3;
21086 break;
21087 case GOMP_MAP_TOFROM:
21088 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
21089 map_seen = 3;
21090 break;
21091 case GOMP_MAP_ALWAYS_TOFROM:
21092 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
21093 map_seen = 3;
21094 break;
21095 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21096 case GOMP_MAP_ALWAYS_POINTER:
21097 case GOMP_MAP_ATTACH_DETACH:
21098 break;
21099 default:
21100 map_seen |= 1;
21101 error_at (OMP_CLAUSE_LOCATION (*pc),
21102 "%<#pragma omp target enter data%> with map-type other "
21103 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21104 *pc = OMP_CLAUSE_CHAIN (*pc);
21105 continue;
21106 }
21107 pc = &OMP_CLAUSE_CHAIN (*pc);
21108 }
21109
21110 if (map_seen != 3)
21111 {
21112 if (map_seen == 0)
21113 error_at (loc,
21114 "%<#pragma omp target enter data%> must contain at least "
21115 "one %<map%> clause");
21116 return true;
21117 }
21118
21119 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
21120 TREE_TYPE (stmt) = void_type_node;
21121 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
21122 SET_EXPR_LOCATION (stmt, loc);
21123 add_stmt (stmt);
21124 return true;
21125 }
21126
21127 /* OpenMP 4.5:
21128 # pragma omp target exit data target-data-clause[optseq] new-line */
21129
21130 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21131 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21136
21137 static bool
21138 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
21139 enum pragma_context context)
21140 {
21141 bool data_seen = false;
21142 if (c_parser_next_token_is (parser, CPP_NAME))
21143 {
21144 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21145 if (strcmp (p, "data") == 0)
21146 {
21147 c_parser_consume_token (parser);
21148 data_seen = true;
21149 }
21150 }
21151 if (!data_seen)
21152 {
21153 c_parser_error (parser, "expected %<data%>");
21154 c_parser_skip_to_pragma_eol (parser);
21155 return false;
21156 }
21157
21158 if (context == pragma_stmt)
21159 {
21160 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21161 "omp target exit data");
21162 c_parser_skip_to_pragma_eol (parser, false);
21163 return true;
21164 }
21165
21166 if (flag_openmp)
21167 omp_requires_mask
21168 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21169
21170 tree clauses
21171 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21172 "#pragma omp target exit data");
21173 c_omp_adjust_map_clauses (clauses, false);
21174 int map_seen = 0;
21175 for (tree *pc = &clauses; *pc;)
21176 {
21177 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21178 switch (OMP_CLAUSE_MAP_KIND (*pc))
21179 {
21180 case GOMP_MAP_FROM:
21181 case GOMP_MAP_ALWAYS_FROM:
21182 case GOMP_MAP_RELEASE:
21183 case GOMP_MAP_DELETE:
21184 map_seen = 3;
21185 break;
21186 case GOMP_MAP_TOFROM:
21187 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
21188 map_seen = 3;
21189 break;
21190 case GOMP_MAP_ALWAYS_TOFROM:
21191 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
21192 map_seen = 3;
21193 break;
21194 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21195 case GOMP_MAP_ALWAYS_POINTER:
21196 case GOMP_MAP_ATTACH_DETACH:
21197 break;
21198 default:
21199 map_seen |= 1;
21200 error_at (OMP_CLAUSE_LOCATION (*pc),
21201 "%<#pragma omp target exit data%> with map-type other "
21202 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
21203 "on %<map%> clause");
21204 *pc = OMP_CLAUSE_CHAIN (*pc);
21205 continue;
21206 }
21207 pc = &OMP_CLAUSE_CHAIN (*pc);
21208 }
21209
21210 if (map_seen != 3)
21211 {
21212 if (map_seen == 0)
21213 error_at (loc,
21214 "%<#pragma omp target exit data%> must contain at least one "
21215 "%<map%> clause");
21216 return true;
21217 }
21218
21219 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
21220 TREE_TYPE (stmt) = void_type_node;
21221 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
21222 SET_EXPR_LOCATION (stmt, loc);
21223 add_stmt (stmt);
21224 return true;
21225 }
21226
21227 /* OpenMP 4.0:
21228 # pragma omp target target-clause[optseq] new-line
21229 structured-block */
21230
21231 #define OMP_TARGET_CLAUSE_MASK \
21232 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21233 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21235 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21236 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21245
21246 static bool
21247 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
21248 {
21249 location_t loc = c_parser_peek_token (parser)->location;
21250 c_parser_consume_pragma (parser);
21251 tree *pc = NULL, stmt, block;
21252
21253 if (context != pragma_stmt && context != pragma_compound)
21254 {
21255 c_parser_error (parser, "expected declaration specifiers");
21256 c_parser_skip_to_pragma_eol (parser);
21257 return false;
21258 }
21259
21260 if (flag_openmp)
21261 omp_requires_mask
21262 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21263
21264 if (c_parser_next_token_is (parser, CPP_NAME))
21265 {
21266 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21267 enum tree_code ccode = ERROR_MARK;
21268
21269 if (strcmp (p, "teams") == 0)
21270 ccode = OMP_TEAMS;
21271 else if (strcmp (p, "parallel") == 0)
21272 ccode = OMP_PARALLEL;
21273 else if (strcmp (p, "simd") == 0)
21274 ccode = OMP_SIMD;
21275 if (ccode != ERROR_MARK)
21276 {
21277 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
21278 char p_name[sizeof ("#pragma omp target teams distribute "
21279 "parallel for simd")];
21280
21281 c_parser_consume_token (parser);
21282 strcpy (p_name, "#pragma omp target");
21283 if (!flag_openmp) /* flag_openmp_simd */
21284 {
21285 tree stmt;
21286 switch (ccode)
21287 {
21288 case OMP_TEAMS:
21289 stmt = c_parser_omp_teams (loc, parser, p_name,
21290 OMP_TARGET_CLAUSE_MASK,
21291 cclauses, if_p);
21292 break;
21293 case OMP_PARALLEL:
21294 stmt = c_parser_omp_parallel (loc, parser, p_name,
21295 OMP_TARGET_CLAUSE_MASK,
21296 cclauses, if_p);
21297 break;
21298 case OMP_SIMD:
21299 stmt = c_parser_omp_simd (loc, parser, p_name,
21300 OMP_TARGET_CLAUSE_MASK,
21301 cclauses, if_p);
21302 break;
21303 default:
21304 gcc_unreachable ();
21305 }
21306 return stmt != NULL_TREE;
21307 }
21308 keep_next_level ();
21309 tree block = c_begin_compound_stmt (true), ret;
21310 switch (ccode)
21311 {
21312 case OMP_TEAMS:
21313 ret = c_parser_omp_teams (loc, parser, p_name,
21314 OMP_TARGET_CLAUSE_MASK, cclauses,
21315 if_p);
21316 break;
21317 case OMP_PARALLEL:
21318 ret = c_parser_omp_parallel (loc, parser, p_name,
21319 OMP_TARGET_CLAUSE_MASK, cclauses,
21320 if_p);
21321 break;
21322 case OMP_SIMD:
21323 ret = c_parser_omp_simd (loc, parser, p_name,
21324 OMP_TARGET_CLAUSE_MASK, cclauses,
21325 if_p);
21326 break;
21327 default:
21328 gcc_unreachable ();
21329 }
21330 block = c_end_compound_stmt (loc, block, true);
21331 if (ret == NULL_TREE)
21332 return false;
21333 if (ccode == OMP_TEAMS)
21334 /* For combined target teams, ensure the num_teams and
21335 thread_limit clause expressions are evaluated on the host,
21336 before entering the target construct. */
21337 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21338 c; c = OMP_CLAUSE_CHAIN (c))
21339 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
21340 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
21341 for (int i = 0;
21342 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
21343 if (OMP_CLAUSE_OPERAND (c, i)
21344 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
21345 {
21346 tree expr = OMP_CLAUSE_OPERAND (c, i);
21347 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
21348 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
21349 expr, NULL_TREE, NULL_TREE);
21350 add_stmt (expr);
21351 OMP_CLAUSE_OPERAND (c, i) = expr;
21352 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
21353 OMP_CLAUSE_FIRSTPRIVATE);
21354 OMP_CLAUSE_DECL (tc) = tmp;
21355 OMP_CLAUSE_CHAIN (tc)
21356 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21357 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
21358 }
21359 tree stmt = make_node (OMP_TARGET);
21360 TREE_TYPE (stmt) = void_type_node;
21361 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21362 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21363 OMP_TARGET_BODY (stmt) = block;
21364 OMP_TARGET_COMBINED (stmt) = 1;
21365 SET_EXPR_LOCATION (stmt, loc);
21366 add_stmt (stmt);
21367 pc = &OMP_TARGET_CLAUSES (stmt);
21368 goto check_clauses;
21369 }
21370 else if (!flag_openmp) /* flag_openmp_simd */
21371 {
21372 c_parser_skip_to_pragma_eol (parser, false);
21373 return false;
21374 }
21375 else if (strcmp (p, "data") == 0)
21376 {
21377 c_parser_consume_token (parser);
21378 c_parser_omp_target_data (loc, parser, if_p);
21379 return true;
21380 }
21381 else if (strcmp (p, "enter") == 0)
21382 {
21383 c_parser_consume_token (parser);
21384 return c_parser_omp_target_enter_data (loc, parser, context);
21385 }
21386 else if (strcmp (p, "exit") == 0)
21387 {
21388 c_parser_consume_token (parser);
21389 return c_parser_omp_target_exit_data (loc, parser, context);
21390 }
21391 else if (strcmp (p, "update") == 0)
21392 {
21393 c_parser_consume_token (parser);
21394 return c_parser_omp_target_update (loc, parser, context);
21395 }
21396 }
21397 if (!flag_openmp) /* flag_openmp_simd */
21398 {
21399 c_parser_skip_to_pragma_eol (parser, false);
21400 return false;
21401 }
21402
21403 stmt = make_node (OMP_TARGET);
21404 TREE_TYPE (stmt) = void_type_node;
21405
21406 OMP_TARGET_CLAUSES (stmt)
21407 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
21408 "#pragma omp target", false);
21409 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
21410 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
21411 {
21412 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
21413 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
21414 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
21415 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
21416 OMP_CLAUSE_CHAIN (c) = nc;
21417 }
21418 OMP_TARGET_CLAUSES (stmt)
21419 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
21420 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21421
21422 pc = &OMP_TARGET_CLAUSES (stmt);
21423 keep_next_level ();
21424 block = c_begin_compound_stmt (true);
21425 add_stmt (c_parser_omp_structured_block (parser, if_p));
21426 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21427
21428 SET_EXPR_LOCATION (stmt, loc);
21429 add_stmt (stmt);
21430
21431 check_clauses:
21432 while (*pc)
21433 {
21434 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21435 switch (OMP_CLAUSE_MAP_KIND (*pc))
21436 {
21437 case GOMP_MAP_TO:
21438 case GOMP_MAP_ALWAYS_TO:
21439 case GOMP_MAP_FROM:
21440 case GOMP_MAP_ALWAYS_FROM:
21441 case GOMP_MAP_TOFROM:
21442 case GOMP_MAP_ALWAYS_TOFROM:
21443 case GOMP_MAP_ALLOC:
21444 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21445 case GOMP_MAP_ALWAYS_POINTER:
21446 case GOMP_MAP_ATTACH_DETACH:
21447 break;
21448 default:
21449 error_at (OMP_CLAUSE_LOCATION (*pc),
21450 "%<#pragma omp target%> with map-type other "
21451 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21452 "on %<map%> clause");
21453 *pc = OMP_CLAUSE_CHAIN (*pc);
21454 continue;
21455 }
21456 pc = &OMP_CLAUSE_CHAIN (*pc);
21457 }
21458 cfun->has_omp_target = true;
21459 return true;
21460 }
21461
21462 /* OpenMP 4.0:
21463 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21464
21465 OpenMP 5.0:
21466 # pragma omp declare variant (identifier) match(context-selector) new-line
21467 */
21468
21469 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21470 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21476
21477 static void
21478 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
21479 {
21480 c_token *token = c_parser_peek_token (parser);
21481 gcc_assert (token->type == CPP_NAME);
21482 tree kind = token->value;
21483 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
21484 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
21485
21486 auto_vec<c_token> clauses;
21487 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21488 {
21489 c_token *token = c_parser_peek_token (parser);
21490 if (token->type == CPP_EOF)
21491 {
21492 c_parser_skip_to_pragma_eol (parser);
21493 return;
21494 }
21495 clauses.safe_push (*token);
21496 c_parser_consume_token (parser);
21497 }
21498 clauses.safe_push (*c_parser_peek_token (parser));
21499 c_parser_skip_to_pragma_eol (parser);
21500
21501 while (c_parser_next_token_is (parser, CPP_PRAGMA))
21502 {
21503 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
21504 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
21505 || c_parser_peek_2nd_token (parser)->value != kind)
21506 {
21507 error ("%<#pragma omp declare %s%> must be followed by "
21508 "function declaration or definition or another "
21509 "%<#pragma omp declare %s%>",
21510 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
21511 return;
21512 }
21513 c_parser_consume_pragma (parser);
21514 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21515 {
21516 c_token *token = c_parser_peek_token (parser);
21517 if (token->type == CPP_EOF)
21518 {
21519 c_parser_skip_to_pragma_eol (parser);
21520 return;
21521 }
21522 clauses.safe_push (*token);
21523 c_parser_consume_token (parser);
21524 }
21525 clauses.safe_push (*c_parser_peek_token (parser));
21526 c_parser_skip_to_pragma_eol (parser);
21527 }
21528
21529 /* Make sure nothing tries to read past the end of the tokens. */
21530 c_token eof_token;
21531 memset (&eof_token, 0, sizeof (eof_token));
21532 eof_token.type = CPP_EOF;
21533 clauses.safe_push (eof_token);
21534 clauses.safe_push (eof_token);
21535
21536 switch (context)
21537 {
21538 case pragma_external:
21539 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21540 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21541 {
21542 int ext = disable_extension_diagnostics ();
21543 do
21544 c_parser_consume_token (parser);
21545 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21546 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21547 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21548 NULL, &clauses);
21549 restore_extension_diagnostics (ext);
21550 }
21551 else
21552 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21553 NULL, &clauses);
21554 break;
21555 case pragma_struct:
21556 case pragma_param:
21557 case pragma_stmt:
21558 error ("%<#pragma omp declare %s%> must be followed by "
21559 "function declaration or definition",
21560 IDENTIFIER_POINTER (kind));
21561 break;
21562 case pragma_compound:
21563 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21564 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21565 {
21566 int ext = disable_extension_diagnostics ();
21567 do
21568 c_parser_consume_token (parser);
21569 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21570 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21571 if (c_parser_next_tokens_start_declaration (parser))
21572 {
21573 c_parser_declaration_or_fndef (parser, true, true, true, true,
21574 true, NULL, &clauses);
21575 restore_extension_diagnostics (ext);
21576 break;
21577 }
21578 restore_extension_diagnostics (ext);
21579 }
21580 else if (c_parser_next_tokens_start_declaration (parser))
21581 {
21582 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
21583 NULL, &clauses);
21584 break;
21585 }
21586 error ("%<#pragma omp declare %s%> must be followed by "
21587 "function declaration or definition",
21588 IDENTIFIER_POINTER (kind));
21589 break;
21590 default:
21591 gcc_unreachable ();
21592 }
21593 }
21594
21595 static const char *const omp_construct_selectors[] = {
21596 "simd", "target", "teams", "parallel", "for", NULL };
21597 static const char *const omp_device_selectors[] = {
21598 "kind", "isa", "arch", NULL };
21599 static const char *const omp_implementation_selectors[] = {
21600 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21601 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
21602 static const char *const omp_user_selectors[] = {
21603 "condition", NULL };
21604
21605 /* OpenMP 5.0:
21606
21607 trait-selector:
21608 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21609
21610 trait-score:
21611 score(score-expression) */
21612
21613 static tree
21614 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
21615 {
21616 tree ret = NULL_TREE;
21617 do
21618 {
21619 tree selector;
21620 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21621 || c_parser_next_token_is (parser, CPP_NAME))
21622 selector = c_parser_peek_token (parser)->value;
21623 else
21624 {
21625 c_parser_error (parser, "expected trait selector name");
21626 return error_mark_node;
21627 }
21628
21629 tree properties = NULL_TREE;
21630 const char *const *selectors = NULL;
21631 bool allow_score = true;
21632 bool allow_user = false;
21633 int property_limit = 0;
21634 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
21635 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
21636 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
21637 switch (IDENTIFIER_POINTER (set)[0])
21638 {
21639 case 'c': /* construct */
21640 selectors = omp_construct_selectors;
21641 allow_score = false;
21642 property_limit = 1;
21643 property_kind = CTX_PROPERTY_SIMD;
21644 break;
21645 case 'd': /* device */
21646 selectors = omp_device_selectors;
21647 allow_score = false;
21648 allow_user = true;
21649 property_limit = 3;
21650 property_kind = CTX_PROPERTY_NAME_LIST;
21651 break;
21652 case 'i': /* implementation */
21653 selectors = omp_implementation_selectors;
21654 allow_user = true;
21655 property_limit = 3;
21656 property_kind = CTX_PROPERTY_NAME_LIST;
21657 break;
21658 case 'u': /* user */
21659 selectors = omp_user_selectors;
21660 property_limit = 1;
21661 property_kind = CTX_PROPERTY_EXPR;
21662 break;
21663 default:
21664 gcc_unreachable ();
21665 }
21666 for (int i = 0; ; i++)
21667 {
21668 if (selectors[i] == NULL)
21669 {
21670 if (allow_user)
21671 {
21672 property_kind = CTX_PROPERTY_USER;
21673 break;
21674 }
21675 else
21676 {
21677 error_at (c_parser_peek_token (parser)->location,
21678 "selector %qs not allowed for context selector "
21679 "set %qs", IDENTIFIER_POINTER (selector),
21680 IDENTIFIER_POINTER (set));
21681 c_parser_consume_token (parser);
21682 return error_mark_node;
21683 }
21684 }
21685 if (i == property_limit)
21686 property_kind = CTX_PROPERTY_NONE;
21687 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
21688 break;
21689 }
21690 if (property_kind == CTX_PROPERTY_NAME_LIST
21691 && IDENTIFIER_POINTER (set)[0] == 'i'
21692 && strcmp (IDENTIFIER_POINTER (selector),
21693 "atomic_default_mem_order") == 0)
21694 property_kind = CTX_PROPERTY_ID;
21695
21696 c_parser_consume_token (parser);
21697
21698 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21699 {
21700 if (property_kind == CTX_PROPERTY_NONE)
21701 {
21702 error_at (c_parser_peek_token (parser)->location,
21703 "selector %qs does not accept any properties",
21704 IDENTIFIER_POINTER (selector));
21705 return error_mark_node;
21706 }
21707
21708 matching_parens parens;
21709 parens.require_open (parser);
21710
21711 c_token *token = c_parser_peek_token (parser);
21712 if (allow_score
21713 && c_parser_next_token_is (parser, CPP_NAME)
21714 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
21715 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
21716 {
21717 c_parser_consume_token (parser);
21718
21719 matching_parens parens2;
21720 parens2.require_open (parser);
21721 tree score = c_parser_expr_no_commas (parser, NULL).value;
21722 parens2.skip_until_found_close (parser);
21723 c_parser_require (parser, CPP_COLON, "expected %<:%>");
21724 if (score != error_mark_node)
21725 {
21726 mark_exp_read (score);
21727 score = c_fully_fold (score, false, NULL);
21728 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
21729 || TREE_CODE (score) != INTEGER_CST)
21730 error_at (token->location, "score argument must be "
21731 "constant integer expression");
21732 else if (tree_int_cst_sgn (score) < 0)
21733 error_at (token->location, "score argument must be "
21734 "non-negative");
21735 else
21736 properties = tree_cons (get_identifier (" score"),
21737 score, properties);
21738 }
21739 token = c_parser_peek_token (parser);
21740 }
21741
21742 switch (property_kind)
21743 {
21744 tree t;
21745 case CTX_PROPERTY_USER:
21746 do
21747 {
21748 t = c_parser_expr_no_commas (parser, NULL).value;
21749 if (TREE_CODE (t) == STRING_CST)
21750 properties = tree_cons (NULL_TREE, t, properties);
21751 else if (t != error_mark_node)
21752 {
21753 mark_exp_read (t);
21754 t = c_fully_fold (t, false, NULL);
21755 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21756 || !tree_fits_shwi_p (t))
21757 error_at (token->location, "property must be "
21758 "constant integer expression or string "
21759 "literal");
21760 else
21761 properties = tree_cons (NULL_TREE, t, properties);
21762 }
21763 else
21764 return error_mark_node;
21765
21766 if (c_parser_next_token_is (parser, CPP_COMMA))
21767 c_parser_consume_token (parser);
21768 else
21769 break;
21770 }
21771 while (1);
21772 break;
21773 case CTX_PROPERTY_ID:
21774 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21775 || c_parser_next_token_is (parser, CPP_NAME))
21776 {
21777 tree prop = c_parser_peek_token (parser)->value;
21778 c_parser_consume_token (parser);
21779 properties = tree_cons (prop, NULL_TREE, properties);
21780 }
21781 else
21782 {
21783 c_parser_error (parser, "expected identifier");
21784 return error_mark_node;
21785 }
21786 break;
21787 case CTX_PROPERTY_NAME_LIST:
21788 do
21789 {
21790 tree prop = NULL_TREE, value = NULL_TREE;
21791 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21792 || c_parser_next_token_is (parser, CPP_NAME))
21793 {
21794 prop = c_parser_peek_token (parser)->value;
21795 c_parser_consume_token (parser);
21796 }
21797 else if (c_parser_next_token_is (parser, CPP_STRING))
21798 value = c_parser_string_literal (parser, false,
21799 false).value;
21800 else
21801 {
21802 c_parser_error (parser, "expected identifier or "
21803 "string literal");
21804 return error_mark_node;
21805 }
21806
21807 properties = tree_cons (prop, value, properties);
21808
21809 if (c_parser_next_token_is (parser, CPP_COMMA))
21810 c_parser_consume_token (parser);
21811 else
21812 break;
21813 }
21814 while (1);
21815 break;
21816 case CTX_PROPERTY_EXPR:
21817 t = c_parser_expr_no_commas (parser, NULL).value;
21818 if (t != error_mark_node)
21819 {
21820 mark_exp_read (t);
21821 t = c_fully_fold (t, false, NULL);
21822 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21823 || !tree_fits_shwi_p (t))
21824 error_at (token->location, "property must be "
21825 "constant integer expression");
21826 else
21827 properties = tree_cons (NULL_TREE, t, properties);
21828 }
21829 else
21830 return error_mark_node;
21831 break;
21832 case CTX_PROPERTY_SIMD:
21833 if (parms == NULL_TREE)
21834 {
21835 error_at (token->location, "properties for %<simd%> "
21836 "selector may not be specified in "
21837 "%<metadirective%>");
21838 return error_mark_node;
21839 }
21840 tree c;
21841 c = c_parser_omp_all_clauses (parser,
21842 OMP_DECLARE_SIMD_CLAUSE_MASK,
21843 "simd", true, 2);
21844 c = c_omp_declare_simd_clauses_to_numbers (parms
21845 == error_mark_node
21846 ? NULL_TREE : parms,
21847 c);
21848 properties = c;
21849 break;
21850 default:
21851 gcc_unreachable ();
21852 }
21853
21854 parens.skip_until_found_close (parser);
21855 properties = nreverse (properties);
21856 }
21857 else if (property_kind == CTX_PROPERTY_NAME_LIST
21858 || property_kind == CTX_PROPERTY_ID
21859 || property_kind == CTX_PROPERTY_EXPR)
21860 {
21861 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
21862 return error_mark_node;
21863 }
21864
21865 ret = tree_cons (selector, properties, ret);
21866
21867 if (c_parser_next_token_is (parser, CPP_COMMA))
21868 c_parser_consume_token (parser);
21869 else
21870 break;
21871 }
21872 while (1);
21873
21874 return nreverse (ret);
21875 }
21876
21877 /* OpenMP 5.0:
21878
21879 trait-set-selector[,trait-set-selector[,...]]
21880
21881 trait-set-selector:
21882 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21883
21884 trait-set-selector-name:
21885 constructor
21886 device
21887 implementation
21888 user */
21889
21890 static tree
21891 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
21892 {
21893 tree ret = NULL_TREE;
21894 do
21895 {
21896 const char *setp = "";
21897 if (c_parser_next_token_is (parser, CPP_NAME))
21898 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21899 switch (setp[0])
21900 {
21901 case 'c':
21902 if (strcmp (setp, "construct") == 0)
21903 setp = NULL;
21904 break;
21905 case 'd':
21906 if (strcmp (setp, "device") == 0)
21907 setp = NULL;
21908 break;
21909 case 'i':
21910 if (strcmp (setp, "implementation") == 0)
21911 setp = NULL;
21912 break;
21913 case 'u':
21914 if (strcmp (setp, "user") == 0)
21915 setp = NULL;
21916 break;
21917 default:
21918 break;
21919 }
21920 if (setp)
21921 {
21922 c_parser_error (parser, "expected %<construct%>, %<device%>, "
21923 "%<implementation%> or %<user%>");
21924 return error_mark_node;
21925 }
21926
21927 tree set = c_parser_peek_token (parser)->value;
21928 c_parser_consume_token (parser);
21929
21930 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21931 return error_mark_node;
21932
21933 matching_braces braces;
21934 if (!braces.require_open (parser))
21935 return error_mark_node;
21936
21937 tree selectors = c_parser_omp_context_selector (parser, set, parms);
21938 if (selectors == error_mark_node)
21939 ret = error_mark_node;
21940 else if (ret != error_mark_node)
21941 ret = tree_cons (set, selectors, ret);
21942
21943 braces.skip_until_found_close (parser);
21944
21945 if (c_parser_next_token_is (parser, CPP_COMMA))
21946 c_parser_consume_token (parser);
21947 else
21948 break;
21949 }
21950 while (1);
21951
21952 if (ret == error_mark_node)
21953 return ret;
21954 return nreverse (ret);
21955 }
21956
21957 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21958 that into "omp declare variant base" attribute. */
21959
21960 static void
21961 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
21962 {
21963 matching_parens parens;
21964 if (!parens.require_open (parser))
21965 {
21966 fail:
21967 c_parser_skip_to_pragma_eol (parser, false);
21968 return;
21969 }
21970
21971 if (c_parser_next_token_is_not (parser, CPP_NAME)
21972 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
21973 {
21974 c_parser_error (parser, "expected identifier");
21975 goto fail;
21976 }
21977
21978 c_token *token = c_parser_peek_token (parser);
21979 tree variant = lookup_name (token->value);
21980
21981 if (variant == NULL_TREE)
21982 {
21983 undeclared_variable (token->location, token->value);
21984 variant = error_mark_node;
21985 }
21986
21987 c_parser_consume_token (parser);
21988
21989 parens.require_close (parser);
21990
21991 const char *clause = "";
21992 location_t match_loc = c_parser_peek_token (parser)->location;
21993 if (c_parser_next_token_is (parser, CPP_NAME))
21994 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21995 if (strcmp (clause, "match"))
21996 {
21997 c_parser_error (parser, "expected %<match%>");
21998 goto fail;
21999 }
22000
22001 c_parser_consume_token (parser);
22002
22003 if (!parens.require_open (parser))
22004 goto fail;
22005
22006 if (parms == NULL_TREE)
22007 parms = error_mark_node;
22008
22009 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
22010 if (ctx == error_mark_node)
22011 goto fail;
22012 ctx = omp_check_context_selector (match_loc, ctx);
22013 if (ctx != error_mark_node && variant != error_mark_node)
22014 {
22015 if (TREE_CODE (variant) != FUNCTION_DECL)
22016 {
22017 error_at (token->location, "variant %qD is not a function", variant);
22018 variant = error_mark_node;
22019 }
22020 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
22021 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
22022 {
22023 error_at (token->location, "variant %qD and base %qD have "
22024 "incompatible types", variant, fndecl);
22025 variant = error_mark_node;
22026 }
22027 else if (fndecl_built_in_p (variant)
22028 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22029 "__builtin_", strlen ("__builtin_")) == 0
22030 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22031 "__sync_", strlen ("__sync_")) == 0
22032 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22033 "__atomic_", strlen ("__atomic_")) == 0))
22034 {
22035 error_at (token->location, "variant %qD is a built-in", variant);
22036 variant = error_mark_node;
22037 }
22038 if (variant != error_mark_node)
22039 {
22040 C_DECL_USED (variant) = 1;
22041 tree construct = omp_get_context_selector (ctx, "construct", NULL);
22042 omp_mark_declare_variant (match_loc, variant, construct);
22043 if (omp_context_selector_matches (ctx))
22044 {
22045 tree attr
22046 = tree_cons (get_identifier ("omp declare variant base"),
22047 build_tree_list (variant, ctx),
22048 DECL_ATTRIBUTES (fndecl));
22049 DECL_ATTRIBUTES (fndecl) = attr;
22050 }
22051 }
22052 }
22053
22054 parens.require_close (parser);
22055 c_parser_skip_to_pragma_eol (parser);
22056 }
22057
22058 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22059 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22060 or "omp declare variant base" attribute. */
22061
22062 static void
22063 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
22064 vec<c_token> *pclauses)
22065 {
22066 vec<c_token> &clauses = *pclauses;
22067
22068 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22069 indicates error has been reported and CPP_PRAGMA that
22070 c_finish_omp_declare_simd has already processed the tokens. */
22071 if (clauses.exists () && clauses[0].type == CPP_EOF)
22072 return;
22073 const char *kind = "simd";
22074 if (clauses.exists ()
22075 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
22076 kind = IDENTIFIER_POINTER (clauses[0].value);
22077 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
22078 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
22079 {
22080 error ("%<#pragma omp declare %s%> not immediately followed by "
22081 "a function declaration or definition", kind);
22082 clauses[0].type = CPP_EOF;
22083 return;
22084 }
22085 if (clauses.exists () && clauses[0].type != CPP_NAME)
22086 {
22087 error_at (DECL_SOURCE_LOCATION (fndecl),
22088 "%<#pragma omp declare %s%> not immediately followed by "
22089 "a single function declaration or definition", kind);
22090 clauses[0].type = CPP_EOF;
22091 return;
22092 }
22093
22094 if (parms == NULL_TREE)
22095 parms = DECL_ARGUMENTS (fndecl);
22096
22097 unsigned int tokens_avail = parser->tokens_avail;
22098 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22099
22100 parser->tokens = clauses.address ();
22101 parser->tokens_avail = clauses.length ();
22102
22103 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22104 while (parser->tokens_avail > 3)
22105 {
22106 c_token *token = c_parser_peek_token (parser);
22107 gcc_assert (token->type == CPP_NAME
22108 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
22109 c_parser_consume_token (parser);
22110 parser->in_pragma = true;
22111
22112 if (strcmp (kind, "simd") == 0)
22113 {
22114 tree c;
22115 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
22116 "#pragma omp declare simd");
22117 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
22118 if (c != NULL_TREE)
22119 c = tree_cons (NULL_TREE, c, NULL_TREE);
22120 c = build_tree_list (get_identifier ("omp declare simd"), c);
22121 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
22122 DECL_ATTRIBUTES (fndecl) = c;
22123 }
22124 else
22125 {
22126 gcc_assert (strcmp (kind, "variant") == 0);
22127 c_finish_omp_declare_variant (parser, fndecl, parms);
22128 }
22129 }
22130
22131 parser->tokens = &parser->tokens_buf[0];
22132 parser->tokens_avail = tokens_avail;
22133 if (clauses.exists ())
22134 clauses[0].type = CPP_PRAGMA;
22135 }
22136
22137
22138 /* OpenMP 4.0:
22139 # pragma omp declare target new-line
22140 declarations and definitions
22141 # pragma omp end declare target new-line
22142
22143 OpenMP 4.5:
22144 # pragma omp declare target ( extended-list ) new-line
22145
22146 # pragma omp declare target declare-target-clauses[seq] new-line */
22147
22148 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22149 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22150 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22153
22154 static void
22155 c_parser_omp_declare_target (c_parser *parser)
22156 {
22157 tree clauses = NULL_TREE;
22158 int device_type = 0;
22159 bool only_device_type = true;
22160 if (c_parser_next_token_is (parser, CPP_NAME))
22161 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
22162 "#pragma omp declare target");
22163 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22164 {
22165 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
22166 clauses);
22167 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22168 c_parser_skip_to_pragma_eol (parser);
22169 }
22170 else
22171 {
22172 c_parser_skip_to_pragma_eol (parser);
22173 current_omp_declare_target_attribute++;
22174 return;
22175 }
22176 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22177 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22178 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22179 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22180 {
22181 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22182 continue;
22183 tree t = OMP_CLAUSE_DECL (c), id;
22184 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
22185 tree at2 = lookup_attribute ("omp declare target link",
22186 DECL_ATTRIBUTES (t));
22187 only_device_type = false;
22188 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
22189 {
22190 id = get_identifier ("omp declare target link");
22191 std::swap (at1, at2);
22192 }
22193 else
22194 id = get_identifier ("omp declare target");
22195 if (at2)
22196 {
22197 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
22198 error_at (OMP_CLAUSE_LOCATION (c),
22199 "%qD specified both in declare target %<link%> and %qs"
22200 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
22201 else
22202 error_at (OMP_CLAUSE_LOCATION (c),
22203 "%qD specified both in declare target %<link%> and "
22204 "%<to%> or %<enter%> clauses", t);
22205 continue;
22206 }
22207 if (!at1)
22208 {
22209 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22210 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
22211 continue;
22212
22213 symtab_node *node = symtab_node::get (t);
22214 if (node != NULL)
22215 {
22216 node->offloadable = 1;
22217 if (ENABLE_OFFLOADING)
22218 {
22219 g->have_offload = true;
22220 if (is_a <varpool_node *> (node))
22221 vec_safe_push (offload_vars, t);
22222 }
22223 }
22224 }
22225 if (TREE_CODE (t) != FUNCTION_DECL)
22226 continue;
22227 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
22228 {
22229 tree at3 = lookup_attribute ("omp declare target host",
22230 DECL_ATTRIBUTES (t));
22231 if (at3 == NULL_TREE)
22232 {
22233 id = get_identifier ("omp declare target host");
22234 DECL_ATTRIBUTES (t)
22235 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22236 }
22237 }
22238 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
22239 {
22240 tree at3 = lookup_attribute ("omp declare target nohost",
22241 DECL_ATTRIBUTES (t));
22242 if (at3 == NULL_TREE)
22243 {
22244 id = get_identifier ("omp declare target nohost");
22245 DECL_ATTRIBUTES (t)
22246 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22247 }
22248 }
22249 }
22250 if (device_type && only_device_type)
22251 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
22252 "directive with only %<device_type%> clauses ignored");
22253 }
22254
22255 static void
22256 c_parser_omp_end_declare_target (c_parser *parser)
22257 {
22258 location_t loc = c_parser_peek_token (parser)->location;
22259 c_parser_consume_pragma (parser);
22260 if (c_parser_next_token_is (parser, CPP_NAME)
22261 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22262 "declare") == 0)
22263 {
22264 c_parser_consume_token (parser);
22265 if (c_parser_next_token_is (parser, CPP_NAME)
22266 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22267 "target") == 0)
22268 c_parser_consume_token (parser);
22269 else
22270 {
22271 c_parser_error (parser, "expected %<target%>");
22272 c_parser_skip_to_pragma_eol (parser);
22273 return;
22274 }
22275 }
22276 else
22277 {
22278 c_parser_error (parser, "expected %<declare%>");
22279 c_parser_skip_to_pragma_eol (parser);
22280 return;
22281 }
22282 c_parser_skip_to_pragma_eol (parser);
22283 if (!current_omp_declare_target_attribute)
22284 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
22285 "%<#pragma omp declare target%>");
22286 else
22287 current_omp_declare_target_attribute--;
22288 }
22289
22290
22291 /* OpenMP 4.0
22292 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22293 initializer-clause[opt] new-line
22294
22295 initializer-clause:
22296 initializer (omp_priv = initializer)
22297 initializer (function-name (argument-list)) */
22298
22299 static void
22300 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
22301 {
22302 unsigned int tokens_avail = 0, i;
22303 vec<tree> types = vNULL;
22304 vec<c_token> clauses = vNULL;
22305 enum tree_code reduc_code = ERROR_MARK;
22306 tree reduc_id = NULL_TREE;
22307 tree type;
22308 location_t rloc = c_parser_peek_token (parser)->location;
22309
22310 if (context == pragma_struct || context == pragma_param)
22311 {
22312 error ("%<#pragma omp declare reduction%> not at file or block scope");
22313 goto fail;
22314 }
22315
22316 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22317 goto fail;
22318
22319 switch (c_parser_peek_token (parser)->type)
22320 {
22321 case CPP_PLUS:
22322 reduc_code = PLUS_EXPR;
22323 break;
22324 case CPP_MULT:
22325 reduc_code = MULT_EXPR;
22326 break;
22327 case CPP_MINUS:
22328 reduc_code = MINUS_EXPR;
22329 break;
22330 case CPP_AND:
22331 reduc_code = BIT_AND_EXPR;
22332 break;
22333 case CPP_XOR:
22334 reduc_code = BIT_XOR_EXPR;
22335 break;
22336 case CPP_OR:
22337 reduc_code = BIT_IOR_EXPR;
22338 break;
22339 case CPP_AND_AND:
22340 reduc_code = TRUTH_ANDIF_EXPR;
22341 break;
22342 case CPP_OR_OR:
22343 reduc_code = TRUTH_ORIF_EXPR;
22344 break;
22345 case CPP_NAME:
22346 const char *p;
22347 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22348 if (strcmp (p, "min") == 0)
22349 {
22350 reduc_code = MIN_EXPR;
22351 break;
22352 }
22353 if (strcmp (p, "max") == 0)
22354 {
22355 reduc_code = MAX_EXPR;
22356 break;
22357 }
22358 reduc_id = c_parser_peek_token (parser)->value;
22359 break;
22360 default:
22361 c_parser_error (parser,
22362 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22363 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22364 goto fail;
22365 }
22366
22367 tree orig_reduc_id, reduc_decl;
22368 orig_reduc_id = reduc_id;
22369 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
22370 reduc_decl = c_omp_reduction_decl (reduc_id);
22371 c_parser_consume_token (parser);
22372
22373 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
22374 goto fail;
22375
22376 while (true)
22377 {
22378 location_t loc = c_parser_peek_token (parser)->location;
22379 struct c_type_name *ctype = c_parser_type_name (parser);
22380 if (ctype != NULL)
22381 {
22382 type = groktypename (ctype, NULL, NULL);
22383 if (type == error_mark_node)
22384 ;
22385 else if ((INTEGRAL_TYPE_P (type)
22386 || TREE_CODE (type) == REAL_TYPE
22387 || TREE_CODE (type) == COMPLEX_TYPE)
22388 && orig_reduc_id == NULL_TREE)
22389 error_at (loc, "predeclared arithmetic type in "
22390 "%<#pragma omp declare reduction%>");
22391 else if (TREE_CODE (type) == FUNCTION_TYPE
22392 || TREE_CODE (type) == ARRAY_TYPE)
22393 error_at (loc, "function or array type in "
22394 "%<#pragma omp declare reduction%>");
22395 else if (TYPE_ATOMIC (type))
22396 error_at (loc, "%<_Atomic%> qualified type in "
22397 "%<#pragma omp declare reduction%>");
22398 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
22399 error_at (loc, "const, volatile or restrict qualified type in "
22400 "%<#pragma omp declare reduction%>");
22401 else
22402 {
22403 tree t;
22404 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
22405 if (comptypes (TREE_PURPOSE (t), type))
22406 {
22407 error_at (loc, "redeclaration of %qs "
22408 "%<#pragma omp declare reduction%> for "
22409 "type %qT",
22410 IDENTIFIER_POINTER (reduc_id)
22411 + sizeof ("omp declare reduction ") - 1,
22412 type);
22413 location_t ploc
22414 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
22415 0));
22416 error_at (ploc, "previous %<#pragma omp declare "
22417 "reduction%>");
22418 break;
22419 }
22420 if (t == NULL_TREE)
22421 types.safe_push (type);
22422 }
22423 if (c_parser_next_token_is (parser, CPP_COMMA))
22424 c_parser_consume_token (parser);
22425 else
22426 break;
22427 }
22428 else
22429 break;
22430 }
22431
22432 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
22433 || types.is_empty ())
22434 {
22435 fail:
22436 clauses.release ();
22437 types.release ();
22438 while (true)
22439 {
22440 c_token *token = c_parser_peek_token (parser);
22441 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
22442 break;
22443 c_parser_consume_token (parser);
22444 }
22445 c_parser_skip_to_pragma_eol (parser);
22446 return;
22447 }
22448
22449 if (types.length () > 1)
22450 {
22451 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22452 {
22453 c_token *token = c_parser_peek_token (parser);
22454 if (token->type == CPP_EOF)
22455 goto fail;
22456 clauses.safe_push (*token);
22457 c_parser_consume_token (parser);
22458 }
22459 clauses.safe_push (*c_parser_peek_token (parser));
22460 c_parser_skip_to_pragma_eol (parser);
22461
22462 /* Make sure nothing tries to read past the end of the tokens. */
22463 c_token eof_token;
22464 memset (&eof_token, 0, sizeof (eof_token));
22465 eof_token.type = CPP_EOF;
22466 clauses.safe_push (eof_token);
22467 clauses.safe_push (eof_token);
22468 }
22469
22470 int errs = errorcount;
22471 FOR_EACH_VEC_ELT (types, i, type)
22472 {
22473 tokens_avail = parser->tokens_avail;
22474 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22475 if (!clauses.is_empty ())
22476 {
22477 parser->tokens = clauses.address ();
22478 parser->tokens_avail = clauses.length ();
22479 parser->in_pragma = true;
22480 }
22481
22482 bool nested = current_function_decl != NULL_TREE;
22483 if (nested)
22484 c_push_function_context ();
22485 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
22486 reduc_id, default_function_type);
22487 current_function_decl = fndecl;
22488 allocate_struct_function (fndecl, true);
22489 push_scope ();
22490 tree stmt = push_stmt_list ();
22491 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22492 warn about these. */
22493 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
22494 get_identifier ("omp_out"), type);
22495 DECL_ARTIFICIAL (omp_out) = 1;
22496 DECL_CONTEXT (omp_out) = fndecl;
22497 pushdecl (omp_out);
22498 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
22499 get_identifier ("omp_in"), type);
22500 DECL_ARTIFICIAL (omp_in) = 1;
22501 DECL_CONTEXT (omp_in) = fndecl;
22502 pushdecl (omp_in);
22503 struct c_expr combiner = c_parser_expression (parser);
22504 struct c_expr initializer;
22505 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
22506 bool bad = false;
22507 initializer.set_error ();
22508 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22509 bad = true;
22510 else if (c_parser_next_token_is (parser, CPP_NAME)
22511 && strcmp (IDENTIFIER_POINTER
22512 (c_parser_peek_token (parser)->value),
22513 "initializer") == 0)
22514 {
22515 c_parser_consume_token (parser);
22516 pop_scope ();
22517 push_scope ();
22518 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
22519 get_identifier ("omp_priv"), type);
22520 DECL_ARTIFICIAL (omp_priv) = 1;
22521 DECL_INITIAL (omp_priv) = error_mark_node;
22522 DECL_CONTEXT (omp_priv) = fndecl;
22523 pushdecl (omp_priv);
22524 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
22525 get_identifier ("omp_orig"), type);
22526 DECL_ARTIFICIAL (omp_orig) = 1;
22527 DECL_CONTEXT (omp_orig) = fndecl;
22528 pushdecl (omp_orig);
22529 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22530 bad = true;
22531 else if (!c_parser_next_token_is (parser, CPP_NAME))
22532 {
22533 c_parser_error (parser, "expected %<omp_priv%> or "
22534 "function-name");
22535 bad = true;
22536 }
22537 else if (strcmp (IDENTIFIER_POINTER
22538 (c_parser_peek_token (parser)->value),
22539 "omp_priv") != 0)
22540 {
22541 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
22542 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22543 {
22544 c_parser_error (parser, "expected function-name %<(%>");
22545 bad = true;
22546 }
22547 else
22548 initializer = c_parser_postfix_expression (parser);
22549 if (initializer.value
22550 && TREE_CODE (initializer.value) == CALL_EXPR)
22551 {
22552 int j;
22553 tree c = initializer.value;
22554 for (j = 0; j < call_expr_nargs (c); j++)
22555 {
22556 tree a = CALL_EXPR_ARG (c, j);
22557 STRIP_NOPS (a);
22558 if (TREE_CODE (a) == ADDR_EXPR
22559 && TREE_OPERAND (a, 0) == omp_priv)
22560 break;
22561 }
22562 if (j == call_expr_nargs (c))
22563 error ("one of the initializer call arguments should be "
22564 "%<&omp_priv%>");
22565 }
22566 }
22567 else
22568 {
22569 c_parser_consume_token (parser);
22570 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22571 bad = true;
22572 else
22573 {
22574 tree st = push_stmt_list ();
22575 location_t loc = c_parser_peek_token (parser)->location;
22576 rich_location richloc (line_table, loc);
22577 start_init (omp_priv, NULL_TREE, 0, &richloc);
22578 struct c_expr init = c_parser_initializer (parser);
22579 finish_init ();
22580 finish_decl (omp_priv, loc, init.value,
22581 init.original_type, NULL_TREE);
22582 pop_stmt_list (st);
22583 }
22584 }
22585 if (!bad
22586 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22587 bad = true;
22588 }
22589
22590 if (!bad)
22591 {
22592 c_parser_skip_to_pragma_eol (parser);
22593
22594 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
22595 DECL_INITIAL (reduc_decl));
22596 DECL_INITIAL (reduc_decl) = t;
22597 DECL_SOURCE_LOCATION (omp_out) = rloc;
22598 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
22599 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
22600 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
22601 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
22602 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
22603 if (omp_priv)
22604 {
22605 DECL_SOURCE_LOCATION (omp_priv) = rloc;
22606 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
22607 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
22608 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
22609 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
22610 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22611 walk_tree (&DECL_INITIAL (omp_priv),
22612 c_check_omp_declare_reduction_r,
22613 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22614 }
22615 }
22616
22617 pop_stmt_list (stmt);
22618 pop_scope ();
22619 if (cfun->language != NULL)
22620 {
22621 ggc_free (cfun->language);
22622 cfun->language = NULL;
22623 }
22624 set_cfun (NULL);
22625 current_function_decl = NULL_TREE;
22626 if (nested)
22627 c_pop_function_context ();
22628
22629 if (!clauses.is_empty ())
22630 {
22631 parser->tokens = &parser->tokens_buf[0];
22632 parser->tokens_avail = tokens_avail;
22633 }
22634 if (bad)
22635 goto fail;
22636 if (errs != errorcount)
22637 break;
22638 }
22639
22640 clauses.release ();
22641 types.release ();
22642 }
22643
22644
22645 /* OpenMP 4.0
22646 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22647 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22648 initializer-clause[opt] new-line
22649 #pragma omp declare target new-line
22650
22651 OpenMP 5.0
22652 #pragma omp declare variant (identifier) match (context-selector) */
22653
22654 static bool
22655 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
22656 {
22657 c_parser_consume_pragma (parser);
22658 if (c_parser_next_token_is (parser, CPP_NAME))
22659 {
22660 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22661 if (strcmp (p, "simd") == 0)
22662 {
22663 /* c_parser_consume_token (parser); done in
22664 c_parser_omp_declare_simd. */
22665 c_parser_omp_declare_simd (parser, context);
22666 return true;
22667 }
22668 if (strcmp (p, "reduction") == 0)
22669 {
22670 c_parser_consume_token (parser);
22671 c_parser_omp_declare_reduction (parser, context);
22672 return false;
22673 }
22674 if (!flag_openmp) /* flag_openmp_simd */
22675 {
22676 c_parser_skip_to_pragma_eol (parser, false);
22677 return false;
22678 }
22679 if (strcmp (p, "target") == 0)
22680 {
22681 c_parser_consume_token (parser);
22682 c_parser_omp_declare_target (parser);
22683 return false;
22684 }
22685 if (strcmp (p, "variant") == 0)
22686 {
22687 /* c_parser_consume_token (parser); done in
22688 c_parser_omp_declare_simd. */
22689 c_parser_omp_declare_simd (parser, context);
22690 return true;
22691 }
22692 }
22693
22694 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
22695 "%<target%> or %<variant%>");
22696 c_parser_skip_to_pragma_eol (parser);
22697 return false;
22698 }
22699
22700 /* OpenMP 5.0
22701 #pragma omp requires clauses[optseq] new-line */
22702
22703 static void
22704 c_parser_omp_requires (c_parser *parser)
22705 {
22706 bool first = true;
22707 enum omp_requires new_req = (enum omp_requires) 0;
22708
22709 c_parser_consume_pragma (parser);
22710
22711 location_t loc = c_parser_peek_token (parser)->location;
22712 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22713 {
22714 if (!first
22715 && c_parser_next_token_is (parser, CPP_COMMA)
22716 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22717 c_parser_consume_token (parser);
22718
22719 first = false;
22720
22721 if (c_parser_next_token_is (parser, CPP_NAME))
22722 {
22723 const char *p
22724 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22725 location_t cloc = c_parser_peek_token (parser)->location;
22726 enum omp_requires this_req = (enum omp_requires) 0;
22727
22728 if (!strcmp (p, "unified_address"))
22729 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
22730 else if (!strcmp (p, "unified_shared_memory"))
22731 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
22732 else if (!strcmp (p, "dynamic_allocators"))
22733 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
22734 else if (!strcmp (p, "reverse_offload"))
22735 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
22736 else if (!strcmp (p, "atomic_default_mem_order"))
22737 {
22738 c_parser_consume_token (parser);
22739
22740 matching_parens parens;
22741 if (parens.require_open (parser))
22742 {
22743 if (c_parser_next_token_is (parser, CPP_NAME))
22744 {
22745 tree v = c_parser_peek_token (parser)->value;
22746 p = IDENTIFIER_POINTER (v);
22747
22748 if (!strcmp (p, "seq_cst"))
22749 this_req
22750 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
22751 else if (!strcmp (p, "relaxed"))
22752 this_req
22753 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
22754 else if (!strcmp (p, "acq_rel"))
22755 this_req
22756 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
22757 }
22758 if (this_req == 0)
22759 {
22760 error_at (c_parser_peek_token (parser)->location,
22761 "expected %<seq_cst%>, %<relaxed%> or "
22762 "%<acq_rel%>");
22763 switch (c_parser_peek_token (parser)->type)
22764 {
22765 case CPP_EOF:
22766 case CPP_PRAGMA_EOL:
22767 case CPP_CLOSE_PAREN:
22768 break;
22769 default:
22770 if (c_parser_peek_2nd_token (parser)->type
22771 == CPP_CLOSE_PAREN)
22772 c_parser_consume_token (parser);
22773 break;
22774 }
22775 }
22776 else
22777 c_parser_consume_token (parser);
22778
22779 parens.skip_until_found_close (parser);
22780 if (this_req == 0)
22781 {
22782 c_parser_skip_to_pragma_eol (parser, false);
22783 return;
22784 }
22785 }
22786 p = NULL;
22787 }
22788 else
22789 {
22790 error_at (cloc, "expected %<unified_address%>, "
22791 "%<unified_shared_memory%>, "
22792 "%<dynamic_allocators%>, "
22793 "%<reverse_offload%> "
22794 "or %<atomic_default_mem_order%> clause");
22795 c_parser_skip_to_pragma_eol (parser, false);
22796 return;
22797 }
22798 if (p)
22799 c_parser_consume_token (parser);
22800 if (this_req)
22801 {
22802 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22803 {
22804 if ((this_req & new_req) != 0)
22805 error_at (cloc, "too many %qs clauses", p);
22806 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
22807 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
22808 error_at (cloc, "%qs clause used lexically after first "
22809 "target construct or offloading API", p);
22810 }
22811 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22812 {
22813 error_at (cloc, "too many %qs clauses",
22814 "atomic_default_mem_order");
22815 this_req = (enum omp_requires) 0;
22816 }
22817 else if ((omp_requires_mask
22818 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22819 {
22820 error_at (cloc, "more than one %<atomic_default_mem_order%>"
22821 " clause in a single compilation unit");
22822 this_req
22823 = (enum omp_requires)
22824 (omp_requires_mask
22825 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
22826 }
22827 else if ((omp_requires_mask
22828 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
22829 error_at (cloc, "%<atomic_default_mem_order%> clause used "
22830 "lexically after first %<atomic%> construct "
22831 "without memory order clause");
22832 new_req = (enum omp_requires) (new_req | this_req);
22833 omp_requires_mask
22834 = (enum omp_requires) (omp_requires_mask | this_req);
22835 continue;
22836 }
22837 }
22838 break;
22839 }
22840 c_parser_skip_to_pragma_eol (parser);
22841
22842 if (new_req == 0)
22843 error_at (loc, "%<pragma omp requires%> requires at least one clause");
22844 }
22845
22846 /* Helper function for c_parser_omp_taskloop.
22847 Disallow zero sized or potentially zero sized task reductions. */
22848
22849 static tree
22850 c_finish_taskloop_clauses (tree clauses)
22851 {
22852 tree *pc = &clauses;
22853 for (tree c = clauses; c; c = *pc)
22854 {
22855 bool remove = false;
22856 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
22857 {
22858 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
22859 if (integer_zerop (TYPE_SIZE_UNIT (type)))
22860 {
22861 error_at (OMP_CLAUSE_LOCATION (c),
22862 "zero sized type %qT in %<reduction%> clause", type);
22863 remove = true;
22864 }
22865 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
22866 {
22867 error_at (OMP_CLAUSE_LOCATION (c),
22868 "variable sized type %qT in %<reduction%> clause",
22869 type);
22870 remove = true;
22871 }
22872 }
22873 if (remove)
22874 *pc = OMP_CLAUSE_CHAIN (c);
22875 else
22876 pc = &OMP_CLAUSE_CHAIN (c);
22877 }
22878 return clauses;
22879 }
22880
22881 /* OpenMP 4.5:
22882 #pragma omp taskloop taskloop-clause[optseq] new-line
22883 for-loop
22884
22885 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22886 for-loop */
22887
22888 #define OMP_TASKLOOP_CLAUSE_MASK \
22889 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22894 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
22895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
22896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
22902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22906
22907 static tree
22908 c_parser_omp_taskloop (location_t loc, c_parser *parser,
22909 char *p_name, omp_clause_mask mask, tree *cclauses,
22910 bool *if_p)
22911 {
22912 tree clauses, block, ret;
22913
22914 strcat (p_name, " taskloop");
22915 mask |= OMP_TASKLOOP_CLAUSE_MASK;
22916 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22917 clause. */
22918 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
22919 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
22920
22921 if (c_parser_next_token_is (parser, CPP_NAME))
22922 {
22923 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22924
22925 if (strcmp (p, "simd") == 0)
22926 {
22927 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22928 if (cclauses == NULL)
22929 cclauses = cclauses_buf;
22930 c_parser_consume_token (parser);
22931 if (!flag_openmp) /* flag_openmp_simd */
22932 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22933 if_p);
22934 block = c_begin_compound_stmt (true);
22935 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22936 block = c_end_compound_stmt (loc, block, true);
22937 if (ret == NULL)
22938 return ret;
22939 ret = make_node (OMP_TASKLOOP);
22940 TREE_TYPE (ret) = void_type_node;
22941 OMP_FOR_BODY (ret) = block;
22942 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22943 OMP_FOR_CLAUSES (ret)
22944 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
22945 SET_EXPR_LOCATION (ret, loc);
22946 add_stmt (ret);
22947 return ret;
22948 }
22949 }
22950 if (!flag_openmp) /* flag_openmp_simd */
22951 {
22952 c_parser_skip_to_pragma_eol (parser, false);
22953 return NULL_TREE;
22954 }
22955
22956 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22957 if (cclauses)
22958 {
22959 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
22960 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22961 }
22962
22963 clauses = c_finish_taskloop_clauses (clauses);
22964 block = c_begin_compound_stmt (true);
22965 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
22966 block = c_end_compound_stmt (loc, block, true);
22967 add_stmt (block);
22968
22969 return ret;
22970 }
22971
22972 /* OpenMP 5.1
22973 #pragma omp nothing new-line */
22974
22975 static void
22976 c_parser_omp_nothing (c_parser *parser)
22977 {
22978 c_parser_consume_pragma (parser);
22979 c_parser_skip_to_pragma_eol (parser);
22980 }
22981
22982 /* OpenMP 5.1
22983 #pragma omp error clauses[optseq] new-line */
22984
22985 static bool
22986 c_parser_omp_error (c_parser *parser, enum pragma_context context)
22987 {
22988 int at_compilation = -1;
22989 int severity_fatal = -1;
22990 tree message = NULL_TREE;
22991 bool first = true;
22992 bool bad = false;
22993 location_t loc = c_parser_peek_token (parser)->location;
22994
22995 c_parser_consume_pragma (parser);
22996
22997 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22998 {
22999 if (!first
23000 && c_parser_next_token_is (parser, CPP_COMMA)
23001 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23002 c_parser_consume_token (parser);
23003
23004 first = false;
23005
23006 if (!c_parser_next_token_is (parser, CPP_NAME))
23007 break;
23008
23009 const char *p
23010 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23011 location_t cloc = c_parser_peek_token (parser)->location;
23012 static const char *args[] = {
23013 "execution", "compilation", "warning", "fatal"
23014 };
23015 int *v = NULL;
23016 int idx = 0, n = -1;
23017 tree m = NULL_TREE;
23018
23019 if (!strcmp (p, "at"))
23020 v = &at_compilation;
23021 else if (!strcmp (p, "severity"))
23022 {
23023 v = &severity_fatal;
23024 idx += 2;
23025 }
23026 else if (strcmp (p, "message"))
23027 {
23028 error_at (cloc,
23029 "expected %<at%>, %<severity%> or %<message%> clause");
23030 c_parser_skip_to_pragma_eol (parser, false);
23031 return false;
23032 }
23033
23034 c_parser_consume_token (parser);
23035
23036 matching_parens parens;
23037 if (parens.require_open (parser))
23038 {
23039 if (v == NULL)
23040 {
23041 location_t expr_loc = c_parser_peek_token (parser)->location;
23042 c_expr expr = c_parser_expr_no_commas (parser, NULL);
23043 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
23044 m = convert (const_string_type_node, expr.value);
23045 m = c_fully_fold (m, false, NULL);
23046 }
23047 else
23048 {
23049 if (c_parser_next_token_is (parser, CPP_NAME))
23050 {
23051 tree val = c_parser_peek_token (parser)->value;
23052 const char *q = IDENTIFIER_POINTER (val);
23053
23054 if (!strcmp (q, args[idx]))
23055 n = 0;
23056 else if (!strcmp (q, args[idx + 1]))
23057 n = 1;
23058 }
23059 if (n == -1)
23060 {
23061 error_at (c_parser_peek_token (parser)->location,
23062 "expected %qs or %qs", args[idx], args[idx + 1]);
23063 bad = true;
23064 switch (c_parser_peek_token (parser)->type)
23065 {
23066 case CPP_EOF:
23067 case CPP_PRAGMA_EOL:
23068 case CPP_CLOSE_PAREN:
23069 break;
23070 default:
23071 if (c_parser_peek_2nd_token (parser)->type
23072 == CPP_CLOSE_PAREN)
23073 c_parser_consume_token (parser);
23074 break;
23075 }
23076 }
23077 else
23078 c_parser_consume_token (parser);
23079 }
23080
23081 parens.skip_until_found_close (parser);
23082
23083 if (v == NULL)
23084 {
23085 if (message)
23086 {
23087 error_at (cloc, "too many %qs clauses", p);
23088 bad = true;
23089 }
23090 else
23091 message = m;
23092 }
23093 else if (n != -1)
23094 {
23095 if (*v != -1)
23096 {
23097 error_at (cloc, "too many %qs clauses", p);
23098 bad = true;
23099 }
23100 else
23101 *v = n;
23102 }
23103 }
23104 else
23105 bad = true;
23106 }
23107 c_parser_skip_to_pragma_eol (parser);
23108 if (bad)
23109 return true;
23110
23111 if (at_compilation == -1)
23112 at_compilation = 1;
23113 if (severity_fatal == -1)
23114 severity_fatal = 1;
23115 if (!at_compilation)
23116 {
23117 if (context != pragma_compound)
23118 {
23119 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
23120 "may only be used in compound statements");
23121 return true;
23122 }
23123 tree fndecl
23124 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
23125 : BUILT_IN_GOMP_WARNING);
23126 if (!message)
23127 message = build_zero_cst (const_string_type_node);
23128 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
23129 build_all_ones_cst (size_type_node));
23130 add_stmt (stmt);
23131 return true;
23132 }
23133 const char *msg = NULL;
23134 if (message)
23135 {
23136 msg = c_getstr (message);
23137 if (msg == NULL)
23138 msg = _("<message unknown at compile time>");
23139 }
23140 if (msg)
23141 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23142 "%<pragma omp error%> encountered: %s", msg);
23143 else
23144 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23145 "%<pragma omp error%> encountered");
23146 return false;
23147 }
23148
23149 /* Main entry point to parsing most OpenMP pragmas. */
23150
23151 static void
23152 c_parser_omp_construct (c_parser *parser, bool *if_p)
23153 {
23154 enum pragma_kind p_kind;
23155 location_t loc;
23156 tree stmt;
23157 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
23158 omp_clause_mask mask (0);
23159
23160 loc = c_parser_peek_token (parser)->location;
23161 p_kind = c_parser_peek_token (parser)->pragma_kind;
23162 c_parser_consume_pragma (parser);
23163
23164 switch (p_kind)
23165 {
23166 case PRAGMA_OACC_ATOMIC:
23167 c_parser_omp_atomic (loc, parser, true);
23168 return;
23169 case PRAGMA_OACC_CACHE:
23170 strcpy (p_name, "#pragma acc");
23171 stmt = c_parser_oacc_cache (loc, parser);
23172 break;
23173 case PRAGMA_OACC_DATA:
23174 stmt = c_parser_oacc_data (loc, parser, if_p);
23175 break;
23176 case PRAGMA_OACC_HOST_DATA:
23177 stmt = c_parser_oacc_host_data (loc, parser, if_p);
23178 break;
23179 case PRAGMA_OACC_KERNELS:
23180 case PRAGMA_OACC_PARALLEL:
23181 case PRAGMA_OACC_SERIAL:
23182 strcpy (p_name, "#pragma acc");
23183 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
23184 break;
23185 case PRAGMA_OACC_LOOP:
23186 strcpy (p_name, "#pragma acc");
23187 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
23188 break;
23189 case PRAGMA_OACC_WAIT:
23190 strcpy (p_name, "#pragma wait");
23191 stmt = c_parser_oacc_wait (loc, parser, p_name);
23192 break;
23193 case PRAGMA_OMP_ALLOCATE:
23194 c_parser_omp_allocate (loc, parser);
23195 return;
23196 case PRAGMA_OMP_ATOMIC:
23197 c_parser_omp_atomic (loc, parser, false);
23198 return;
23199 case PRAGMA_OMP_CRITICAL:
23200 stmt = c_parser_omp_critical (loc, parser, if_p);
23201 break;
23202 case PRAGMA_OMP_DISTRIBUTE:
23203 strcpy (p_name, "#pragma omp");
23204 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
23205 break;
23206 case PRAGMA_OMP_FOR:
23207 strcpy (p_name, "#pragma omp");
23208 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
23209 break;
23210 case PRAGMA_OMP_LOOP:
23211 strcpy (p_name, "#pragma omp");
23212 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
23213 break;
23214 case PRAGMA_OMP_MASKED:
23215 strcpy (p_name, "#pragma omp");
23216 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
23217 break;
23218 case PRAGMA_OMP_MASTER:
23219 strcpy (p_name, "#pragma omp");
23220 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
23221 break;
23222 case PRAGMA_OMP_PARALLEL:
23223 strcpy (p_name, "#pragma omp");
23224 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
23225 break;
23226 case PRAGMA_OMP_SCOPE:
23227 stmt = c_parser_omp_scope (loc, parser, if_p);
23228 break;
23229 case PRAGMA_OMP_SECTIONS:
23230 strcpy (p_name, "#pragma omp");
23231 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
23232 break;
23233 case PRAGMA_OMP_SIMD:
23234 strcpy (p_name, "#pragma omp");
23235 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
23236 break;
23237 case PRAGMA_OMP_SINGLE:
23238 stmt = c_parser_omp_single (loc, parser, if_p);
23239 break;
23240 case PRAGMA_OMP_TASK:
23241 stmt = c_parser_omp_task (loc, parser, if_p);
23242 break;
23243 case PRAGMA_OMP_TASKGROUP:
23244 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
23245 break;
23246 case PRAGMA_OMP_TASKLOOP:
23247 strcpy (p_name, "#pragma omp");
23248 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
23249 break;
23250 case PRAGMA_OMP_TEAMS:
23251 strcpy (p_name, "#pragma omp");
23252 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
23253 break;
23254 default:
23255 gcc_unreachable ();
23256 }
23257
23258 if (stmt && stmt != error_mark_node)
23259 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
23260 }
23261
23262
23263 /* OpenMP 2.5:
23264 # pragma omp threadprivate (variable-list) */
23265
23266 static void
23267 c_parser_omp_threadprivate (c_parser *parser)
23268 {
23269 tree vars, t;
23270 location_t loc;
23271
23272 c_parser_consume_pragma (parser);
23273 loc = c_parser_peek_token (parser)->location;
23274 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
23275
23276 /* Mark every variable in VARS to be assigned thread local storage. */
23277 for (t = vars; t; t = TREE_CHAIN (t))
23278 {
23279 tree v = TREE_PURPOSE (t);
23280
23281 /* FIXME diagnostics: Ideally we should keep individual
23282 locations for all the variables in the var list to make the
23283 following errors more precise. Perhaps
23284 c_parser_omp_var_list_parens() should construct a list of
23285 locations to go along with the var list. */
23286
23287 /* If V had already been marked threadprivate, it doesn't matter
23288 whether it had been used prior to this point. */
23289 if (!VAR_P (v))
23290 error_at (loc, "%qD is not a variable", v);
23291 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
23292 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
23293 else if (! is_global_var (v))
23294 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
23295 else if (TREE_TYPE (v) == error_mark_node)
23296 ;
23297 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
23298 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
23299 else
23300 {
23301 if (! DECL_THREAD_LOCAL_P (v))
23302 {
23303 set_decl_tls_model (v, decl_default_tls_model (v));
23304 /* If rtl has been already set for this var, call
23305 make_decl_rtl once again, so that encode_section_info
23306 has a chance to look at the new decl flags. */
23307 if (DECL_RTL_SET_P (v))
23308 make_decl_rtl (v);
23309 }
23310 C_DECL_THREADPRIVATE_P (v) = 1;
23311 }
23312 }
23313
23314 c_parser_skip_to_pragma_eol (parser);
23315 }
23316
23317 /* Parse a transaction attribute (GCC Extension).
23318
23319 transaction-attribute:
23320 gnu-attributes
23321 attribute-specifier
23322 */
23323
23324 static tree
23325 c_parser_transaction_attributes (c_parser *parser)
23326 {
23327 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
23328 return c_parser_gnu_attributes (parser);
23329
23330 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
23331 return NULL_TREE;
23332 return c_parser_std_attribute_specifier (parser, true);
23333 }
23334
23335 /* Parse a __transaction_atomic or __transaction_relaxed statement
23336 (GCC Extension).
23337
23338 transaction-statement:
23339 __transaction_atomic transaction-attribute[opt] compound-statement
23340 __transaction_relaxed compound-statement
23341
23342 Note that the only valid attribute is: "outer".
23343 */
23344
23345 static tree
23346 c_parser_transaction (c_parser *parser, enum rid keyword)
23347 {
23348 unsigned int old_in = parser->in_transaction;
23349 unsigned int this_in = 1, new_in;
23350 location_t loc = c_parser_peek_token (parser)->location;
23351 tree stmt, attrs;
23352
23353 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23354 || keyword == RID_TRANSACTION_RELAXED)
23355 && c_parser_next_token_is_keyword (parser, keyword));
23356 c_parser_consume_token (parser);
23357
23358 if (keyword == RID_TRANSACTION_RELAXED)
23359 this_in |= TM_STMT_ATTR_RELAXED;
23360 else
23361 {
23362 attrs = c_parser_transaction_attributes (parser);
23363 if (attrs)
23364 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
23365 }
23366
23367 /* Keep track if we're in the lexical scope of an outer transaction. */
23368 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
23369
23370 parser->in_transaction = new_in;
23371 stmt = c_parser_compound_statement (parser);
23372 parser->in_transaction = old_in;
23373
23374 if (flag_tm)
23375 stmt = c_finish_transaction (loc, stmt, this_in);
23376 else
23377 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23378 "%<__transaction_atomic%> without transactional memory support enabled"
23379 : "%<__transaction_relaxed %> "
23380 "without transactional memory support enabled"));
23381
23382 return stmt;
23383 }
23384
23385 /* Parse a __transaction_atomic or __transaction_relaxed expression
23386 (GCC Extension).
23387
23388 transaction-expression:
23389 __transaction_atomic ( expression )
23390 __transaction_relaxed ( expression )
23391 */
23392
23393 static struct c_expr
23394 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
23395 {
23396 struct c_expr ret;
23397 unsigned int old_in = parser->in_transaction;
23398 unsigned int this_in = 1;
23399 location_t loc = c_parser_peek_token (parser)->location;
23400 tree attrs;
23401
23402 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23403 || keyword == RID_TRANSACTION_RELAXED)
23404 && c_parser_next_token_is_keyword (parser, keyword));
23405 c_parser_consume_token (parser);
23406
23407 if (keyword == RID_TRANSACTION_RELAXED)
23408 this_in |= TM_STMT_ATTR_RELAXED;
23409 else
23410 {
23411 attrs = c_parser_transaction_attributes (parser);
23412 if (attrs)
23413 this_in |= parse_tm_stmt_attr (attrs, 0);
23414 }
23415
23416 parser->in_transaction = this_in;
23417 matching_parens parens;
23418 if (parens.require_open (parser))
23419 {
23420 tree expr = c_parser_expression (parser).value;
23421 ret.original_type = TREE_TYPE (expr);
23422 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
23423 if (this_in & TM_STMT_ATTR_RELAXED)
23424 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
23425 SET_EXPR_LOCATION (ret.value, loc);
23426 ret.original_code = TRANSACTION_EXPR;
23427 if (!parens.require_close (parser))
23428 {
23429 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
23430 goto error;
23431 }
23432 }
23433 else
23434 {
23435 error:
23436 ret.set_error ();
23437 ret.original_code = ERROR_MARK;
23438 ret.original_type = NULL;
23439 }
23440 parser->in_transaction = old_in;
23441
23442 if (!flag_tm)
23443 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23444 "%<__transaction_atomic%> without transactional memory support enabled"
23445 : "%<__transaction_relaxed %> "
23446 "without transactional memory support enabled"));
23447
23448 set_c_expr_source_range (&ret, loc, loc);
23449
23450 return ret;
23451 }
23452
23453 /* Parse a __transaction_cancel statement (GCC Extension).
23454
23455 transaction-cancel-statement:
23456 __transaction_cancel transaction-attribute[opt] ;
23457
23458 Note that the only valid attribute is "outer".
23459 */
23460
23461 static tree
23462 c_parser_transaction_cancel (c_parser *parser)
23463 {
23464 location_t loc = c_parser_peek_token (parser)->location;
23465 tree attrs;
23466 bool is_outer = false;
23467
23468 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
23469 c_parser_consume_token (parser);
23470
23471 attrs = c_parser_transaction_attributes (parser);
23472 if (attrs)
23473 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
23474
23475 if (!flag_tm)
23476 {
23477 error_at (loc, "%<__transaction_cancel%> without "
23478 "transactional memory support enabled");
23479 goto ret_error;
23480 }
23481 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
23482 {
23483 error_at (loc, "%<__transaction_cancel%> within a "
23484 "%<__transaction_relaxed%>");
23485 goto ret_error;
23486 }
23487 else if (is_outer)
23488 {
23489 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
23490 && !is_tm_may_cancel_outer (current_function_decl))
23491 {
23492 error_at (loc, "outer %<__transaction_cancel%> not "
23493 "within outer %<__transaction_atomic%> or "
23494 "a %<transaction_may_cancel_outer%> function");
23495 goto ret_error;
23496 }
23497 }
23498 else if (parser->in_transaction == 0)
23499 {
23500 error_at (loc, "%<__transaction_cancel%> not within "
23501 "%<__transaction_atomic%>");
23502 goto ret_error;
23503 }
23504
23505 return add_stmt (build_tm_abort_call (loc, is_outer));
23506
23507 ret_error:
23508 return build1 (NOP_EXPR, void_type_node, error_mark_node);
23509 }
23510 \f
23511 /* Parse a single source file. */
23512
23513 void
23514 c_parse_file (void)
23515 {
23516 /* Use local storage to begin. If the first token is a pragma, parse it.
23517 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23518 which will cause garbage collection. */
23519 c_parser tparser;
23520
23521 memset (&tparser, 0, sizeof tparser);
23522 tparser.translate_strings_p = true;
23523 tparser.tokens = &tparser.tokens_buf[0];
23524 the_parser = &tparser;
23525
23526 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
23527 c_parser_pragma_pch_preprocess (&tparser);
23528 else
23529 c_common_no_more_pch ();
23530
23531 the_parser = ggc_alloc<c_parser> ();
23532 *the_parser = tparser;
23533 if (tparser.tokens == &tparser.tokens_buf[0])
23534 the_parser->tokens = &the_parser->tokens_buf[0];
23535
23536 /* Initialize EH, if we've been told to do so. */
23537 if (flag_exceptions)
23538 using_eh_for_cleanups ();
23539
23540 c_parser_translation_unit (the_parser);
23541 the_parser = NULL;
23542 }
23543
23544 /* Parse the body of a function declaration marked with "__RTL".
23545
23546 The RTL parser works on the level of characters read from a
23547 FILE *, whereas c_parser works at the level of tokens.
23548 Square this circle by consuming all of the tokens up to and
23549 including the closing brace, recording the start/end of the RTL
23550 fragment, and reopening the file and re-reading the relevant
23551 lines within the RTL parser.
23552
23553 This requires the opening and closing braces of the C function
23554 to be on separate lines from the RTL they wrap.
23555
23556 Take ownership of START_WITH_PASS, if non-NULL. */
23557
23558 location_t
23559 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
23560 {
23561 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23562 {
23563 free (start_with_pass);
23564 return c_parser_peek_token (parser)->location;
23565 }
23566
23567 location_t start_loc = c_parser_peek_token (parser)->location;
23568
23569 /* Consume all tokens, up to the closing brace, handling
23570 matching pairs of braces in the rtl dump. */
23571 int num_open_braces = 1;
23572 while (1)
23573 {
23574 switch (c_parser_peek_token (parser)->type)
23575 {
23576 case CPP_OPEN_BRACE:
23577 num_open_braces++;
23578 break;
23579 case CPP_CLOSE_BRACE:
23580 if (--num_open_braces == 0)
23581 goto found_closing_brace;
23582 break;
23583 case CPP_EOF:
23584 error_at (start_loc, "no closing brace");
23585 free (start_with_pass);
23586 return c_parser_peek_token (parser)->location;
23587 default:
23588 break;
23589 }
23590 c_parser_consume_token (parser);
23591 }
23592
23593 found_closing_brace:
23594 /* At the closing brace; record its location. */
23595 location_t end_loc = c_parser_peek_token (parser)->location;
23596
23597 /* Consume the closing brace. */
23598 c_parser_consume_token (parser);
23599
23600 /* Invoke the RTL parser. */
23601 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
23602 {
23603 free (start_with_pass);
23604 return end_loc;
23605 }
23606
23607 /* Run the backend on the cfun created above, transferring ownership of
23608 START_WITH_PASS. */
23609 run_rtl_passes (start_with_pass);
23610 return end_loc;
23611 }
23612
23613 #include "gt-c-c-parser.h"