c: Improve some diagnostics for __builtin_stdc_bit_* [PR114042]
[official-gcc.git] / gcc / c / c-parser.cc
blob53e99aa29d9695d4e32abb5c8f6527fce1c1b8e2
1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2024 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
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.
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.
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/>. */
23 /* TODO:
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.
29 Add testcases covering every input symbol in every state in old and
30 new parsers.
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
38 #include "config.h"
39 #define INCLUDE_MEMORY
40 #include "system.h"
41 #include "coretypes.h"
42 #include "target.h"
43 #include "function.h"
44 #include "c-tree.h"
45 #include "timevar.h"
46 #include "stringpool.h"
47 #include "cgraph.h"
48 #include "attribs.h"
49 #include "stor-layout.h"
50 #include "varasm.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
53 #include "c-lang.h"
54 #include "c-family/c-objc.h"
55 #include "plugin.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
58 #include "builtins.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
62 #include "context.h"
63 #include "gcc-rich-location.h"
64 #include "c-parser.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
68 #include "intl.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
72 #include "memmodel.h"
73 #include "c-family/known-headers.h"
74 #include "bitmap.h"
75 #include "analyzer/analyzer-language.h"
76 #include "toplev.h"
78 /* We need to walk over decls with incomplete struct/union/enum types
79 after parsing the whole translation unit.
80 In finish_decl(), if the decl is static, has incomplete
81 struct/union/enum type, it is appended to incomplete_record_decls.
82 In c_parser_translation_unit(), we iterate over incomplete_record_decls
83 and report error if any of the decls are still incomplete. */
85 vec<tree> incomplete_record_decls;
87 void
88 set_c_expr_source_range (c_expr *expr,
89 location_t start, location_t finish)
91 expr->src_range.m_start = start;
92 expr->src_range.m_finish = finish;
93 if (expr->value)
94 set_source_range (expr->value, start, finish);
97 void
98 set_c_expr_source_range (c_expr *expr,
99 source_range src_range)
101 expr->src_range = src_range;
102 if (expr->value)
103 set_source_range (expr->value, src_range);
107 /* Initialization routine for this file. */
109 void
110 c_parse_init (void)
112 /* The only initialization required is of the reserved word
113 identifiers. */
114 unsigned int i;
115 tree id;
116 int mask = 0;
118 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
119 the c_token structure. */
120 gcc_assert (RID_MAX <= 255);
122 mask |= D_CXXONLY;
123 if (!flag_isoc99)
124 mask |= D_C99;
125 if (!flag_isoc23)
126 mask |= D_C23;
127 if (flag_no_asm)
129 mask |= D_ASM | D_EXT;
130 if (!flag_isoc99)
131 mask |= D_EXT89;
132 if (!flag_isoc23)
133 mask |= D_EXT11;
135 if (!c_dialect_objc ())
136 mask |= D_OBJC | D_CXX_OBJC;
138 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
139 for (i = 0; i < num_c_common_reswords; i++)
141 /* If a keyword is disabled, do not enter it into the table
142 and so create a canonical spelling that isn't a keyword. */
143 if (c_common_reswords[i].disable & mask)
145 if (warn_cxx_compat
146 && (c_common_reswords[i].disable & D_CXXWARN))
148 id = get_identifier (c_common_reswords[i].word);
149 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
150 C_IS_RESERVED_WORD (id) = 1;
152 continue;
155 id = get_identifier (c_common_reswords[i].word);
156 C_SET_RID_CODE (id, c_common_reswords[i].rid);
157 C_IS_RESERVED_WORD (id) = 1;
158 ridpointers [(int) c_common_reswords[i].rid] = id;
161 for (i = 0; i < NUM_INT_N_ENTS; i++)
163 /* We always create the symbols but they aren't always supported. */
164 char name[50];
165 sprintf (name, "__int%d", int_n_data[i].bitsize);
166 id = get_identifier (name);
167 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
168 C_IS_RESERVED_WORD (id) = 1;
170 sprintf (name, "__int%d__", int_n_data[i].bitsize);
171 id = get_identifier (name);
172 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
173 C_IS_RESERVED_WORD (id) = 1;
176 if (flag_openmp)
178 id = get_identifier ("omp_all_memory");
179 C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
180 C_IS_RESERVED_WORD (id) = 1;
181 ridpointers [RID_OMP_ALL_MEMORY] = id;
185 /* A parser structure recording information about the state and
186 context of parsing. Includes lexer information with up to two
187 tokens of look-ahead; more are not needed for C. */
188 struct GTY(()) c_parser {
189 /* The look-ahead tokens. */
190 c_token * GTY((skip)) tokens;
191 /* Buffer for look-ahead tokens. */
192 c_token tokens_buf[4];
193 /* How many look-ahead tokens are available (0 - 4, or
194 more if parsing from pre-lexed tokens). */
195 unsigned int tokens_avail;
196 /* Raw look-ahead tokens, used only for checking in Objective-C
197 whether '[[' starts attributes. */
198 vec<c_token, va_gc> *raw_tokens;
199 /* The number of raw look-ahead tokens that have since been fully
200 lexed. */
201 unsigned int raw_tokens_used;
202 /* True if a syntax error is being recovered from; false otherwise.
203 c_parser_error sets this flag. It should clear this flag when
204 enough tokens have been consumed to recover from the error. */
205 BOOL_BITFIELD error : 1;
206 /* True if we're processing a pragma, and shouldn't automatically
207 consume CPP_PRAGMA_EOL. */
208 BOOL_BITFIELD in_pragma : 1;
209 /* True if we're parsing the outermost block of an if statement. */
210 BOOL_BITFIELD in_if_block : 1;
211 /* True if we want to lex a translated, joined string (for an
212 initial #pragma pch_preprocess). Otherwise the parser is
213 responsible for concatenating strings and translating to the
214 execution character set as needed. */
215 BOOL_BITFIELD lex_joined_string : 1;
216 /* True if, when the parser is concatenating string literals, it
217 should translate them to the execution character set (false
218 inside attributes). */
219 BOOL_BITFIELD translate_strings_p : 1;
221 /* Objective-C specific parser/lexer information. */
223 /* True if we are in a context where the Objective-C "PQ" keywords
224 are considered keywords. */
225 BOOL_BITFIELD objc_pq_context : 1;
226 /* True if we are parsing a (potential) Objective-C foreach
227 statement. This is set to true after we parsed 'for (' and while
228 we wait for 'in' or ';' to decide if it's a standard C for loop or an
229 Objective-C foreach loop. */
230 BOOL_BITFIELD objc_could_be_foreach_context : 1;
231 /* The following flag is needed to contextualize Objective-C lexical
232 analysis. In some cases (e.g., 'int NSObject;'), it is
233 undesirable to bind an identifier to an Objective-C class, even
234 if a class with that name exists. */
235 BOOL_BITFIELD objc_need_raw_identifier : 1;
236 /* Nonzero if we're processing a __transaction statement. The value
237 is 1 | TM_STMT_ATTR_*. */
238 unsigned int in_transaction : 4;
239 /* True if we are in a context where the Objective-C "Property attribute"
240 keywords are valid. */
241 BOOL_BITFIELD objc_property_attr_context : 1;
243 /* Whether we have just seen/constructed a string-literal. Set when
244 returning a string-literal from c_parser_string_literal. Reset
245 in consume_token. Useful when we get a parse error and see an
246 unknown token, which could have been a string-literal constant
247 macro. */
248 BOOL_BITFIELD seen_string_literal : 1;
250 /* TRUE if omp::directive, omp::decl or omp::sequence attributes may not
251 appear. */
252 BOOL_BITFIELD omp_attrs_forbidden_p : 1;
254 /* Location of the last consumed token. */
255 location_t last_token_location;
257 /* Holds state for parsing collapsed OMP_FOR loops. Managed by
258 c_parser_omp_for_loop. */
259 struct omp_for_parse_data * GTY((skip)) omp_for_parse_state;
261 /* If we're in the context of OpenMP directives written as C23
262 attributes turned into pragma, vector of tokens created from that,
263 otherwise NULL. */
264 vec<c_token, va_gc> *in_omp_attribute_pragma;
266 /* Set for omp::decl attribute parsing to the decl to which it
267 appertains. */
268 tree in_omp_decl_attribute;
271 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
273 c_token *
274 c_parser_tokens_buf (c_parser *parser, unsigned n)
276 return &parser->tokens_buf[n];
279 /* Return the error state of PARSER. */
281 bool
282 c_parser_error (c_parser *parser)
284 return parser->error;
287 /* Set the error state of PARSER to ERR. */
289 void
290 c_parser_set_error (c_parser *parser, bool err)
292 parser->error = err;
296 /* The actual parser and external interface. ??? Does this need to be
297 garbage-collected? */
299 static GTY (()) c_parser *the_parser;
301 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
302 context-sensitive postprocessing of the token is not done. */
304 static void
305 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
307 timevar_push (TV_LEX);
309 if (raw || vec_safe_length (parser->raw_tokens) == 0)
311 token->type = c_lex_with_flags (&token->value, &token->location,
312 &token->flags,
313 (parser->lex_joined_string
314 ? 0 : C_LEX_STRING_NO_JOIN));
315 token->id_kind = C_ID_NONE;
316 token->keyword = RID_MAX;
317 token->pragma_kind = PRAGMA_NONE;
319 else
321 /* Use a token previously lexed as a raw look-ahead token, and
322 complete the processing on it. */
323 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
324 ++parser->raw_tokens_used;
325 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
327 vec_free (parser->raw_tokens);
328 parser->raw_tokens_used = 0;
332 if (raw)
333 goto out;
335 switch (token->type)
337 case CPP_NAME:
339 tree decl;
341 bool objc_force_identifier = parser->objc_need_raw_identifier;
342 if (c_dialect_objc ())
343 parser->objc_need_raw_identifier = false;
345 if (C_IS_RESERVED_WORD (token->value))
347 enum rid rid_code = C_RID_CODE (token->value);
349 if (rid_code == RID_CXX_COMPAT_WARN)
351 warning_at (token->location,
352 OPT_Wc___compat,
353 "identifier %qE conflicts with C++ keyword",
354 token->value);
356 else if (rid_code >= RID_FIRST_ADDR_SPACE
357 && rid_code <= RID_LAST_ADDR_SPACE)
359 addr_space_t as;
360 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
361 targetm.addr_space.diagnose_usage (as, token->location);
362 token->id_kind = C_ID_ADDRSPACE;
363 token->keyword = rid_code;
364 break;
366 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
368 /* We found an Objective-C "pq" keyword (in, out,
369 inout, bycopy, byref, oneway). They need special
370 care because the interpretation depends on the
371 context. */
372 if (parser->objc_pq_context)
374 token->type = CPP_KEYWORD;
375 token->keyword = rid_code;
376 break;
378 else if (parser->objc_could_be_foreach_context
379 && rid_code == RID_IN)
381 /* We are in Objective-C, inside a (potential)
382 foreach context (which means after having
383 parsed 'for (', but before having parsed ';'),
384 and we found 'in'. We consider it the keyword
385 which terminates the declaration at the
386 beginning of a foreach-statement. Note that
387 this means you can't use 'in' for anything else
388 in that context; in particular, in Objective-C
389 you can't use 'in' as the name of the running
390 variable in a C for loop. We could potentially
391 try to add code here to disambiguate, but it
392 seems a reasonable limitation. */
393 token->type = CPP_KEYWORD;
394 token->keyword = rid_code;
395 break;
397 /* Else, "pq" keywords outside of the "pq" context are
398 not keywords, and we fall through to the code for
399 normal tokens. */
401 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
403 /* We found an Objective-C "property attribute"
404 keyword (getter, setter, readonly, etc). These are
405 only valid in the property context. */
406 if (parser->objc_property_attr_context)
408 token->type = CPP_KEYWORD;
409 token->keyword = rid_code;
410 break;
412 /* Else they are not special keywords.
415 else if (c_dialect_objc ()
416 && (OBJC_IS_AT_KEYWORD (rid_code)
417 || OBJC_IS_CXX_KEYWORD (rid_code)))
419 /* We found one of the Objective-C "@" keywords (defs,
420 selector, synchronized, etc) or one of the
421 Objective-C "cxx" keywords (class, private,
422 protected, public, try, catch, throw) without a
423 preceding '@' sign. Do nothing and fall through to
424 the code for normal tokens (in C++ we would still
425 consider the CXX ones keywords, but not in C). */
428 else
430 token->type = CPP_KEYWORD;
431 token->keyword = rid_code;
432 break;
436 decl = lookup_name (token->value);
437 if (decl)
439 if (TREE_CODE (decl) == TYPE_DECL)
441 token->id_kind = C_ID_TYPENAME;
442 break;
445 else if (c_dialect_objc ())
447 tree objc_interface_decl = objc_is_class_name (token->value);
448 /* Objective-C class names are in the same namespace as
449 variables and typedefs, and hence are shadowed by local
450 declarations. */
451 if (objc_interface_decl
452 && (!objc_force_identifier || global_bindings_p ()))
454 token->value = objc_interface_decl;
455 token->id_kind = C_ID_CLASSNAME;
456 break;
459 token->id_kind = C_ID_ID;
461 break;
462 case CPP_AT_NAME:
463 /* This only happens in Objective-C; it must be a keyword. */
464 token->type = CPP_KEYWORD;
465 switch (C_RID_CODE (token->value))
467 /* Replace 'class' with '@class', 'private' with '@private',
468 etc. This prevents confusion with the C++ keyword
469 'class', and makes the tokens consistent with other
470 Objective-C 'AT' keywords. For example '@class' is
471 reported as RID_AT_CLASS which is consistent with
472 '@synchronized', which is reported as
473 RID_AT_SYNCHRONIZED.
475 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
476 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
477 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
478 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
479 case RID_THROW: token->keyword = RID_AT_THROW; break;
480 case RID_TRY: token->keyword = RID_AT_TRY; break;
481 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
482 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
483 default: token->keyword = C_RID_CODE (token->value);
485 break;
486 case CPP_COLON:
487 case CPP_COMMA:
488 case CPP_CLOSE_PAREN:
489 case CPP_SEMICOLON:
490 /* These tokens may affect the interpretation of any identifiers
491 following, if doing Objective-C. */
492 if (c_dialect_objc ())
493 parser->objc_need_raw_identifier = false;
494 break;
495 case CPP_PRAGMA:
496 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
497 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
498 token->value = NULL;
499 break;
500 default:
501 break;
503 out:
504 timevar_pop (TV_LEX);
507 /* Return a pointer to the next token from PARSER, reading it in if
508 necessary. */
510 c_token *
511 c_parser_peek_token (c_parser *parser)
513 if (parser->tokens_avail == 0)
515 c_lex_one_token (parser, &parser->tokens[0]);
516 parser->tokens_avail = 1;
518 return &parser->tokens[0];
521 /* Return a pointer to the next-but-one token from PARSER, reading it
522 in if necessary. The next token is already read in. */
524 c_token *
525 c_parser_peek_2nd_token (c_parser *parser)
527 if (parser->tokens_avail >= 2)
528 return &parser->tokens[1];
529 gcc_assert (parser->tokens_avail == 1);
530 gcc_assert (parser->tokens[0].type != CPP_EOF);
531 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
532 c_lex_one_token (parser, &parser->tokens[1]);
533 parser->tokens_avail = 2;
534 return &parser->tokens[1];
537 /* Return a pointer to the Nth token from PARSER, reading it
538 in if necessary. The N-1th token is already read in. */
540 c_token *
541 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
543 /* N is 1-based, not zero-based. */
544 gcc_assert (n > 0);
546 if (parser->tokens_avail >= n)
547 return &parser->tokens[n - 1];
548 gcc_assert (parser->tokens_avail == n - 1);
549 c_lex_one_token (parser, &parser->tokens[n - 1]);
550 parser->tokens_avail = n;
551 return &parser->tokens[n - 1];
554 /* Return a pointer to the Nth token from PARSER, reading it in as a
555 raw look-ahead token if necessary. The N-1th token is already read
556 in. Raw look-ahead tokens remain available for when the non-raw
557 functions above are called. */
559 c_token *
560 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
562 /* N is 1-based, not zero-based. */
563 gcc_assert (n > 0);
565 if (parser->tokens_avail >= n)
566 return &parser->tokens[n - 1];
567 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
568 unsigned int raw_avail
569 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
570 gcc_assert (raw_avail >= n - 1);
571 if (raw_avail >= n)
572 return &(*parser->raw_tokens)[parser->raw_tokens_used
573 + n - 1 - parser->tokens_avail];
574 vec_safe_reserve (parser->raw_tokens, 1);
575 parser->raw_tokens->quick_grow (raw_len + 1);
576 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
577 return &(*parser->raw_tokens)[raw_len];
580 bool
581 c_keyword_starts_typename (enum rid keyword)
583 switch (keyword)
585 case RID_UNSIGNED:
586 case RID_LONG:
587 case RID_SHORT:
588 case RID_SIGNED:
589 case RID_COMPLEX:
590 case RID_INT:
591 case RID_CHAR:
592 case RID_FLOAT:
593 case RID_DOUBLE:
594 case RID_VOID:
595 case RID_DFLOAT32:
596 case RID_DFLOAT64:
597 case RID_DFLOAT128:
598 CASE_RID_FLOATN_NX:
599 case RID_BOOL:
600 case RID_BITINT:
601 case RID_ENUM:
602 case RID_STRUCT:
603 case RID_UNION:
604 case RID_TYPEOF:
605 case RID_TYPEOF_UNQUAL:
606 case RID_CONST:
607 case RID_ATOMIC:
608 case RID_VOLATILE:
609 case RID_RESTRICT:
610 case RID_ATTRIBUTE:
611 case RID_FRACT:
612 case RID_ACCUM:
613 case RID_SAT:
614 case RID_AUTO_TYPE:
615 case RID_ALIGNAS:
616 return true;
617 default:
618 if (keyword >= RID_FIRST_INT_N
619 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
620 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
621 return true;
622 return false;
626 /* Return true if TOKEN can start a type name,
627 false otherwise. */
628 bool
629 c_token_starts_typename (c_token *token)
631 switch (token->type)
633 case CPP_NAME:
634 switch (token->id_kind)
636 case C_ID_ID:
637 return false;
638 case C_ID_ADDRSPACE:
639 return true;
640 case C_ID_TYPENAME:
641 return true;
642 case C_ID_CLASSNAME:
643 gcc_assert (c_dialect_objc ());
644 return true;
645 default:
646 gcc_unreachable ();
648 case CPP_KEYWORD:
649 return c_keyword_starts_typename (token->keyword);
650 case CPP_LESS:
651 if (c_dialect_objc ())
652 return true;
653 return false;
654 default:
655 return false;
659 /* Return true if the next token from PARSER can start a type name,
660 false otherwise. LA specifies how to do lookahead in order to
661 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
663 static inline bool
664 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
666 c_token *token = c_parser_peek_token (parser);
667 if (c_token_starts_typename (token))
668 return true;
670 /* Try a bit harder to detect an unknown typename. */
671 if (la != cla_prefer_id
672 && token->type == CPP_NAME
673 && token->id_kind == C_ID_ID
675 /* Do not try too hard when we could have "object in array". */
676 && !parser->objc_could_be_foreach_context
678 && (la == cla_prefer_type
679 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
680 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
682 /* Only unknown identifiers. */
683 && !lookup_name (token->value))
684 return true;
686 return false;
689 /* Return true if TOKEN, after an open parenthesis, can start a
690 compound literal (either a storage class specifier allowed in that
691 context, or a type name), false otherwise. */
692 static bool
693 c_token_starts_compound_literal (c_token *token)
695 switch (token->type)
697 case CPP_KEYWORD:
698 switch (token->keyword)
700 case RID_CONSTEXPR:
701 case RID_REGISTER:
702 case RID_STATIC:
703 case RID_THREAD:
704 return true;
705 default:
706 break;
708 /* Fall through. */
709 default:
710 return c_token_starts_typename (token);
714 /* Return true if TOKEN is a type qualifier, false otherwise. */
715 static bool
716 c_token_is_qualifier (c_token *token)
718 switch (token->type)
720 case CPP_NAME:
721 switch (token->id_kind)
723 case C_ID_ADDRSPACE:
724 return true;
725 default:
726 return false;
728 case CPP_KEYWORD:
729 switch (token->keyword)
731 case RID_CONST:
732 case RID_VOLATILE:
733 case RID_RESTRICT:
734 case RID_ATTRIBUTE:
735 case RID_ATOMIC:
736 return true;
737 default:
738 return false;
740 case CPP_LESS:
741 return false;
742 default:
743 gcc_unreachable ();
747 /* Return true if the next token from PARSER is a type qualifier,
748 false otherwise. */
749 static inline bool
750 c_parser_next_token_is_qualifier (c_parser *parser)
752 c_token *token = c_parser_peek_token (parser);
753 return c_token_is_qualifier (token);
756 /* Return true if TOKEN can start declaration specifiers (not
757 including standard attributes), false otherwise. */
758 static bool
759 c_token_starts_declspecs (c_token *token)
761 switch (token->type)
763 case CPP_NAME:
764 switch (token->id_kind)
766 case C_ID_ID:
767 return false;
768 case C_ID_ADDRSPACE:
769 return true;
770 case C_ID_TYPENAME:
771 return true;
772 case C_ID_CLASSNAME:
773 gcc_assert (c_dialect_objc ());
774 return true;
775 default:
776 gcc_unreachable ();
778 case CPP_KEYWORD:
779 switch (token->keyword)
781 case RID_STATIC:
782 case RID_EXTERN:
783 case RID_REGISTER:
784 case RID_TYPEDEF:
785 case RID_INLINE:
786 case RID_NORETURN:
787 case RID_AUTO:
788 case RID_THREAD:
789 case RID_UNSIGNED:
790 case RID_LONG:
791 case RID_SHORT:
792 case RID_SIGNED:
793 case RID_COMPLEX:
794 case RID_INT:
795 case RID_CHAR:
796 case RID_FLOAT:
797 case RID_DOUBLE:
798 case RID_VOID:
799 case RID_DFLOAT32:
800 case RID_DFLOAT64:
801 case RID_DFLOAT128:
802 CASE_RID_FLOATN_NX:
803 case RID_BOOL:
804 case RID_BITINT:
805 case RID_ENUM:
806 case RID_STRUCT:
807 case RID_UNION:
808 case RID_TYPEOF:
809 case RID_TYPEOF_UNQUAL:
810 case RID_CONST:
811 case RID_VOLATILE:
812 case RID_RESTRICT:
813 case RID_ATTRIBUTE:
814 case RID_FRACT:
815 case RID_ACCUM:
816 case RID_SAT:
817 case RID_ALIGNAS:
818 case RID_ATOMIC:
819 case RID_AUTO_TYPE:
820 case RID_CONSTEXPR:
821 return true;
822 default:
823 if (token->keyword >= RID_FIRST_INT_N
824 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
825 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
826 return true;
827 return false;
829 case CPP_LESS:
830 if (c_dialect_objc ())
831 return true;
832 return false;
833 default:
834 return false;
839 /* Return true if TOKEN can start declaration specifiers (not
840 including standard attributes) or a static assertion, false
841 otherwise. */
842 static bool
843 c_token_starts_declaration (c_token *token)
845 if (c_token_starts_declspecs (token)
846 || token->keyword == RID_STATIC_ASSERT)
847 return true;
848 else
849 return false;
852 /* Return true if the next token from PARSER can start declaration
853 specifiers (not including standard attributes), false
854 otherwise. */
855 bool
856 c_parser_next_token_starts_declspecs (c_parser *parser)
858 c_token *token = c_parser_peek_token (parser);
860 /* In Objective-C, a classname normally starts a declspecs unless it
861 is immediately followed by a dot. In that case, it is the
862 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
863 setter/getter on the class. c_token_starts_declspecs() can't
864 differentiate between the two cases because it only checks the
865 current token, so we have a special check here. */
866 if (c_dialect_objc ()
867 && token->type == CPP_NAME
868 && token->id_kind == C_ID_CLASSNAME
869 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
870 return false;
872 return c_token_starts_declspecs (token);
875 /* Return true if the next tokens from PARSER can start declaration
876 specifiers (not including standard attributes) or a static
877 assertion, false otherwise. */
878 bool
879 c_parser_next_tokens_start_declaration (c_parser *parser)
881 c_token *token = c_parser_peek_token (parser);
883 /* Same as above. */
884 if (c_dialect_objc ()
885 && token->type == CPP_NAME
886 && token->id_kind == C_ID_CLASSNAME
887 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
888 return false;
890 /* Labels do not start declarations. */
891 if (token->type == CPP_NAME
892 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
893 return false;
895 if (c_token_starts_declaration (token))
896 return true;
898 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
899 return true;
901 return false;
904 /* Consume the next token from PARSER. */
906 void
907 c_parser_consume_token (c_parser *parser)
909 gcc_assert (parser->tokens_avail >= 1);
910 gcc_assert (parser->tokens[0].type != CPP_EOF);
911 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
912 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
913 parser->last_token_location = parser->tokens[0].location;
914 if (parser->tokens != &parser->tokens_buf[0])
915 parser->tokens++;
916 else if (parser->tokens_avail >= 2)
918 parser->tokens[0] = parser->tokens[1];
919 if (parser->tokens_avail >= 3)
921 parser->tokens[1] = parser->tokens[2];
922 if (parser->tokens_avail >= 4)
923 parser->tokens[2] = parser->tokens[3];
926 parser->tokens_avail--;
927 parser->seen_string_literal = false;
930 /* Expect the current token to be a #pragma. Consume it and remember
931 that we've begun parsing a pragma. */
933 static void
934 c_parser_consume_pragma (c_parser *parser)
936 gcc_assert (!parser->in_pragma);
937 gcc_assert (parser->tokens_avail >= 1);
938 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
939 if (parser->tokens != &parser->tokens_buf[0])
940 parser->tokens++;
941 else if (parser->tokens_avail >= 2)
943 parser->tokens[0] = parser->tokens[1];
944 if (parser->tokens_avail >= 3)
945 parser->tokens[1] = parser->tokens[2];
947 parser->tokens_avail--;
948 parser->in_pragma = true;
951 /* Update the global input_location from TOKEN. */
952 static inline void
953 c_parser_set_source_position_from_token (c_token *token)
955 if (token->type != CPP_EOF)
957 input_location = token->location;
961 /* Helper function for c_parser_error.
962 Having peeked a token of kind TOK1_KIND that might signify
963 a conflict marker, peek successor tokens to determine
964 if we actually do have a conflict marker.
965 Specifically, we consider a run of 7 '<', '=' or '>' characters
966 at the start of a line as a conflict marker.
967 These come through the lexer as three pairs and a single,
968 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
969 If it returns true, *OUT_LOC is written to with the location/range
970 of the marker. */
972 static bool
973 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
974 location_t *out_loc)
976 c_token *token2 = c_parser_peek_2nd_token (parser);
977 if (token2->type != tok1_kind)
978 return false;
979 c_token *token3 = c_parser_peek_nth_token (parser, 3);
980 if (token3->type != tok1_kind)
981 return false;
982 c_token *token4 = c_parser_peek_nth_token (parser, 4);
983 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
984 return false;
986 /* It must be at the start of the line. */
987 location_t start_loc = c_parser_peek_token (parser)->location;
988 if (LOCATION_COLUMN (start_loc) != 1)
989 return false;
991 /* We have a conflict marker. Construct a location of the form:
992 <<<<<<<
993 ^~~~~~~
994 with start == caret, finishing at the end of the marker. */
995 location_t finish_loc = get_finish (token4->location);
996 *out_loc = make_location (start_loc, start_loc, finish_loc);
998 return true;
1001 /* Issue a diagnostic of the form
1002 FILE:LINE: MESSAGE before TOKEN
1003 where TOKEN is the next token in the input stream of PARSER.
1004 MESSAGE (specified by the caller) is usually of the form "expected
1005 OTHER-TOKEN".
1007 Use RICHLOC as the location of the diagnostic.
1009 Do not issue a diagnostic if still recovering from an error.
1011 Return true iff an error was actually emitted.
1013 ??? This is taken from the C++ parser, but building up messages in
1014 this way is not i18n-friendly and some other approach should be
1015 used. */
1017 static bool
1018 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
1019 rich_location *richloc)
1021 c_token *token = c_parser_peek_token (parser);
1022 if (parser->error)
1023 return false;
1024 parser->error = true;
1025 if (!gmsgid)
1026 return false;
1028 /* If this is actually a conflict marker, report it as such. */
1029 if (token->type == CPP_LSHIFT
1030 || token->type == CPP_RSHIFT
1031 || token->type == CPP_EQ_EQ)
1033 location_t loc;
1034 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
1036 error_at (loc, "version control conflict marker in file");
1037 return true;
1041 /* If we were parsing a string-literal and there is an unknown name
1042 token right after, then check to see if that could also have been
1043 a literal string by checking the name against a list of known
1044 standard string literal constants defined in header files. If
1045 there is one, then add that as an hint to the error message. */
1046 auto_diagnostic_group d;
1047 name_hint h;
1048 if (parser->seen_string_literal && token->type == CPP_NAME)
1050 tree name = token->value;
1051 const char *token_name = IDENTIFIER_POINTER (name);
1052 const char *header_hint
1053 = get_c_stdlib_header_for_string_macro_name (token_name);
1054 if (header_hint != NULL)
1055 h = name_hint (NULL, new suggest_missing_header (token->location,
1056 token_name,
1057 header_hint));
1060 c_parse_error (gmsgid,
1061 /* Because c_parse_error does not understand
1062 CPP_KEYWORD, keywords are treated like
1063 identifiers. */
1064 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1065 /* ??? The C parser does not save the cpp flags of a
1066 token, we need to pass 0 here and we will not get
1067 the source spelling of some tokens but rather the
1068 canonical spelling. */
1069 token->value, /*flags=*/0, richloc);
1070 return true;
1073 /* As c_parser_error_richloc, but issue the message at the
1074 location of PARSER's next token, or at input_location
1075 if the next token is EOF. */
1077 bool
1078 c_parser_error (c_parser *parser, const char *gmsgid)
1080 c_token *token = c_parser_peek_token (parser);
1081 c_parser_set_source_position_from_token (token);
1082 rich_location richloc (line_table, input_location);
1083 return c_parser_error_richloc (parser, gmsgid, &richloc);
1086 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1087 This class is for tracking such a matching pair of symbols.
1088 In particular, it tracks the location of the first token,
1089 so that if the second token is missing, we can highlight the
1090 location of the first token when notifying the user about the
1091 problem. */
1093 template <typename traits_t>
1094 class token_pair
1096 public:
1097 /* token_pair's ctor. */
1098 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1100 /* If the next token is the opening symbol for this pair, consume it and
1101 return true.
1102 Otherwise, issue an error and return false.
1103 In either case, record the location of the opening token. */
1105 bool require_open (c_parser *parser)
1107 c_token *token = c_parser_peek_token (parser);
1108 if (token)
1109 m_open_loc = token->location;
1111 return c_parser_require (parser, traits_t::open_token_type,
1112 traits_t::open_gmsgid);
1115 /* Consume the next token from PARSER, recording its location as
1116 that of the opening token within the pair. */
1118 void consume_open (c_parser *parser)
1120 c_token *token = c_parser_peek_token (parser);
1121 gcc_assert (token->type == traits_t::open_token_type);
1122 m_open_loc = token->location;
1123 c_parser_consume_token (parser);
1126 /* If the next token is the closing symbol for this pair, consume it
1127 and return true.
1128 Otherwise, issue an error, highlighting the location of the
1129 corresponding opening token, and return false. */
1131 bool require_close (c_parser *parser) const
1133 return c_parser_require (parser, traits_t::close_token_type,
1134 traits_t::close_gmsgid, m_open_loc);
1137 /* Like token_pair::require_close, except that tokens will be skipped
1138 until the desired token is found. An error message is still produced
1139 if the next token is not as expected. */
1141 void skip_until_found_close (c_parser *parser) const
1143 c_parser_skip_until_found (parser, traits_t::close_token_type,
1144 traits_t::close_gmsgid, m_open_loc);
1147 private:
1148 location_t m_open_loc;
1151 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1153 struct matching_paren_traits
1155 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1156 static const char * const open_gmsgid;
1157 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1158 static const char * const close_gmsgid;
1161 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1162 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1164 /* "matching_parens" is a token_pair<T> class for tracking matching
1165 pairs of parentheses. */
1167 typedef token_pair<matching_paren_traits> matching_parens;
1169 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1171 struct matching_brace_traits
1173 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1174 static const char * const open_gmsgid;
1175 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1176 static const char * const close_gmsgid;
1179 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1180 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1182 /* "matching_braces" is a token_pair<T> class for tracking matching
1183 pairs of braces. */
1185 typedef token_pair<matching_brace_traits> matching_braces;
1187 /* Get a description of the matching symbol to TYPE e.g. "(" for
1188 CPP_CLOSE_PAREN. */
1190 static const char *
1191 get_matching_symbol (enum cpp_ttype type)
1193 switch (type)
1195 default:
1196 gcc_unreachable ();
1197 case CPP_CLOSE_PAREN:
1198 return "(";
1199 case CPP_CLOSE_BRACE:
1200 return "{";
1204 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1205 issue the error MSGID. If MSGID is NULL then a message has already
1206 been produced and no message will be produced this time. Returns
1207 true if found, false otherwise.
1209 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1210 within any error as the location of an "opening" token matching
1211 the close token TYPE (e.g. the location of the '(' when TYPE is
1212 CPP_CLOSE_PAREN).
1214 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1215 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1216 attempt to generate a fix-it hint for the problem.
1217 Otherwise msgid describes multiple token types (e.g.
1218 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1219 generate a fix-it hint. */
1221 bool
1222 c_parser_require (c_parser *parser,
1223 enum cpp_ttype type,
1224 const char *msgid,
1225 location_t matching_location,
1226 bool type_is_unique)
1228 if (c_parser_next_token_is (parser, type))
1230 c_parser_consume_token (parser);
1231 return true;
1233 else
1235 location_t next_token_loc = c_parser_peek_token (parser)->location;
1236 gcc_rich_location richloc (next_token_loc);
1238 /* Potentially supply a fix-it hint, suggesting to add the
1239 missing token immediately after the *previous* token.
1240 This may move the primary location within richloc. */
1241 if (!parser->error && type_is_unique)
1242 maybe_suggest_missing_token_insertion (&richloc, type,
1243 parser->last_token_location);
1245 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1246 Attempt to consolidate diagnostics by printing it as a
1247 secondary range within the main diagnostic. */
1248 bool added_matching_location = false;
1249 if (matching_location != UNKNOWN_LOCATION)
1250 added_matching_location
1251 = richloc.add_location_if_nearby (matching_location);
1253 if (c_parser_error_richloc (parser, msgid, &richloc))
1254 /* If we weren't able to consolidate matching_location, then
1255 print it as a secondary diagnostic. */
1256 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1257 inform (matching_location, "to match this %qs",
1258 get_matching_symbol (type));
1260 return false;
1264 /* If the next token is the indicated keyword, consume it. Otherwise,
1265 issue the error MSGID. Returns true if found, false otherwise. */
1267 static bool
1268 c_parser_require_keyword (c_parser *parser,
1269 enum rid keyword,
1270 const char *msgid)
1272 if (c_parser_next_token_is_keyword (parser, keyword))
1274 c_parser_consume_token (parser);
1275 return true;
1277 else
1279 c_parser_error (parser, msgid);
1280 return false;
1284 /* Like c_parser_require, except that tokens will be skipped until the
1285 desired token is found. An error message is still produced if the
1286 next token is not as expected. If MSGID is NULL then a message has
1287 already been produced and no message will be produced this
1288 time.
1290 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1291 within any error as the location of an "opening" token matching
1292 the close token TYPE (e.g. the location of the '(' when TYPE is
1293 CPP_CLOSE_PAREN). */
1295 void
1296 c_parser_skip_until_found (c_parser *parser,
1297 enum cpp_ttype type,
1298 const char *msgid,
1299 location_t matching_location)
1301 unsigned nesting_depth = 0;
1303 if (c_parser_require (parser, type, msgid, matching_location))
1305 if (UNLIKELY (type == CPP_PRAGMA_EOL) && parser->in_omp_attribute_pragma)
1307 c_token *token = c_parser_peek_token (parser);
1308 if (token->type == CPP_EOF)
1310 parser->tokens = &parser->tokens_buf[0];
1311 parser->tokens_avail = token->flags;
1312 parser->in_omp_attribute_pragma = NULL;
1315 return;
1318 /* Skip tokens until the desired token is found. */
1319 while (true)
1321 /* Peek at the next token. */
1322 c_token *token = c_parser_peek_token (parser);
1323 /* If we've reached the token we want, consume it and stop. */
1324 if (token->type == type && !nesting_depth)
1326 c_parser_consume_token (parser);
1327 if (UNLIKELY (type == CPP_PRAGMA_EOL)
1328 && parser->in_omp_attribute_pragma)
1330 c_token *token = c_parser_peek_token (parser);
1331 if (token->type == CPP_EOF)
1333 parser->tokens = &parser->tokens_buf[0];
1334 parser->tokens_avail = token->flags;
1335 parser->in_omp_attribute_pragma = NULL;
1338 break;
1341 /* If we've run out of tokens, stop. */
1342 if (token->type == CPP_EOF)
1343 return;
1344 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1345 return;
1346 if (token->type == CPP_OPEN_BRACE
1347 || token->type == CPP_OPEN_PAREN
1348 || token->type == CPP_OPEN_SQUARE)
1349 ++nesting_depth;
1350 else if (token->type == CPP_CLOSE_BRACE
1351 || token->type == CPP_CLOSE_PAREN
1352 || token->type == CPP_CLOSE_SQUARE)
1354 if (nesting_depth-- == 0)
1355 break;
1357 /* Consume this token. */
1358 c_parser_consume_token (parser);
1360 parser->error = false;
1363 /* Skip tokens until the end of a parameter is found, but do not
1364 consume the comma, semicolon or closing delimiter. */
1366 static void
1367 c_parser_skip_to_end_of_parameter (c_parser *parser)
1369 unsigned nesting_depth = 0;
1371 while (true)
1373 c_token *token = c_parser_peek_token (parser);
1374 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1375 && !nesting_depth)
1376 break;
1377 /* If we've run out of tokens, stop. */
1378 if (token->type == CPP_EOF)
1379 return;
1380 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1381 return;
1382 if (token->type == CPP_OPEN_BRACE
1383 || token->type == CPP_OPEN_PAREN
1384 || token->type == CPP_OPEN_SQUARE)
1385 ++nesting_depth;
1386 else if (token->type == CPP_CLOSE_BRACE
1387 || token->type == CPP_CLOSE_PAREN
1388 || token->type == CPP_CLOSE_SQUARE)
1390 if (nesting_depth-- == 0)
1391 break;
1393 /* Consume this token. */
1394 c_parser_consume_token (parser);
1396 parser->error = false;
1399 /* Expect to be at the end of the pragma directive and consume an
1400 end of line marker. */
1402 static void
1403 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1405 gcc_assert (parser->in_pragma);
1406 parser->in_pragma = false;
1408 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1409 c_parser_error (parser, "expected end of line");
1411 cpp_ttype token_type;
1414 c_token *token = c_parser_peek_token (parser);
1415 token_type = token->type;
1416 if (token_type == CPP_EOF)
1417 break;
1418 c_parser_consume_token (parser);
1420 while (token_type != CPP_PRAGMA_EOL);
1422 if (parser->in_omp_attribute_pragma)
1424 c_token *token = c_parser_peek_token (parser);
1425 if (token->type == CPP_EOF)
1427 parser->tokens = &parser->tokens_buf[0];
1428 parser->tokens_avail = token->flags;
1429 parser->in_omp_attribute_pragma = NULL;
1433 parser->error = false;
1436 /* Skip tokens until we have consumed an entire block, or until we
1437 have consumed a non-nested ';'. */
1439 static void
1440 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1442 unsigned nesting_depth = 0;
1443 bool save_error = parser->error;
1445 while (true)
1447 c_token *token;
1449 /* Peek at the next token. */
1450 token = c_parser_peek_token (parser);
1452 switch (token->type)
1454 case CPP_EOF:
1455 return;
1457 case CPP_PRAGMA_EOL:
1458 if (parser->in_pragma)
1459 return;
1460 break;
1462 case CPP_SEMICOLON:
1463 /* If the next token is a ';', we have reached the
1464 end of the statement. */
1465 if (!nesting_depth)
1467 /* Consume the ';'. */
1468 c_parser_consume_token (parser);
1469 goto finished;
1471 break;
1473 case CPP_CLOSE_BRACE:
1474 /* If the next token is a non-nested '}', then we have
1475 reached the end of the current block. */
1476 if (nesting_depth == 0 || --nesting_depth == 0)
1478 c_parser_consume_token (parser);
1479 goto finished;
1481 break;
1483 case CPP_OPEN_BRACE:
1484 /* If it the next token is a '{', then we are entering a new
1485 block. Consume the entire block. */
1486 ++nesting_depth;
1487 break;
1489 case CPP_PRAGMA:
1490 /* If we see a pragma, consume the whole thing at once. We
1491 have some safeguards against consuming pragmas willy-nilly.
1492 Normally, we'd expect to be here with parser->error set,
1493 which disables these safeguards. But it's possible to get
1494 here for secondary error recovery, after parser->error has
1495 been cleared. */
1496 c_parser_consume_pragma (parser);
1497 c_parser_skip_to_pragma_eol (parser);
1498 parser->error = save_error;
1499 continue;
1501 default:
1502 break;
1505 c_parser_consume_token (parser);
1508 finished:
1509 parser->error = false;
1512 /* CPP's options (initialized by c-opts.cc). */
1513 extern cpp_options *cpp_opts;
1515 /* Save the warning flags which are controlled by __extension__. */
1517 static inline int
1518 disable_extension_diagnostics (void)
1520 int ret = (pedantic
1521 | (warn_pointer_arith << 1)
1522 | (warn_traditional << 2)
1523 | (flag_iso << 3)
1524 | (warn_long_long << 4)
1525 | (warn_cxx_compat << 5)
1526 | (warn_overlength_strings << 6)
1527 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1528 play tricks to properly restore it. */
1529 | ((warn_c90_c99_compat == 1) << 7)
1530 | ((warn_c90_c99_compat == -1) << 8)
1531 /* Similarly for warn_c99_c11_compat. */
1532 | ((warn_c99_c11_compat == 1) << 9)
1533 | ((warn_c99_c11_compat == -1) << 10)
1534 /* Similarly for warn_c11_c23_compat. */
1535 | ((warn_c11_c23_compat == 1) << 11)
1536 | ((warn_c11_c23_compat == -1) << 12)
1538 cpp_opts->cpp_pedantic = pedantic = 0;
1539 warn_pointer_arith = 0;
1540 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1541 flag_iso = 0;
1542 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1543 warn_cxx_compat = 0;
1544 warn_overlength_strings = 0;
1545 warn_c90_c99_compat = 0;
1546 warn_c99_c11_compat = 0;
1547 warn_c11_c23_compat = 0;
1548 return ret;
1551 /* Restore the warning flags which are controlled by __extension__.
1552 FLAGS is the return value from disable_extension_diagnostics. */
1554 static inline void
1555 restore_extension_diagnostics (int flags)
1557 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1558 warn_pointer_arith = (flags >> 1) & 1;
1559 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1560 flag_iso = (flags >> 3) & 1;
1561 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1562 warn_cxx_compat = (flags >> 5) & 1;
1563 warn_overlength_strings = (flags >> 6) & 1;
1564 /* See above for why is this needed. */
1565 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1566 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1567 warn_c11_c23_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1570 /* Helper data structure for parsing #pragma acc routine. */
1571 struct oacc_routine_data {
1572 bool error_seen; /* Set if error has been reported. */
1573 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1574 tree clauses;
1575 location_t loc;
1578 /* Used for parsing objc foreach statements. */
1579 static tree objc_foreach_break_label, objc_foreach_continue_label;
1581 /* Used for parsing OMP for loops.
1583 Some notes on flags used for context:
1584 parser->omp_for_parse_state is non-null anywhere inside the OMP FOR
1585 construct, except for the final-loop-body.
1586 The want_nested_loop flag is true if inside a {} sequence where
1587 a loop-nest (or another {} sequence containing a loop-nest) is expected,
1588 but has not yet been seen. It's false when parsing intervening code
1589 statements or their substatements that cannot contain a loop-nest.
1590 The in_intervening_code flag is true when parsing any intervening code,
1591 including substatements, and whether or not want_nested_loop is true.
1593 And, about error handling:
1594 The saw_intervening_code flag is set if the loop is not perfectly
1595 nested, even in the usual case where this is not an error.
1596 perfect_nesting_fail is set if an error has been diagnosed because an
1597 imperfectly-nested loop was found where a perfectly-nested one is
1598 required (we diagnose this only once).
1599 fail is set if any kind of structural error in the loop nest
1600 has been found and diagnosed.
1602 struct omp_for_parse_data {
1603 enum tree_code code;
1604 tree declv, condv, incrv, initv;
1605 tree pre_body;
1606 tree bindings;
1607 int count; /* Expected nesting depth. */
1608 int depth; /* Current nesting depth. */
1609 location_t for_loc;
1610 bool ordered : 1;
1611 bool inscan : 1;
1612 bool want_nested_loop : 1;
1613 bool in_intervening_code : 1;
1614 bool saw_intervening_code: 1;
1615 bool perfect_nesting_fail : 1;
1616 bool fail : 1;
1619 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1620 unsigned int);
1621 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1622 static void c_parser_external_declaration (c_parser *);
1623 static void c_parser_asm_definition (c_parser *);
1624 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1625 bool, bool, tree * = NULL,
1626 vec<c_token> * = NULL,
1627 bool have_attrs = false,
1628 tree attrs = NULL,
1629 struct oacc_routine_data * = NULL,
1630 bool * = NULL);
1631 static bool c_parser_handle_statement_omp_attributes (c_parser *, tree &,
1632 bool *);
1633 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1634 static void c_parser_static_assert_declaration (c_parser *);
1635 static struct c_typespec c_parser_enum_specifier (c_parser *);
1636 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1637 static tree c_parser_struct_declaration (c_parser *, tree *);
1638 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1639 static tree c_parser_alignas_specifier (c_parser *);
1640 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1641 c_dtr_syn, bool *);
1642 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1643 bool,
1644 struct c_declarator *);
1645 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1646 bool);
1647 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1648 tree, bool);
1649 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1650 static tree c_parser_simple_asm_expr (c_parser *);
1651 static tree c_parser_gnu_attributes (c_parser *);
1652 static struct c_expr c_parser_initializer (c_parser *, tree);
1653 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1654 struct obstack *, tree);
1655 static void c_parser_initelt (c_parser *, struct obstack *);
1656 static void c_parser_initval (c_parser *, struct c_expr *,
1657 struct obstack *);
1658 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1659 static location_t c_parser_compound_statement_nostart (c_parser *);
1660 static void c_parser_label (c_parser *, tree);
1661 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1662 static void c_parser_statement_after_labels (c_parser *, bool *,
1663 vec<tree> * = NULL);
1664 static tree c_parser_c99_block_statement (c_parser *, bool *,
1665 location_t * = NULL);
1666 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1667 static void c_parser_switch_statement (c_parser *, bool *);
1668 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool,
1669 bool *);
1670 static void c_parser_do_statement (c_parser *, bool, unsigned short, bool);
1671 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool,
1672 bool *);
1673 static tree c_parser_asm_statement (c_parser *);
1674 static tree c_parser_asm_operands (c_parser *);
1675 static tree c_parser_asm_goto_operands (c_parser *);
1676 static tree c_parser_asm_clobbers (c_parser *);
1677 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1678 tree = NULL_TREE);
1679 static struct c_expr c_parser_conditional_expression (c_parser *,
1680 struct c_expr *, tree);
1681 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1682 tree);
1683 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1684 static struct c_expr c_parser_unary_expression (c_parser *);
1685 static struct c_expr c_parser_sizeof_expression (c_parser *);
1686 static struct c_expr c_parser_alignof_expression (c_parser *);
1687 static struct c_expr c_parser_postfix_expression (c_parser *);
1688 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1689 struct c_declspecs *,
1690 struct c_type_name *,
1691 location_t);
1692 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1693 location_t loc,
1694 struct c_expr);
1695 static tree c_parser_transaction (c_parser *, enum rid);
1696 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1697 static tree c_parser_transaction_cancel (c_parser *);
1698 static struct c_expr c_parser_expression (c_parser *);
1699 static struct c_expr c_parser_expression_conv (c_parser *);
1700 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1701 vec<tree, va_gc> **, location_t *,
1702 tree *, vec<location_t> *,
1703 unsigned int * = NULL);
1704 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1706 static void c_parser_oacc_declare (c_parser *);
1707 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1708 static void c_parser_oacc_update (c_parser *);
1709 static void c_parser_omp_construct (c_parser *, bool *);
1710 static void c_parser_omp_threadprivate (c_parser *);
1711 static void c_parser_omp_barrier (c_parser *);
1712 static void c_parser_omp_depobj (c_parser *);
1713 static void c_parser_omp_flush (c_parser *);
1714 static tree c_parser_omp_loop_nest (c_parser *, bool *);
1715 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1716 tree, tree *, bool *);
1717 static void c_parser_omp_taskwait (c_parser *);
1718 static void c_parser_omp_taskyield (c_parser *);
1719 static void c_parser_omp_cancel (c_parser *);
1720 static void c_parser_omp_nothing (c_parser *);
1722 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1723 pragma_stmt, pragma_compound };
1724 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1725 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1726 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1727 static void c_parser_omp_begin (c_parser *);
1728 static void c_parser_omp_end (c_parser *);
1729 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1730 static void c_parser_omp_requires (c_parser *);
1731 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1732 static void c_parser_omp_assumption_clauses (c_parser *, bool);
1733 static void c_parser_omp_allocate (c_parser *);
1734 static void c_parser_omp_assumes (c_parser *);
1735 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1736 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1738 /* These Objective-C parser functions are only ever called when
1739 compiling Objective-C. */
1740 static void c_parser_objc_class_definition (c_parser *, tree);
1741 static void c_parser_objc_class_instance_variables (c_parser *);
1742 static void c_parser_objc_class_declaration (c_parser *);
1743 static void c_parser_objc_alias_declaration (c_parser *);
1744 static void c_parser_objc_protocol_definition (c_parser *, tree);
1745 static bool c_parser_objc_method_type (c_parser *);
1746 static void c_parser_objc_method_definition (c_parser *);
1747 static void c_parser_objc_methodprotolist (c_parser *);
1748 static void c_parser_objc_methodproto (c_parser *);
1749 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1750 static tree c_parser_objc_type_name (c_parser *);
1751 static tree c_parser_objc_protocol_refs (c_parser *);
1752 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1753 static void c_parser_objc_synchronized_statement (c_parser *);
1754 static tree c_parser_objc_selector (c_parser *);
1755 static tree c_parser_objc_selector_arg (c_parser *);
1756 static tree c_parser_objc_receiver (c_parser *);
1757 static tree c_parser_objc_message_args (c_parser *);
1758 static tree c_parser_objc_keywordexpr (c_parser *);
1759 static void c_parser_objc_at_property_declaration (c_parser *);
1760 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1761 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1762 static bool c_parser_objc_diagnose_bad_element_prefix
1763 (c_parser *, struct c_declspecs *);
1764 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1766 #if ENABLE_ANALYZER
1768 namespace ana {
1770 /* Concrete implementation of ana::translation_unit for the C frontend. */
1772 class c_translation_unit : public translation_unit
1774 public:
1775 /* Implementation of translation_unit::lookup_constant_by_id for use by the
1776 analyzer to look up named constants in the user's source code. */
1777 tree lookup_constant_by_id (tree id) const final override
1779 /* Consider decls. */
1780 if (tree decl = lookup_name (id))
1781 if (TREE_CODE (decl) == CONST_DECL)
1782 if (tree value = DECL_INITIAL (decl))
1783 if (TREE_CODE (value) == INTEGER_CST)
1784 return value;
1786 /* Consider macros. */
1787 cpp_hashnode *hashnode = C_CPP_HASHNODE (id);
1788 if (cpp_macro_p (hashnode))
1789 if (tree value = consider_macro (hashnode->value.macro))
1790 return value;
1792 return NULL_TREE;
1795 tree
1796 lookup_type_by_id (tree id) const final override
1798 if (tree type_decl = lookup_name (id))
1799 if (TREE_CODE (type_decl) == TYPE_DECL)
1801 tree record_type = TREE_TYPE (type_decl);
1802 if (TREE_CODE (record_type) == RECORD_TYPE)
1803 return record_type;
1806 return NULL_TREE;
1809 tree
1810 lookup_global_var_by_id (tree id) const final override
1812 if (tree var_decl = lookup_name (id))
1813 if (TREE_CODE (var_decl) == VAR_DECL)
1814 return var_decl;
1816 return NULL_TREE;
1819 private:
1820 /* Attempt to get an INTEGER_CST from MACRO.
1821 Only handle the simplest cases: where MACRO's definition is a single
1822 token containing a number, by lexing the number again.
1823 This will handle e.g.
1824 #define NAME 42
1825 and other bases but not negative numbers, parentheses or e.g.
1826 #define NAME 1 << 7
1827 as doing so would require a parser. */
1828 tree consider_macro (cpp_macro *macro) const
1830 if (macro->paramc > 0)
1831 return NULL_TREE;
1832 if (macro->kind != cmk_macro)
1833 return NULL_TREE;
1834 if (macro->count != 1)
1835 return NULL_TREE;
1836 const cpp_token &tok = macro->exp.tokens[0];
1837 if (tok.type != CPP_NUMBER)
1838 return NULL_TREE;
1840 cpp_reader *old_parse_in = parse_in;
1841 parse_in = cpp_create_reader (CLK_GNUC89, NULL, line_table);
1843 pretty_printer pp;
1844 pp_string (&pp, (const char *) tok.val.str.text);
1845 pp_newline (&pp);
1846 cpp_push_buffer (parse_in,
1847 (const unsigned char *) pp_formatted_text (&pp),
1848 strlen (pp_formatted_text (&pp)),
1851 tree value;
1852 location_t loc;
1853 unsigned char cpp_flags;
1854 c_lex_with_flags (&value, &loc, &cpp_flags, 0);
1856 cpp_destroy (parse_in);
1857 parse_in = old_parse_in;
1859 if (value && TREE_CODE (value) == INTEGER_CST)
1860 return value;
1862 return NULL_TREE;
1866 } // namespace ana
1868 #endif /* #if ENABLE_ANALYZER */
1870 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1872 translation-unit:
1873 external-declarations
1875 external-declarations:
1876 external-declaration
1877 external-declarations external-declaration
1879 GNU extensions:
1881 translation-unit:
1882 empty
1885 static void
1886 c_parser_translation_unit (c_parser *parser)
1888 if (c_parser_next_token_is (parser, CPP_EOF))
1890 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1891 "ISO C forbids an empty translation unit");
1893 else
1895 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1896 mark_valid_location_for_stdc_pragma (false);
1899 ggc_collect ();
1900 c_parser_external_declaration (parser);
1901 obstack_free (&parser_obstack, obstack_position);
1903 while (c_parser_next_token_is_not (parser, CPP_EOF));
1906 unsigned int i;
1907 tree decl;
1908 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1909 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1910 error ("storage size of %q+D isn%'t known", decl);
1912 if (vec_safe_length (current_omp_declare_target_attribute))
1914 c_omp_declare_target_attr
1915 a = current_omp_declare_target_attribute->pop ();
1916 if (!errorcount)
1917 error ("%qs without corresponding %qs",
1918 a.device_type >= 0 ? "#pragma omp begin declare target"
1919 : "#pragma omp declare target",
1920 "#pragma omp end declare target");
1921 vec_safe_truncate (current_omp_declare_target_attribute, 0);
1923 if (vec_safe_length (current_omp_begin_assumes))
1925 if (!errorcount)
1926 error ("%qs without corresponding %qs",
1927 "#pragma omp begin assumes", "#pragma omp end assumes");
1928 vec_safe_truncate (current_omp_begin_assumes, 0);
1931 #if ENABLE_ANALYZER
1932 if (flag_analyzer)
1934 ana::c_translation_unit tu;
1935 ana::on_finish_translation_unit (tu);
1937 #endif
1940 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1942 external-declaration:
1943 function-definition
1944 declaration
1946 GNU extensions:
1948 external-declaration:
1949 asm-definition
1951 __extension__ external-declaration
1953 Objective-C:
1955 external-declaration:
1956 objc-class-definition
1957 objc-class-declaration
1958 objc-alias-declaration
1959 objc-protocol-definition
1960 objc-method-definition
1961 @end
1964 static void
1965 c_parser_external_declaration (c_parser *parser)
1967 int ext;
1968 switch (c_parser_peek_token (parser)->type)
1970 case CPP_KEYWORD:
1971 switch (c_parser_peek_token (parser)->keyword)
1973 case RID_EXTENSION:
1974 ext = disable_extension_diagnostics ();
1975 c_parser_consume_token (parser);
1976 c_parser_external_declaration (parser);
1977 restore_extension_diagnostics (ext);
1978 break;
1979 case RID_ASM:
1980 c_parser_asm_definition (parser);
1981 break;
1982 case RID_AT_INTERFACE:
1983 case RID_AT_IMPLEMENTATION:
1984 gcc_assert (c_dialect_objc ());
1985 c_parser_objc_class_definition (parser, NULL_TREE);
1986 break;
1987 case RID_AT_CLASS:
1988 gcc_assert (c_dialect_objc ());
1989 c_parser_objc_class_declaration (parser);
1990 break;
1991 case RID_AT_ALIAS:
1992 gcc_assert (c_dialect_objc ());
1993 c_parser_objc_alias_declaration (parser);
1994 break;
1995 case RID_AT_PROTOCOL:
1996 gcc_assert (c_dialect_objc ());
1997 c_parser_objc_protocol_definition (parser, NULL_TREE);
1998 break;
1999 case RID_AT_PROPERTY:
2000 gcc_assert (c_dialect_objc ());
2001 c_parser_objc_at_property_declaration (parser);
2002 break;
2003 case RID_AT_SYNTHESIZE:
2004 gcc_assert (c_dialect_objc ());
2005 c_parser_objc_at_synthesize_declaration (parser);
2006 break;
2007 case RID_AT_DYNAMIC:
2008 gcc_assert (c_dialect_objc ());
2009 c_parser_objc_at_dynamic_declaration (parser);
2010 break;
2011 case RID_AT_END:
2012 gcc_assert (c_dialect_objc ());
2013 c_parser_consume_token (parser);
2014 objc_finish_implementation ();
2015 break;
2016 default:
2017 goto decl_or_fndef;
2019 break;
2020 case CPP_SEMICOLON:
2021 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
2022 "ISO C does not allow extra %<;%> outside of a function");
2023 c_parser_consume_token (parser);
2024 break;
2025 case CPP_PRAGMA:
2026 mark_valid_location_for_stdc_pragma (true);
2027 c_parser_pragma (parser, pragma_external, NULL);
2028 mark_valid_location_for_stdc_pragma (false);
2029 break;
2030 case CPP_PLUS:
2031 case CPP_MINUS:
2032 if (c_dialect_objc ())
2034 c_parser_objc_method_definition (parser);
2035 break;
2037 /* Else fall through, and yield a syntax error trying to parse
2038 as a declaration or function definition. */
2039 /* FALLTHRU */
2040 default:
2041 decl_or_fndef:
2042 /* A declaration or a function definition (or, in Objective-C,
2043 an @interface or @protocol with prefix attributes). We can
2044 only tell which after parsing the declaration specifiers, if
2045 any, and the first declarator. */
2046 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
2047 break;
2051 static void c_parser_handle_directive_omp_attributes (tree &, vec<c_token> *&,
2052 vec<c_token> *);
2053 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
2054 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
2056 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
2058 static void
2059 add_debug_begin_stmt (location_t loc)
2061 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
2062 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
2063 return;
2065 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
2066 SET_EXPR_LOCATION (stmt, loc);
2067 add_stmt (stmt);
2070 /* Helper function for c_parser_declaration_or_fndef and
2071 Handle assume attribute(s). */
2073 static tree
2074 handle_assume_attribute (location_t here, tree attrs, bool nested)
2076 if (nested)
2077 for (tree attr = lookup_attribute ("gnu", "assume", attrs); attr;
2078 attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
2080 tree args = TREE_VALUE (attr);
2081 int nargs = list_length (args);
2082 if (nargs != 1)
2084 error_at (here, "wrong number of arguments specified "
2085 "for %qE attribute",
2086 get_attribute_name (attr));
2087 inform (here, "expected %i, found %i", 1, nargs);
2089 else
2091 tree arg = TREE_VALUE (args);
2092 arg = c_objc_common_truthvalue_conversion (here, arg);
2093 arg = c_fully_fold (arg, false, NULL);
2094 if (arg != error_mark_node)
2096 tree fn = build_call_expr_internal_loc (here, IFN_ASSUME,
2097 void_type_node, 1,
2098 arg);
2099 add_stmt (fn);
2103 else
2104 pedwarn (here, OPT_Wattributes,
2105 "%<assume%> attribute at top level");
2107 return remove_attribute ("gnu", "assume", attrs);
2110 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
2111 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
2112 is accepted; otherwise (old-style parameter declarations) only other
2113 declarations are accepted. If STATIC_ASSERT_OK is true, a static
2114 assertion is accepted; otherwise (old-style parameter declarations)
2115 it is not. If NESTED is true, we are inside a function or parsing
2116 old-style parameter declarations; any functions encountered are
2117 nested functions and declaration specifiers are required; otherwise
2118 we are at top level and functions are normal functions and
2119 declaration specifiers may be optional. If EMPTY_OK is true, empty
2120 declarations are OK (subject to all other constraints); otherwise
2121 (old-style parameter declarations) they are diagnosed. If
2122 START_ATTR_OK is true, the declaration specifiers may start with
2123 attributes (GNU or standard); otherwise they may not.
2124 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
2125 declaration when parsing an Objective-C foreach statement.
2126 FALLTHRU_ATTR_P is used to signal whether this function parsed
2127 "__attribute__((fallthrough));". ATTRS are any standard attributes
2128 parsed in the caller (in contexts where such attributes had to be
2129 parsed to determine whether what follows is a declaration or a
2130 statement); HAVE_ATTRS says whether there were any such attributes
2131 (even empty).
2133 declaration:
2134 declaration-specifiers init-declarator-list[opt] ;
2135 static_assert-declaration
2137 function-definition:
2138 declaration-specifiers[opt] declarator declaration-list[opt]
2139 compound-statement
2141 declaration-list:
2142 declaration
2143 declaration-list declaration
2145 init-declarator-list:
2146 init-declarator
2147 init-declarator-list , init-declarator
2149 init-declarator:
2150 declarator simple-asm-expr[opt] gnu-attributes[opt]
2151 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
2153 GNU extensions:
2155 nested-function-definition:
2156 declaration-specifiers declarator declaration-list[opt]
2157 compound-statement
2159 attribute ;
2161 Objective-C:
2162 gnu-attributes objc-class-definition
2163 gnu-attributes objc-category-definition
2164 gnu-attributes objc-protocol-definition
2166 The simple-asm-expr and gnu-attributes are GNU extensions.
2168 This function does not handle __extension__; that is handled in its
2169 callers. ??? Following the old parser, __extension__ may start
2170 external declarations, declarations in functions and declarations
2171 at the start of "for" loops, but not old-style parameter
2172 declarations.
2174 C99 requires declaration specifiers in a function definition; the
2175 absence is diagnosed through the diagnosis of implicit int. In GNU
2176 C we also allow but diagnose declarations without declaration
2177 specifiers, but only at top level (elsewhere they conflict with
2178 other syntax).
2180 In Objective-C, declarations of the looping variable in a foreach
2181 statement are exceptionally terminated by 'in' (for example, 'for
2182 (NSObject *object in array) { ... }').
2184 OpenMP:
2186 declaration:
2187 threadprivate-directive
2189 GIMPLE:
2191 gimple-function-definition:
2192 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
2193 declaration-list[opt] compound-statement
2195 rtl-function-definition:
2196 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
2197 declaration-list[opt] compound-statement */
2199 static void
2200 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
2201 bool static_assert_ok, bool empty_ok,
2202 bool nested, bool start_attr_ok,
2203 tree *objc_foreach_object_declaration
2204 /* = NULL */,
2205 vec<c_token> *omp_declare_simd_clauses
2206 /* = NULL */,
2207 bool have_attrs /* = false */,
2208 tree attrs /* = NULL_TREE */,
2209 struct oacc_routine_data *oacc_routine_data
2210 /* = NULL */,
2211 bool *fallthru_attr_p /* = NULL */)
2213 struct c_declspecs *specs;
2214 tree prefix_attrs;
2215 tree all_prefix_attrs;
2216 bool diagnosed_no_specs = false;
2217 location_t here = c_parser_peek_token (parser)->location;
2219 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
2221 if (static_assert_ok
2222 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
2224 c_parser_static_assert_declaration (parser);
2225 return;
2227 specs = build_null_declspecs ();
2229 /* Handle any standard attributes parsed in the caller. */
2230 if (have_attrs)
2232 declspecs_add_attrs (here, specs, attrs);
2233 specs->non_std_attrs_seen_p = false;
2236 /* Try to detect an unknown type name when we have "A B" or "A *B". */
2237 if (c_parser_peek_token (parser)->type == CPP_NAME
2238 && c_parser_peek_token (parser)->id_kind == C_ID_ID
2239 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
2240 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
2241 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
2243 tree name = c_parser_peek_token (parser)->value;
2245 /* Issue a warning about NAME being an unknown type name, perhaps
2246 with some kind of hint.
2247 If the user forgot a "struct" etc, suggest inserting
2248 it. Otherwise, attempt to look for misspellings. */
2249 gcc_rich_location richloc (here);
2250 if (tag_exists_p (RECORD_TYPE, name))
2252 /* This is not C++ with its implicit typedef. */
2253 richloc.add_fixit_insert_before ("struct ");
2254 error_at (&richloc,
2255 "unknown type name %qE;"
2256 " use %<struct%> keyword to refer to the type",
2257 name);
2259 else if (tag_exists_p (UNION_TYPE, name))
2261 richloc.add_fixit_insert_before ("union ");
2262 error_at (&richloc,
2263 "unknown type name %qE;"
2264 " use %<union%> keyword to refer to the type",
2265 name);
2267 else if (tag_exists_p (ENUMERAL_TYPE, name))
2269 richloc.add_fixit_insert_before ("enum ");
2270 error_at (&richloc,
2271 "unknown type name %qE;"
2272 " use %<enum%> keyword to refer to the type",
2273 name);
2275 else
2277 auto_diagnostic_group d;
2278 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
2279 here);
2280 if (const char *suggestion = hint.suggestion ())
2282 richloc.add_fixit_replace (suggestion);
2283 error_at (&richloc,
2284 "unknown type name %qE; did you mean %qs?",
2285 name, suggestion);
2287 else
2288 error_at (here, "unknown type name %qE", name);
2291 /* Parse declspecs normally to get a correct pointer type, but avoid
2292 a further "fails to be a type name" error. Refuse nested functions
2293 since it is not how the user likely wants us to recover. */
2294 c_parser_peek_token (parser)->type = CPP_KEYWORD;
2295 c_parser_peek_token (parser)->keyword = RID_VOID;
2296 c_parser_peek_token (parser)->value = error_mark_node;
2297 fndef_ok = !nested;
2300 /* When there are standard attributes at the start of the
2301 declaration (to apply to the entity being declared), an
2302 init-declarator-list or function definition must be present. */
2303 if (c_parser_nth_token_starts_std_attributes (parser, 1))
2304 have_attrs = true;
2306 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2307 true, true, start_attr_ok, true, cla_nonabstract_decl);
2308 if (parser->error)
2310 c_parser_skip_to_end_of_block_or_statement (parser);
2311 return;
2313 if (nested && !specs->declspecs_seen_p)
2315 c_parser_error (parser, "expected declaration specifiers");
2316 c_parser_skip_to_end_of_block_or_statement (parser);
2317 return;
2320 finish_declspecs (specs);
2321 bool gnu_auto_type_p = specs->typespec_word == cts_auto_type;
2322 bool std_auto_type_p = specs->c23_auto_p;
2323 bool any_auto_type_p = gnu_auto_type_p || std_auto_type_p;
2324 gcc_assert (!(gnu_auto_type_p && std_auto_type_p));
2325 const char *auto_type_keyword = gnu_auto_type_p ? "__auto_type" : "auto";
2326 if (specs->constexpr_p)
2328 /* An underspecified declaration may not declare tags or members
2329 or structures or unions; it is undefined behavior to declare
2330 the members of an enumeration. Where the structure, union or
2331 enumeration type is declared within an initializer, this is
2332 diagnosed elsewhere. Diagnose here the case of declaring
2333 such a type in the type specifiers of a constexpr
2334 declaration. */
2335 switch (specs->typespec_kind)
2337 case ctsk_tagfirstref:
2338 case ctsk_tagfirstref_attrs:
2339 error_at (here, "%qT declared in underspecified object declaration",
2340 specs->type);
2341 break;
2343 case ctsk_tagdef:
2344 error_at (here, "%qT defined in underspecified object declaration",
2345 specs->type);
2346 break;
2348 default:
2349 break;
2352 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2354 bool handled_assume = false;
2355 if (specs->attrs
2356 && !nested
2357 && specs->typespec_kind == ctsk_none
2358 && c_parser_handle_statement_omp_attributes (parser, specs->attrs,
2359 NULL))
2361 if (specs->attrs)
2362 c_warn_unused_attributes (specs->attrs);
2363 while (parser->in_omp_attribute_pragma)
2365 gcc_assert (c_parser_next_token_is (parser, CPP_PRAGMA));
2366 c_parser_pragma (parser, pragma_external, NULL);
2368 c_parser_consume_token (parser);
2369 return;
2371 if (specs->typespec_kind == ctsk_none
2372 && lookup_attribute ("gnu", "assume", specs->attrs))
2374 handled_assume = true;
2375 specs->attrs
2376 = handle_assume_attribute (here, specs->attrs, nested);
2378 if (any_auto_type_p)
2379 error_at (here, "%qs in empty declaration", auto_type_keyword);
2380 else if (specs->typespec_kind == ctsk_none
2381 && attribute_fallthrough_p (specs->attrs))
2383 if (fallthru_attr_p != NULL)
2384 *fallthru_attr_p = true;
2385 if (nested)
2387 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2388 void_type_node, 0);
2389 add_stmt (fn);
2391 else
2392 pedwarn (here, OPT_Wattributes,
2393 "%<fallthrough%> attribute at top level");
2395 else if (empty_ok
2396 && !(have_attrs && specs->non_std_attrs_seen_p)
2397 && !handled_assume)
2398 shadow_tag (specs);
2399 else
2401 shadow_tag_warned (specs, 1);
2402 if (!handled_assume)
2403 pedwarn (here, 0, "empty declaration");
2405 /* We still have to evaluate size expressions. */
2406 if (specs->expr)
2407 add_stmt (fold_convert (void_type_node, specs->expr));
2408 c_parser_consume_token (parser);
2409 if (oacc_routine_data)
2410 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2411 return;
2414 /* Provide better error recovery. Note that a type name here is usually
2415 better diagnosed as a redeclaration. */
2416 if (empty_ok
2417 && specs->typespec_kind == ctsk_tagdef
2418 && c_parser_next_token_starts_declspecs (parser)
2419 && !c_parser_next_token_is (parser, CPP_NAME))
2421 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2422 parser->error = false;
2423 shadow_tag_warned (specs, 1);
2424 return;
2426 else if (c_dialect_objc () && !any_auto_type_p)
2428 /* Prefix attributes are an error on method decls. */
2429 switch (c_parser_peek_token (parser)->type)
2431 case CPP_PLUS:
2432 case CPP_MINUS:
2433 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2434 return;
2435 if (specs->attrs)
2437 warning_at (c_parser_peek_token (parser)->location,
2438 OPT_Wattributes,
2439 "prefix attributes are ignored for methods");
2440 specs->attrs = NULL_TREE;
2442 if (fndef_ok)
2443 c_parser_objc_method_definition (parser);
2444 else
2445 c_parser_objc_methodproto (parser);
2446 return;
2447 break;
2448 default:
2449 break;
2451 /* This is where we parse 'attributes @interface ...',
2452 'attributes @implementation ...', 'attributes @protocol ...'
2453 (where attributes could be, for example, __attribute__
2454 ((deprecated)).
2456 switch (c_parser_peek_token (parser)->keyword)
2458 case RID_AT_INTERFACE:
2460 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2461 return;
2462 c_parser_objc_class_definition (parser, specs->attrs);
2463 return;
2465 break;
2466 case RID_AT_IMPLEMENTATION:
2468 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2469 return;
2470 if (specs->attrs)
2472 warning_at (c_parser_peek_token (parser)->location,
2473 OPT_Wattributes,
2474 "prefix attributes are ignored for implementations");
2475 specs->attrs = NULL_TREE;
2477 c_parser_objc_class_definition (parser, NULL_TREE);
2478 return;
2480 break;
2481 case RID_AT_PROTOCOL:
2483 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2484 return;
2485 c_parser_objc_protocol_definition (parser, specs->attrs);
2486 return;
2488 break;
2489 case RID_AT_ALIAS:
2490 case RID_AT_CLASS:
2491 case RID_AT_END:
2492 case RID_AT_PROPERTY:
2493 if (specs->attrs)
2495 c_parser_error (parser, "unexpected attribute");
2496 specs->attrs = NULL;
2498 break;
2499 default:
2500 break;
2503 else if (attribute_fallthrough_p (specs->attrs))
2504 warning_at (here, OPT_Wattributes,
2505 "%<fallthrough%> attribute not followed by %<;%>");
2506 else if (lookup_attribute ("gnu", "assume", specs->attrs))
2507 warning_at (here, OPT_Wattributes,
2508 "%<assume%> attribute not followed by %<;%>");
2510 auto_vec<c_token> omp_declare_simd_attr_clauses;
2511 c_parser_handle_directive_omp_attributes (specs->attrs,
2512 omp_declare_simd_clauses,
2513 &omp_declare_simd_attr_clauses);
2514 pending_xref_error ();
2515 prefix_attrs = specs->attrs;
2516 all_prefix_attrs = prefix_attrs;
2517 specs->attrs = NULL_TREE;
2518 while (true)
2520 struct c_declarator *declarator;
2521 bool dummy = false;
2522 timevar_id_t tv;
2523 tree fnbody = NULL_TREE;
2524 tree underspec_name = NULL_TREE;
2525 auto_vec<c_token> omp_dsimd_idattr_clauses;
2526 /* Declaring either one or more declarators (in which case we
2527 should diagnose if there were no declaration specifiers) or a
2528 function definition (in which case the diagnostic for
2529 implicit int suffices). */
2530 declarator = c_parser_declarator (parser,
2531 specs->typespec_kind != ctsk_none,
2532 C_DTR_NORMAL, &dummy);
2533 if (declarator == NULL)
2535 if (omp_declare_simd_clauses)
2536 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2537 omp_declare_simd_clauses);
2538 if (oacc_routine_data)
2539 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2540 c_parser_skip_to_end_of_block_or_statement (parser);
2541 return;
2543 if (flag_openmp || flag_openmp_simd)
2545 struct c_declarator *d = declarator;
2546 while (d->kind != cdk_id)
2547 d = d->declarator;
2548 vec<c_token> *dummy = NULL;
2549 c_parser_handle_directive_omp_attributes (d->u.id.attrs, dummy,
2550 &omp_dsimd_idattr_clauses);
2552 if (gnu_auto_type_p && declarator->kind != cdk_id)
2554 error_at (here,
2555 "%<__auto_type%> requires a plain identifier"
2556 " as declarator");
2557 c_parser_skip_to_end_of_block_or_statement (parser);
2558 return;
2560 if (std_auto_type_p)
2562 struct c_declarator *d = declarator;
2563 while (d->kind == cdk_attrs)
2564 d = d->declarator;
2565 if (d->kind != cdk_id)
2567 error_at (here,
2568 "%<auto%> requires a plain identifier, possibly with"
2569 " attributes, as declarator");
2570 c_parser_skip_to_end_of_block_or_statement (parser);
2571 return;
2573 underspec_name = d->u.id.id;
2575 else if (specs->constexpr_p)
2577 struct c_declarator *d = declarator;
2578 while (d->kind != cdk_id)
2579 d = d->declarator;
2580 underspec_name = d->u.id.id;
2582 if (c_parser_next_token_is (parser, CPP_EQ)
2583 || c_parser_next_token_is (parser, CPP_COMMA)
2584 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2585 || c_parser_next_token_is_keyword (parser, RID_ASM)
2586 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2587 || c_parser_next_token_is_keyword (parser, RID_IN))
2589 tree asm_name = NULL_TREE;
2590 tree postfix_attrs = NULL_TREE;
2591 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2593 diagnosed_no_specs = true;
2594 pedwarn (here, 0, "data definition has no type or storage class");
2596 /* Having seen a data definition, there cannot now be a
2597 function definition. */
2598 fndef_ok = false;
2599 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2600 asm_name = c_parser_simple_asm_expr (parser);
2601 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2603 postfix_attrs = c_parser_gnu_attributes (parser);
2604 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2606 /* This means there is an attribute specifier after
2607 the declarator in a function definition. Provide
2608 some more information for the user. */
2609 error_at (here, "attributes should be specified before the "
2610 "declarator in a function definition");
2611 c_parser_skip_to_end_of_block_or_statement (parser);
2612 return;
2615 if (c_parser_next_token_is (parser, CPP_EQ))
2617 tree d;
2618 struct c_expr init;
2619 location_t init_loc;
2620 c_parser_consume_token (parser);
2621 if (any_auto_type_p)
2623 init_loc = c_parser_peek_token (parser)->location;
2624 rich_location richloc (line_table, init_loc);
2625 unsigned int underspec_state = 0;
2626 if (std_auto_type_p)
2627 underspec_state =
2628 start_underspecified_init (init_loc, underspec_name);
2629 start_init (NULL_TREE, asm_name,
2630 (global_bindings_p ()
2631 || specs->storage_class == csc_static
2632 || specs->constexpr_p),
2633 specs->constexpr_p, &richloc);
2634 /* A parameter is initialized, which is invalid. Don't
2635 attempt to instrument the initializer. */
2636 int flag_sanitize_save = flag_sanitize;
2637 if (nested && !empty_ok)
2638 flag_sanitize = 0;
2639 init = c_parser_expr_no_commas (parser, NULL);
2640 if (std_auto_type_p)
2641 finish_underspecified_init (underspec_name,
2642 underspec_state);
2643 flag_sanitize = flag_sanitize_save;
2644 if (gnu_auto_type_p
2645 && TREE_CODE (init.value) == COMPONENT_REF
2646 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2647 error_at (here,
2648 "%<__auto_type%> used with a bit-field"
2649 " initializer");
2650 init = convert_lvalue_to_rvalue (init_loc, init, true, true,
2651 true);
2652 tree init_type = TREE_TYPE (init.value);
2653 bool vm_type = c_type_variably_modified_p (init_type);
2654 if (vm_type)
2655 init.value = save_expr (init.value);
2656 finish_init ();
2657 specs->typespec_kind = ctsk_typeof;
2658 specs->locations[cdw_typedef] = init_loc;
2659 specs->typedef_p = true;
2660 specs->type = init_type;
2661 if (specs->postfix_attrs)
2663 /* Postfix [[]] attributes are valid with C23
2664 auto, although not with __auto_type, and
2665 modify the type given by the initializer. */
2666 specs->postfix_attrs =
2667 c_warn_type_attributes (specs->postfix_attrs);
2668 decl_attributes (&specs->type, specs->postfix_attrs, 0);
2669 specs->postfix_attrs = NULL_TREE;
2671 if (vm_type)
2673 bool maybe_const = true;
2674 tree type_expr = c_fully_fold (init.value, false,
2675 &maybe_const);
2676 specs->expr_const_operands &= maybe_const;
2677 if (specs->expr)
2678 specs->expr = build2 (COMPOUND_EXPR,
2679 TREE_TYPE (type_expr),
2680 specs->expr, type_expr);
2681 else
2682 specs->expr = type_expr;
2684 d = start_decl (declarator, specs, true,
2685 chainon (postfix_attrs, all_prefix_attrs));
2686 if (!d)
2687 d = error_mark_node;
2688 if (omp_declare_simd_clauses)
2689 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2690 omp_declare_simd_clauses);
2691 if (!omp_dsimd_idattr_clauses.is_empty ())
2692 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2693 &omp_dsimd_idattr_clauses);
2695 else
2697 /* The declaration of the variable is in effect while
2698 its initializer is parsed, except for a constexpr
2699 variable. */
2700 init_loc = c_parser_peek_token (parser)->location;
2701 rich_location richloc (line_table, init_loc);
2702 unsigned int underspec_state = 0;
2703 if (specs->constexpr_p)
2704 underspec_state =
2705 start_underspecified_init (init_loc, underspec_name);
2706 d = start_decl (declarator, specs, true,
2707 chainon (postfix_attrs,
2708 all_prefix_attrs),
2709 !specs->constexpr_p);
2710 if (!d)
2711 d = error_mark_node;
2712 if (!specs->constexpr_p && omp_declare_simd_clauses)
2713 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2714 omp_declare_simd_clauses);
2715 if (!specs->constexpr_p
2716 && !omp_dsimd_idattr_clauses.is_empty ())
2717 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2718 &omp_dsimd_idattr_clauses);
2719 start_init (d, asm_name,
2720 TREE_STATIC (d) || specs->constexpr_p,
2721 specs->constexpr_p, &richloc);
2722 /* A parameter is initialized, which is invalid. Don't
2723 attempt to instrument the initializer. */
2724 int flag_sanitize_save = flag_sanitize;
2725 if (TREE_CODE (d) == PARM_DECL)
2726 flag_sanitize = 0;
2727 init = c_parser_initializer (parser, d);
2728 flag_sanitize = flag_sanitize_save;
2729 if (specs->constexpr_p)
2731 finish_underspecified_init (underspec_name,
2732 underspec_state);
2733 d = pushdecl (d);
2734 if (omp_declare_simd_clauses)
2735 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2736 omp_declare_simd_clauses);
2737 if (!specs->constexpr_p
2738 && !omp_dsimd_idattr_clauses.is_empty ())
2739 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2740 &omp_dsimd_idattr_clauses);
2742 finish_init ();
2744 if (oacc_routine_data)
2745 c_finish_oacc_routine (oacc_routine_data, d, false);
2746 if (d != error_mark_node)
2748 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2749 finish_decl (d, init_loc, init.value,
2750 init.original_type, asm_name);
2753 else
2755 if (any_auto_type_p || specs->constexpr_p)
2757 error_at (here,
2758 "%qs requires an initialized data declaration",
2759 any_auto_type_p ? auto_type_keyword : "constexpr");
2760 c_parser_skip_to_end_of_block_or_statement (parser);
2761 return;
2764 location_t lastloc = UNKNOWN_LOCATION;
2765 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2766 tree d = start_decl (declarator, specs, false, attrs, true,
2767 &lastloc);
2768 if (d && TREE_CODE (d) == FUNCTION_DECL)
2770 /* Find the innermost declarator that is neither cdk_id
2771 nor cdk_attrs. */
2772 const struct c_declarator *decl = declarator;
2773 const struct c_declarator *last_non_id_attrs = NULL;
2775 while (decl)
2776 switch (decl->kind)
2778 case cdk_array:
2779 case cdk_function:
2780 case cdk_pointer:
2781 last_non_id_attrs = decl;
2782 decl = decl->declarator;
2783 break;
2785 case cdk_attrs:
2786 decl = decl->declarator;
2787 break;
2789 case cdk_id:
2790 decl = 0;
2791 break;
2793 default:
2794 gcc_unreachable ();
2797 /* If it exists and is cdk_function declaration whose
2798 arguments have not been set yet, use its arguments. */
2799 if (last_non_id_attrs
2800 && last_non_id_attrs->kind == cdk_function)
2802 tree parms = last_non_id_attrs->u.arg_info->parms;
2803 if (DECL_ARGUMENTS (d) == NULL_TREE
2804 && DECL_INITIAL (d) == NULL_TREE)
2805 DECL_ARGUMENTS (d) = parms;
2807 warn_parm_array_mismatch (lastloc, d, parms);
2810 if (omp_declare_simd_clauses
2811 || !omp_dsimd_idattr_clauses.is_empty ())
2813 tree parms = NULL_TREE;
2814 if (d && TREE_CODE (d) == FUNCTION_DECL)
2816 struct c_declarator *ce = declarator;
2817 while (ce != NULL)
2818 if (ce->kind == cdk_function)
2820 parms = ce->u.arg_info->parms;
2821 break;
2823 else
2824 ce = ce->declarator;
2826 if (parms)
2827 temp_store_parm_decls (d, parms);
2828 if (omp_declare_simd_clauses)
2829 c_finish_omp_declare_simd (parser, d, parms,
2830 omp_declare_simd_clauses);
2831 if (!specs->constexpr_p
2832 && !omp_dsimd_idattr_clauses.is_empty ())
2833 c_finish_omp_declare_simd (parser, d, parms,
2834 &omp_dsimd_idattr_clauses);
2835 if (parms)
2836 temp_pop_parm_decls ();
2838 if (oacc_routine_data)
2839 c_finish_oacc_routine (oacc_routine_data, d, false);
2840 if (d)
2841 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2842 NULL_TREE, asm_name);
2844 if (c_parser_next_token_is_keyword (parser, RID_IN))
2846 if (d)
2847 *objc_foreach_object_declaration = d;
2848 else
2849 *objc_foreach_object_declaration = error_mark_node;
2852 if (c_parser_next_token_is (parser, CPP_COMMA))
2854 if (any_auto_type_p || specs->constexpr_p)
2856 error_at (here,
2857 "%qs may only be used with a single declarator",
2858 any_auto_type_p ? auto_type_keyword : "constexpr");
2859 c_parser_skip_to_end_of_block_or_statement (parser);
2860 return;
2862 c_parser_consume_token (parser);
2863 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2864 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2865 prefix_attrs);
2866 else
2867 all_prefix_attrs = prefix_attrs;
2868 continue;
2870 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2872 c_parser_consume_token (parser);
2873 return;
2875 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2877 /* This can only happen in Objective-C: we found the
2878 'in' that terminates the declaration inside an
2879 Objective-C foreach statement. Do not consume the
2880 token, so that the caller can use it to determine
2881 that this indeed is a foreach context. */
2882 return;
2884 else
2886 c_parser_error (parser, "expected %<,%> or %<;%>");
2887 c_parser_skip_to_end_of_block_or_statement (parser);
2888 return;
2891 else if (any_auto_type_p || specs->constexpr_p)
2893 error_at (here,
2894 "%qs requires an initialized data declaration",
2895 any_auto_type_p ? auto_type_keyword : "constexpr");
2896 c_parser_skip_to_end_of_block_or_statement (parser);
2897 return;
2899 else if (!fndef_ok)
2901 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2902 "%<asm%> or %<__attribute__%>");
2903 c_parser_skip_to_end_of_block_or_statement (parser);
2904 return;
2906 /* Function definition (nested or otherwise). */
2907 if (nested)
2909 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2910 c_push_function_context ();
2912 if (!start_function (specs, declarator, all_prefix_attrs))
2914 /* At this point we've consumed:
2915 declaration-specifiers declarator
2916 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2917 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2918 but the
2919 declaration-specifiers declarator
2920 aren't grokkable as a function definition, so we have
2921 an error. */
2922 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2923 if (c_parser_next_token_starts_declspecs (parser))
2925 /* If we have
2926 declaration-specifiers declarator decl-specs
2927 then assume we have a missing semicolon, which would
2928 give us:
2929 declaration-specifiers declarator decl-specs
2932 <~~~~~~~~~ declaration ~~~~~~~~~~>
2933 Use c_parser_require to get an error with a fix-it hint. */
2934 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2935 parser->error = false;
2937 else
2939 /* This can appear in many cases looking nothing like a
2940 function definition, so we don't give a more specific
2941 error suggesting there was one. */
2942 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2943 "or %<__attribute__%>");
2945 if (nested)
2946 c_pop_function_context ();
2947 break;
2950 if (DECL_DECLARED_INLINE_P (current_function_decl))
2951 tv = TV_PARSE_INLINE;
2952 else
2953 tv = TV_PARSE_FUNC;
2954 auto_timevar at (g_timer, tv);
2956 /* Parse old-style parameter declarations. ??? Attributes are
2957 not allowed to start declaration specifiers here because of a
2958 syntax conflict between a function declaration with attribute
2959 suffix and a function definition with an attribute prefix on
2960 first old-style parameter declaration. Following the old
2961 parser, they are not accepted on subsequent old-style
2962 parameter declarations either. However, there is no
2963 ambiguity after the first declaration, nor indeed on the
2964 first as long as we don't allow postfix attributes after a
2965 declarator with a nonempty identifier list in a definition;
2966 and postfix attributes have never been accepted here in
2967 function definitions either. */
2968 int save_debug_nonbind_markers_p = debug_nonbind_markers_p;
2969 debug_nonbind_markers_p = 0;
2970 while (c_parser_next_token_is_not (parser, CPP_EOF)
2971 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2972 c_parser_declaration_or_fndef (parser, false, false, false,
2973 true, false);
2974 debug_nonbind_markers_p = save_debug_nonbind_markers_p;
2975 store_parm_decls ();
2976 if (omp_declare_simd_clauses)
2977 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2978 omp_declare_simd_clauses);
2979 if (!omp_dsimd_idattr_clauses.is_empty ())
2980 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2981 &omp_dsimd_idattr_clauses);
2982 if (oacc_routine_data)
2983 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2984 location_t startloc = c_parser_peek_token (parser)->location;
2985 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2986 = startloc;
2987 location_t endloc = startloc;
2989 /* If the definition was marked with __RTL, use the RTL parser now,
2990 consuming the function body. */
2991 if (specs->declspec_il == cdil_rtl)
2993 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2995 /* Normally, store_parm_decls sets next_is_function_body,
2996 anticipating a function body. We need a push_scope/pop_scope
2997 pair to flush out this state, or subsequent function parsing
2998 will go wrong. */
2999 push_scope ();
3000 pop_scope ();
3002 finish_function (endloc);
3003 return;
3005 /* If the definition was marked with __GIMPLE then parse the
3006 function body as GIMPLE. */
3007 else if (specs->declspec_il != cdil_none)
3009 bool saved = in_late_binary_op;
3010 in_late_binary_op = true;
3011 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
3012 specs->declspec_il,
3013 specs->entry_bb_count);
3014 in_late_binary_op = saved;
3016 else
3017 fnbody = c_parser_compound_statement (parser, &endloc);
3018 tree fndecl = current_function_decl;
3019 if (nested)
3021 tree decl = current_function_decl;
3022 /* Mark nested functions as needing static-chain initially.
3023 lower_nested_functions will recompute it but the
3024 DECL_STATIC_CHAIN flag is also used before that happens,
3025 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
3026 DECL_STATIC_CHAIN (decl) = 1;
3027 add_stmt (fnbody);
3028 finish_function (endloc);
3029 c_pop_function_context ();
3030 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
3032 else
3034 if (fnbody)
3035 add_stmt (fnbody);
3036 finish_function (endloc);
3038 /* Get rid of the empty stmt list for GIMPLE/RTL. */
3039 if (specs->declspec_il != cdil_none)
3040 DECL_SAVED_TREE (fndecl) = NULL_TREE;
3042 break;
3046 /* Parse an asm-definition (asm() outside a function body). This is a
3047 GNU extension.
3049 asm-definition:
3050 simple-asm-expr ;
3053 static void
3054 c_parser_asm_definition (c_parser *parser)
3056 tree asm_str = c_parser_simple_asm_expr (parser);
3057 if (asm_str)
3058 symtab->finalize_toplevel_asm (asm_str);
3059 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
3062 /* Parse a static assertion (C11 6.7.10).
3064 static_assert-declaration:
3065 static_assert-declaration-no-semi ;
3068 static void
3069 c_parser_static_assert_declaration (c_parser *parser)
3071 c_parser_static_assert_declaration_no_semi (parser);
3072 if (parser->error
3073 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
3074 c_parser_skip_to_end_of_block_or_statement (parser);
3077 /* Parse a static assertion (C11 6.7.10), without the trailing
3078 semicolon.
3080 static_assert-declaration-no-semi:
3081 _Static_assert ( constant-expression , string-literal )
3083 C23:
3084 static_assert-declaration-no-semi:
3085 _Static_assert ( constant-expression )
3088 static void
3089 c_parser_static_assert_declaration_no_semi (c_parser *parser)
3091 location_t assert_loc, value_loc;
3092 tree value;
3093 tree string = NULL_TREE;
3095 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
3096 tree spelling = c_parser_peek_token (parser)->value;
3097 assert_loc = c_parser_peek_token (parser)->location;
3098 if (flag_isoc99)
3099 pedwarn_c99 (assert_loc, OPT_Wpedantic,
3100 "ISO C99 does not support %qE", spelling);
3101 else
3102 pedwarn_c99 (assert_loc, OPT_Wpedantic,
3103 "ISO C90 does not support %qE", spelling);
3104 c_parser_consume_token (parser);
3105 matching_parens parens;
3106 if (!parens.require_open (parser))
3107 return;
3108 location_t value_tok_loc = c_parser_peek_token (parser)->location;
3109 value = convert_lvalue_to_rvalue (value_tok_loc,
3110 c_parser_expr_no_commas (parser, NULL),
3111 true, true).value;
3112 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
3113 if (c_parser_next_token_is (parser, CPP_COMMA))
3115 c_parser_consume_token (parser);
3116 switch (c_parser_peek_token (parser)->type)
3118 case CPP_STRING:
3119 case CPP_STRING16:
3120 case CPP_STRING32:
3121 case CPP_WSTRING:
3122 case CPP_UTF8STRING:
3123 string = c_parser_string_literal (parser, false, true).value;
3124 break;
3125 default:
3126 c_parser_error (parser, "expected string literal");
3127 return;
3130 else if (flag_isoc11)
3131 /* If pedantic for pre-C11, the use of _Static_assert itself will
3132 have been diagnosed, so do not also diagnose the use of this
3133 new C23 feature of _Static_assert. */
3134 pedwarn_c11 (assert_loc, OPT_Wpedantic,
3135 "ISO C11 does not support omitting the string in "
3136 "%qE", spelling);
3137 parens.require_close (parser);
3139 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
3141 error_at (value_loc, "expression in static assertion is not an integer");
3142 return;
3144 if (TREE_CODE (value) != INTEGER_CST)
3146 value = c_fully_fold (value, false, NULL);
3147 /* Strip no-op conversions. */
3148 STRIP_TYPE_NOPS (value);
3149 if (TREE_CODE (value) == INTEGER_CST)
3150 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
3151 "is not an integer constant expression");
3153 if (TREE_CODE (value) != INTEGER_CST)
3155 error_at (value_loc, "expression in static assertion is not constant");
3156 return;
3158 constant_expression_warning (value);
3159 if (integer_zerop (value))
3161 if (string)
3162 error_at (assert_loc, "static assertion failed: %E", string);
3163 else
3164 error_at (assert_loc, "static assertion failed");
3168 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
3169 6.7, C11 6.7), adding them to SPECS (which may already include some).
3170 Storage class specifiers are accepted iff SCSPEC_OK; type
3171 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
3172 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
3173 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
3174 addition to the syntax shown, standard attributes are accepted at
3175 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
3176 unlike gnu-attributes, they are not accepted in the middle of the
3177 list. (This combines various different syntax productions in the C
3178 standard, and in some cases gnu-attributes and standard attributes
3179 at the start may already have been parsed before this function is
3180 called.)
3182 declaration-specifiers:
3183 storage-class-specifier declaration-specifiers[opt]
3184 type-specifier declaration-specifiers[opt]
3185 type-qualifier declaration-specifiers[opt]
3186 function-specifier declaration-specifiers[opt]
3187 alignment-specifier declaration-specifiers[opt]
3189 Function specifiers (inline) are from C99, and are currently
3190 handled as storage class specifiers, as is __thread. Alignment
3191 specifiers are from C11.
3193 C90 6.5.1, C99 6.7.1, C11 6.7.1:
3194 storage-class-specifier:
3195 typedef
3196 extern
3197 static
3198 auto
3199 register
3200 _Thread_local
3202 (_Thread_local is new in C11.)
3204 C99 6.7.4, C11 6.7.4:
3205 function-specifier:
3206 inline
3207 _Noreturn
3209 (_Noreturn is new in C11.)
3211 C90 6.5.2, C99 6.7.2, C11 6.7.2:
3212 type-specifier:
3213 void
3214 char
3215 short
3217 long
3218 float
3219 double
3220 signed
3221 unsigned
3222 _Bool
3223 _Complex
3224 [_Imaginary removed in C99 TC2]
3225 _BitInt ( constant-expression )
3226 struct-or-union-specifier
3227 enum-specifier
3228 typedef-name
3229 atomic-type-specifier
3231 (_Bool and _Complex are new in C99.)
3232 (atomic-type-specifier is new in C11.)
3233 (_BitInt is new in C23.)
3235 C90 6.5.3, C99 6.7.3, C11 6.7.3:
3237 type-qualifier:
3238 const
3239 restrict
3240 volatile
3241 address-space-qualifier
3242 _Atomic
3244 (restrict is new in C99.)
3245 (_Atomic is new in C11.)
3247 GNU extensions:
3249 declaration-specifiers:
3250 gnu-attributes declaration-specifiers[opt]
3252 type-qualifier:
3253 address-space
3255 address-space:
3256 identifier recognized by the target
3258 storage-class-specifier:
3259 __thread
3261 type-specifier:
3262 typeof-specifier
3263 __auto_type
3264 __intN
3265 _Decimal32
3266 _Decimal64
3267 _Decimal128
3268 _Fract
3269 _Accum
3270 _Sat
3272 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
3273 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
3275 atomic-type-specifier
3276 _Atomic ( type-name )
3278 Objective-C:
3280 type-specifier:
3281 class-name objc-protocol-refs[opt]
3282 typedef-name objc-protocol-refs
3283 objc-protocol-refs
3286 void
3287 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
3288 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
3289 bool alignspec_ok, bool auto_type_ok,
3290 bool start_std_attr_ok, bool end_std_attr_ok,
3291 enum c_lookahead_kind la)
3293 bool attrs_ok = start_attr_ok;
3294 bool seen_type = specs->typespec_kind != ctsk_none;
3296 if (!typespec_ok)
3297 gcc_assert (la == cla_prefer_id);
3299 if (start_std_attr_ok
3300 && c_parser_nth_token_starts_std_attributes (parser, 1))
3302 gcc_assert (!specs->non_std_attrs_seen_p);
3303 location_t loc = c_parser_peek_token (parser)->location;
3304 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
3305 declspecs_add_attrs (loc, specs, attrs);
3306 specs->non_std_attrs_seen_p = false;
3309 while (c_parser_next_token_is (parser, CPP_NAME)
3310 || c_parser_next_token_is (parser, CPP_KEYWORD)
3311 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
3313 struct c_typespec t;
3314 tree attrs;
3315 tree align;
3316 location_t loc = c_parser_peek_token (parser)->location;
3318 /* If we cannot accept a type, exit if the next token must start
3319 one. Also, if we already have seen a tagged definition,
3320 a typename would be an error anyway and likely the user
3321 has simply forgotten a semicolon, so we exit. */
3322 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
3323 && c_parser_next_tokens_start_typename (parser, la)
3324 && !c_parser_next_token_is_qualifier (parser)
3325 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
3326 break;
3328 if (c_parser_next_token_is (parser, CPP_NAME))
3330 c_token *name_token = c_parser_peek_token (parser);
3331 tree value = name_token->value;
3332 c_id_kind kind = name_token->id_kind;
3334 if (kind == C_ID_ADDRSPACE)
3336 addr_space_t as
3337 = name_token->keyword - RID_FIRST_ADDR_SPACE;
3338 declspecs_add_addrspace (name_token->location, specs, as);
3339 c_parser_consume_token (parser);
3340 attrs_ok = true;
3341 continue;
3344 gcc_assert (!c_parser_next_token_is_qualifier (parser));
3346 /* If we cannot accept a type, and the next token must start one,
3347 exit. Do the same if we already have seen a tagged definition,
3348 since it would be an error anyway and likely the user has simply
3349 forgotten a semicolon. */
3350 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
3351 break;
3353 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
3354 a C_ID_CLASSNAME. */
3355 c_parser_consume_token (parser);
3356 seen_type = true;
3357 attrs_ok = true;
3358 if (kind == C_ID_ID)
3360 auto_diagnostic_group d;
3361 name_hint hint = lookup_name_fuzzy (value, FUZZY_LOOKUP_TYPENAME,
3362 loc);
3363 if (const char *suggestion = hint.suggestion ())
3365 gcc_rich_location richloc (loc);
3366 richloc.add_fixit_replace (suggestion);
3367 error_at (&richloc,
3368 "unknown type name %qE; did you mean %qs?",
3369 value, suggestion);
3371 else
3372 error_at (loc, "unknown type name %qE", value);
3373 t.kind = ctsk_typedef;
3374 t.spec = error_mark_node;
3376 else if (kind == C_ID_TYPENAME
3377 && (!c_dialect_objc ()
3378 || c_parser_next_token_is_not (parser, CPP_LESS)))
3380 t.kind = ctsk_typedef;
3381 /* For a typedef name, record the meaning, not the name.
3382 In case of 'foo foo, bar;'. */
3383 t.spec = lookup_name (value);
3385 else
3387 tree proto = NULL_TREE;
3388 gcc_assert (c_dialect_objc ());
3389 t.kind = ctsk_objc;
3390 if (c_parser_next_token_is (parser, CPP_LESS))
3391 proto = c_parser_objc_protocol_refs (parser);
3392 t.spec = objc_get_protocol_qualified_type (value, proto);
3394 t.expr = NULL_TREE;
3395 t.expr_const_operands = true;
3396 t.has_enum_type_specifier = false;
3397 declspecs_add_type (name_token->location, specs, t);
3398 continue;
3400 if (c_parser_next_token_is (parser, CPP_LESS))
3402 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3403 nisse@lysator.liu.se. */
3404 tree proto;
3405 gcc_assert (c_dialect_objc ());
3406 if (!typespec_ok || seen_type)
3407 break;
3408 proto = c_parser_objc_protocol_refs (parser);
3409 t.kind = ctsk_objc;
3410 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
3411 t.expr = NULL_TREE;
3412 t.expr_const_operands = true;
3413 t.has_enum_type_specifier = false;
3414 declspecs_add_type (loc, specs, t);
3415 continue;
3417 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
3418 switch (c_parser_peek_token (parser)->keyword)
3420 case RID_STATIC:
3421 case RID_EXTERN:
3422 case RID_REGISTER:
3423 case RID_TYPEDEF:
3424 case RID_INLINE:
3425 case RID_NORETURN:
3426 case RID_AUTO:
3427 case RID_THREAD:
3428 case RID_CONSTEXPR:
3429 if (!scspec_ok)
3430 goto out;
3431 attrs_ok = true;
3432 /* TODO: Distinguish between function specifiers (inline, noreturn)
3433 and storage class specifiers, either here or in
3434 declspecs_add_scspec. */
3435 declspecs_add_scspec (loc, specs,
3436 c_parser_peek_token (parser)->value);
3437 c_parser_consume_token (parser);
3438 break;
3439 case RID_AUTO_TYPE:
3440 if (!auto_type_ok)
3441 goto out;
3442 /* Fall through. */
3443 case RID_UNSIGNED:
3444 case RID_LONG:
3445 case RID_SHORT:
3446 case RID_SIGNED:
3447 case RID_COMPLEX:
3448 case RID_INT:
3449 case RID_CHAR:
3450 case RID_FLOAT:
3451 case RID_DOUBLE:
3452 case RID_VOID:
3453 case RID_DFLOAT32:
3454 case RID_DFLOAT64:
3455 case RID_DFLOAT128:
3456 CASE_RID_FLOATN_NX:
3457 case RID_BOOL:
3458 case RID_FRACT:
3459 case RID_ACCUM:
3460 case RID_SAT:
3461 case RID_INT_N_0:
3462 case RID_INT_N_1:
3463 case RID_INT_N_2:
3464 case RID_INT_N_3:
3465 if (!typespec_ok)
3466 goto out;
3467 attrs_ok = true;
3468 seen_type = true;
3469 if (c_dialect_objc ())
3470 parser->objc_need_raw_identifier = true;
3471 t.kind = ctsk_resword;
3472 t.spec = c_parser_peek_token (parser)->value;
3473 t.expr = NULL_TREE;
3474 t.expr_const_operands = true;
3475 t.has_enum_type_specifier = false;
3476 declspecs_add_type (loc, specs, t);
3477 c_parser_consume_token (parser);
3478 break;
3479 case RID_ENUM:
3480 if (!typespec_ok)
3481 goto out;
3482 attrs_ok = true;
3483 seen_type = true;
3484 t = c_parser_enum_specifier (parser);
3485 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3486 declspecs_add_type (loc, specs, t);
3487 break;
3488 case RID_STRUCT:
3489 case RID_UNION:
3490 if (!typespec_ok)
3491 goto out;
3492 attrs_ok = true;
3493 seen_type = true;
3494 t = c_parser_struct_or_union_specifier (parser);
3495 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3496 declspecs_add_type (loc, specs, t);
3497 break;
3498 case RID_TYPEOF:
3499 case RID_TYPEOF_UNQUAL:
3500 /* ??? The old parser rejected typeof after other type
3501 specifiers, but is a syntax error the best way of
3502 handling this? */
3503 if (!typespec_ok || seen_type)
3504 goto out;
3505 attrs_ok = true;
3506 seen_type = true;
3507 t = c_parser_typeof_specifier (parser);
3508 declspecs_add_type (loc, specs, t);
3509 break;
3510 case RID_BITINT:
3511 if (!typespec_ok)
3512 goto out;
3513 else
3515 attrs_ok = true;
3516 seen_type = true;
3517 t.kind = ctsk_resword;
3518 t.spec = c_parser_peek_token (parser)->value;
3519 t.expr = error_mark_node;
3520 t.expr_const_operands = true;
3521 t.has_enum_type_specifier = false;
3522 c_parser_consume_token (parser);
3523 matching_parens parens;
3524 if (parens.require_open (parser))
3526 c_expr expr = c_parser_expr_no_commas (parser, NULL);
3527 t.expr = convert_lvalue_to_rvalue (loc, expr, true,
3528 true).value;
3529 parens.skip_until_found_close (parser);
3531 declspecs_add_type (loc, specs, t);
3533 break;
3534 case RID_ATOMIC:
3535 /* C parser handling of Objective-C constructs needs
3536 checking for correct lvalue-to-rvalue conversions, and
3537 the code in build_modify_expr handling various
3538 Objective-C cases, and that in build_unary_op handling
3539 Objective-C cases for increment / decrement, also needs
3540 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3541 and objc_types_are_equivalent may also need updates. */
3542 if (c_dialect_objc ())
3543 sorry ("%<_Atomic%> in Objective-C");
3544 if (flag_isoc99)
3545 pedwarn_c99 (loc, OPT_Wpedantic,
3546 "ISO C99 does not support the %<_Atomic%> qualifier");
3547 else
3548 pedwarn_c99 (loc, OPT_Wpedantic,
3549 "ISO C90 does not support the %<_Atomic%> qualifier");
3550 attrs_ok = true;
3551 tree value;
3552 value = c_parser_peek_token (parser)->value;
3553 c_parser_consume_token (parser);
3554 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3556 /* _Atomic ( type-name ). */
3557 seen_type = true;
3558 c_parser_consume_token (parser);
3559 struct c_type_name *type = c_parser_type_name (parser);
3560 t.kind = ctsk_typeof;
3561 t.spec = error_mark_node;
3562 t.expr = NULL_TREE;
3563 t.expr_const_operands = true;
3564 t.has_enum_type_specifier = false;
3565 if (type != NULL)
3566 t.spec = groktypename (type, &t.expr,
3567 &t.expr_const_operands);
3568 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3569 "expected %<)%>");
3570 if (t.spec != error_mark_node)
3572 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3573 error_at (loc, "%<_Atomic%>-qualified array type");
3574 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3575 error_at (loc, "%<_Atomic%>-qualified function type");
3576 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3577 error_at (loc, "%<_Atomic%> applied to a qualified type");
3578 else
3579 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3581 declspecs_add_type (loc, specs, t);
3583 else
3584 declspecs_add_qual (loc, specs, value);
3585 break;
3586 case RID_CONST:
3587 case RID_VOLATILE:
3588 case RID_RESTRICT:
3589 attrs_ok = true;
3590 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3591 c_parser_consume_token (parser);
3592 break;
3593 case RID_ATTRIBUTE:
3594 if (!attrs_ok)
3595 goto out;
3596 attrs = c_parser_gnu_attributes (parser);
3597 declspecs_add_attrs (loc, specs, attrs);
3598 break;
3599 case RID_ALIGNAS:
3600 if (!alignspec_ok)
3601 goto out;
3602 align = c_parser_alignas_specifier (parser);
3603 declspecs_add_alignas (loc, specs, align);
3604 break;
3605 case RID_GIMPLE:
3606 if (! flag_gimple)
3607 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3608 c_parser_consume_token (parser);
3609 specs->declspec_il = cdil_gimple;
3610 specs->locations[cdw_gimple] = loc;
3611 c_parser_gimple_or_rtl_pass_list (parser, specs);
3612 break;
3613 case RID_RTL:
3614 c_parser_consume_token (parser);
3615 specs->declspec_il = cdil_rtl;
3616 specs->locations[cdw_rtl] = loc;
3617 c_parser_gimple_or_rtl_pass_list (parser, specs);
3618 break;
3619 default:
3620 goto out;
3623 out:
3624 if (end_std_attr_ok
3625 && c_parser_nth_token_starts_std_attributes (parser, 1))
3626 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3629 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3631 enum-specifier:
3632 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3633 { enumerator-list } gnu-attributes[opt]
3634 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3635 { enumerator-list , } gnu-attributes[opt] enum-type-specifier[opt]
3636 enum gnu-attributes[opt] identifier
3638 The form with trailing comma is new in C99; enum-type-specifiers
3639 are new in C23. The forms with gnu-attributes are GNU extensions.
3640 In GNU C, we accept any expression without commas in the syntax
3641 (assignment expressions, not just conditional expressions);
3642 assignment expressions will be diagnosed as non-constant.
3644 enum-type-specifier:
3645 : specifier-qualifier-list
3647 enumerator-list:
3648 enumerator
3649 enumerator-list , enumerator
3651 enumerator:
3652 enumeration-constant attribute-specifier-sequence[opt]
3653 enumeration-constant attribute-specifier-sequence[opt]
3654 = constant-expression
3656 GNU Extensions:
3658 enumerator:
3659 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3660 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3661 = constant-expression
3665 static struct c_typespec
3666 c_parser_enum_specifier (c_parser *parser)
3668 struct c_typespec ret;
3669 bool have_std_attrs;
3670 bool potential_nesting_p = false;
3671 tree std_attrs = NULL_TREE;
3672 tree attrs;
3673 tree ident = NULL_TREE;
3674 tree fixed_underlying_type = NULL_TREE;
3675 location_t enum_loc;
3676 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3677 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3678 c_parser_consume_token (parser);
3679 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3680 if (have_std_attrs)
3681 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3682 attrs = c_parser_gnu_attributes (parser);
3683 enum_loc = c_parser_peek_token (parser)->location;
3684 /* Set the location in case we create a decl now. */
3685 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3686 if (c_parser_next_token_is (parser, CPP_NAME))
3688 ident = c_parser_peek_token (parser)->value;
3689 ident_loc = c_parser_peek_token (parser)->location;
3690 enum_loc = ident_loc;
3691 c_parser_consume_token (parser);
3693 if (c_parser_next_token_is (parser, CPP_COLON)
3694 /* Distinguish an enum-type-specifier from a bit-field
3695 declaration of the form "enum e : constant-expression;". */
3696 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
3698 pedwarn_c11 (enum_loc, OPT_Wpedantic,
3699 "ISO C does not support specifying %<enum%> underlying "
3700 "types before C23");
3701 if (ident)
3703 /* The tag is in scope during the enum-type-specifier (which
3704 may refer to the tag inside typeof). */
3705 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident,
3706 have_std_attrs, std_attrs, true);
3707 if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec))
3708 error_at (enum_loc, "%<enum%> declared both with and without "
3709 "fixed underlying type");
3710 potential_nesting_p = NULL_TREE == TYPE_VALUES (ret.spec);
3712 else
3714 /* There must be an enum definition, so this initialization
3715 (to avoid possible warnings about uninitialized data)
3716 will be replaced later (either with the results of that
3717 definition, or with the results of error handling for the
3718 case of no tag and no definition). */
3719 ret.spec = NULL_TREE;
3720 ret.kind = ctsk_tagdef;
3721 ret.expr = NULL_TREE;
3722 ret.expr_const_operands = true;
3723 ret.has_enum_type_specifier = true;
3725 c_parser_consume_token (parser);
3726 struct c_declspecs *specs = build_null_declspecs ();
3727 c_parser_declspecs (parser, specs, false, true, false, false, false,
3728 false, true, cla_prefer_id);
3729 finish_declspecs (specs);
3730 if (specs->default_int_p)
3731 error_at (enum_loc, "no %<enum%> underlying type specified");
3732 else if (TREE_CODE (specs->type) != INTEGER_TYPE
3733 && TREE_CODE (specs->type) != BOOLEAN_TYPE)
3735 error_at (enum_loc, "invalid %<enum%> underlying type");
3736 specs->type = integer_type_node;
3738 else if (specs->restrict_p)
3739 error_at (enum_loc, "invalid use of %<restrict%>");
3740 fixed_underlying_type = TYPE_MAIN_VARIANT (specs->type);
3741 if (ident)
3743 /* The type specified must be consistent with any previously
3744 specified underlying type. If this is a newly declared
3745 type, it is now a complete type. */
3746 if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
3747 && ENUM_UNDERLYING_TYPE (ret.spec) == NULL_TREE)
3749 TYPE_MIN_VALUE (ret.spec) =
3750 TYPE_MIN_VALUE (fixed_underlying_type);
3751 TYPE_MAX_VALUE (ret.spec) =
3752 TYPE_MAX_VALUE (fixed_underlying_type);
3753 TYPE_UNSIGNED (ret.spec) = TYPE_UNSIGNED (fixed_underlying_type);
3754 SET_TYPE_ALIGN (ret.spec, TYPE_ALIGN (fixed_underlying_type));
3755 TYPE_SIZE (ret.spec) = NULL_TREE;
3756 TYPE_PRECISION (ret.spec) =
3757 TYPE_PRECISION (fixed_underlying_type);
3758 ENUM_UNDERLYING_TYPE (ret.spec) = fixed_underlying_type;
3759 layout_type (ret.spec);
3761 else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
3762 && !comptypes (fixed_underlying_type,
3763 ENUM_UNDERLYING_TYPE (ret.spec)))
3765 error_at (enum_loc, "%<enum%> underlying type incompatible with "
3766 "previous declaration");
3767 fixed_underlying_type = ENUM_UNDERLYING_TYPE (ret.spec);
3771 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3773 /* Parse an enum definition. */
3774 struct c_enum_contents the_enum;
3775 tree type;
3776 tree postfix_attrs;
3777 /* We chain the enumerators in reverse order, then put them in
3778 forward order at the end. */
3779 tree values;
3780 timevar_push (TV_PARSE_ENUM);
3781 type = start_enum (enum_loc, &the_enum, ident, fixed_underlying_type,
3782 potential_nesting_p);
3783 values = NULL_TREE;
3784 c_parser_consume_token (parser);
3785 while (true)
3787 tree enum_id;
3788 tree enum_value;
3789 tree enum_decl;
3790 bool seen_comma;
3791 c_token *token;
3792 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3793 location_t decl_loc, value_loc;
3794 if (c_parser_next_token_is_not (parser, CPP_NAME))
3796 /* Give a nicer error for "enum {}". */
3797 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3798 && !parser->error)
3800 error_at (c_parser_peek_token (parser)->location,
3801 "empty enum is invalid");
3802 parser->error = true;
3804 else
3805 c_parser_error (parser, "expected identifier");
3806 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3807 values = error_mark_node;
3808 break;
3810 token = c_parser_peek_token (parser);
3811 enum_id = token->value;
3812 /* Set the location in case we create a decl now. */
3813 c_parser_set_source_position_from_token (token);
3814 decl_loc = value_loc = token->location;
3815 c_parser_consume_token (parser);
3816 /* Parse any specified attributes. */
3817 tree std_attrs = NULL_TREE;
3818 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3819 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3820 tree enum_attrs = chainon (std_attrs,
3821 c_parser_gnu_attributes (parser));
3822 if (c_parser_next_token_is (parser, CPP_EQ))
3824 c_parser_consume_token (parser);
3825 value_loc = c_parser_peek_token (parser)->location;
3826 enum_value = convert_lvalue_to_rvalue (value_loc,
3827 (c_parser_expr_no_commas
3828 (parser, NULL)),
3829 true, true).value;
3831 else
3832 enum_value = NULL_TREE;
3833 enum_decl = build_enumerator (decl_loc, value_loc,
3834 &the_enum, enum_id, enum_value);
3835 if (enum_attrs)
3836 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3837 TREE_CHAIN (enum_decl) = values;
3838 values = enum_decl;
3839 seen_comma = false;
3840 if (c_parser_next_token_is (parser, CPP_COMMA))
3842 comma_loc = c_parser_peek_token (parser)->location;
3843 seen_comma = true;
3844 c_parser_consume_token (parser);
3846 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3848 if (seen_comma)
3849 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3850 "comma at end of enumerator list");
3851 c_parser_consume_token (parser);
3852 break;
3854 if (!seen_comma)
3856 c_parser_error (parser, "expected %<,%> or %<}%>");
3857 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3858 values = error_mark_node;
3859 break;
3862 postfix_attrs = c_parser_gnu_attributes (parser);
3863 ret.spec = finish_enum (type, nreverse (values),
3864 chainon (std_attrs,
3865 chainon (attrs, postfix_attrs)));
3866 ret.kind = ctsk_tagdef;
3867 ret.expr = NULL_TREE;
3868 ret.expr_const_operands = true;
3869 ret.has_enum_type_specifier = fixed_underlying_type != NULL_TREE;
3870 timevar_pop (TV_PARSE_ENUM);
3871 return ret;
3873 else if (!ident)
3875 c_parser_error (parser, "expected %<{%>");
3876 ret.spec = error_mark_node;
3877 ret.kind = ctsk_tagref;
3878 ret.expr = NULL_TREE;
3879 ret.expr_const_operands = true;
3880 ret.has_enum_type_specifier = false;
3881 return ret;
3883 /* Attributes may only appear when the members are defined or in
3884 certain forward declarations (treat enum forward declarations in
3885 GNU C analogously to struct and union forward declarations in
3886 standard C). */
3887 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3888 c_parser_error (parser, "expected %<;%>");
3889 if (fixed_underlying_type == NULL_TREE)
3891 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3892 std_attrs, false);
3893 /* In ISO C, enumerated types without a fixed underlying type
3894 can be referred to only if already defined. */
3895 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3897 gcc_assert (ident);
3898 pedwarn (enum_loc, OPT_Wpedantic,
3899 "ISO C forbids forward references to %<enum%> types");
3902 return ret;
3905 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3907 struct-or-union-specifier:
3908 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3909 identifier[opt] { struct-contents } gnu-attributes[opt]
3910 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3911 identifier
3913 struct-contents:
3914 struct-declaration-list
3916 struct-declaration-list:
3917 struct-declaration ;
3918 struct-declaration-list struct-declaration ;
3920 GNU extensions:
3922 struct-contents:
3923 empty
3924 struct-declaration
3925 struct-declaration-list struct-declaration
3927 struct-declaration-list:
3928 struct-declaration-list ;
3931 (Note that in the syntax here, unlike that in ISO C, the semicolons
3932 are included here rather than in struct-declaration, in order to
3933 describe the syntax with extra semicolons and missing semicolon at
3934 end.)
3936 Objective-C:
3938 struct-declaration-list:
3939 @defs ( class-name )
3941 (Note this does not include a trailing semicolon, but can be
3942 followed by further declarations, and gets a pedwarn-if-pedantic
3943 when followed by a semicolon.) */
3945 static struct c_typespec
3946 c_parser_struct_or_union_specifier (c_parser *parser)
3948 struct c_typespec ret;
3949 bool have_std_attrs;
3950 tree std_attrs = NULL_TREE;
3951 tree attrs;
3952 tree ident = NULL_TREE;
3953 location_t struct_loc;
3954 location_t ident_loc = UNKNOWN_LOCATION;
3955 enum tree_code code;
3956 switch (c_parser_peek_token (parser)->keyword)
3958 case RID_STRUCT:
3959 code = RECORD_TYPE;
3960 break;
3961 case RID_UNION:
3962 code = UNION_TYPE;
3963 break;
3964 default:
3965 gcc_unreachable ();
3967 struct_loc = c_parser_peek_token (parser)->location;
3968 c_parser_consume_token (parser);
3969 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3970 if (have_std_attrs)
3971 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3972 attrs = c_parser_gnu_attributes (parser);
3974 /* Set the location in case we create a decl now. */
3975 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3977 if (c_parser_next_token_is (parser, CPP_NAME))
3979 ident = c_parser_peek_token (parser)->value;
3980 ident_loc = c_parser_peek_token (parser)->location;
3981 struct_loc = ident_loc;
3982 c_parser_consume_token (parser);
3984 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3986 /* Parse a struct or union definition. Start the scope of the
3987 tag before parsing components. */
3988 class c_struct_parse_info *struct_info;
3989 tree type = start_struct (struct_loc, code, ident, &struct_info);
3990 tree postfix_attrs;
3991 /* We chain the components in reverse order, then put them in
3992 forward order at the end. Each struct-declaration may
3993 declare multiple components (comma-separated), so we must use
3994 chainon to join them, although when parsing each
3995 struct-declaration we can use TREE_CHAIN directly.
3997 The theory behind all this is that there will be more
3998 semicolon separated fields than comma separated fields, and
3999 so we'll be minimizing the number of node traversals required
4000 by chainon. */
4001 tree contents;
4002 tree expr = NULL;
4003 timevar_push (TV_PARSE_STRUCT);
4004 contents = NULL_TREE;
4005 c_parser_consume_token (parser);
4006 /* Handle the Objective-C @defs construct,
4007 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
4008 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
4010 tree name;
4011 gcc_assert (c_dialect_objc ());
4012 c_parser_consume_token (parser);
4013 matching_parens parens;
4014 if (!parens.require_open (parser))
4015 goto end_at_defs;
4016 if (c_parser_next_token_is (parser, CPP_NAME)
4017 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
4019 name = c_parser_peek_token (parser)->value;
4020 c_parser_consume_token (parser);
4022 else
4024 c_parser_error (parser, "expected class name");
4025 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4026 goto end_at_defs;
4028 parens.skip_until_found_close (parser);
4029 contents = nreverse (objc_get_class_ivars (name));
4031 end_at_defs:
4032 /* Parse the struct-declarations and semicolons. Problems with
4033 semicolons are diagnosed here; empty structures are diagnosed
4034 elsewhere. */
4035 while (true)
4037 tree decls;
4038 /* Parse any stray semicolon. */
4039 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4041 location_t semicolon_loc
4042 = c_parser_peek_token (parser)->location;
4043 gcc_rich_location richloc (semicolon_loc);
4044 richloc.add_fixit_remove ();
4045 pedwarn (&richloc, OPT_Wpedantic,
4046 "extra semicolon in struct or union specified");
4047 c_parser_consume_token (parser);
4048 continue;
4050 /* Stop if at the end of the struct or union contents. */
4051 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4053 c_parser_consume_token (parser);
4054 break;
4056 /* Accept #pragmas at struct scope. */
4057 if (c_parser_next_token_is (parser, CPP_PRAGMA))
4059 c_parser_pragma (parser, pragma_struct, NULL);
4060 continue;
4062 /* Parse some comma-separated declarations, but not the
4063 trailing semicolon if any. */
4064 decls = c_parser_struct_declaration (parser, &expr);
4065 contents = chainon (decls, contents);
4066 /* If no semicolon follows, either we have a parse error or
4067 are at the end of the struct or union and should
4068 pedwarn. */
4069 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4070 c_parser_consume_token (parser);
4071 else
4073 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4074 pedwarn (c_parser_peek_token (parser)->location, 0,
4075 "no semicolon at end of struct or union");
4076 else if (parser->error
4077 || !c_parser_next_token_starts_declspecs (parser))
4079 c_parser_error (parser, "expected %<;%>");
4080 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
4081 break;
4084 /* If we come here, we have already emitted an error
4085 for an expected `;', identifier or `(', and we also
4086 recovered already. Go on with the next field. */
4089 postfix_attrs = c_parser_gnu_attributes (parser);
4090 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
4091 chainon (std_attrs,
4092 chainon (attrs, postfix_attrs)),
4093 struct_info, &expr);
4094 ret.kind = ctsk_tagdef;
4095 ret.expr = expr;
4096 ret.expr_const_operands = true;
4097 ret.has_enum_type_specifier = false;
4098 timevar_pop (TV_PARSE_STRUCT);
4099 return ret;
4101 else if (!ident)
4103 c_parser_error (parser, "expected %<{%>");
4104 ret.spec = error_mark_node;
4105 ret.kind = ctsk_tagref;
4106 ret.expr = NULL_TREE;
4107 ret.expr_const_operands = true;
4108 ret.has_enum_type_specifier = false;
4109 return ret;
4111 /* Attributes may only appear when the members are defined or in
4112 certain forward declarations. */
4113 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
4114 c_parser_error (parser, "expected %<;%>");
4115 /* ??? Existing practice is that GNU attributes are ignored after
4116 the struct or union keyword when not defining the members. */
4117 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs,
4118 false);
4119 return ret;
4122 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
4123 *without* the trailing semicolon.
4125 struct-declaration:
4126 attribute-specifier-sequence[opt] specifier-qualifier-list
4127 attribute-specifier-sequence[opt] struct-declarator-list
4128 static_assert-declaration-no-semi
4130 specifier-qualifier-list:
4131 type-specifier specifier-qualifier-list[opt]
4132 type-qualifier specifier-qualifier-list[opt]
4133 alignment-specifier specifier-qualifier-list[opt]
4134 gnu-attributes specifier-qualifier-list[opt]
4136 struct-declarator-list:
4137 struct-declarator
4138 struct-declarator-list , gnu-attributes[opt] struct-declarator
4140 struct-declarator:
4141 declarator gnu-attributes[opt]
4142 declarator[opt] : constant-expression gnu-attributes[opt]
4144 GNU extensions:
4146 struct-declaration:
4147 __extension__ struct-declaration
4148 specifier-qualifier-list
4150 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
4151 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
4152 any expression without commas in the syntax (assignment
4153 expressions, not just conditional expressions); assignment
4154 expressions will be diagnosed as non-constant. */
4156 static tree
4157 c_parser_struct_declaration (c_parser *parser, tree *expr)
4159 struct c_declspecs *specs;
4160 tree prefix_attrs;
4161 tree all_prefix_attrs;
4162 tree decls;
4163 location_t decl_loc;
4164 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
4166 int ext;
4167 tree decl;
4168 ext = disable_extension_diagnostics ();
4169 c_parser_consume_token (parser);
4170 decl = c_parser_struct_declaration (parser, expr);
4171 restore_extension_diagnostics (ext);
4172 return decl;
4174 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
4176 c_parser_static_assert_declaration_no_semi (parser);
4177 return NULL_TREE;
4179 specs = build_null_declspecs ();
4180 decl_loc = c_parser_peek_token (parser)->location;
4181 /* Strictly by the standard, we shouldn't allow _Alignas here,
4182 but it appears to have been intended to allow it there, so
4183 we're keeping it as it is until WG14 reaches a conclusion
4184 of N1731.
4185 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
4186 c_parser_declspecs (parser, specs, false, true, true,
4187 true, false, true, true, cla_nonabstract_decl);
4188 if (parser->error)
4189 return NULL_TREE;
4190 if (!specs->declspecs_seen_p)
4192 c_parser_error (parser, "expected specifier-qualifier-list");
4193 return NULL_TREE;
4195 finish_declspecs (specs);
4196 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
4197 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4199 tree ret;
4200 if (specs->typespec_kind == ctsk_none)
4202 pedwarn (decl_loc, OPT_Wpedantic,
4203 "ISO C forbids member declarations with no members");
4204 shadow_tag_warned (specs, pedantic);
4205 ret = NULL_TREE;
4207 else
4209 /* Support for unnamed structs or unions as members of
4210 structs or unions (which is [a] useful and [b] supports
4211 MS P-SDK). */
4212 tree attrs = NULL;
4214 ret = grokfield (c_parser_peek_token (parser)->location,
4215 build_id_declarator (NULL_TREE), specs,
4216 NULL_TREE, &attrs, expr);
4217 if (ret)
4218 decl_attributes (&ret, attrs, 0);
4220 return ret;
4223 /* Provide better error recovery. Note that a type name here is valid,
4224 and will be treated as a field name. */
4225 if (specs->typespec_kind == ctsk_tagdef
4226 && TREE_CODE (specs->type) != ENUMERAL_TYPE
4227 && c_parser_next_token_starts_declspecs (parser)
4228 && !c_parser_next_token_is (parser, CPP_NAME))
4230 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
4231 parser->error = false;
4232 return NULL_TREE;
4235 pending_xref_error ();
4236 prefix_attrs = specs->attrs;
4237 all_prefix_attrs = prefix_attrs;
4238 specs->attrs = NULL_TREE;
4239 decls = NULL_TREE;
4240 while (true)
4242 /* Declaring one or more declarators or un-named bit-fields. */
4243 struct c_declarator *declarator;
4244 bool dummy = false;
4245 if (c_parser_next_token_is (parser, CPP_COLON))
4246 declarator = build_id_declarator (NULL_TREE);
4247 else
4248 declarator = c_parser_declarator (parser,
4249 specs->typespec_kind != ctsk_none,
4250 C_DTR_NORMAL, &dummy);
4251 if (declarator == NULL)
4253 c_parser_skip_to_end_of_block_or_statement (parser);
4254 break;
4256 if (c_parser_next_token_is (parser, CPP_COLON)
4257 || c_parser_next_token_is (parser, CPP_COMMA)
4258 || c_parser_next_token_is (parser, CPP_SEMICOLON)
4259 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
4260 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4262 tree postfix_attrs = NULL_TREE;
4263 tree width = NULL_TREE;
4264 tree d;
4265 if (c_parser_next_token_is (parser, CPP_COLON))
4267 c_parser_consume_token (parser);
4268 location_t loc = c_parser_peek_token (parser)->location;
4269 width = convert_lvalue_to_rvalue (loc,
4270 (c_parser_expr_no_commas
4271 (parser, NULL)),
4272 true, true).value;
4274 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4275 postfix_attrs = c_parser_gnu_attributes (parser);
4276 d = grokfield (c_parser_peek_token (parser)->location,
4277 declarator, specs, width, &all_prefix_attrs, expr);
4278 decl_attributes (&d, chainon (postfix_attrs,
4279 all_prefix_attrs), 0);
4280 DECL_CHAIN (d) = decls;
4281 decls = d;
4282 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4283 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
4284 prefix_attrs);
4285 else
4286 all_prefix_attrs = prefix_attrs;
4287 if (c_parser_next_token_is (parser, CPP_COMMA))
4288 c_parser_consume_token (parser);
4289 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
4290 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4292 /* Semicolon consumed in caller. */
4293 break;
4295 else
4297 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
4298 break;
4301 else
4303 c_parser_error (parser,
4304 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
4305 "%<__attribute__%>");
4306 break;
4309 return decls;
4312 /* Parse a typeof specifier (a GNU extension adopted in C23).
4314 typeof-specifier:
4315 typeof ( expression )
4316 typeof ( type-name )
4317 typeof_unqual ( expression )
4318 typeof_unqual ( type-name )
4321 static struct c_typespec
4322 c_parser_typeof_specifier (c_parser *parser)
4324 bool is_unqual;
4325 bool is_std;
4326 struct c_typespec ret;
4327 ret.kind = ctsk_typeof;
4328 ret.spec = error_mark_node;
4329 ret.expr = NULL_TREE;
4330 ret.expr_const_operands = true;
4331 ret.has_enum_type_specifier = false;
4332 if (c_parser_next_token_is_keyword (parser, RID_TYPEOF))
4334 is_unqual = false;
4335 tree spelling = c_parser_peek_token (parser)->value;
4336 is_std = (flag_isoc23
4337 && strcmp (IDENTIFIER_POINTER (spelling), "typeof") == 0);
4339 else
4341 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF_UNQUAL));
4342 is_unqual = true;
4343 tree spelling = c_parser_peek_token (parser)->value;
4344 is_std = strcmp (IDENTIFIER_POINTER (spelling), "typeof_unqual") == 0;
4346 c_parser_consume_token (parser);
4347 c_inhibit_evaluation_warnings++;
4348 in_typeof++;
4349 matching_parens parens;
4350 if (!parens.require_open (parser))
4352 c_inhibit_evaluation_warnings--;
4353 in_typeof--;
4354 return ret;
4356 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
4358 struct c_type_name *type = c_parser_type_name (parser);
4359 c_inhibit_evaluation_warnings--;
4360 in_typeof--;
4361 if (type != NULL)
4363 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
4364 pop_maybe_used (c_type_variably_modified_p (ret.spec));
4367 else
4369 bool was_vm;
4370 location_t here = c_parser_peek_token (parser)->location;
4371 struct c_expr expr = c_parser_expression (parser);
4372 c_inhibit_evaluation_warnings--;
4373 in_typeof--;
4374 if (TREE_CODE (expr.value) == COMPONENT_REF
4375 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
4376 error_at (here, "%<typeof%> applied to a bit-field");
4377 mark_exp_read (expr.value);
4378 ret.spec = TREE_TYPE (expr.value);
4379 was_vm = c_type_variably_modified_p (ret.spec);
4380 /* This is returned with the type so that when the type is
4381 evaluated, this can be evaluated. */
4382 if (was_vm)
4383 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
4384 pop_maybe_used (was_vm);
4386 parens.skip_until_found_close (parser);
4387 if (ret.spec != error_mark_node)
4389 if (is_unqual && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
4390 ret.spec = TYPE_MAIN_VARIANT (ret.spec);
4391 if (is_std)
4393 /* In ISO C terms, _Noreturn is not part of the type of
4394 expressions such as &abort, but in GCC it is represented
4395 internally as a type qualifier. */
4396 if (TREE_CODE (ret.spec) == FUNCTION_TYPE
4397 && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
4398 ret.spec = TYPE_MAIN_VARIANT (ret.spec);
4399 else if (FUNCTION_POINTER_TYPE_P (ret.spec)
4400 && TYPE_QUALS (TREE_TYPE (ret.spec)) != TYPE_UNQUALIFIED)
4401 ret.spec
4402 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret.spec)));
4405 return ret;
4408 /* Parse an alignment-specifier.
4410 C11 6.7.5:
4412 alignment-specifier:
4413 _Alignas ( type-name )
4414 _Alignas ( constant-expression )
4417 static tree
4418 c_parser_alignas_specifier (c_parser * parser)
4420 tree ret = error_mark_node;
4421 location_t loc = c_parser_peek_token (parser)->location;
4422 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
4423 tree spelling = c_parser_peek_token (parser)->value;
4424 c_parser_consume_token (parser);
4425 if (flag_isoc99)
4426 pedwarn_c99 (loc, OPT_Wpedantic,
4427 "ISO C99 does not support %qE", spelling);
4428 else
4429 pedwarn_c99 (loc, OPT_Wpedantic,
4430 "ISO C90 does not support %qE", spelling);
4431 matching_parens parens;
4432 if (!parens.require_open (parser))
4433 return ret;
4434 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
4436 struct c_type_name *type = c_parser_type_name (parser);
4437 if (type != NULL)
4438 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
4439 false, true, 1);
4441 else
4442 ret = convert_lvalue_to_rvalue (loc,
4443 c_parser_expr_no_commas (parser, NULL),
4444 true, true).value;
4445 parens.skip_until_found_close (parser);
4446 return ret;
4449 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
4450 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
4451 a typedef name may be redeclared; otherwise it may not. KIND
4452 indicates which kind of declarator is wanted. Returns a valid
4453 declarator except in the case of a syntax error in which case NULL is
4454 returned. *SEEN_ID is set to true if an identifier being declared is
4455 seen; this is used to diagnose bad forms of abstract array declarators
4456 and to determine whether an identifier list is syntactically permitted.
4458 declarator:
4459 pointer[opt] direct-declarator
4461 direct-declarator:
4462 identifier
4463 ( gnu-attributes[opt] declarator )
4464 direct-declarator array-declarator
4465 direct-declarator ( parameter-type-list )
4466 direct-declarator ( identifier-list[opt] )
4468 pointer:
4469 * type-qualifier-list[opt]
4470 * type-qualifier-list[opt] pointer
4472 type-qualifier-list:
4473 type-qualifier
4474 gnu-attributes
4475 type-qualifier-list type-qualifier
4476 type-qualifier-list gnu-attributes
4478 array-declarator:
4479 [ type-qualifier-list[opt] assignment-expression[opt] ]
4480 [ static type-qualifier-list[opt] assignment-expression ]
4481 [ type-qualifier-list static assignment-expression ]
4482 [ type-qualifier-list[opt] * ]
4484 parameter-type-list:
4485 parameter-list
4486 parameter-list , ...
4488 parameter-list:
4489 parameter-declaration
4490 parameter-list , parameter-declaration
4492 parameter-declaration:
4493 declaration-specifiers declarator gnu-attributes[opt]
4494 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
4496 identifier-list:
4497 identifier
4498 identifier-list , identifier
4500 abstract-declarator:
4501 pointer
4502 pointer[opt] direct-abstract-declarator
4504 direct-abstract-declarator:
4505 ( gnu-attributes[opt] abstract-declarator )
4506 direct-abstract-declarator[opt] array-declarator
4507 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
4509 GNU extensions:
4511 direct-declarator:
4512 direct-declarator ( parameter-forward-declarations
4513 parameter-type-list[opt] )
4515 direct-abstract-declarator:
4516 direct-abstract-declarator[opt] ( parameter-forward-declarations
4517 parameter-type-list[opt] )
4519 parameter-forward-declarations:
4520 parameter-list ;
4521 parameter-forward-declarations parameter-list ;
4523 The uses of gnu-attributes shown above are GNU extensions.
4525 Some forms of array declarator are not included in C99 in the
4526 syntax for abstract declarators; these are disallowed elsewhere.
4527 This may be a defect (DR#289).
4529 This function also accepts an omitted abstract declarator as being
4530 an abstract declarator, although not part of the formal syntax. */
4532 struct c_declarator *
4533 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4534 bool *seen_id)
4536 /* Parse any initial pointer part. */
4537 if (c_parser_next_token_is (parser, CPP_MULT))
4539 struct c_declspecs *quals_attrs = build_null_declspecs ();
4540 struct c_declarator *inner;
4541 c_parser_consume_token (parser);
4542 c_parser_declspecs (parser, quals_attrs, false, false, true,
4543 false, false, true, false, cla_prefer_id);
4544 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4545 if (inner == NULL)
4546 return NULL;
4547 else
4548 return make_pointer_declarator (quals_attrs, inner);
4550 /* Now we have a direct declarator, direct abstract declarator or
4551 nothing (which counts as a direct abstract declarator here). */
4552 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
4555 /* Parse a direct declarator or direct abstract declarator; arguments
4556 as c_parser_declarator. */
4558 static struct c_declarator *
4559 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4560 bool *seen_id)
4562 /* The direct declarator must start with an identifier (possibly
4563 omitted) or a parenthesized declarator (possibly abstract). In
4564 an ordinary declarator, initial parentheses must start a
4565 parenthesized declarator. In an abstract declarator or parameter
4566 declarator, they could start a parenthesized declarator or a
4567 parameter list. To tell which, the open parenthesis and any
4568 following gnu-attributes must be read. If a declaration
4569 specifier or standard attributes follow, then it is a parameter
4570 list; if the specifier is a typedef name, there might be an
4571 ambiguity about redeclaring it, which is resolved in the
4572 direction of treating it as a typedef name. If a close
4573 parenthesis follows, it is also an empty parameter list, as the
4574 syntax does not permit empty abstract declarators. Otherwise, it
4575 is a parenthesized declarator (in which case the analysis may be
4576 repeated inside it, recursively).
4578 ??? There is an ambiguity in a parameter declaration "int
4579 (__attribute__((foo)) x)", where x is not a typedef name: it
4580 could be an abstract declarator for a function, or declare x with
4581 parentheses. The proper resolution of this ambiguity needs
4582 documenting. At present we follow an accident of the old
4583 parser's implementation, whereby the first parameter must have
4584 some declaration specifiers other than just gnu-attributes. Thus as
4585 a parameter declaration it is treated as a parenthesized
4586 parameter named x, and as an abstract declarator it is
4587 rejected.
4589 ??? Also following the old parser, gnu-attributes inside an empty
4590 parameter list are ignored, making it a list not yielding a
4591 prototype, rather than giving an error or making it have one
4592 parameter with implicit type int.
4594 ??? Also following the old parser, typedef names may be
4595 redeclared in declarators, but not Objective-C class names. */
4597 if (kind != C_DTR_ABSTRACT
4598 && c_parser_next_token_is (parser, CPP_NAME)
4599 && ((type_seen_p
4600 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
4601 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
4602 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
4604 struct c_declarator *inner
4605 = build_id_declarator (c_parser_peek_token (parser)->value);
4606 *seen_id = true;
4607 inner->id_loc = c_parser_peek_token (parser)->location;
4608 c_parser_consume_token (parser);
4609 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4610 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
4611 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4614 if (kind != C_DTR_NORMAL
4615 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4616 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4618 struct c_declarator *inner = build_id_declarator (NULL_TREE);
4619 inner->id_loc = c_parser_peek_token (parser)->location;
4620 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4623 /* Either we are at the end of an abstract declarator, or we have
4624 parentheses. */
4626 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4628 tree attrs;
4629 struct c_declarator *inner;
4630 c_parser_consume_token (parser);
4631 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4632 RID_ATTRIBUTE);
4633 attrs = c_parser_gnu_attributes (parser);
4634 if (kind != C_DTR_NORMAL
4635 && (c_parser_next_token_starts_declspecs (parser)
4636 || (!have_gnu_attrs
4637 && (c_parser_nth_token_starts_std_attributes (parser, 1)
4638 || c_parser_next_token_is (parser, CPP_ELLIPSIS)))
4639 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
4641 struct c_arg_info *args
4642 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
4643 attrs, have_gnu_attrs);
4644 if (args == NULL)
4645 return NULL;
4646 else
4648 inner = build_id_declarator (NULL_TREE);
4649 if (!(args->types
4650 && args->types != error_mark_node
4651 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4652 && c_parser_nth_token_starts_std_attributes (parser, 1))
4654 tree std_attrs
4655 = c_parser_std_attribute_specifier_sequence (parser);
4656 if (std_attrs)
4657 inner = build_attrs_declarator (std_attrs, inner);
4659 inner = build_function_declarator (args, inner);
4660 return c_parser_direct_declarator_inner (parser, *seen_id,
4661 inner);
4664 /* A parenthesized declarator. */
4665 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4666 if (inner != NULL && attrs != NULL)
4667 inner = build_attrs_declarator (attrs, inner);
4668 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4670 c_parser_consume_token (parser);
4671 if (inner == NULL)
4672 return NULL;
4673 else
4674 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4676 else
4678 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4679 "expected %<)%>");
4680 return NULL;
4683 else
4685 if (kind == C_DTR_NORMAL)
4687 c_parser_error (parser, "expected identifier or %<(%>");
4688 return NULL;
4690 else
4691 return build_id_declarator (NULL_TREE);
4695 /* Parse part of a direct declarator or direct abstract declarator,
4696 given that some (in INNER) has already been parsed; ID_PRESENT is
4697 true if an identifier is present, false for an abstract
4698 declarator. */
4700 static struct c_declarator *
4701 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4702 struct c_declarator *inner)
4704 /* Parse a sequence of array declarators and parameter lists. */
4705 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4706 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4708 location_t brace_loc = c_parser_peek_token (parser)->location;
4709 struct c_declarator *declarator;
4710 struct c_declspecs *quals_attrs = build_null_declspecs ();
4711 bool static_seen;
4712 bool star_seen;
4713 struct c_expr dimen;
4714 dimen.value = NULL_TREE;
4715 dimen.original_code = ERROR_MARK;
4716 dimen.original_type = NULL_TREE;
4717 c_parser_consume_token (parser);
4718 c_parser_declspecs (parser, quals_attrs, false, false, true,
4719 false, false, false, false, cla_prefer_id);
4720 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4721 if (static_seen)
4722 c_parser_consume_token (parser);
4723 if (static_seen && !quals_attrs->declspecs_seen_p)
4724 c_parser_declspecs (parser, quals_attrs, false, false, true,
4725 false, false, false, false, cla_prefer_id);
4726 if (!quals_attrs->declspecs_seen_p)
4727 quals_attrs = NULL;
4728 /* If "static" is present, there must be an array dimension.
4729 Otherwise, there may be a dimension, "*", or no
4730 dimension. */
4731 if (static_seen)
4733 star_seen = false;
4734 dimen = c_parser_expr_no_commas (parser, NULL);
4736 else
4738 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4740 dimen.value = NULL_TREE;
4741 star_seen = false;
4743 else if (c_parser_next_token_is (parser, CPP_MULT))
4745 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4747 dimen.value = NULL_TREE;
4748 star_seen = true;
4749 c_parser_consume_token (parser);
4751 else
4753 star_seen = false;
4754 dimen = c_parser_expr_no_commas (parser, NULL);
4757 else
4759 star_seen = false;
4760 dimen = c_parser_expr_no_commas (parser, NULL);
4763 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4764 c_parser_consume_token (parser);
4765 else
4767 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4768 "expected %<]%>");
4769 return NULL;
4771 if (dimen.value)
4772 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4773 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4774 static_seen, star_seen);
4775 if (declarator == NULL)
4776 return NULL;
4777 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4779 tree std_attrs
4780 = c_parser_std_attribute_specifier_sequence (parser);
4781 if (std_attrs)
4782 inner = build_attrs_declarator (std_attrs, inner);
4784 inner = set_array_declarator_inner (declarator, inner);
4785 return c_parser_direct_declarator_inner (parser, id_present, inner);
4787 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4789 tree attrs;
4790 struct c_arg_info *args;
4791 c_parser_consume_token (parser);
4792 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4793 RID_ATTRIBUTE);
4794 attrs = c_parser_gnu_attributes (parser);
4795 args = c_parser_parms_declarator (parser, id_present, attrs,
4796 have_gnu_attrs);
4797 if (args == NULL)
4798 return NULL;
4799 else
4801 if (!(args->types
4802 && args->types != error_mark_node
4803 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4804 && c_parser_nth_token_starts_std_attributes (parser, 1))
4806 tree std_attrs
4807 = c_parser_std_attribute_specifier_sequence (parser);
4808 if (std_attrs)
4809 inner = build_attrs_declarator (std_attrs, inner);
4811 inner = build_function_declarator (args, inner);
4812 return c_parser_direct_declarator_inner (parser, id_present, inner);
4815 return inner;
4818 /* Parse a parameter list or identifier list, including the closing
4819 parenthesis but not the opening one. ATTRS are the gnu-attributes
4820 at the start of the list. ID_LIST_OK is true if an identifier list
4821 is acceptable; such a list must not have attributes at the start.
4822 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4823 attributes) were present (in which case standard attributes cannot
4824 occur). */
4826 static struct c_arg_info *
4827 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4828 bool have_gnu_attrs)
4830 push_scope ();
4831 declare_parm_level ();
4832 /* If the list starts with an identifier, it is an identifier list.
4833 Otherwise, it is either a prototype list or an empty list. */
4834 if (id_list_ok
4835 && !attrs
4836 && c_parser_next_token_is (parser, CPP_NAME)
4837 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4839 /* Look ahead to detect typos in type names. */
4840 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4841 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4842 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4843 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4844 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4846 tree list = NULL_TREE, *nextp = &list;
4847 while (c_parser_next_token_is (parser, CPP_NAME)
4848 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4850 *nextp = build_tree_list (NULL_TREE,
4851 c_parser_peek_token (parser)->value);
4852 nextp = & TREE_CHAIN (*nextp);
4853 c_parser_consume_token (parser);
4854 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4855 break;
4856 c_parser_consume_token (parser);
4857 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4859 c_parser_error (parser, "expected identifier");
4860 break;
4863 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4865 struct c_arg_info *ret = build_arg_info ();
4866 ret->types = list;
4867 c_parser_consume_token (parser);
4868 pop_scope ();
4869 return ret;
4871 else
4873 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4874 "expected %<)%>");
4875 pop_scope ();
4876 return NULL;
4879 else
4881 struct c_arg_info *ret
4882 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4883 pop_scope ();
4884 return ret;
4888 /* Parse a parameter list (possibly empty), including the closing
4889 parenthesis but not the opening one. ATTRS are the gnu-attributes
4890 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4891 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4892 which means standard attributes cannot start the list. EXPR is
4893 NULL or an expression that needs to be evaluated for the side
4894 effects of array size expressions in the parameters. */
4896 static struct c_arg_info *
4897 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4898 bool have_gnu_attrs)
4900 bool bad_parm = false;
4902 /* ??? Following the old parser, forward parameter declarations may
4903 use abstract declarators, and if no real parameter declarations
4904 follow the forward declarations then this is not diagnosed. Also
4905 note as above that gnu-attributes are ignored as the only contents of
4906 the parentheses, or as the only contents after forward
4907 declarations. */
4908 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4910 struct c_arg_info *ret = build_arg_info ();
4911 c_parser_consume_token (parser);
4912 return ret;
4914 if (c_parser_next_token_is (parser, CPP_ELLIPSIS) && !have_gnu_attrs)
4916 struct c_arg_info *ret = build_arg_info ();
4918 ret->types = NULL_TREE;
4919 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
4920 "ISO C requires a named argument before %<...%> "
4921 "before C23");
4922 c_parser_consume_token (parser);
4923 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4925 ret->no_named_args_stdarg_p = true;
4926 c_parser_consume_token (parser);
4927 return ret;
4929 else
4931 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4932 "expected %<)%>");
4933 return NULL;
4936 /* Nonempty list of parameters, either terminated with semicolon
4937 (forward declarations; recurse) or with close parenthesis (normal
4938 function) or with ", ... )" (variadic function). */
4939 while (true)
4941 /* Parse a parameter. */
4942 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4943 have_gnu_attrs);
4944 attrs = NULL_TREE;
4945 have_gnu_attrs = false;
4946 if (parm == NULL)
4947 bad_parm = true;
4948 else
4949 push_parm_decl (parm, &expr);
4950 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4952 tree new_attrs;
4953 c_parser_consume_token (parser);
4954 mark_forward_parm_decls ();
4955 bool new_have_gnu_attrs
4956 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4957 new_attrs = c_parser_gnu_attributes (parser);
4958 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4959 new_have_gnu_attrs);
4961 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4963 c_parser_consume_token (parser);
4964 if (bad_parm)
4965 return NULL;
4966 else
4967 return get_parm_info (false, expr);
4969 if (!c_parser_require (parser, CPP_COMMA,
4970 "expected %<;%>, %<,%> or %<)%>",
4971 UNKNOWN_LOCATION, false))
4973 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4974 return NULL;
4976 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4978 c_parser_consume_token (parser);
4979 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4981 c_parser_consume_token (parser);
4982 if (bad_parm)
4983 return NULL;
4984 else
4985 return get_parm_info (true, expr);
4987 else
4989 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4990 "expected %<)%>");
4991 return NULL;
4997 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4998 start of the declaration if it is the first parameter;
4999 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
5000 empty) there. */
5002 static struct c_parm *
5003 c_parser_parameter_declaration (c_parser *parser, tree attrs,
5004 bool have_gnu_attrs)
5006 struct c_declspecs *specs;
5007 struct c_declarator *declarator;
5008 tree prefix_attrs;
5009 tree postfix_attrs = NULL_TREE;
5010 bool dummy = false;
5012 /* Accept #pragmas between parameter declarations. */
5013 while (c_parser_next_token_is (parser, CPP_PRAGMA))
5014 c_parser_pragma (parser, pragma_param, NULL);
5016 if (!c_parser_next_token_starts_declspecs (parser)
5017 && !c_parser_nth_token_starts_std_attributes (parser, 1))
5019 c_token *token = c_parser_peek_token (parser);
5020 if (parser->error)
5021 return NULL;
5022 c_parser_set_source_position_from_token (token);
5023 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
5025 auto_diagnostic_group d;
5026 name_hint hint = lookup_name_fuzzy (token->value,
5027 FUZZY_LOOKUP_TYPENAME,
5028 token->location);
5029 if (const char *suggestion = hint.suggestion ())
5031 gcc_rich_location richloc (token->location);
5032 richloc.add_fixit_replace (suggestion);
5033 error_at (&richloc,
5034 "unknown type name %qE; did you mean %qs?",
5035 token->value, suggestion);
5037 else
5038 error_at (token->location, "unknown type name %qE", token->value);
5039 parser->error = true;
5041 /* ??? In some Objective-C cases '...' isn't applicable so there
5042 should be a different message. */
5043 else
5044 c_parser_error (parser,
5045 "expected declaration specifiers or %<...%>");
5046 c_parser_skip_to_end_of_parameter (parser);
5047 return NULL;
5050 location_t start_loc = c_parser_peek_token (parser)->location;
5052 specs = build_null_declspecs ();
5053 if (attrs)
5055 declspecs_add_attrs (input_location, specs, attrs);
5056 attrs = NULL_TREE;
5058 c_parser_declspecs (parser, specs, true, true, true, true, false,
5059 !have_gnu_attrs, true, cla_nonabstract_decl);
5060 finish_declspecs (specs);
5061 pending_xref_error ();
5062 prefix_attrs = specs->attrs;
5063 specs->attrs = NULL_TREE;
5064 declarator = c_parser_declarator (parser,
5065 specs->typespec_kind != ctsk_none,
5066 C_DTR_PARM, &dummy);
5067 if (declarator == NULL)
5069 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5070 return NULL;
5072 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5073 postfix_attrs = c_parser_gnu_attributes (parser);
5075 /* Generate a location for the parameter, ranging from the start of the
5076 initial token to the end of the final token.
5078 If we have a identifier, then use it for the caret location, e.g.
5080 extern int callee (int one, int (*two)(int, int), float three);
5081 ~~~~~~^~~~~~~~~~~~~~
5083 otherwise, reuse the start location for the caret location e.g.:
5085 extern int callee (int one, int (*)(int, int), float three);
5086 ^~~~~~~~~~~~~~~~~
5088 location_t end_loc = parser->last_token_location;
5090 /* Find any cdk_id declarator; determine if we have an identifier. */
5091 c_declarator *id_declarator = declarator;
5092 while (id_declarator && id_declarator->kind != cdk_id)
5093 id_declarator = id_declarator->declarator;
5094 location_t caret_loc = (id_declarator->u.id.id
5095 ? id_declarator->id_loc
5096 : start_loc);
5097 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
5099 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
5100 declarator, param_loc);
5103 /* Parse a string literal in an asm expression. It should not be
5104 translated, and wide string literals are an error although
5105 permitted by the syntax. This is a GNU extension.
5107 asm-string-literal:
5108 string-literal
5111 static tree
5112 c_parser_asm_string_literal (c_parser *parser)
5114 tree str;
5115 int save_flag = warn_overlength_strings;
5116 warn_overlength_strings = 0;
5117 str = c_parser_string_literal (parser, false, false).value;
5118 warn_overlength_strings = save_flag;
5119 return str;
5122 /* Parse a simple asm expression. This is used in restricted
5123 contexts, where a full expression with inputs and outputs does not
5124 make sense. This is a GNU extension.
5126 simple-asm-expr:
5127 asm ( asm-string-literal )
5130 static tree
5131 c_parser_simple_asm_expr (c_parser *parser)
5133 tree str;
5134 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
5135 c_parser_consume_token (parser);
5136 matching_parens parens;
5137 if (!parens.require_open (parser))
5138 return NULL_TREE;
5139 str = c_parser_asm_string_literal (parser);
5140 if (!parens.require_close (parser))
5142 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5143 return NULL_TREE;
5145 return str;
5148 static tree
5149 c_parser_gnu_attribute_any_word (c_parser *parser)
5151 tree attr_name = NULL_TREE;
5153 if (c_parser_next_token_is (parser, CPP_KEYWORD))
5155 /* ??? See comment above about what keywords are accepted here. */
5156 bool ok;
5157 switch (c_parser_peek_token (parser)->keyword)
5159 case RID_STATIC:
5160 case RID_UNSIGNED:
5161 case RID_LONG:
5162 case RID_CONST:
5163 case RID_EXTERN:
5164 case RID_REGISTER:
5165 case RID_TYPEDEF:
5166 case RID_SHORT:
5167 case RID_INLINE:
5168 case RID_NORETURN:
5169 case RID_VOLATILE:
5170 case RID_SIGNED:
5171 case RID_AUTO:
5172 case RID_RESTRICT:
5173 case RID_COMPLEX:
5174 case RID_THREAD:
5175 case RID_INT:
5176 case RID_CHAR:
5177 case RID_FLOAT:
5178 case RID_DOUBLE:
5179 case RID_VOID:
5180 case RID_DFLOAT32:
5181 case RID_DFLOAT64:
5182 case RID_DFLOAT128:
5183 CASE_RID_FLOATN_NX:
5184 case RID_BOOL:
5185 case RID_BITINT:
5186 case RID_FRACT:
5187 case RID_ACCUM:
5188 case RID_SAT:
5189 case RID_TRANSACTION_ATOMIC:
5190 case RID_TRANSACTION_CANCEL:
5191 case RID_ATOMIC:
5192 case RID_AUTO_TYPE:
5193 case RID_CONSTEXPR:
5194 case RID_INT_N_0:
5195 case RID_INT_N_1:
5196 case RID_INT_N_2:
5197 case RID_INT_N_3:
5198 ok = true;
5199 break;
5200 default:
5201 ok = false;
5202 break;
5204 if (!ok)
5205 return NULL_TREE;
5207 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
5208 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
5210 else if (c_parser_next_token_is (parser, CPP_NAME))
5211 attr_name = c_parser_peek_token (parser)->value;
5213 return attr_name;
5216 /* Parse attribute arguments. This is a common form of syntax
5217 covering all currently valid GNU and standard attributes.
5219 gnu-attribute-arguments:
5220 identifier
5221 identifier , nonempty-expr-list
5222 expr-list
5224 where the "identifier" must not be declared as a type. ??? Why not
5225 allow identifiers declared as types to start the arguments? */
5227 static tree
5228 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
5229 bool require_string, bool assume_attr,
5230 bool allow_empty_args)
5232 vec<tree, va_gc> *expr_list;
5233 tree attr_args;
5234 /* Parse the attribute contents. If they start with an
5235 identifier which is followed by a comma or close
5236 parenthesis, then the arguments start with that
5237 identifier; otherwise they are an expression list.
5238 In objective-c the identifier may be a classname. */
5239 if (c_parser_next_token_is (parser, CPP_NAME)
5240 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
5241 || (c_dialect_objc ()
5242 && c_parser_peek_token (parser)->id_kind
5243 == C_ID_CLASSNAME))
5244 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
5245 || (c_parser_peek_2nd_token (parser)->type
5246 == CPP_CLOSE_PAREN))
5247 && (takes_identifier
5248 || (c_dialect_objc ()
5249 && !assume_attr
5250 && c_parser_peek_token (parser)->id_kind
5251 == C_ID_CLASSNAME)))
5253 tree arg1 = c_parser_peek_token (parser)->value;
5254 c_parser_consume_token (parser);
5255 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5256 attr_args = build_tree_list (NULL_TREE, arg1);
5257 else
5259 tree tree_list;
5260 c_parser_consume_token (parser);
5261 expr_list = c_parser_expr_list (parser, false, true,
5262 NULL, NULL, NULL, NULL);
5263 tree_list = build_tree_list_vec (expr_list);
5264 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
5265 release_tree_vector (expr_list);
5268 else
5270 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5272 if (!allow_empty_args)
5273 error_at (c_parser_peek_token (parser)->location,
5274 "parentheses must be omitted if "
5275 "attribute argument list is empty");
5276 attr_args = NULL_TREE;
5278 else if (require_string)
5280 /* The only valid argument for this attribute is a string
5281 literal. Handle this specially here to avoid accepting
5282 string literals with excess parentheses. */
5283 tree string = c_parser_string_literal (parser, false, true).value;
5284 attr_args = build_tree_list (NULL_TREE, string);
5286 else if (assume_attr)
5288 tree cond
5289 = c_parser_conditional_expression (parser, NULL, NULL_TREE).value;
5290 if (!c_parser_next_token_is (parser, CPP_COMMA))
5291 attr_args = build_tree_list (NULL_TREE, cond);
5292 else
5294 tree tree_list;
5295 c_parser_consume_token (parser);
5296 expr_list = c_parser_expr_list (parser, false, true,
5297 NULL, NULL, NULL, NULL);
5298 tree_list = build_tree_list_vec (expr_list);
5299 attr_args = tree_cons (NULL_TREE, cond, tree_list);
5300 release_tree_vector (expr_list);
5303 else
5305 expr_list = c_parser_expr_list (parser, false, true,
5306 NULL, NULL, NULL, NULL);
5307 attr_args = build_tree_list_vec (expr_list);
5308 release_tree_vector (expr_list);
5311 return attr_args;
5314 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
5316 gnu-attributes:
5317 empty
5318 gnu-attributes gnu-attribute
5320 gnu-attribute:
5321 __attribute__ ( ( gnu-attribute-list ) )
5323 gnu-attribute-list:
5324 gnu-attrib
5325 gnu-attribute_list , gnu-attrib
5327 gnu-attrib:
5328 empty
5329 any-word
5330 any-word ( gnu-attribute-arguments )
5332 where "any-word" may be any identifier (including one declared as a
5333 type), a reserved word storage class specifier, type specifier or
5334 type qualifier. ??? This still leaves out most reserved keywords
5335 (following the old parser), shouldn't we include them?
5336 When EXPECT_COMMA is true, expect the attribute to be preceded
5337 by a comma and fail if it isn't.
5338 When EMPTY_OK is true, allow and consume any number of consecutive
5339 commas with no attributes in between. */
5341 static tree
5342 c_parser_gnu_attribute (c_parser *parser, tree attrs,
5343 bool expect_comma = false, bool empty_ok = true)
5345 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
5346 if (!comma_first
5347 && !c_parser_next_token_is (parser, CPP_NAME)
5348 && !c_parser_next_token_is (parser, CPP_KEYWORD))
5349 return NULL_TREE;
5351 while (c_parser_next_token_is (parser, CPP_COMMA))
5353 c_parser_consume_token (parser);
5354 if (!empty_ok)
5355 return attrs;
5358 tree attr_name = c_parser_gnu_attribute_any_word (parser);
5359 if (attr_name == NULL_TREE)
5360 return NULL_TREE;
5362 attr_name = canonicalize_attr_name (attr_name);
5363 c_parser_consume_token (parser);
5365 tree attr;
5366 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5368 if (expect_comma && !comma_first)
5370 /* A comma is missing between the last attribute on the chain
5371 and this one. */
5372 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5373 "expected %<)%>");
5374 return error_mark_node;
5376 attr = build_tree_list (attr_name, NULL_TREE);
5377 /* Add this attribute to the list. */
5378 attrs = chainon (attrs, attr);
5379 return attrs;
5381 c_parser_consume_token (parser);
5383 tree attr_args
5384 = c_parser_attribute_arguments (parser,
5385 attribute_takes_identifier_p (attr_name),
5386 false,
5387 is_attribute_p ("assume", attr_name),
5388 true);
5390 attr = build_tree_list (attr_name, attr_args);
5391 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5392 c_parser_consume_token (parser);
5393 else
5395 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5396 "expected %<)%>");
5397 return error_mark_node;
5400 if (expect_comma && !comma_first)
5402 /* A comma is missing between the last attribute on the chain
5403 and this one. */
5404 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5405 "expected %<)%>");
5406 return error_mark_node;
5409 /* Add this attribute to the list. */
5410 attrs = chainon (attrs, attr);
5411 return attrs;
5414 static tree
5415 c_parser_gnu_attributes (c_parser *parser)
5417 tree attrs = NULL_TREE;
5418 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5420 bool save_translate_strings_p = parser->translate_strings_p;
5421 parser->translate_strings_p = false;
5422 /* Consume the `__attribute__' keyword. */
5423 c_parser_consume_token (parser);
5424 /* Look for the two `(' tokens. */
5425 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5427 parser->translate_strings_p = save_translate_strings_p;
5428 return attrs;
5430 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5432 parser->translate_strings_p = save_translate_strings_p;
5433 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5434 return attrs;
5436 /* Parse the attribute list. Require a comma between successive
5437 (possibly empty) attributes. */
5438 for (bool expect_comma = false; ; expect_comma = true)
5440 /* Parse a single attribute. */
5441 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
5442 if (attr == error_mark_node)
5443 return attrs;
5444 if (!attr)
5445 break;
5446 attrs = attr;
5449 /* Look for the two `)' tokens. */
5450 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5451 c_parser_consume_token (parser);
5452 else
5454 parser->translate_strings_p = save_translate_strings_p;
5455 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5456 "expected %<)%>");
5457 return attrs;
5459 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5460 c_parser_consume_token (parser);
5461 else
5463 parser->translate_strings_p = save_translate_strings_p;
5464 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5465 "expected %<)%>");
5466 return attrs;
5468 parser->translate_strings_p = save_translate_strings_p;
5471 return attrs;
5474 /* Parse an optional balanced token sequence.
5476 balanced-token-sequence:
5477 balanced-token
5478 balanced-token-sequence balanced-token
5480 balanced-token:
5481 ( balanced-token-sequence[opt] )
5482 [ balanced-token-sequence[opt] ]
5483 { balanced-token-sequence[opt] }
5484 any token other than ()[]{}
5487 static void
5488 c_parser_balanced_token_sequence (c_parser *parser)
5490 while (true)
5492 c_token *token = c_parser_peek_token (parser);
5493 switch (token->type)
5495 case CPP_OPEN_BRACE:
5497 matching_braces braces;
5498 braces.consume_open (parser);
5499 c_parser_balanced_token_sequence (parser);
5500 braces.require_close (parser);
5501 break;
5504 case CPP_OPEN_PAREN:
5506 matching_parens parens;
5507 parens.consume_open (parser);
5508 c_parser_balanced_token_sequence (parser);
5509 parens.require_close (parser);
5510 break;
5513 case CPP_OPEN_SQUARE:
5514 c_parser_consume_token (parser);
5515 c_parser_balanced_token_sequence (parser);
5516 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5517 break;
5519 case CPP_CLOSE_BRACE:
5520 case CPP_CLOSE_PAREN:
5521 case CPP_CLOSE_SQUARE:
5522 case CPP_EOF:
5523 return;
5525 case CPP_PRAGMA:
5526 c_parser_consume_pragma (parser);
5527 c_parser_skip_to_pragma_eol (parser, false);
5528 break;
5530 default:
5531 c_parser_consume_token (parser);
5532 break;
5537 static bool c_parser_check_balanced_raw_token_sequence (c_parser *,
5538 unsigned int *);
5540 /* Parse arguments of omp::directive or omp::decl attribute.
5542 directive-name ,[opt] clause-list[opt]
5544 For directive just remember the tokens in a vector for subsequent
5545 parsing. */
5547 static void
5548 c_parser_omp_directive_args (c_parser *parser, tree attribute, bool decl_p)
5550 unsigned int n = 1;
5551 c_token *first = c_parser_peek_token (parser);
5552 if (!c_parser_check_balanced_raw_token_sequence (parser, &n)
5553 || (c_parser_peek_nth_token_raw (parser, n)->type
5554 != CPP_CLOSE_PAREN))
5556 c_parser_balanced_token_sequence (parser);
5557 TREE_VALUE (attribute) = NULL_TREE;
5558 return;
5560 if (n == 1)
5562 error_at (first->location, "expected OpenMP directive name");
5563 TREE_VALUE (attribute) = NULL_TREE;
5564 return;
5566 vec<c_token, va_gc> *v;
5567 vec_alloc (v, n - 1);
5568 for (--n; n; --n)
5570 c_token *tok = c_parser_peek_token (parser);
5571 v->quick_push (*tok);
5572 c_parser_consume_token (parser);
5574 tree arg = make_node (C_TOKEN_VEC);
5575 C_TOKEN_VEC_TOKENS (arg) = v;
5576 if (decl_p)
5577 TREE_PUBLIC (arg) = 1;
5578 TREE_VALUE (attribute) = tree_cons (NULL_TREE, arg, TREE_VALUE (attribute));
5581 /* Parse arguments of omp::sequence attribute.
5583 omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... */
5585 static void
5586 c_parser_omp_sequence_args (c_parser *parser, tree attribute)
5590 c_token *token = c_parser_peek_token (parser);
5591 if (token->type == CPP_NAME
5592 && strcmp (IDENTIFIER_POINTER (token->value), "omp") == 0
5593 && c_parser_peek_2nd_token (parser)->type == CPP_SCOPE)
5595 c_parser_consume_token (parser);
5596 c_parser_consume_token (parser);
5597 token = c_parser_peek_token (parser);
5599 bool directive = false;
5600 const char *p;
5601 if (token->type != CPP_NAME)
5602 p = "";
5603 else
5604 p = IDENTIFIER_POINTER (token->value);
5605 if (strcmp (p, "directive") == 0)
5606 directive = true;
5607 else if (strcmp (p, "sequence") != 0)
5609 error_at (token->location, "expected %<directive%> or %<sequence%>");
5610 unsigned nesting_depth = 0;
5612 while (true)
5614 /* Peek at the next token. */
5615 token = c_parser_peek_token (parser);
5616 /* If we've reached the token we want, consume it and stop. */
5617 if ((token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
5618 && !nesting_depth)
5619 break;
5620 /* If we've run out of tokens, stop. */
5621 if (token->type == CPP_EOF)
5622 break;
5623 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
5624 break;
5625 if (token->type == CPP_OPEN_BRACE
5626 || token->type == CPP_OPEN_PAREN
5627 || token->type == CPP_OPEN_SQUARE)
5628 ++nesting_depth;
5629 else if (token->type == CPP_CLOSE_BRACE
5630 || token->type == CPP_CLOSE_PAREN
5631 || token->type == CPP_CLOSE_SQUARE)
5633 if (nesting_depth-- == 0)
5634 break;
5636 /* Consume this token. */
5637 c_parser_consume_token (parser);
5639 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5640 break;
5641 c_parser_consume_token (parser);
5642 continue;
5644 c_parser_consume_token (parser);
5645 matching_parens parens;
5646 if (parens.require_open (parser))
5648 if (directive)
5649 c_parser_omp_directive_args (parser, attribute, false);
5650 else
5651 c_parser_omp_sequence_args (parser, attribute);
5652 parens.skip_until_found_close (parser);
5653 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5654 break;
5655 c_parser_consume_token (parser);
5657 else if (c_parser_next_token_is_not (parser, CPP_COMMA))
5658 break;
5659 else
5660 c_parser_consume_token (parser);
5662 while (1);
5665 /* Parse standard (C23) attributes (including GNU attributes in the
5666 gnu:: namespace).
5668 attribute-specifier-sequence:
5669 attribute-specifier-sequence[opt] attribute-specifier
5671 attribute-specifier:
5672 [ [ attribute-list ] ]
5674 attribute-list:
5675 attribute[opt]
5676 attribute-list, attribute[opt]
5678 attribute:
5679 attribute-token attribute-argument-clause[opt]
5681 attribute-token:
5682 standard-attribute
5683 attribute-prefixed-token
5685 standard-attribute:
5686 identifier
5688 attribute-prefixed-token:
5689 attribute-prefix :: identifier
5691 attribute-prefix:
5692 identifier
5694 attribute-argument-clause:
5695 ( balanced-token-sequence[opt] )
5697 Keywords are accepted as identifiers for this purpose.
5699 As an extension, we permit an attribute-specifier to be:
5701 [ [ __extension__ attribute-list ] ]
5703 Two colons are then accepted as a synonym for ::. No attempt is made
5704 to check whether the colons are immediately adjacent. LOOSE_SCOPE_P
5705 indicates whether this relaxation is in effect. */
5707 static tree
5708 c_parser_std_attribute (c_parser *parser, bool for_tm)
5710 c_token *token = c_parser_peek_token (parser);
5711 tree ns, name, attribute;
5713 /* Parse the attribute-token. */
5714 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5716 c_parser_error (parser, "expected identifier");
5717 return error_mark_node;
5719 name = canonicalize_attr_name (token->value);
5720 c_parser_consume_token (parser);
5721 if (c_parser_next_token_is (parser, CPP_SCOPE)
5722 || (c_parser_next_token_is (parser, CPP_COLON)
5723 && (c_parser_peek_token (parser)->flags & COLON_SCOPE) != 0
5724 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5726 ns = name;
5727 if (c_parser_next_token_is (parser, CPP_COLON))
5728 c_parser_consume_token (parser);
5729 c_parser_consume_token (parser);
5730 token = c_parser_peek_token (parser);
5731 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5733 c_parser_error (parser, "expected identifier");
5734 return error_mark_node;
5736 name = canonicalize_attr_name (token->value);
5737 c_parser_consume_token (parser);
5739 else
5740 ns = NULL_TREE;
5741 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
5743 /* Parse the arguments, if any. */
5744 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
5745 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5747 if ((flag_openmp || flag_openmp_simd)
5748 && ns
5749 && is_attribute_p ("omp", ns)
5750 && (is_attribute_p ("directive", name)
5751 || is_attribute_p ("sequence", name)
5752 || is_attribute_p ("decl", name)))
5754 error ("%<omp::%E%> attribute requires argument", name);
5755 return error_mark_node;
5757 goto out;
5760 location_t open_loc = c_parser_peek_token (parser)->location;
5761 matching_parens parens;
5762 parens.consume_open (parser);
5763 if ((as && as->max_length == 0)
5764 /* Special-case the transactional-memory attribute "outer",
5765 which is specially handled but not registered as an
5766 attribute, to avoid allowing arbitrary balanced token
5767 sequences as arguments. */
5768 || is_attribute_p ("outer", name))
5770 error_at (open_loc, "%qE attribute does not take any arguments", name);
5771 parens.skip_until_found_close (parser);
5772 return error_mark_node;
5774 /* If this is a fake attribute created to handle -Wno-attributes,
5775 we must skip parsing the arguments. */
5776 if (as && !attribute_ignored_p (as))
5778 bool takes_identifier
5779 = (ns != NULL_TREE
5780 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5781 && attribute_takes_identifier_p (name));
5782 bool require_string
5783 = (ns == NULL_TREE
5784 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
5785 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
5786 bool assume_attr
5787 = (ns != NULL_TREE
5788 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5789 && strcmp (IDENTIFIER_POINTER (name), "assume") == 0);
5790 TREE_VALUE (attribute)
5791 = c_parser_attribute_arguments (parser, takes_identifier,
5792 require_string, assume_attr, false);
5794 else
5796 if ((flag_openmp || flag_openmp_simd)
5797 && ns
5798 && is_attribute_p ("omp", ns))
5800 if (is_attribute_p ("directive", name))
5802 c_parser_omp_directive_args (parser, attribute, false);
5803 parens.skip_until_found_close (parser);
5804 return attribute;
5806 else if (is_attribute_p ("decl", name))
5808 TREE_VALUE (TREE_PURPOSE (attribute))
5809 = get_identifier ("directive");
5810 c_parser_omp_directive_args (parser, attribute, true);
5811 parens.skip_until_found_close (parser);
5812 return attribute;
5814 else if (is_attribute_p ("sequence", name))
5816 TREE_VALUE (TREE_PURPOSE (attribute))
5817 = get_identifier ("directive");
5818 c_parser_omp_sequence_args (parser, attribute);
5819 parens.skip_until_found_close (parser);
5820 TREE_VALUE (attribute) = nreverse (TREE_VALUE (attribute));
5821 return attribute;
5824 c_parser_balanced_token_sequence (parser);
5826 parens.require_close (parser);
5828 out:
5829 if (ns == NULL_TREE && !for_tm && !as)
5831 /* An attribute with standard syntax and no namespace specified
5832 is a constraint violation if it is not one of the known
5833 standard attributes. Diagnose it here with a pedwarn and
5834 then discard it to prevent a duplicate warning later. */
5835 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
5836 name);
5837 return error_mark_node;
5839 return attribute;
5842 static tree
5843 c_parser_std_attribute_list (c_parser *parser, bool for_tm)
5845 tree attributes = NULL_TREE;
5846 while (true)
5848 c_token *token = c_parser_peek_token (parser);
5849 if (token->type == CPP_CLOSE_SQUARE)
5850 break;
5851 if (token->type == CPP_COMMA)
5853 c_parser_consume_token (parser);
5854 continue;
5856 tree attribute = c_parser_std_attribute (parser, for_tm);
5857 if (attribute != error_mark_node)
5859 TREE_CHAIN (attribute) = attributes;
5860 attributes = attribute;
5862 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5863 break;
5865 return attributes;
5868 static tree
5869 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
5871 location_t loc = c_parser_peek_token (parser)->location;
5872 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5873 return NULL_TREE;
5874 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5876 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5877 return NULL_TREE;
5879 tree attributes;
5880 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5882 auto ext = disable_extension_diagnostics ();
5883 c_parser_consume_token (parser);
5884 attributes = c_parser_std_attribute_list (parser, for_tm);
5885 restore_extension_diagnostics (ext);
5887 else
5889 if (!for_tm)
5890 pedwarn_c11 (loc, OPT_Wpedantic,
5891 "ISO C does not support %<[[]]%> attributes before C23");
5892 attributes = c_parser_std_attribute_list (parser, for_tm);
5894 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5895 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5896 return nreverse (attributes);
5899 /* Look past an optional balanced token sequence of raw look-ahead
5900 tokens starting with the *Nth token. *N is updated to point to the
5901 following token. Return true if such a sequence was found, false
5902 if the tokens parsed were not balanced. */
5904 static bool
5905 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5907 while (true)
5909 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5910 switch (token->type)
5912 case CPP_OPEN_BRACE:
5914 ++*n;
5915 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5917 token = c_parser_peek_nth_token_raw (parser, *n);
5918 if (token->type == CPP_CLOSE_BRACE)
5919 ++*n;
5920 else
5921 return false;
5923 else
5924 return false;
5925 break;
5928 case CPP_OPEN_PAREN:
5930 ++*n;
5931 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5933 token = c_parser_peek_nth_token_raw (parser, *n);
5934 if (token->type == CPP_CLOSE_PAREN)
5935 ++*n;
5936 else
5937 return false;
5939 else
5940 return false;
5941 break;
5944 case CPP_OPEN_SQUARE:
5946 ++*n;
5947 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5949 token = c_parser_peek_nth_token_raw (parser, *n);
5950 if (token->type == CPP_CLOSE_SQUARE)
5951 ++*n;
5952 else
5953 return false;
5955 else
5956 return false;
5957 break;
5960 case CPP_CLOSE_BRACE:
5961 case CPP_CLOSE_PAREN:
5962 case CPP_CLOSE_SQUARE:
5963 case CPP_EOF:
5964 return true;
5966 default:
5967 ++*n;
5968 break;
5973 /* Return whether standard attributes start with the Nth token. */
5975 static bool
5976 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5978 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5979 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5980 return false;
5981 /* In C, '[[' must start attributes. In Objective-C, we need to
5982 check whether '[[' is matched by ']]'. */
5983 if (!c_dialect_objc ())
5984 return true;
5985 n += 2;
5986 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5987 return false;
5988 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5989 if (token->type != CPP_CLOSE_SQUARE)
5990 return false;
5991 token = c_parser_peek_nth_token_raw (parser, n + 1);
5992 return token->type == CPP_CLOSE_SQUARE;
5995 static tree
5996 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5998 tree attributes = NULL_TREE;
6001 tree attrs = c_parser_std_attribute_specifier (parser, false);
6002 attributes = chainon (attributes, attrs);
6004 while (c_parser_nth_token_starts_std_attributes (parser, 1));
6005 return attributes;
6008 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
6009 says whether alignment specifiers are OK (only in cases that might
6010 be the type name of a compound literal).
6012 type-name:
6013 specifier-qualifier-list abstract-declarator[opt]
6016 struct c_type_name *
6017 c_parser_type_name (c_parser *parser, bool alignas_ok)
6019 struct c_declspecs *specs = build_null_declspecs ();
6020 struct c_declarator *declarator;
6021 struct c_type_name *ret;
6022 bool dummy = false;
6023 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
6024 false, true, cla_prefer_type);
6025 if (!specs->declspecs_seen_p)
6027 c_parser_error (parser, "expected specifier-qualifier-list");
6028 return NULL;
6030 if (specs->type != error_mark_node)
6032 pending_xref_error ();
6033 finish_declspecs (specs);
6035 declarator = c_parser_declarator (parser,
6036 specs->typespec_kind != ctsk_none,
6037 C_DTR_ABSTRACT, &dummy);
6038 if (declarator == NULL)
6039 return NULL;
6040 ret = XOBNEW (&parser_obstack, struct c_type_name);
6041 ret->specs = specs;
6042 ret->declarator = declarator;
6043 return ret;
6046 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
6048 initializer:
6049 assignment-expression
6050 { initializer-list }
6051 { initializer-list , }
6053 initializer-list:
6054 designation[opt] initializer
6055 initializer-list , designation[opt] initializer
6057 designation:
6058 designator-list =
6060 designator-list:
6061 designator
6062 designator-list designator
6064 designator:
6065 array-designator
6066 . identifier
6068 array-designator:
6069 [ constant-expression ]
6071 GNU extensions:
6073 initializer:
6076 designation:
6077 array-designator
6078 identifier :
6080 array-designator:
6081 [ constant-expression ... constant-expression ]
6083 Any expression without commas is accepted in the syntax for the
6084 constant-expressions, with non-constant expressions rejected later.
6086 DECL is the declaration we're parsing this initializer for.
6088 This function is only used for top-level initializers; for nested
6089 ones, see c_parser_initval. */
6091 static struct c_expr
6092 c_parser_initializer (c_parser *parser, tree decl)
6094 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6095 return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
6096 else
6098 struct c_expr ret;
6099 location_t loc = c_parser_peek_token (parser)->location;
6100 ret = c_parser_expr_no_commas (parser, NULL);
6101 if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
6103 error_at (loc,
6104 "variable-sized object may not be initialized except "
6105 "with an empty initializer");
6106 ret.set_error ();
6108 /* This is handled mostly by gimplify.cc, but we have to deal with
6109 not warning about int x = x; as it is a GCC extension to turn off
6110 this warning but only if warn_init_self is zero. */
6111 if (VAR_P (decl)
6112 && !DECL_EXTERNAL (decl)
6113 && !TREE_STATIC (decl)
6114 && ret.value == decl
6115 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl), OPT_Winit_self))
6116 suppress_warning (decl, OPT_Winit_self);
6117 if (TREE_CODE (ret.value) != STRING_CST
6118 && (TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR
6119 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6120 (ret.value))))
6121 ret = convert_lvalue_to_rvalue (loc, ret, true, true, true);
6122 return ret;
6126 /* The location of the last comma within the current initializer list,
6127 or UNKNOWN_LOCATION if not within one. */
6129 location_t last_init_list_comma;
6131 /* Parse a braced initializer list. TYPE is the type specified for a
6132 compound literal, and NULL_TREE for other initializers and for
6133 nested braced lists. NESTED_P is true for nested braced lists,
6134 false for the list of a compound literal or the list that is the
6135 top-level initializer in a declaration. DECL is the declaration for
6136 the top-level initializer for a declaration, otherwise NULL_TREE. */
6138 static struct c_expr
6139 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
6140 struct obstack *outer_obstack, tree decl)
6142 struct c_expr ret;
6143 struct obstack braced_init_obstack;
6144 location_t brace_loc = c_parser_peek_token (parser)->location;
6145 gcc_obstack_init (&braced_init_obstack);
6146 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
6147 bool save_c_omp_array_section_p = c_omp_array_section_p;
6148 c_omp_array_section_p = false;
6149 matching_braces braces;
6150 braces.consume_open (parser);
6151 if (nested_p)
6153 finish_implicit_inits (brace_loc, outer_obstack);
6154 push_init_level (brace_loc, 0, &braced_init_obstack);
6156 else
6157 really_start_incremental_init (type);
6158 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6160 pedwarn_c11 (brace_loc, OPT_Wpedantic,
6161 "ISO C forbids empty initializer braces before C23");
6163 else
6165 if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
6166 error_at (brace_loc,
6167 "variable-sized object may not be initialized except "
6168 "with an empty initializer");
6169 /* Parse a non-empty initializer list, possibly with a trailing
6170 comma. */
6171 while (true)
6173 c_parser_initelt (parser, &braced_init_obstack);
6174 if (parser->error)
6175 break;
6176 if (c_parser_next_token_is (parser, CPP_COMMA))
6178 last_init_list_comma = c_parser_peek_token (parser)->location;
6179 c_parser_consume_token (parser);
6181 else
6182 break;
6183 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6184 break;
6187 c_omp_array_section_p = save_c_omp_array_section_p;
6188 c_token *next_tok = c_parser_peek_token (parser);
6189 if (next_tok->type != CPP_CLOSE_BRACE)
6191 ret.set_error ();
6192 ret.original_code = ERROR_MARK;
6193 ret.original_type = NULL;
6194 braces.skip_until_found_close (parser);
6195 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
6196 obstack_free (&braced_init_obstack, NULL);
6197 return ret;
6199 location_t close_loc = next_tok->location;
6200 c_parser_consume_token (parser);
6201 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
6202 obstack_free (&braced_init_obstack, NULL);
6203 set_c_expr_source_range (&ret, brace_loc, close_loc);
6204 return ret;
6207 /* Parse a nested initializer, including designators. */
6209 static void
6210 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
6212 /* Parse any designator or designator list. A single array
6213 designator may have the subsequent "=" omitted in GNU C, but a
6214 longer list or a structure member designator may not. */
6215 if (c_parser_next_token_is (parser, CPP_NAME)
6216 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
6218 /* Old-style structure member designator. */
6219 set_init_label (c_parser_peek_token (parser)->location,
6220 c_parser_peek_token (parser)->value,
6221 c_parser_peek_token (parser)->location,
6222 braced_init_obstack);
6223 /* Use the colon as the error location. */
6224 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
6225 "obsolete use of designated initializer with %<:%>");
6226 c_parser_consume_token (parser);
6227 c_parser_consume_token (parser);
6229 else
6231 /* des_seen is 0 if there have been no designators, 1 if there
6232 has been a single array designator and 2 otherwise. */
6233 int des_seen = 0;
6234 /* Location of a designator. */
6235 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6236 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
6237 || c_parser_next_token_is (parser, CPP_DOT))
6239 int des_prev = des_seen;
6240 if (!des_seen)
6241 des_loc = c_parser_peek_token (parser)->location;
6242 if (des_seen < 2)
6243 des_seen++;
6244 if (c_parser_next_token_is (parser, CPP_DOT))
6246 des_seen = 2;
6247 c_parser_consume_token (parser);
6248 if (c_parser_next_token_is (parser, CPP_NAME))
6250 set_init_label (des_loc, c_parser_peek_token (parser)->value,
6251 c_parser_peek_token (parser)->location,
6252 braced_init_obstack);
6253 c_parser_consume_token (parser);
6255 else
6257 struct c_expr init;
6258 init.set_error ();
6259 init.original_code = ERROR_MARK;
6260 init.original_type = NULL;
6261 c_parser_error (parser, "expected identifier");
6262 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
6263 process_init_element (input_location, init, false,
6264 braced_init_obstack);
6265 return;
6268 else
6270 struct c_expr first_expr;
6271 tree first, second;
6272 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6273 location_t array_index_loc = UNKNOWN_LOCATION;
6274 /* ??? Following the old parser, [ objc-receiver
6275 objc-message-args ] is accepted as an initializer,
6276 being distinguished from a designator by what follows
6277 the first assignment expression inside the square
6278 brackets, but after a first array designator a
6279 subsequent square bracket is for Objective-C taken to
6280 start an expression, using the obsolete form of
6281 designated initializer without '=', rather than
6282 possibly being a second level of designation: in LALR
6283 terms, the '[' is shifted rather than reducing
6284 designator to designator-list. */
6285 if (des_prev == 1 && c_dialect_objc ())
6287 des_seen = des_prev;
6288 break;
6290 if (des_prev == 0 && c_dialect_objc ())
6292 /* This might be an array designator or an
6293 Objective-C message expression. If the former,
6294 continue parsing here; if the latter, parse the
6295 remainder of the initializer given the starting
6296 primary-expression. ??? It might make sense to
6297 distinguish when des_prev == 1 as well; see
6298 previous comment. */
6299 tree rec, args;
6300 struct c_expr mexpr;
6301 c_parser_consume_token (parser);
6302 if (c_parser_peek_token (parser)->type == CPP_NAME
6303 && ((c_parser_peek_token (parser)->id_kind
6304 == C_ID_TYPENAME)
6305 || (c_parser_peek_token (parser)->id_kind
6306 == C_ID_CLASSNAME)))
6308 /* Type name receiver. */
6309 tree id = c_parser_peek_token (parser)->value;
6310 c_parser_consume_token (parser);
6311 rec = objc_get_class_reference (id);
6312 goto parse_message_args;
6314 array_index_loc = c_parser_peek_token (parser)->location;
6315 first_expr = c_parser_expr_no_commas (parser, NULL);
6316 mark_exp_read (first_expr.value);
6317 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
6318 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
6319 goto array_desig_after_first;
6320 first = first_expr.value;
6321 /* Expression receiver. So far only one part
6322 without commas has been parsed; there might be
6323 more of the expression. */
6324 rec = first;
6325 while (c_parser_next_token_is (parser, CPP_COMMA))
6327 struct c_expr next;
6328 location_t comma_loc, exp_loc;
6329 comma_loc = c_parser_peek_token (parser)->location;
6330 c_parser_consume_token (parser);
6331 exp_loc = c_parser_peek_token (parser)->location;
6332 next = c_parser_expr_no_commas (parser, NULL);
6333 next = convert_lvalue_to_rvalue (exp_loc, next,
6334 true, true);
6335 rec = build_compound_expr (comma_loc, rec, next.value);
6337 parse_message_args:
6338 /* Now parse the objc-message-args. */
6339 args = c_parser_objc_message_args (parser);
6340 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6341 "expected %<]%>");
6342 mexpr.value
6343 = objc_build_message_expr (rec, args);
6344 mexpr.original_code = ERROR_MARK;
6345 mexpr.original_type = NULL;
6346 mexpr.m_decimal = 0;
6347 /* Now parse and process the remainder of the
6348 initializer, starting with this message
6349 expression as a primary-expression. */
6350 c_parser_initval (parser, &mexpr, braced_init_obstack);
6351 return;
6353 c_parser_consume_token (parser);
6354 array_index_loc = c_parser_peek_token (parser)->location;
6355 first_expr = c_parser_expr_no_commas (parser, NULL);
6356 mark_exp_read (first_expr.value);
6357 array_desig_after_first:
6358 first_expr = convert_lvalue_to_rvalue (array_index_loc,
6359 first_expr,
6360 true, true);
6361 first = first_expr.value;
6362 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
6364 ellipsis_loc = c_parser_peek_token (parser)->location;
6365 c_parser_consume_token (parser);
6366 second = convert_lvalue_to_rvalue (ellipsis_loc,
6367 (c_parser_expr_no_commas
6368 (parser, NULL)),
6369 true, true).value;
6370 mark_exp_read (second);
6372 else
6373 second = NULL_TREE;
6374 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
6376 c_parser_consume_token (parser);
6377 set_init_index (array_index_loc, first, second,
6378 braced_init_obstack);
6379 if (second)
6380 pedwarn (ellipsis_loc, OPT_Wpedantic,
6381 "ISO C forbids specifying range of elements to initialize");
6383 else
6384 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6385 "expected %<]%>");
6388 if (des_seen >= 1)
6390 if (c_parser_next_token_is (parser, CPP_EQ))
6392 pedwarn_c90 (des_loc, OPT_Wpedantic,
6393 "ISO C90 forbids specifying subobject "
6394 "to initialize");
6395 c_parser_consume_token (parser);
6397 else
6399 if (des_seen == 1)
6400 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
6401 "obsolete use of designated initializer without %<=%>");
6402 else
6404 struct c_expr init;
6405 init.set_error ();
6406 init.original_code = ERROR_MARK;
6407 init.original_type = NULL;
6408 c_parser_error (parser, "expected %<=%>");
6409 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
6410 process_init_element (input_location, init, false,
6411 braced_init_obstack);
6412 return;
6417 c_parser_initval (parser, NULL, braced_init_obstack);
6420 /* Parse a nested initializer; as c_parser_initializer but parses
6421 initializers within braced lists, after any designators have been
6422 applied. If AFTER is not NULL then it is an Objective-C message
6423 expression which is the primary-expression starting the
6424 initializer. */
6426 static void
6427 c_parser_initval (c_parser *parser, struct c_expr *after,
6428 struct obstack * braced_init_obstack)
6430 struct c_expr init;
6431 gcc_assert (!after || c_dialect_objc ());
6432 location_t loc = c_parser_peek_token (parser)->location;
6434 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
6435 init = c_parser_braced_init (parser, NULL_TREE, true,
6436 braced_init_obstack, NULL_TREE);
6437 else
6439 init = c_parser_expr_no_commas (parser, after);
6440 if (init.value != NULL_TREE
6441 && TREE_CODE (init.value) != STRING_CST
6442 && (TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR
6443 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6444 (init.value))))
6445 init = convert_lvalue_to_rvalue (loc, init, true, true, true);
6447 process_init_element (loc, init, false, braced_init_obstack);
6450 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6451 C99 6.8.2, C11 6.8.2, C23 6.8.2).
6453 compound-statement:
6454 { block-item-list[opt] }
6455 { label-declarations block-item-list }
6457 block-item-list:
6458 block-item
6459 block-item-list block-item
6461 block-item:
6462 label
6463 nested-declaration
6464 statement
6466 nested-declaration:
6467 declaration
6469 GNU extensions:
6471 compound-statement:
6472 { label-declarations block-item-list }
6474 nested-declaration:
6475 __extension__ nested-declaration
6476 nested-function-definition
6478 label-declarations:
6479 label-declaration
6480 label-declarations label-declaration
6482 label-declaration:
6483 __label__ identifier-list ;
6485 Allowing the mixing of declarations and code is new in C99. The
6486 GNU syntax also permits (not shown above) labels at the end of
6487 compound statements, which yield an error. We don't allow labels
6488 on declarations; this might seem like a natural extension, but
6489 there would be a conflict between gnu-attributes on the label and
6490 prefix gnu-attributes on the declaration. ??? The syntax follows the
6491 old parser in requiring something after label declarations.
6492 Although they are erroneous if the labels declared aren't defined,
6493 is it useful for the syntax to be this way?
6495 OpenACC:
6497 block-item:
6498 openacc-directive
6500 openacc-directive:
6501 update-directive
6503 OpenMP:
6505 block-item:
6506 openmp-directive
6508 openmp-directive:
6509 barrier-directive
6510 flush-directive
6511 taskwait-directive
6512 taskyield-directive
6513 cancel-directive
6514 cancellation-point-directive */
6516 static tree
6517 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
6519 tree stmt;
6520 location_t brace_loc;
6521 brace_loc = c_parser_peek_token (parser)->location;
6522 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
6524 /* Ensure a scope is entered and left anyway to avoid confusion
6525 if we have just prepared to enter a function body. */
6526 stmt = c_begin_compound_stmt (true);
6527 c_end_compound_stmt (brace_loc, stmt, true);
6528 return error_mark_node;
6530 stmt = c_begin_compound_stmt (true);
6531 location_t end_loc = c_parser_compound_statement_nostart (parser);
6532 if (endlocp)
6533 *endlocp = end_loc;
6535 return c_end_compound_stmt (brace_loc, stmt, true);
6538 /* Diagnose errors related to imperfectly nested loops in an OMP
6539 loop construct. This function is called when such code is seen.
6540 Only issue one such diagnostic no matter how much invalid
6541 intervening code there is in the loop.
6542 FIXME: maybe the location associated with the diagnostic should
6543 be the current parser token instead of the location of the outer loop
6544 nest. */
6546 static void
6547 check_omp_intervening_code (c_parser *parser)
6549 struct omp_for_parse_data *omp_for_parse_state = parser->omp_for_parse_state;
6550 gcc_assert (omp_for_parse_state);
6552 if (!omp_for_parse_state->in_intervening_code)
6553 return;
6554 omp_for_parse_state->saw_intervening_code = true;
6556 /* Only diagnose errors related to perfect nesting once. */
6557 if (!omp_for_parse_state->perfect_nesting_fail)
6560 /* OpenACC does not (yet) permit intervening code, in
6561 addition to situations forbidden by the OpenMP spec. */
6562 if (omp_for_parse_state->code == OACC_LOOP)
6564 error_at (omp_for_parse_state->for_loc,
6565 "inner loops must be perfectly nested in "
6566 "%<#pragma acc loop%>");
6567 omp_for_parse_state->perfect_nesting_fail = true;
6569 else if (omp_for_parse_state->ordered)
6571 error_at (omp_for_parse_state->for_loc,
6572 "inner loops must be perfectly nested with "
6573 "%<ordered%> clause");
6574 omp_for_parse_state->perfect_nesting_fail = true;
6576 else if (omp_for_parse_state->inscan)
6578 error_at (omp_for_parse_state->for_loc,
6579 "inner loops must be perfectly nested with "
6580 "%<reduction%> %<inscan%> clause");
6581 omp_for_parse_state->perfect_nesting_fail = true;
6583 /* TODO: Also reject loops with TILE directive. */
6584 if (omp_for_parse_state->perfect_nesting_fail)
6585 omp_for_parse_state->fail = true;
6589 /* Helper function for below: wrap an OMP_STRUCTURED_BLOCK around SL
6590 and add the statement to the current list. If SL is an empty statement
6591 list, do nothing. */
6592 static void
6593 add_structured_block_stmt (tree sl)
6595 if (TREE_CODE (sl) != STATEMENT_LIST
6596 || !tsi_end_p (tsi_start (sl)))
6597 add_stmt (build1 (OMP_STRUCTURED_BLOCK, void_type_node, sl));
6600 struct c_omp_attribute_data
6602 vec<c_token, va_gc> *tokens;
6603 const c_omp_directive *dir;
6604 c_omp_directive_kind kind;
6607 /* Handle omp::directive and omp::sequence attributes in ATTRS
6608 (if any) at the start of a statement or in attribute-declaration. */
6610 static bool
6611 c_parser_handle_statement_omp_attributes (c_parser *parser, tree &attrs,
6612 bool *have_std_attrs)
6614 if (!flag_openmp && !flag_openmp_simd)
6615 return false;
6617 auto_vec<c_omp_attribute_data, 16> vd;
6618 int cnt = 0;
6619 int tokens = 0;
6620 bool bad = false;
6621 for (tree *pa = &attrs; *pa; )
6622 if (is_attribute_namespace_p ("omp", *pa)
6623 && is_attribute_p ("directive", get_attribute_name (*pa)))
6625 cnt++;
6626 for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
6628 tree d = TREE_VALUE (a);
6629 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
6630 vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
6631 c_token *first = toks->address ();
6632 c_token *last = first + toks->length ();
6633 if (parser->omp_attrs_forbidden_p)
6635 error_at (first->location,
6636 "mixing OpenMP directives with attribute and pragma "
6637 "syntax on the same statement");
6638 parser->omp_attrs_forbidden_p = false;
6639 bad = true;
6641 else if (TREE_PUBLIC (d))
6643 error_at (first->location,
6644 "OpenMP %<omp::decl%> attribute on a statement");
6645 bad = true;
6647 const char *directive[3] = {};
6648 for (int i = 0; i < 3; i++)
6650 tree id = NULL_TREE;
6651 if (first + i == last)
6652 break;
6653 if (first[i].type == CPP_NAME)
6654 id = first[i].value;
6655 else if (first[i].type == CPP_KEYWORD)
6656 id = ridpointers[(int) first[i].keyword];
6657 else
6658 break;
6659 directive[i] = IDENTIFIER_POINTER (id);
6661 const c_omp_directive *dir = NULL;
6662 if (directive[0])
6663 dir = c_omp_categorize_directive (directive[0], directive[1],
6664 directive[2]);
6665 if (dir == NULL)
6667 error_at (first->location,
6668 "unknown OpenMP directive name in %qs attribute "
6669 "argument",
6670 TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
6671 continue;
6673 c_omp_directive_kind kind = dir->kind;
6674 if (dir->id == PRAGMA_OMP_ORDERED)
6676 /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
6677 depend/doacross clause. */
6678 if (directive[1]
6679 && (strcmp (directive[1], "depend") == 0
6680 || strcmp (directive[1], "doacross") == 0))
6681 kind = C_OMP_DIR_STANDALONE;
6682 else if (first + 2 < last
6683 && first[1].type == CPP_COMMA
6684 && first[2].type == CPP_NAME
6685 && (strcmp (IDENTIFIER_POINTER (first[2].value),
6686 "depend") == 0
6687 || strcmp (IDENTIFIER_POINTER (first[2].value),
6688 "doacross") == 0))
6689 kind = C_OMP_DIR_STANDALONE;
6691 else if (dir->id == PRAGMA_OMP_ERROR)
6693 /* error with at(execution) clause is C_OMP_DIR_STANDALONE. */
6694 int paren_depth = 0;
6695 for (int i = 1; first + i < last; i++)
6696 if (first[i].type == CPP_OPEN_PAREN)
6697 paren_depth++;
6698 else if (first[i].type == CPP_CLOSE_PAREN)
6699 paren_depth--;
6700 else if (paren_depth == 0
6701 && first + i + 2 < last
6702 && first[i].type == CPP_NAME
6703 && first[i + 1].type == CPP_OPEN_PAREN
6704 && first[i + 2].type == CPP_NAME
6705 && !strcmp (IDENTIFIER_POINTER (first[i].value),
6706 "at")
6707 && !strcmp (IDENTIFIER_POINTER (first[i
6708 + 2].value),
6709 "execution"))
6711 kind = C_OMP_DIR_STANDALONE;
6712 break;
6715 c_omp_attribute_data v = { toks, dir, kind };
6716 vd.safe_push (v);
6717 if (flag_openmp || dir->simd)
6718 tokens += (last - first) + 1;
6720 c_omp_attribute_data v = {};
6721 vd.safe_push (v);
6722 *pa = TREE_CHAIN (*pa);
6724 else
6725 pa = &TREE_CHAIN (*pa);
6727 if (bad)
6729 fail:
6730 if (have_std_attrs && attrs == NULL)
6731 *have_std_attrs = false;
6732 return false;
6735 unsigned int i;
6736 c_omp_attribute_data *v;
6737 c_omp_attribute_data *construct_seen = nullptr;
6738 c_omp_attribute_data *standalone_seen = nullptr;
6739 c_omp_attribute_data *prev_standalone_seen = nullptr;
6740 FOR_EACH_VEC_ELT (vd, i, v)
6741 if (v->tokens)
6743 if (v->kind == C_OMP_DIR_CONSTRUCT && !construct_seen)
6744 construct_seen = v;
6745 else if (v->kind == C_OMP_DIR_STANDALONE && !standalone_seen)
6746 standalone_seen = v;
6748 else
6750 if (standalone_seen && !prev_standalone_seen)
6752 prev_standalone_seen = standalone_seen;
6753 standalone_seen = nullptr;
6757 if (cnt > 1 && construct_seen)
6759 error_at ((*construct_seen->tokens)[0].location,
6760 "OpenMP construct among %<omp::directive%> attributes"
6761 " requires all %<omp::directive%> attributes on the"
6762 " same statement to be in the same %<omp::sequence%>");
6763 goto fail;
6765 if (cnt > 1 && standalone_seen && prev_standalone_seen)
6767 error_at ((*standalone_seen->tokens)[0].location,
6768 "multiple OpenMP standalone directives among"
6769 " %<omp::directive%> attributes must be all within the"
6770 " same %<omp::sequence%>");
6771 goto fail;
6774 if (prev_standalone_seen)
6775 standalone_seen = prev_standalone_seen;
6776 if (standalone_seen
6777 && !c_parser_next_token_is (parser, CPP_SEMICOLON))
6779 error_at (standalone_seen->tokens->address ()->location,
6780 "standalone OpenMP directives in %<omp::directive%> attribute"
6781 " can only appear on an empty statement");
6782 goto fail;
6784 if (cnt && c_parser_next_token_is (parser, CPP_PRAGMA))
6786 c_token *token = c_parser_peek_token (parser);
6787 enum pragma_kind kind = token->pragma_kind;
6788 if (kind >= PRAGMA_OMP__START_ && kind <= PRAGMA_OMP__LAST_)
6790 error_at (token->location,
6791 "mixing OpenMP directives with attribute and pragma "
6792 "syntax on the same statement");
6793 goto fail;
6797 if (!tokens)
6798 return false;
6800 unsigned int tokens_avail = parser->tokens_avail;
6801 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
6803 tokens++;
6804 vec<c_token, va_gc> *toks = NULL;
6805 vec_safe_reserve (toks, tokens, true);
6806 FOR_EACH_VEC_ELT (vd, i, v)
6808 if (!v->tokens)
6809 continue;
6810 if (!flag_openmp && !v->dir->simd)
6811 continue;
6812 c_token *first = v->tokens->address ();
6813 c_token *last = first + v->tokens->length ();
6814 c_token tok = {};
6815 tok.type = CPP_PRAGMA;
6816 tok.keyword = RID_MAX;
6817 tok.pragma_kind = pragma_kind (v->dir->id);
6818 tok.location = first->location;
6819 toks->quick_push (tok);
6820 while (++first < last)
6821 toks->quick_push (*first);
6822 tok = {};
6823 tok.type = CPP_PRAGMA_EOL;
6824 tok.keyword = RID_MAX;
6825 tok.location = last[-1].location;
6826 toks->quick_push (tok);
6829 c_token tok = {};
6830 tok.type = CPP_EOF;
6831 tok.keyword = RID_MAX;
6832 tok.location = toks->last ().location;
6833 tok.flags = tokens_avail;
6834 toks->quick_push (tok);
6836 parser->tokens = toks->address ();
6837 parser->tokens_avail = tokens;
6838 parser->in_omp_attribute_pragma = toks;
6839 return true;
6842 /* Handle omp::directive and omp::sequence attributes in ATTRS
6843 (if any) at the start or after declaration-id of a declaration. */
6845 static void
6846 c_parser_handle_directive_omp_attributes (tree &attrs,
6847 vec<c_token> *&pragma_clauses,
6848 vec<c_token> *attr_clauses)
6850 if (!flag_openmp && !flag_openmp_simd)
6851 return;
6853 for (tree *pa = &attrs; *pa; )
6854 if (is_attribute_namespace_p ("omp", *pa)
6855 && is_attribute_p ("directive", get_attribute_name (*pa)))
6857 int cnt = 0;
6858 for (tree *pa2 = &TREE_VALUE (*pa); *pa2; )
6860 tree a = *pa2;
6861 tree d = TREE_VALUE (a);
6862 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
6863 vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
6864 c_token *first = toks->address ();
6865 c_token *last = first + toks->length ();
6866 const char *directive[3] = {};
6867 for (int i = 0; i < 3; i++)
6869 tree id = NULL_TREE;
6870 if (first + i == last)
6871 break;
6872 if (first[i].type == CPP_NAME)
6873 id = first[i].value;
6874 else if (first[i].type == CPP_KEYWORD)
6875 id = ridpointers[(int) first[i].keyword];
6876 else
6877 break;
6878 directive[i] = IDENTIFIER_POINTER (id);
6880 const c_omp_directive *dir = NULL;
6881 if (directive[0])
6882 dir = c_omp_categorize_directive (directive[0], directive[1],
6883 directive[2]);
6884 if (dir == NULL)
6886 error_at (first->location,
6887 "unknown OpenMP directive name in "
6888 "%qs attribute argument",
6889 TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
6890 *pa2 = TREE_CHAIN (a);
6892 else if (dir->id == PRAGMA_OMP_DECLARE
6893 && (strcmp (directive[1], "simd") == 0
6894 || strcmp (directive[1], "variant") == 0))
6896 if (pragma_clauses)
6898 error_at (first->location,
6899 "mixing OpenMP directives with attribute and "
6900 "pragma syntax on the same declaration");
6901 for (pa = &attrs; *pa; )
6902 if (is_attribute_namespace_p ("omp", *pa)
6903 && is_attribute_p ("directive",
6904 get_attribute_name (*pa)))
6905 *pa = TREE_CHAIN (*pa);
6906 else
6907 pa = &TREE_CHAIN (*pa);
6908 return;
6910 ++cnt;
6911 attr_clauses->reserve (attr_clauses->length ()
6912 + toks->length () + 2);
6913 for (++first; first < last; ++first)
6914 attr_clauses->quick_push (*first);
6915 c_token tok = {};
6916 tok.type = CPP_PRAGMA_EOL;
6917 tok.keyword = RID_MAX;
6918 tok.location = last[-1].location;
6919 attr_clauses->quick_push (tok);
6920 *pa2 = TREE_CHAIN (a);
6922 else
6923 pa2 = &TREE_CHAIN (a);
6925 if (cnt && TREE_VALUE (*pa) == NULL_TREE)
6926 *pa = TREE_CHAIN (*pa);
6927 else
6928 pa = &TREE_CHAIN (*pa);
6930 else
6931 pa = &TREE_CHAIN (*pa);
6932 if (attr_clauses->length ())
6934 c_token tok = {};
6935 tok.type = CPP_EOF;
6936 tok.keyword = RID_MAX;
6937 tok.location = attr_clauses->last ().location;
6938 attr_clauses->quick_push (tok);
6939 attr_clauses->quick_push (tok);
6940 pragma_clauses = attr_clauses;
6944 /* Parse a compound statement except for the opening brace. This is
6945 used for parsing both compound statements and statement expressions
6946 (which follow different paths to handling the opening). */
6948 static location_t
6949 c_parser_compound_statement_nostart (c_parser *parser)
6951 bool last_stmt = false;
6952 bool last_label = false;
6953 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
6954 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6955 struct omp_for_parse_data *omp_for_parse_state
6956 = parser->omp_for_parse_state;
6957 bool in_omp_loop_block
6958 = omp_for_parse_state ? omp_for_parse_state->want_nested_loop : false;
6959 tree sl = NULL_TREE;
6961 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6963 location_t endloc = c_parser_peek_token (parser)->location;
6964 add_debug_begin_stmt (endloc);
6965 c_parser_consume_token (parser);
6966 return endloc;
6969 /* If we're parsing a {} sequence in an OMP_FOR body, start a
6970 statement list for intervening code. */
6971 if (in_omp_loop_block)
6972 sl = push_stmt_list ();
6974 mark_valid_location_for_stdc_pragma (true);
6975 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
6977 /* Read zero or more forward-declarations for labels that nested
6978 functions can jump to. */
6979 mark_valid_location_for_stdc_pragma (false);
6980 if (in_omp_loop_block)
6981 check_omp_intervening_code (parser);
6982 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
6984 label_loc = c_parser_peek_token (parser)->location;
6985 c_parser_consume_token (parser);
6986 /* Any identifiers, including those declared as type names,
6987 are OK here. */
6988 while (true)
6990 tree label;
6991 if (c_parser_next_token_is_not (parser, CPP_NAME))
6993 c_parser_error (parser, "expected identifier");
6994 break;
6996 label
6997 = declare_label (c_parser_peek_token (parser)->value);
6998 C_DECLARED_LABEL_FLAG (label) = 1;
6999 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
7000 c_parser_consume_token (parser);
7001 if (c_parser_next_token_is (parser, CPP_COMMA))
7002 c_parser_consume_token (parser);
7003 else
7004 break;
7006 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7008 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
7010 /* We must now have at least one statement, label or declaration. */
7011 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
7013 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7014 c_parser_error (parser, "expected declaration or statement");
7015 location_t endloc = c_parser_peek_token (parser)->location;
7016 c_parser_consume_token (parser);
7017 return endloc;
7019 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
7021 location_t loc = c_parser_peek_token (parser)->location;
7022 loc = expansion_point_location_if_in_system_header (loc);
7024 bool want_nested_loop = (omp_for_parse_state
7025 ? omp_for_parse_state->want_nested_loop
7026 : false);
7028 /* First take care of special cases for OpenMP "canonical loop
7029 nest form", that do not allow standard attributes, labels, or
7030 __extension__ before the nested statement. */
7031 if (in_omp_loop_block && !last_label)
7033 if (want_nested_loop
7034 && c_parser_next_token_is_keyword (parser, RID_FOR))
7036 /* Found the next nested loop. If there were intervening
7037 code statements collected before now, wrap them in an
7038 OMP_STRUCTURED_BLOCK node, and start a new structured
7039 block to hold statements that may come after the FOR. */
7040 gcc_assert (sl);
7041 add_structured_block_stmt (pop_stmt_list (sl));
7042 omp_for_parse_state->depth++;
7043 add_stmt (c_parser_omp_loop_nest (parser, NULL));
7044 omp_for_parse_state->depth--;
7045 sl = push_stmt_list ();
7046 parser->error = false;
7047 continue;
7049 else if (want_nested_loop
7050 && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7052 /* If this nested compound statement contains the nested loop,
7053 we need to separate the other statements in the current
7054 statement into separate blocks of intervening code. If
7055 there's no nested loop, it's all part of the same
7056 chunk of intervening code. */
7057 tree pre_sl = pop_stmt_list (sl);
7058 tree nested_sl = push_stmt_list ();
7059 mark_valid_location_for_stdc_pragma (false);
7060 c_parser_statement_after_labels (parser, NULL);
7061 nested_sl = pop_stmt_list (nested_sl);
7062 if (omp_for_parse_state->want_nested_loop)
7064 /* This block didn't contain a loop-nest, so it's
7065 all part of the same chunk of intervening code. */
7066 check_omp_intervening_code (parser);
7067 sl = push_stmt_list ();
7068 add_stmt (pre_sl);
7069 add_stmt (nested_sl);
7071 else
7073 /* It contains the nested loop. */
7074 add_structured_block_stmt (pre_sl);
7075 add_stmt (nested_sl);
7076 sl = push_stmt_list ();
7078 parser->error = false;
7079 continue;
7081 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7083 /* Prior to implementing the OpenMP 5.1 syntax for canonical
7084 loop form, GCC used to accept an empty statements that
7085 would now be flagged as intervening code. Continue to
7086 do that, as an extension. */
7087 /* FIXME: Maybe issue a warning or something here? */
7088 c_parser_consume_token (parser);
7089 continue;
7093 /* Standard attributes may start a label, statement or declaration. */
7094 bool have_std_attrs
7095 = c_parser_nth_token_starts_std_attributes (parser, 1);
7096 tree std_attrs = NULL_TREE;
7097 if (have_std_attrs)
7098 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7099 if (c_parser_next_token_is_keyword (parser, RID_CASE)
7100 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
7101 || (c_parser_next_token_is (parser, CPP_NAME)
7102 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
7104 if (c_parser_next_token_is_keyword (parser, RID_CASE))
7105 label_loc = c_parser_peek_2nd_token (parser)->location;
7106 else
7107 label_loc = c_parser_peek_token (parser)->location;
7108 last_label = true;
7109 last_stmt = false;
7110 mark_valid_location_for_stdc_pragma (false);
7111 if (in_omp_loop_block)
7112 check_omp_intervening_code (parser);
7113 c_parser_label (parser, std_attrs);
7115 else if (c_parser_next_tokens_start_declaration (parser)
7116 || (have_std_attrs
7117 && !c_parser_handle_statement_omp_attributes
7118 (parser, std_attrs, &have_std_attrs)
7119 && c_parser_next_token_is (parser, CPP_SEMICOLON)
7120 && (have_std_attrs = true)))
7122 if (last_label)
7123 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
7124 "a label can only be part of a statement and "
7125 "a declaration is not a statement");
7126 /* It's unlikely we'll see a nested loop in a declaration in
7127 intervening code in an OMP loop, but disallow it anyway. */
7128 if (in_omp_loop_block)
7130 check_omp_intervening_code (parser);
7131 omp_for_parse_state->want_nested_loop = false;
7133 mark_valid_location_for_stdc_pragma (false);
7134 bool fallthru_attr_p = false;
7135 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
7136 true, true, true, NULL,
7137 NULL, have_std_attrs, std_attrs,
7138 NULL, &fallthru_attr_p);
7140 if (in_omp_loop_block)
7141 omp_for_parse_state->want_nested_loop = want_nested_loop;
7142 if (last_stmt && !fallthru_attr_p)
7143 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
7144 "ISO C90 forbids mixed declarations and code");
7145 last_stmt = fallthru_attr_p;
7146 last_label = false;
7148 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
7150 /* __extension__ can start a declaration, but is also an
7151 unary operator that can start an expression. Consume all
7152 but the last of a possible series of __extension__ to
7153 determine which. If standard attributes have already
7154 been seen, it must start a statement, not a declaration,
7155 but standard attributes starting a declaration may appear
7156 after __extension__. */
7157 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
7158 && (c_parser_peek_2nd_token (parser)->keyword
7159 == RID_EXTENSION))
7160 c_parser_consume_token (parser);
7161 if (!have_std_attrs
7162 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
7163 || c_parser_nth_token_starts_std_attributes (parser, 2)))
7165 int ext;
7166 ext = disable_extension_diagnostics ();
7167 c_parser_consume_token (parser);
7168 last_label = false;
7169 /* It's unlikely we'll see a nested loop in a declaration in
7170 intervening code in an OMP loop, but disallow it anyway. */
7171 if (in_omp_loop_block)
7173 check_omp_intervening_code (parser);
7174 omp_for_parse_state->want_nested_loop = false;
7176 mark_valid_location_for_stdc_pragma (false);
7177 c_parser_declaration_or_fndef (parser, true, true, true, true,
7178 true);
7179 if (in_omp_loop_block)
7180 omp_for_parse_state->want_nested_loop = want_nested_loop;
7181 /* Following the old parser, __extension__ does not
7182 disable this diagnostic. */
7183 restore_extension_diagnostics (ext);
7184 if (last_stmt)
7185 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
7186 "ISO C90 forbids mixed declarations and code");
7187 last_stmt = false;
7189 else
7190 goto statement;
7192 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
7194 if (have_std_attrs && !parser->in_omp_attribute_pragma)
7195 c_parser_error (parser, "expected declaration or statement");
7196 else if (std_attrs)
7197 c_warn_unused_attributes (std_attrs);
7198 /* External pragmas, and some omp pragmas, are not associated
7199 with regular c code, and so are not to be considered statements
7200 syntactically. This ensures that the user doesn't put them
7201 places that would turn into syntax errors if the directive
7202 were ignored. */
7203 if (omp_for_parse_state)
7204 omp_for_parse_state->want_nested_loop = false;
7205 if (c_parser_pragma (parser,
7206 last_label ? pragma_stmt : pragma_compound,
7207 NULL))
7209 last_label = false;
7210 last_stmt = true;
7211 if (omp_for_parse_state)
7212 check_omp_intervening_code (parser);
7214 if (omp_for_parse_state)
7215 omp_for_parse_state->want_nested_loop = want_nested_loop;
7217 else if (c_parser_next_token_is (parser, CPP_EOF))
7219 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7220 c_parser_error (parser, "expected declaration or statement");
7221 return c_parser_peek_token (parser)->location;
7223 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
7225 if (parser->in_if_block)
7227 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7228 error_at (loc, "expected %<}%> before %<else%>");
7229 return c_parser_peek_token (parser)->location;
7231 else
7233 error_at (loc, "%<else%> without a previous %<if%>");
7234 c_parser_consume_token (parser);
7235 continue;
7238 else
7240 statement:
7241 c_warn_unused_attributes (std_attrs);
7242 last_label = false;
7243 last_stmt = true;
7244 mark_valid_location_for_stdc_pragma (false);
7245 if (!omp_for_parse_state)
7246 c_parser_statement_after_labels (parser, NULL);
7247 else
7249 /* In canonical loop nest form, nested loops can only appear
7250 directly, or in a directly nested compound statement. We
7251 already took care of those cases above, so now we have
7252 something else. This statement and everything inside
7253 it must be intervening code. */
7254 omp_for_parse_state->want_nested_loop = false;
7255 check_omp_intervening_code (parser);
7256 c_parser_statement_after_labels (parser, NULL);
7257 omp_for_parse_state->want_nested_loop = want_nested_loop;
7261 parser->error = false;
7263 if (last_label)
7264 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
7265 location_t endloc = c_parser_peek_token (parser)->location;
7266 c_parser_consume_token (parser);
7268 /* Restore the value we started with. */
7269 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7271 /* Package leftover intervening code, or the whole contents of the
7272 compound statement if we were looking for a nested loop in an OMP_FOR
7273 construct and didn't find one. */
7274 if (sl)
7276 sl = pop_stmt_list (sl);
7277 if (omp_for_parse_state->want_nested_loop)
7278 add_stmt (sl);
7279 else
7280 add_structured_block_stmt (sl);
7282 return endloc;
7285 /* Parse all consecutive labels, possibly preceded by standard
7286 attributes. In this context, a statement is required, not a
7287 declaration, so attributes must be followed by a statement that is
7288 not just a semicolon. */
7290 static void
7291 c_parser_all_labels (c_parser *parser)
7293 bool have_std_attrs;
7294 tree std_attrs = NULL;
7295 if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1)))
7296 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7297 while (c_parser_next_token_is_keyword (parser, RID_CASE)
7298 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
7299 || (c_parser_next_token_is (parser, CPP_NAME)
7300 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
7302 c_parser_label (parser, std_attrs);
7303 std_attrs = NULL;
7304 if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser,
7305 1)))
7306 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7308 if (std_attrs
7309 && (!c_parser_handle_statement_omp_attributes (parser, std_attrs, &have_std_attrs)
7310 || std_attrs))
7312 if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
7313 c_parser_error (parser, "expected statement");
7314 c_warn_unused_attributes (std_attrs);
7316 else if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
7317 c_parser_error (parser, "expected statement");
7320 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
7322 label:
7323 identifier : gnu-attributes[opt]
7324 case constant-expression :
7325 default :
7327 GNU extensions:
7329 label:
7330 case constant-expression ... constant-expression :
7332 The use of gnu-attributes on labels is a GNU extension. The syntax in
7333 GNU C accepts any expressions without commas, non-constant
7334 expressions being rejected later. Any standard
7335 attribute-specifier-sequence before the first label has been parsed
7336 in the caller, to distinguish statements from declarations. Any
7337 attribute-specifier-sequence after the label is parsed in this
7338 function. */
7339 static void
7340 c_parser_label (c_parser *parser, tree std_attrs)
7342 location_t loc1 = c_parser_peek_token (parser)->location;
7343 tree label = NULL_TREE;
7345 /* Remember whether this case or a user-defined label is allowed to fall
7346 through to. */
7347 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
7349 if (c_parser_next_token_is_keyword (parser, RID_CASE))
7351 tree exp1, exp2;
7352 c_parser_consume_token (parser);
7353 exp1 = convert_lvalue_to_rvalue (loc1,
7354 c_parser_expr_no_commas (parser, NULL),
7355 true, true).value;
7356 if (c_parser_next_token_is (parser, CPP_COLON))
7358 c_parser_consume_token (parser);
7359 label = do_case (loc1, exp1, NULL_TREE, std_attrs);
7361 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
7363 c_parser_consume_token (parser);
7364 exp2 = convert_lvalue_to_rvalue (loc1,
7365 c_parser_expr_no_commas (parser,
7366 NULL),
7367 true, true).value;
7368 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7369 label = do_case (loc1, exp1, exp2, std_attrs);
7371 else
7372 c_parser_error (parser, "expected %<:%> or %<...%>");
7374 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
7376 c_parser_consume_token (parser);
7377 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7378 label = do_case (loc1, NULL_TREE, NULL_TREE, std_attrs);
7380 else
7382 tree name = c_parser_peek_token (parser)->value;
7383 tree tlab;
7384 tree attrs;
7385 location_t loc2 = c_parser_peek_token (parser)->location;
7386 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
7387 c_parser_consume_token (parser);
7388 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
7389 c_parser_consume_token (parser);
7390 attrs = c_parser_gnu_attributes (parser);
7391 tlab = define_label (loc2, name);
7392 if (tlab)
7394 decl_attributes (&tlab, attrs, 0);
7395 decl_attributes (&tlab, std_attrs, 0);
7396 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
7398 if (attrs
7399 && c_parser_next_tokens_start_declaration (parser))
7400 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
7401 " label and declaration appertains to the label");
7403 if (label)
7405 if (TREE_CODE (label) == LABEL_EXPR)
7406 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
7407 else
7408 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
7412 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
7414 statement:
7415 labeled-statement
7416 attribute-specifier-sequence[opt] compound-statement
7417 expression-statement
7418 attribute-specifier-sequence[opt] selection-statement
7419 attribute-specifier-sequence[opt] iteration-statement
7420 attribute-specifier-sequence[opt] jump-statement
7422 labeled-statement:
7423 attribute-specifier-sequence[opt] label statement
7425 expression-statement:
7426 expression[opt] ;
7427 attribute-specifier-sequence expression ;
7429 selection-statement:
7430 if-statement
7431 switch-statement
7433 iteration-statement:
7434 while-statement
7435 do-statement
7436 for-statement
7438 jump-statement:
7439 goto identifier ;
7440 continue ;
7441 break ;
7442 return expression[opt] ;
7444 GNU extensions:
7446 statement:
7447 attribute-specifier-sequence[opt] asm-statement
7449 jump-statement:
7450 goto * expression ;
7452 expression-statement:
7453 gnu-attributes ;
7455 Objective-C:
7457 statement:
7458 attribute-specifier-sequence[opt] objc-throw-statement
7459 attribute-specifier-sequence[opt] objc-try-catch-statement
7460 attribute-specifier-sequence[opt] objc-synchronized-statement
7462 objc-throw-statement:
7463 @throw expression ;
7464 @throw ;
7466 OpenACC:
7468 statement:
7469 attribute-specifier-sequence[opt] openacc-construct
7471 openacc-construct:
7472 parallel-construct
7473 kernels-construct
7474 data-construct
7475 loop-construct
7477 parallel-construct:
7478 parallel-directive structured-block
7480 kernels-construct:
7481 kernels-directive structured-block
7483 data-construct:
7484 data-directive structured-block
7486 loop-construct:
7487 loop-directive structured-block
7489 OpenMP:
7491 statement:
7492 attribute-specifier-sequence[opt] openmp-construct
7494 openmp-construct:
7495 parallel-construct
7496 for-construct
7497 simd-construct
7498 for-simd-construct
7499 sections-construct
7500 single-construct
7501 parallel-for-construct
7502 parallel-for-simd-construct
7503 parallel-sections-construct
7504 master-construct
7505 critical-construct
7506 atomic-construct
7507 ordered-construct
7509 parallel-construct:
7510 parallel-directive structured-block
7512 for-construct:
7513 for-directive iteration-statement
7515 simd-construct:
7516 simd-directive iteration-statements
7518 for-simd-construct:
7519 for-simd-directive iteration-statements
7521 sections-construct:
7522 sections-directive section-scope
7524 single-construct:
7525 single-directive structured-block
7527 parallel-for-construct:
7528 parallel-for-directive iteration-statement
7530 parallel-for-simd-construct:
7531 parallel-for-simd-directive iteration-statement
7533 parallel-sections-construct:
7534 parallel-sections-directive section-scope
7536 master-construct:
7537 master-directive structured-block
7539 critical-construct:
7540 critical-directive structured-block
7542 atomic-construct:
7543 atomic-directive expression-statement
7545 ordered-construct:
7546 ordered-directive structured-block
7548 Transactional Memory:
7550 statement:
7551 attribute-specifier-sequence[opt] transaction-statement
7552 attribute-specifier-sequence[opt] transaction-cancel-statement
7554 IF_P is used to track whether there's a (possibly labeled) if statement
7555 which is not enclosed in braces and has an else clause. This is used to
7556 implement -Wparentheses. */
7558 static void
7559 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
7561 c_parser_all_labels (parser);
7562 if (loc_after_labels)
7563 *loc_after_labels = c_parser_peek_token (parser)->location;
7564 parser->omp_attrs_forbidden_p = false;
7565 c_parser_statement_after_labels (parser, if_p, NULL);
7568 /* Parse a statement, other than a labeled statement. CHAIN is a vector
7569 of if-else-if conditions. All labels and standard attributes have
7570 been parsed in the caller.
7572 IF_P is used to track whether there's a (possibly labeled) if statement
7573 which is not enclosed in braces and has an else clause. This is used to
7574 implement -Wparentheses. */
7576 static void
7577 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
7578 vec<tree> *chain)
7580 location_t loc = c_parser_peek_token (parser)->location;
7581 tree stmt = NULL_TREE;
7582 bool in_if_block = parser->in_if_block;
7583 parser->in_if_block = false;
7584 if (if_p != NULL)
7585 *if_p = false;
7587 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
7588 add_debug_begin_stmt (loc);
7590 restart:
7591 switch (c_parser_peek_token (parser)->type)
7593 case CPP_OPEN_BRACE:
7594 add_stmt (c_parser_compound_statement (parser));
7595 break;
7596 case CPP_KEYWORD:
7597 switch (c_parser_peek_token (parser)->keyword)
7599 case RID_IF:
7600 c_parser_if_statement (parser, if_p, chain);
7601 break;
7602 case RID_SWITCH:
7603 c_parser_switch_statement (parser, if_p);
7604 break;
7605 case RID_WHILE:
7606 c_parser_while_statement (parser, false, 0, false, if_p);
7607 break;
7608 case RID_DO:
7609 c_parser_do_statement (parser, false, 0, false);
7610 break;
7611 case RID_FOR:
7612 c_parser_for_statement (parser, false, 0, false, if_p);
7613 break;
7614 case RID_GOTO:
7615 c_parser_consume_token (parser);
7616 if (c_parser_next_token_is (parser, CPP_NAME))
7618 stmt = c_finish_goto_label (loc,
7619 c_parser_peek_token (parser)->value);
7620 c_parser_consume_token (parser);
7622 else if (c_parser_next_token_is (parser, CPP_MULT))
7624 struct c_expr val;
7626 c_parser_consume_token (parser);
7627 val = c_parser_expression (parser);
7628 val = convert_lvalue_to_rvalue (loc, val, false, true);
7629 stmt = c_finish_goto_ptr (loc, val);
7631 else
7632 c_parser_error (parser, "expected identifier or %<*%>");
7633 goto expect_semicolon;
7634 case RID_CONTINUE:
7635 c_parser_consume_token (parser);
7636 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
7637 goto expect_semicolon;
7638 case RID_BREAK:
7639 c_parser_consume_token (parser);
7640 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
7641 goto expect_semicolon;
7642 case RID_RETURN:
7643 c_parser_consume_token (parser);
7644 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7646 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
7647 c_parser_consume_token (parser);
7649 else
7651 location_t xloc = c_parser_peek_token (parser)->location;
7652 struct c_expr expr = c_parser_expression_conv (parser);
7653 mark_exp_read (expr.value);
7654 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
7655 expr.value, expr.original_type);
7656 goto expect_semicolon;
7658 break;
7659 case RID_ASM:
7660 stmt = c_parser_asm_statement (parser);
7661 break;
7662 case RID_TRANSACTION_ATOMIC:
7663 case RID_TRANSACTION_RELAXED:
7664 stmt = c_parser_transaction (parser,
7665 c_parser_peek_token (parser)->keyword);
7666 break;
7667 case RID_TRANSACTION_CANCEL:
7668 stmt = c_parser_transaction_cancel (parser);
7669 goto expect_semicolon;
7670 case RID_AT_THROW:
7671 gcc_assert (c_dialect_objc ());
7672 c_parser_consume_token (parser);
7673 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7675 stmt = objc_build_throw_stmt (loc, NULL_TREE);
7676 c_parser_consume_token (parser);
7678 else
7680 struct c_expr expr = c_parser_expression (parser);
7681 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
7682 expr.value = c_fully_fold (expr.value, false, NULL);
7683 stmt = objc_build_throw_stmt (loc, expr.value);
7684 goto expect_semicolon;
7686 break;
7687 case RID_AT_TRY:
7688 gcc_assert (c_dialect_objc ());
7689 c_parser_objc_try_catch_finally_statement (parser);
7690 break;
7691 case RID_AT_SYNCHRONIZED:
7692 gcc_assert (c_dialect_objc ());
7693 c_parser_objc_synchronized_statement (parser);
7694 break;
7695 case RID_ATTRIBUTE:
7697 /* Allow '__attribute__((fallthrough));' or
7698 '__attribute__((assume(cond)));'. */
7699 tree attrs = c_parser_gnu_attributes (parser);
7700 bool has_assume = lookup_attribute ("assume", attrs);
7701 if (has_assume)
7703 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7704 attrs = handle_assume_attribute (loc, attrs, true);
7705 else
7707 warning_at (loc, OPT_Wattributes,
7708 "%<assume%> attribute not followed by %<;%>");
7709 has_assume = false;
7712 if (attribute_fallthrough_p (attrs))
7714 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7716 tree fn = build_call_expr_internal_loc (loc,
7717 IFN_FALLTHROUGH,
7718 void_type_node, 0);
7719 add_stmt (fn);
7720 /* Eat the ';'. */
7721 c_parser_consume_token (parser);
7723 else
7724 warning_at (loc, OPT_Wattributes,
7725 "%<fallthrough%> attribute not followed "
7726 "by %<;%>");
7728 else if (has_assume)
7729 /* Eat the ';'. */
7730 c_parser_consume_token (parser);
7731 else if (attrs != NULL_TREE)
7732 warning_at (loc, OPT_Wattributes,
7733 "only attribute %<fallthrough%> or %<assume%> can "
7734 "be applied to a null statement");
7735 break;
7737 default:
7738 goto expr_stmt;
7740 break;
7741 case CPP_SEMICOLON:
7742 c_parser_consume_token (parser);
7743 break;
7744 case CPP_CLOSE_PAREN:
7745 case CPP_CLOSE_SQUARE:
7746 /* Avoid infinite loop in error recovery:
7747 c_parser_skip_until_found stops at a closing nesting
7748 delimiter without consuming it, but here we need to consume
7749 it to proceed further. */
7750 c_parser_error (parser, "expected statement");
7751 c_parser_consume_token (parser);
7752 break;
7753 case CPP_PRAGMA:
7754 if (!c_parser_pragma (parser, pragma_stmt, if_p))
7755 goto restart;
7756 break;
7757 default:
7758 expr_stmt:
7759 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
7760 expect_semicolon:
7761 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7762 break;
7764 /* Two cases cannot and do not have line numbers associated: If stmt
7765 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
7766 cannot hold line numbers. But that's OK because the statement
7767 will either be changed to a MODIFY_EXPR during gimplification of
7768 the statement expr, or discarded. If stmt was compound, but
7769 without new variables, we will have skipped the creation of a
7770 BIND and will have a bare STATEMENT_LIST. But that's OK because
7771 (recursively) all of the component statements should already have
7772 line numbers assigned. ??? Can we discard no-op statements
7773 earlier? */
7774 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
7775 protected_set_expr_location (stmt, loc);
7777 parser->in_if_block = in_if_block;
7780 /* Parse the condition from an if, do, while or for statements. */
7782 static tree
7783 c_parser_condition (c_parser *parser)
7785 location_t loc = c_parser_peek_token (parser)->location;
7786 tree cond;
7787 cond = c_parser_expression_conv (parser).value;
7788 cond = c_objc_common_truthvalue_conversion (loc, cond);
7789 cond = c_fully_fold (cond, false, NULL);
7790 if (warn_sequence_point)
7791 verify_sequence_points (cond);
7792 return cond;
7795 /* Parse a parenthesized condition from an if, do or while statement.
7797 condition:
7798 ( expression )
7800 static tree
7801 c_parser_paren_condition (c_parser *parser)
7803 tree cond;
7804 matching_parens parens;
7805 if (!parens.require_open (parser))
7806 return error_mark_node;
7807 cond = c_parser_condition (parser);
7808 parens.skip_until_found_close (parser);
7809 return cond;
7812 /* Parse a statement which is a block in C99.
7814 IF_P is used to track whether there's a (possibly labeled) if statement
7815 which is not enclosed in braces and has an else clause. This is used to
7816 implement -Wparentheses. */
7818 static tree
7819 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
7820 location_t *loc_after_labels)
7822 tree block = c_begin_compound_stmt (flag_isoc99);
7823 location_t loc = c_parser_peek_token (parser)->location;
7824 c_parser_statement (parser, if_p, loc_after_labels);
7825 return c_end_compound_stmt (loc, block, flag_isoc99);
7828 /* Parse the body of an if statement. This is just parsing a
7829 statement but (a) it is a block in C99, (b) we track whether the
7830 body is an if statement for the sake of -Wparentheses warnings, (c)
7831 we handle an empty body specially for the sake of -Wempty-body
7832 warnings, and (d) we call parser_compound_statement directly
7833 because c_parser_statement_after_labels resets
7834 parser->in_if_block.
7836 IF_P is used to track whether there's a (possibly labeled) if statement
7837 which is not enclosed in braces and has an else clause. This is used to
7838 implement -Wparentheses. */
7840 static tree
7841 c_parser_if_body (c_parser *parser, bool *if_p,
7842 const token_indent_info &if_tinfo)
7844 tree block = c_begin_compound_stmt (flag_isoc99);
7845 location_t body_loc = c_parser_peek_token (parser)->location;
7846 location_t body_loc_after_labels = UNKNOWN_LOCATION;
7847 token_indent_info body_tinfo
7848 = get_token_indent_info (c_parser_peek_token (parser));
7850 c_parser_all_labels (parser);
7851 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7853 location_t loc = c_parser_peek_token (parser)->location;
7854 add_stmt (build_empty_stmt (loc));
7855 c_parser_consume_token (parser);
7856 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
7857 warning_at (loc, OPT_Wempty_body,
7858 "suggest braces around empty body in an %<if%> statement");
7860 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7861 add_stmt (c_parser_compound_statement (parser));
7862 else
7864 body_loc_after_labels = c_parser_peek_token (parser)->location;
7865 c_parser_statement_after_labels (parser, if_p);
7868 token_indent_info next_tinfo
7869 = get_token_indent_info (c_parser_peek_token (parser));
7870 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
7871 if (body_loc_after_labels != UNKNOWN_LOCATION
7872 && next_tinfo.type != CPP_SEMICOLON)
7873 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
7874 if_tinfo.location, RID_IF);
7876 return c_end_compound_stmt (body_loc, block, flag_isoc99);
7879 /* Parse the else body of an if statement. This is just parsing a
7880 statement but (a) it is a block in C99, (b) we handle an empty body
7881 specially for the sake of -Wempty-body warnings. CHAIN is a vector
7882 of if-else-if conditions. */
7884 static tree
7885 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
7886 vec<tree> *chain)
7888 location_t body_loc = c_parser_peek_token (parser)->location;
7889 tree block = c_begin_compound_stmt (flag_isoc99);
7890 token_indent_info body_tinfo
7891 = get_token_indent_info (c_parser_peek_token (parser));
7892 location_t body_loc_after_labels = UNKNOWN_LOCATION;
7894 c_parser_all_labels (parser);
7895 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7897 location_t loc = c_parser_peek_token (parser)->location;
7898 warning_at (loc,
7899 OPT_Wempty_body,
7900 "suggest braces around empty body in an %<else%> statement");
7901 add_stmt (build_empty_stmt (loc));
7902 c_parser_consume_token (parser);
7904 else
7906 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7907 body_loc_after_labels = c_parser_peek_token (parser)->location;
7908 c_parser_statement_after_labels (parser, NULL, chain);
7911 token_indent_info next_tinfo
7912 = get_token_indent_info (c_parser_peek_token (parser));
7913 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
7914 if (body_loc_after_labels != UNKNOWN_LOCATION
7915 && next_tinfo.type != CPP_SEMICOLON)
7916 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
7917 else_tinfo.location, RID_ELSE);
7919 return c_end_compound_stmt (body_loc, block, flag_isoc99);
7922 /* We might need to reclassify any previously-lexed identifier, e.g.
7923 when we've left a for loop with an if-statement without else in the
7924 body - we might have used a wrong scope for the token. See PR67784. */
7926 static void
7927 c_parser_maybe_reclassify_token (c_parser *parser)
7929 if (c_parser_next_token_is (parser, CPP_NAME))
7931 c_token *token = c_parser_peek_token (parser);
7933 if (token->id_kind != C_ID_CLASSNAME)
7935 tree decl = lookup_name (token->value);
7937 token->id_kind = C_ID_ID;
7938 if (decl)
7940 if (TREE_CODE (decl) == TYPE_DECL)
7941 token->id_kind = C_ID_TYPENAME;
7943 else if (c_dialect_objc ())
7945 tree objc_interface_decl = objc_is_class_name (token->value);
7946 /* Objective-C class names are in the same namespace as
7947 variables and typedefs, and hence are shadowed by local
7948 declarations. */
7949 if (objc_interface_decl)
7951 token->value = objc_interface_decl;
7952 token->id_kind = C_ID_CLASSNAME;
7959 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
7961 if-statement:
7962 if ( expression ) statement
7963 if ( expression ) statement else statement
7965 CHAIN is a vector of if-else-if conditions.
7966 IF_P is used to track whether there's a (possibly labeled) if statement
7967 which is not enclosed in braces and has an else clause. This is used to
7968 implement -Wparentheses. */
7970 static void
7971 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
7973 tree block;
7974 location_t loc;
7975 tree cond;
7976 bool nested_if = false;
7977 tree first_body, second_body;
7978 bool in_if_block;
7980 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
7981 token_indent_info if_tinfo
7982 = get_token_indent_info (c_parser_peek_token (parser));
7983 c_parser_consume_token (parser);
7984 block = c_begin_compound_stmt (flag_isoc99);
7985 loc = c_parser_peek_token (parser)->location;
7986 cond = c_parser_paren_condition (parser);
7987 in_if_block = parser->in_if_block;
7988 parser->in_if_block = true;
7989 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
7990 parser->in_if_block = in_if_block;
7992 if (warn_duplicated_cond)
7993 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
7995 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
7997 token_indent_info else_tinfo
7998 = get_token_indent_info (c_parser_peek_token (parser));
7999 c_parser_consume_token (parser);
8000 if (warn_duplicated_cond)
8002 if (c_parser_next_token_is_keyword (parser, RID_IF)
8003 && chain == NULL)
8005 /* We've got "if (COND) else if (COND2)". Start the
8006 condition chain and add COND as the first element. */
8007 chain = new vec<tree> ();
8008 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
8009 chain->safe_push (cond);
8011 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
8012 /* This is if-else without subsequent if. Zap the condition
8013 chain; we would have already warned at this point. */
8014 vec_free (chain);
8016 second_body = c_parser_else_body (parser, else_tinfo, chain);
8017 /* Set IF_P to true to indicate that this if statement has an
8018 else clause. This may trigger the Wparentheses warning
8019 below when we get back up to the parent if statement. */
8020 if (if_p != NULL)
8021 *if_p = true;
8023 else
8025 second_body = NULL_TREE;
8027 /* Diagnose an ambiguous else if if-then-else is nested inside
8028 if-then. */
8029 if (nested_if)
8030 warning_at (loc, OPT_Wdangling_else,
8031 "suggest explicit braces to avoid ambiguous %<else%>");
8033 if (warn_duplicated_cond)
8034 /* This if statement does not have an else clause. We don't
8035 need the condition chain anymore. */
8036 vec_free (chain);
8038 c_finish_if_stmt (loc, cond, first_body, second_body);
8039 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8041 c_parser_maybe_reclassify_token (parser);
8044 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8046 switch-statement:
8047 switch (expression) statement
8050 static void
8051 c_parser_switch_statement (c_parser *parser, bool *if_p)
8053 struct c_expr ce;
8054 tree block, expr, body;
8055 unsigned char save_in_statement;
8056 location_t switch_loc = c_parser_peek_token (parser)->location;
8057 location_t switch_cond_loc;
8058 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
8059 c_parser_consume_token (parser);
8060 block = c_begin_compound_stmt (flag_isoc99);
8061 bool explicit_cast_p = false;
8062 matching_parens parens;
8063 if (parens.require_open (parser))
8065 switch_cond_loc = c_parser_peek_token (parser)->location;
8066 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8067 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8068 explicit_cast_p = true;
8069 ce = c_parser_expression (parser);
8070 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
8071 expr = ce.value;
8072 /* ??? expr has no valid location? */
8073 parens.skip_until_found_close (parser);
8075 else
8077 switch_cond_loc = UNKNOWN_LOCATION;
8078 expr = error_mark_node;
8079 ce.original_type = error_mark_node;
8081 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
8082 save_in_statement = in_statement;
8083 in_statement |= IN_SWITCH_STMT;
8084 location_t loc_after_labels;
8085 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
8086 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8087 location_t next_loc = c_parser_peek_token (parser)->location;
8088 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
8089 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
8090 RID_SWITCH);
8091 c_finish_switch (body, ce.original_type);
8092 in_statement = save_in_statement;
8093 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
8094 c_parser_maybe_reclassify_token (parser);
8097 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8099 while-statement:
8100 while (expression) statement
8102 IF_P is used to track whether there's a (possibly labeled) if statement
8103 which is not enclosed in braces and has an else clause. This is used to
8104 implement -Wparentheses. */
8106 static void
8107 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8108 bool novector, bool *if_p)
8110 tree block, cond, body;
8111 unsigned char save_in_statement;
8112 location_t loc;
8113 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
8114 token_indent_info while_tinfo
8115 = get_token_indent_info (c_parser_peek_token (parser));
8117 if (parser->omp_for_parse_state)
8119 error_at (c_parser_peek_token (parser)->location,
8120 "loop not permitted in intervening code in OpenMP loop body");
8121 parser->omp_for_parse_state->fail = true;
8124 c_parser_consume_token (parser);
8125 block = c_begin_compound_stmt (flag_isoc99);
8126 loc = c_parser_peek_token (parser)->location;
8127 cond = c_parser_paren_condition (parser);
8128 if (ivdep && cond != error_mark_node)
8129 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8130 build_int_cst (integer_type_node,
8131 annot_expr_ivdep_kind),
8132 integer_zero_node);
8133 if (unroll && cond != error_mark_node)
8134 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8135 build_int_cst (integer_type_node,
8136 annot_expr_unroll_kind),
8137 build_int_cst (integer_type_node, unroll));
8138 if (novector && cond != error_mark_node)
8139 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8140 build_int_cst (integer_type_node,
8141 annot_expr_no_vector_kind),
8142 integer_zero_node);
8143 save_in_statement = in_statement;
8144 in_statement = IN_ITERATION_STMT;
8146 token_indent_info body_tinfo
8147 = get_token_indent_info (c_parser_peek_token (parser));
8149 location_t loc_after_labels;
8150 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
8151 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8152 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
8153 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8154 c_parser_maybe_reclassify_token (parser);
8156 token_indent_info next_tinfo
8157 = get_token_indent_info (c_parser_peek_token (parser));
8158 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
8160 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
8161 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
8162 while_tinfo.location, RID_WHILE);
8164 in_statement = save_in_statement;
8167 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8169 do-statement:
8170 do statement while ( expression ) ;
8173 static void
8174 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8175 bool novector)
8177 tree block, cond, body;
8178 unsigned char save_in_statement;
8179 location_t loc;
8180 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
8182 if (parser->omp_for_parse_state)
8184 error_at (c_parser_peek_token (parser)->location,
8185 "loop not permitted in intervening code in OpenMP loop body");
8186 parser->omp_for_parse_state->fail = true;
8189 c_parser_consume_token (parser);
8190 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8191 warning_at (c_parser_peek_token (parser)->location,
8192 OPT_Wempty_body,
8193 "suggest braces around empty body in %<do%> statement");
8194 block = c_begin_compound_stmt (flag_isoc99);
8195 loc = c_parser_peek_token (parser)->location;
8196 save_in_statement = in_statement;
8197 in_statement = IN_ITERATION_STMT;
8198 body = c_parser_c99_block_statement (parser, NULL);
8199 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
8200 in_statement = save_in_statement;
8201 cond = c_parser_paren_condition (parser);
8202 if (ivdep && cond != error_mark_node)
8203 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8204 build_int_cst (integer_type_node,
8205 annot_expr_ivdep_kind),
8206 integer_zero_node);
8207 if (unroll && cond != error_mark_node)
8208 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8209 build_int_cst (integer_type_node,
8210 annot_expr_unroll_kind),
8211 build_int_cst (integer_type_node, unroll));
8212 if (novector && cond != error_mark_node)
8213 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8214 build_int_cst (integer_type_node,
8215 annot_expr_no_vector_kind),
8216 integer_zero_node);
8217 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
8218 c_parser_skip_to_end_of_block_or_statement (parser);
8220 add_stmt (build_stmt (loc, DO_STMT, cond, body));
8221 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8224 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8226 for-statement:
8227 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
8228 for ( nested-declaration expression[opt] ; expression[opt] ) statement
8230 The form with a declaration is new in C99.
8232 ??? In accordance with the old parser, the declaration may be a
8233 nested function, which is then rejected in check_for_loop_decls,
8234 but does it make any sense for this to be included in the grammar?
8235 Note in particular that the nested function does not include a
8236 trailing ';', whereas the "declaration" production includes one.
8237 Also, can we reject bad declarations earlier and cheaper than
8238 check_for_loop_decls?
8240 In Objective-C, there are two additional variants:
8242 foreach-statement:
8243 for ( expression in expresssion ) statement
8244 for ( declaration in expression ) statement
8246 This is inconsistent with C, because the second variant is allowed
8247 even if c99 is not enabled.
8249 The rest of the comment documents these Objective-C foreach-statement.
8251 Here is the canonical example of the first variant:
8252 for (object in array) { do something with object }
8253 we call the first expression ("object") the "object_expression" and
8254 the second expression ("array") the "collection_expression".
8255 object_expression must be an lvalue of type "id" (a generic Objective-C
8256 object) because the loop works by assigning to object_expression the
8257 various objects from the collection_expression. collection_expression
8258 must evaluate to something of type "id" which responds to the method
8259 countByEnumeratingWithState:objects:count:.
8261 The canonical example of the second variant is:
8262 for (id object in array) { do something with object }
8263 which is completely equivalent to
8265 id object;
8266 for (object in array) { do something with object }
8268 Note that initizializing 'object' in some way (eg, "for ((object =
8269 xxx) in array) { do something with object }") is possibly
8270 technically valid, but completely pointless as 'object' will be
8271 assigned to something else as soon as the loop starts. We should
8272 most likely reject it (TODO).
8274 The beginning of the Objective-C foreach-statement looks exactly
8275 like the beginning of the for-statement, and we can tell it is a
8276 foreach-statement only because the initial declaration or
8277 expression is terminated by 'in' instead of ';'.
8279 IF_P is used to track whether there's a (possibly labeled) if statement
8280 which is not enclosed in braces and has an else clause. This is used to
8281 implement -Wparentheses. */
8283 static void
8284 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8285 bool novector, bool *if_p)
8287 tree block, cond, incr, body;
8288 unsigned char save_in_statement;
8289 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
8290 /* The following are only used when parsing an ObjC foreach statement. */
8291 tree object_expression;
8292 /* Silence the bogus uninitialized warning. */
8293 tree collection_expression = NULL;
8294 location_t loc = c_parser_peek_token (parser)->location;
8295 location_t for_loc = loc;
8296 bool is_foreach_statement = false;
8297 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
8298 token_indent_info for_tinfo
8299 = get_token_indent_info (c_parser_peek_token (parser));
8301 if (parser->omp_for_parse_state)
8303 error_at (for_loc,
8304 "loop not permitted in intervening code in OpenMP loop body");
8305 parser->omp_for_parse_state->fail = true;
8308 c_parser_consume_token (parser);
8309 /* Open a compound statement in Objective-C as well, just in case this is
8310 as foreach expression. */
8311 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
8312 cond = error_mark_node;
8313 incr = error_mark_node;
8314 matching_parens parens;
8315 if (parens.require_open (parser))
8317 /* Parse the initialization declaration or expression. */
8318 object_expression = error_mark_node;
8319 parser->objc_could_be_foreach_context = c_dialect_objc ();
8320 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8322 parser->objc_could_be_foreach_context = false;
8323 c_parser_consume_token (parser);
8324 c_finish_expr_stmt (loc, NULL_TREE);
8326 else if (c_parser_next_tokens_start_declaration (parser)
8327 || c_parser_nth_token_starts_std_attributes (parser, 1))
8329 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
8330 &object_expression);
8331 parser->objc_could_be_foreach_context = false;
8333 if (c_parser_next_token_is_keyword (parser, RID_IN))
8335 c_parser_consume_token (parser);
8336 is_foreach_statement = true;
8337 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
8338 c_parser_error (parser, "multiple iterating variables in "
8339 "fast enumeration");
8341 else
8342 check_for_loop_decls (for_loc, flag_isoc99);
8344 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
8346 /* __extension__ can start a declaration, but is also an
8347 unary operator that can start an expression. Consume all
8348 but the last of a possible series of __extension__ to
8349 determine which. */
8350 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
8351 && (c_parser_peek_2nd_token (parser)->keyword
8352 == RID_EXTENSION))
8353 c_parser_consume_token (parser);
8354 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
8355 || c_parser_nth_token_starts_std_attributes (parser, 2))
8357 int ext;
8358 ext = disable_extension_diagnostics ();
8359 c_parser_consume_token (parser);
8360 c_parser_declaration_or_fndef (parser, true, true, true, true,
8361 true, &object_expression);
8362 parser->objc_could_be_foreach_context = false;
8364 restore_extension_diagnostics (ext);
8365 if (c_parser_next_token_is_keyword (parser, RID_IN))
8367 c_parser_consume_token (parser);
8368 is_foreach_statement = true;
8369 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
8370 c_parser_error (parser, "multiple iterating variables in "
8371 "fast enumeration");
8373 else
8374 check_for_loop_decls (for_loc, flag_isoc99);
8376 else
8377 goto init_expr;
8379 else
8381 init_expr:
8383 struct c_expr ce;
8384 tree init_expression;
8385 ce = c_parser_expression (parser);
8386 init_expression = ce.value;
8387 parser->objc_could_be_foreach_context = false;
8388 if (c_parser_next_token_is_keyword (parser, RID_IN))
8390 c_parser_consume_token (parser);
8391 is_foreach_statement = true;
8392 if (! lvalue_p (init_expression))
8393 c_parser_error (parser, "invalid iterating variable in "
8394 "fast enumeration");
8395 object_expression
8396 = c_fully_fold (init_expression, false, NULL);
8398 else
8400 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
8401 init_expression = ce.value;
8402 c_finish_expr_stmt (loc, init_expression);
8403 c_parser_skip_until_found (parser, CPP_SEMICOLON,
8404 "expected %<;%>");
8408 /* Parse the loop condition. In the case of a foreach
8409 statement, there is no loop condition. */
8410 gcc_assert (!parser->objc_could_be_foreach_context);
8411 if (!is_foreach_statement)
8413 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8415 if (ivdep)
8417 c_parser_error (parser, "missing loop condition in loop "
8418 "with %<GCC ivdep%> pragma");
8419 cond = error_mark_node;
8421 else if (unroll)
8423 c_parser_error (parser, "missing loop condition in loop "
8424 "with %<GCC unroll%> pragma");
8425 cond = error_mark_node;
8427 else
8429 c_parser_consume_token (parser);
8430 cond = NULL_TREE;
8433 else
8435 cond = c_parser_condition (parser);
8436 c_parser_skip_until_found (parser, CPP_SEMICOLON,
8437 "expected %<;%>");
8439 if (ivdep && cond != error_mark_node)
8440 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8441 build_int_cst (integer_type_node,
8442 annot_expr_ivdep_kind),
8443 integer_zero_node);
8444 if (unroll && cond != error_mark_node)
8445 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8446 build_int_cst (integer_type_node,
8447 annot_expr_unroll_kind),
8448 build_int_cst (integer_type_node, unroll));
8449 if (novector && cond && cond != error_mark_node)
8450 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8451 build_int_cst (integer_type_node,
8452 annot_expr_no_vector_kind),
8453 integer_zero_node);
8455 /* Parse the increment expression (the third expression in a
8456 for-statement). In the case of a foreach-statement, this is
8457 the expression that follows the 'in'. */
8458 loc = c_parser_peek_token (parser)->location;
8459 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8461 if (is_foreach_statement)
8463 c_parser_error (parser,
8464 "missing collection in fast enumeration");
8465 collection_expression = error_mark_node;
8467 else
8468 incr = c_process_expr_stmt (loc, NULL_TREE);
8470 else
8472 if (is_foreach_statement)
8473 collection_expression
8474 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
8475 else
8477 struct c_expr ce = c_parser_expression (parser);
8478 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
8479 incr = c_process_expr_stmt (loc, ce.value);
8482 parens.skip_until_found_close (parser);
8484 save_in_statement = in_statement;
8485 if (is_foreach_statement)
8487 in_statement = IN_OBJC_FOREACH;
8488 save_objc_foreach_break_label = objc_foreach_break_label;
8489 save_objc_foreach_continue_label = objc_foreach_continue_label;
8490 objc_foreach_break_label = create_artificial_label (loc);
8491 objc_foreach_continue_label = create_artificial_label (loc);
8493 else
8494 in_statement = IN_ITERATION_STMT;
8496 token_indent_info body_tinfo
8497 = get_token_indent_info (c_parser_peek_token (parser));
8499 location_t loc_after_labels;
8500 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
8501 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8503 if (is_foreach_statement)
8504 objc_finish_foreach_loop (for_loc, object_expression,
8505 collection_expression, body,
8506 objc_foreach_break_label,
8507 objc_foreach_continue_label);
8508 else
8509 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
8510 body, NULL_TREE));
8511 add_stmt (c_end_compound_stmt (for_loc, block,
8512 flag_isoc99 || c_dialect_objc ()));
8513 c_parser_maybe_reclassify_token (parser);
8515 token_indent_info next_tinfo
8516 = get_token_indent_info (c_parser_peek_token (parser));
8517 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
8519 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
8520 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
8521 for_tinfo.location, RID_FOR);
8523 in_statement = save_in_statement;
8524 if (is_foreach_statement)
8526 objc_foreach_break_label = save_objc_foreach_break_label;
8527 objc_foreach_continue_label = save_objc_foreach_continue_label;
8531 /* Parse an asm statement, a GNU extension. This is a full-blown asm
8532 statement with inputs, outputs, clobbers, and volatile, inline, and goto
8533 tags allowed.
8535 asm-qualifier:
8536 volatile
8537 inline
8538 goto
8540 asm-qualifier-list:
8541 asm-qualifier-list asm-qualifier
8542 asm-qualifier
8544 asm-statement:
8545 asm asm-qualifier-list[opt] ( asm-argument ) ;
8547 asm-argument:
8548 asm-string-literal
8549 asm-string-literal : asm-operands[opt]
8550 asm-string-literal : asm-operands[opt] : asm-operands[opt]
8551 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
8552 : asm-clobbers[opt]
8553 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
8554 : asm-goto-operands
8556 The form with asm-goto-operands is valid if and only if the
8557 asm-qualifier-list contains goto, and is the only allowed form in that case.
8558 Duplicate asm-qualifiers are not allowed.
8560 The :: token is considered equivalent to two consecutive : tokens. */
8562 static tree
8563 c_parser_asm_statement (c_parser *parser)
8565 tree str, outputs, inputs, clobbers, labels, ret;
8566 bool simple;
8567 location_t asm_loc = c_parser_peek_token (parser)->location;
8568 int section, nsections;
8570 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
8571 c_parser_consume_token (parser);
8573 /* Handle the asm-qualifier-list. */
8574 location_t volatile_loc = UNKNOWN_LOCATION;
8575 location_t inline_loc = UNKNOWN_LOCATION;
8576 location_t goto_loc = UNKNOWN_LOCATION;
8577 for (;;)
8579 c_token *token = c_parser_peek_token (parser);
8580 location_t loc = token->location;
8581 switch (token->keyword)
8583 case RID_VOLATILE:
8584 if (volatile_loc)
8586 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8587 inform (volatile_loc, "first seen here");
8589 else
8590 volatile_loc = loc;
8591 c_parser_consume_token (parser);
8592 continue;
8594 case RID_INLINE:
8595 if (inline_loc)
8597 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8598 inform (inline_loc, "first seen here");
8600 else
8601 inline_loc = loc;
8602 c_parser_consume_token (parser);
8603 continue;
8605 case RID_GOTO:
8606 if (goto_loc)
8608 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8609 inform (goto_loc, "first seen here");
8611 else
8612 goto_loc = loc;
8613 c_parser_consume_token (parser);
8614 continue;
8616 case RID_CONST:
8617 case RID_RESTRICT:
8618 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
8619 c_parser_consume_token (parser);
8620 continue;
8622 default:
8623 break;
8625 break;
8628 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
8629 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
8630 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
8632 ret = NULL;
8634 matching_parens parens;
8635 if (!parens.require_open (parser))
8636 goto error;
8638 str = c_parser_asm_string_literal (parser);
8639 if (str == NULL_TREE)
8640 goto error_close_paren;
8642 simple = true;
8643 outputs = NULL_TREE;
8644 inputs = NULL_TREE;
8645 clobbers = NULL_TREE;
8646 labels = NULL_TREE;
8648 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
8649 goto done_asm;
8651 /* Parse each colon-delimited section of operands. */
8652 nsections = 3 + is_goto;
8653 for (section = 0; section < nsections; ++section)
8655 if (c_parser_next_token_is (parser, CPP_SCOPE))
8657 ++section;
8658 if (section == nsections)
8660 c_parser_error (parser, "expected %<)%>");
8661 goto error_close_paren;
8663 c_parser_consume_token (parser);
8665 else if (!c_parser_require (parser, CPP_COLON,
8666 is_goto
8667 ? G_("expected %<:%>")
8668 : G_("expected %<:%> or %<)%>"),
8669 UNKNOWN_LOCATION, is_goto))
8670 goto error_close_paren;
8672 /* Once past any colon, we're no longer a simple asm. */
8673 simple = false;
8675 if ((!c_parser_next_token_is (parser, CPP_COLON)
8676 && !c_parser_next_token_is (parser, CPP_SCOPE)
8677 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8678 || section == 3)
8679 switch (section)
8681 case 0:
8682 outputs = c_parser_asm_operands (parser);
8683 break;
8684 case 1:
8685 inputs = c_parser_asm_operands (parser);
8686 break;
8687 case 2:
8688 clobbers = c_parser_asm_clobbers (parser);
8689 break;
8690 case 3:
8691 labels = c_parser_asm_goto_operands (parser);
8692 break;
8693 default:
8694 gcc_unreachable ();
8697 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
8698 goto done_asm;
8701 done_asm:
8702 if (!parens.require_close (parser))
8704 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8705 goto error;
8708 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
8709 c_parser_skip_to_end_of_block_or_statement (parser);
8711 ret = build_asm_stmt (is_volatile,
8712 build_asm_expr (asm_loc, str, outputs, inputs,
8713 clobbers, labels, simple, is_inline));
8715 error:
8716 return ret;
8718 error_close_paren:
8719 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8720 goto error;
8723 /* Parse asm operands, a GNU extension.
8725 asm-operands:
8726 asm-operand
8727 asm-operands , asm-operand
8729 asm-operand:
8730 asm-string-literal ( expression )
8731 [ identifier ] asm-string-literal ( expression )
8734 static tree
8735 c_parser_asm_operands (c_parser *parser)
8737 tree list = NULL_TREE;
8738 while (true)
8740 tree name, str;
8741 struct c_expr expr;
8742 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
8744 c_parser_consume_token (parser);
8745 if (c_parser_next_token_is (parser, CPP_NAME))
8747 tree id = c_parser_peek_token (parser)->value;
8748 c_parser_consume_token (parser);
8749 name = build_string (IDENTIFIER_LENGTH (id),
8750 IDENTIFIER_POINTER (id));
8752 else
8754 c_parser_error (parser, "expected identifier");
8755 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
8756 return NULL_TREE;
8758 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
8759 "expected %<]%>");
8761 else
8762 name = NULL_TREE;
8763 str = c_parser_asm_string_literal (parser);
8764 if (str == NULL_TREE)
8765 return NULL_TREE;
8766 matching_parens parens;
8767 if (!parens.require_open (parser))
8768 return NULL_TREE;
8769 expr = c_parser_expression (parser);
8770 mark_exp_read (expr.value);
8771 if (!parens.require_close (parser))
8773 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8774 return NULL_TREE;
8776 list = chainon (list, build_tree_list (build_tree_list (name, str),
8777 expr.value));
8778 if (c_parser_next_token_is (parser, CPP_COMMA))
8779 c_parser_consume_token (parser);
8780 else
8781 break;
8783 return list;
8786 /* Parse asm clobbers, a GNU extension.
8788 asm-clobbers:
8789 asm-string-literal
8790 asm-clobbers , asm-string-literal
8793 static tree
8794 c_parser_asm_clobbers (c_parser *parser)
8796 tree list = NULL_TREE;
8797 while (true)
8799 tree str = c_parser_asm_string_literal (parser);
8800 if (str)
8801 list = tree_cons (NULL_TREE, str, list);
8802 else
8803 return NULL_TREE;
8804 if (c_parser_next_token_is (parser, CPP_COMMA))
8805 c_parser_consume_token (parser);
8806 else
8807 break;
8809 return list;
8812 /* Parse asm goto labels, a GNU extension.
8814 asm-goto-operands:
8815 identifier
8816 asm-goto-operands , identifier
8819 static tree
8820 c_parser_asm_goto_operands (c_parser *parser)
8822 tree list = NULL_TREE;
8823 while (true)
8825 tree name, label;
8827 if (c_parser_next_token_is (parser, CPP_NAME))
8829 c_token *tok = c_parser_peek_token (parser);
8830 name = tok->value;
8831 label = lookup_label_for_goto (tok->location, name);
8832 c_parser_consume_token (parser);
8833 TREE_USED (label) = 1;
8835 else
8837 c_parser_error (parser, "expected identifier");
8838 return NULL_TREE;
8841 name = build_string (IDENTIFIER_LENGTH (name),
8842 IDENTIFIER_POINTER (name));
8843 list = tree_cons (name, label, list);
8844 if (c_parser_next_token_is (parser, CPP_COMMA))
8845 c_parser_consume_token (parser);
8846 else
8847 return nreverse (list);
8851 /* Parse a possibly concatenated sequence of string literals.
8852 TRANSLATE says whether to translate them to the execution character
8853 set; WIDE_OK says whether any kind of prefixed string literal is
8854 permitted in this context. This code is based on that in
8855 lex_string. */
8857 struct c_expr
8858 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
8860 struct c_expr ret;
8861 size_t count;
8862 struct obstack str_ob;
8863 struct obstack loc_ob;
8864 cpp_string str, istr, *strs;
8865 c_token *tok;
8866 location_t loc, last_tok_loc;
8867 enum cpp_ttype type;
8868 tree value, string_tree;
8870 tok = c_parser_peek_token (parser);
8871 loc = tok->location;
8872 last_tok_loc = linemap_resolve_location (line_table, loc,
8873 LRK_MACRO_DEFINITION_LOCATION,
8874 NULL);
8875 type = tok->type;
8876 switch (type)
8878 case CPP_STRING:
8879 case CPP_WSTRING:
8880 case CPP_STRING16:
8881 case CPP_STRING32:
8882 case CPP_UTF8STRING:
8883 string_tree = tok->value;
8884 break;
8886 default:
8887 c_parser_error (parser, "expected string literal");
8888 ret.set_error ();
8889 ret.value = NULL_TREE;
8890 ret.original_code = ERROR_MARK;
8891 ret.original_type = NULL_TREE;
8892 return ret;
8895 /* Try to avoid the overhead of creating and destroying an obstack
8896 for the common case of just one string. */
8897 switch (c_parser_peek_2nd_token (parser)->type)
8899 default:
8900 c_parser_consume_token (parser);
8901 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
8902 str.len = TREE_STRING_LENGTH (string_tree);
8903 count = 1;
8904 strs = &str;
8905 break;
8907 case CPP_STRING:
8908 case CPP_WSTRING:
8909 case CPP_STRING16:
8910 case CPP_STRING32:
8911 case CPP_UTF8STRING:
8912 gcc_obstack_init (&str_ob);
8913 gcc_obstack_init (&loc_ob);
8914 count = 0;
8917 c_parser_consume_token (parser);
8918 count++;
8919 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
8920 str.len = TREE_STRING_LENGTH (string_tree);
8921 if (type != tok->type)
8923 if (type == CPP_STRING)
8924 type = tok->type;
8925 else if (tok->type != CPP_STRING)
8926 error ("unsupported non-standard concatenation "
8927 "of string literals");
8929 obstack_grow (&str_ob, &str, sizeof (cpp_string));
8930 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
8931 tok = c_parser_peek_token (parser);
8932 string_tree = tok->value;
8933 last_tok_loc
8934 = linemap_resolve_location (line_table, tok->location,
8935 LRK_MACRO_DEFINITION_LOCATION, NULL);
8937 while (tok->type == CPP_STRING
8938 || tok->type == CPP_WSTRING
8939 || tok->type == CPP_STRING16
8940 || tok->type == CPP_STRING32
8941 || tok->type == CPP_UTF8STRING);
8942 strs = (cpp_string *) obstack_finish (&str_ob);
8945 if (count > 1 && !in_system_header_at (input_location))
8946 warning (OPT_Wtraditional,
8947 "traditional C rejects string constant concatenation");
8949 if ((type == CPP_STRING || wide_ok)
8950 && ((translate
8951 ? cpp_interpret_string : cpp_interpret_string_notranslate)
8952 (parse_in, strs, count, &istr, type)))
8954 value = build_string (istr.len, (const char *) istr.text);
8955 free (CONST_CAST (unsigned char *, istr.text));
8956 if (count > 1)
8958 location_t *locs = (location_t *) obstack_finish (&loc_ob);
8959 gcc_assert (g_string_concat_db);
8960 g_string_concat_db->record_string_concatenation (count, locs);
8963 else
8965 if (type != CPP_STRING && !wide_ok)
8967 error_at (loc, "a wide string is invalid in this context");
8968 type = CPP_STRING;
8970 /* Callers cannot generally handle error_mark_node in this
8971 context, so return the empty string instead. An error has
8972 been issued, either above or from cpp_interpret_string. */
8973 switch (type)
8975 default:
8976 case CPP_STRING:
8977 case CPP_UTF8STRING:
8978 if (type == CPP_UTF8STRING && flag_char8_t)
8980 value = build_string (TYPE_PRECISION (char8_type_node)
8981 / TYPE_PRECISION (char_type_node),
8982 ""); /* char8_t is 8 bits */
8984 else
8985 value = build_string (1, "");
8986 break;
8987 case CPP_STRING16:
8988 value = build_string (TYPE_PRECISION (char16_type_node)
8989 / TYPE_PRECISION (char_type_node),
8990 "\0"); /* char16_t is 16 bits */
8991 break;
8992 case CPP_STRING32:
8993 value = build_string (TYPE_PRECISION (char32_type_node)
8994 / TYPE_PRECISION (char_type_node),
8995 "\0\0\0"); /* char32_t is 32 bits */
8996 break;
8997 case CPP_WSTRING:
8998 value = build_string (TYPE_PRECISION (wchar_type_node)
8999 / TYPE_PRECISION (char_type_node),
9000 "\0\0\0"); /* widest supported wchar_t
9001 is 32 bits */
9002 break;
9006 switch (type)
9008 default:
9009 case CPP_STRING:
9010 TREE_TYPE (value) = char_array_type_node;
9011 break;
9012 case CPP_UTF8STRING:
9013 if (flag_char8_t)
9014 TREE_TYPE (value) = char8_array_type_node;
9015 else
9016 TREE_TYPE (value) = char_array_type_node;
9017 break;
9018 case CPP_STRING16:
9019 TREE_TYPE (value) = char16_array_type_node;
9020 break;
9021 case CPP_STRING32:
9022 TREE_TYPE (value) = char32_array_type_node;
9023 break;
9024 case CPP_WSTRING:
9025 TREE_TYPE (value) = wchar_array_type_node;
9027 value = fix_string_type (value);
9029 if (count > 1)
9031 obstack_free (&str_ob, 0);
9032 obstack_free (&loc_ob, 0);
9035 ret.value = value;
9036 ret.original_code = STRING_CST;
9037 ret.original_type = NULL_TREE;
9038 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
9039 ret.m_decimal = 0;
9040 parser->seen_string_literal = true;
9041 return ret;
9044 /* Parse an expression other than a compound expression; that is, an
9045 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
9046 AFTER is not NULL then it is an Objective-C message expression which
9047 is the primary-expression starting the expression as an initializer.
9049 assignment-expression:
9050 conditional-expression
9051 unary-expression assignment-operator assignment-expression
9053 assignment-operator: one of
9054 = *= /= %= += -= <<= >>= &= ^= |=
9056 In GNU C we accept any conditional expression on the LHS and
9057 diagnose the invalid lvalue rather than producing a syntax
9058 error. */
9060 static struct c_expr
9061 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
9062 tree omp_atomic_lhs)
9064 struct c_expr lhs, rhs, ret;
9065 enum tree_code code;
9066 location_t op_location, exp_location;
9067 bool save_in_omp_for = c_in_omp_for;
9068 c_in_omp_for = false;
9069 gcc_assert (!after || c_dialect_objc ());
9070 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
9071 op_location = c_parser_peek_token (parser)->location;
9072 switch (c_parser_peek_token (parser)->type)
9074 case CPP_EQ:
9075 code = NOP_EXPR;
9076 break;
9077 case CPP_MULT_EQ:
9078 code = MULT_EXPR;
9079 break;
9080 case CPP_DIV_EQ:
9081 code = TRUNC_DIV_EXPR;
9082 break;
9083 case CPP_MOD_EQ:
9084 code = TRUNC_MOD_EXPR;
9085 break;
9086 case CPP_PLUS_EQ:
9087 code = PLUS_EXPR;
9088 break;
9089 case CPP_MINUS_EQ:
9090 code = MINUS_EXPR;
9091 break;
9092 case CPP_LSHIFT_EQ:
9093 code = LSHIFT_EXPR;
9094 break;
9095 case CPP_RSHIFT_EQ:
9096 code = RSHIFT_EXPR;
9097 break;
9098 case CPP_AND_EQ:
9099 code = BIT_AND_EXPR;
9100 break;
9101 case CPP_XOR_EQ:
9102 code = BIT_XOR_EXPR;
9103 break;
9104 case CPP_OR_EQ:
9105 code = BIT_IOR_EXPR;
9106 break;
9107 default:
9108 c_in_omp_for = save_in_omp_for;
9109 return lhs;
9111 c_parser_consume_token (parser);
9112 exp_location = c_parser_peek_token (parser)->location;
9113 rhs = c_parser_expr_no_commas (parser, NULL);
9114 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
9116 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
9117 code, exp_location, rhs.value,
9118 rhs.original_type);
9119 ret.m_decimal = 0;
9120 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
9121 if (code == NOP_EXPR)
9122 ret.original_code = MODIFY_EXPR;
9123 else
9125 suppress_warning (ret.value, OPT_Wparentheses);
9126 ret.original_code = ERROR_MARK;
9128 ret.original_type = NULL;
9129 c_in_omp_for = save_in_omp_for;
9130 return ret;
9133 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
9134 AFTER is not NULL then it is an Objective-C message expression which is
9135 the primary-expression starting the expression as an initializer.
9137 conditional-expression:
9138 logical-OR-expression
9139 logical-OR-expression ? expression : conditional-expression
9141 GNU extensions:
9143 conditional-expression:
9144 logical-OR-expression ? : conditional-expression
9147 static struct c_expr
9148 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
9149 tree omp_atomic_lhs)
9151 struct c_expr cond, exp1, exp2, ret;
9152 location_t start, cond_loc, colon_loc;
9153 bool save_c_omp_array_section_p = c_omp_array_section_p;
9155 gcc_assert (!after || c_dialect_objc ());
9157 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
9159 if (c_parser_next_token_is_not (parser, CPP_QUERY))
9160 return cond;
9161 c_omp_array_section_p = false;
9162 if (cond.value != error_mark_node)
9163 start = cond.get_start ();
9164 else
9165 start = UNKNOWN_LOCATION;
9166 cond_loc = c_parser_peek_token (parser)->location;
9167 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
9168 c_parser_consume_token (parser);
9169 if (c_parser_next_token_is (parser, CPP_COLON))
9171 tree eptype = NULL_TREE;
9173 location_t middle_loc = c_parser_peek_token (parser)->location;
9174 pedwarn (middle_loc, OPT_Wpedantic,
9175 "ISO C forbids omitting the middle term of a %<?:%> expression");
9176 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
9178 eptype = TREE_TYPE (cond.value);
9179 cond.value = TREE_OPERAND (cond.value, 0);
9181 tree e = cond.value;
9182 while (TREE_CODE (e) == COMPOUND_EXPR)
9183 e = TREE_OPERAND (e, 1);
9184 warn_for_omitted_condop (middle_loc, e);
9185 /* Make sure first operand is calculated only once. */
9186 exp1.value = save_expr (default_conversion (cond.value));
9187 if (eptype)
9188 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
9189 exp1.original_type = NULL;
9190 exp1.src_range = cond.src_range;
9191 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
9192 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
9194 else
9196 cond.value
9197 = c_objc_common_truthvalue_conversion
9198 (cond_loc, default_conversion (cond.value));
9199 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
9200 exp1 = c_parser_expression_conv (parser);
9201 mark_exp_read (exp1.value);
9202 c_inhibit_evaluation_warnings +=
9203 ((cond.value == truthvalue_true_node)
9204 - (cond.value == truthvalue_false_node));
9207 colon_loc = c_parser_peek_token (parser)->location;
9208 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
9210 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
9211 ret.set_error ();
9212 ret.original_code = ERROR_MARK;
9213 ret.original_type = NULL;
9214 c_omp_array_section_p = save_c_omp_array_section_p;
9215 return ret;
9218 location_t exp2_loc = c_parser_peek_token (parser)->location;
9219 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
9220 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
9222 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
9223 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
9224 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
9225 if (UNLIKELY (omp_atomic_lhs != NULL)
9226 && (TREE_CODE (cond.value) == GT_EXPR
9227 || TREE_CODE (cond.value) == LT_EXPR
9228 || TREE_CODE (cond.value) == EQ_EXPR)
9229 && c_tree_equal (exp2.value, omp_atomic_lhs)
9230 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
9231 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
9232 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
9233 cond.value, exp1.value, exp2.value);
9234 else
9235 ret.value
9236 = build_conditional_expr (colon_loc, cond.value,
9237 cond.original_code == C_MAYBE_CONST_EXPR,
9238 exp1.value, exp1.original_type, loc1,
9239 exp2.value, exp2.original_type, loc2);
9240 ret.original_code = ERROR_MARK;
9241 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
9242 ret.original_type = NULL;
9243 else
9245 tree t1, t2;
9247 /* If both sides are enum type, the default conversion will have
9248 made the type of the result be an integer type. We want to
9249 remember the enum types we started with. */
9250 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
9251 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
9252 ret.original_type = ((t1 != error_mark_node
9253 && t2 != error_mark_node
9254 && (TYPE_MAIN_VARIANT (t1)
9255 == TYPE_MAIN_VARIANT (t2)))
9256 ? t1
9257 : NULL);
9259 set_c_expr_source_range (&ret, start, exp2.get_finish ());
9260 ret.m_decimal = 0;
9261 c_omp_array_section_p = save_c_omp_array_section_p;
9262 return ret;
9265 /* Parse a binary expression; that is, a logical-OR-expression (C90
9266 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
9267 NULL then it is an Objective-C message expression which is the
9268 primary-expression starting the expression as an initializer.
9270 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
9271 when it should be the unfolded lhs. In a valid OpenMP source,
9272 one of the operands of the toplevel binary expression must be equal
9273 to it. In that case, just return a build2 created binary operation
9274 rather than result of parser_build_binary_op.
9276 multiplicative-expression:
9277 cast-expression
9278 multiplicative-expression * cast-expression
9279 multiplicative-expression / cast-expression
9280 multiplicative-expression % cast-expression
9282 additive-expression:
9283 multiplicative-expression
9284 additive-expression + multiplicative-expression
9285 additive-expression - multiplicative-expression
9287 shift-expression:
9288 additive-expression
9289 shift-expression << additive-expression
9290 shift-expression >> additive-expression
9292 relational-expression:
9293 shift-expression
9294 relational-expression < shift-expression
9295 relational-expression > shift-expression
9296 relational-expression <= shift-expression
9297 relational-expression >= shift-expression
9299 equality-expression:
9300 relational-expression
9301 equality-expression == relational-expression
9302 equality-expression != relational-expression
9304 AND-expression:
9305 equality-expression
9306 AND-expression & equality-expression
9308 exclusive-OR-expression:
9309 AND-expression
9310 exclusive-OR-expression ^ AND-expression
9312 inclusive-OR-expression:
9313 exclusive-OR-expression
9314 inclusive-OR-expression | exclusive-OR-expression
9316 logical-AND-expression:
9317 inclusive-OR-expression
9318 logical-AND-expression && inclusive-OR-expression
9320 logical-OR-expression:
9321 logical-AND-expression
9322 logical-OR-expression || logical-AND-expression
9325 static struct c_expr
9326 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
9327 tree omp_atomic_lhs)
9329 /* A binary expression is parsed using operator-precedence parsing,
9330 with the operands being cast expressions. All the binary
9331 operators are left-associative. Thus a binary expression is of
9332 form:
9334 E0 op1 E1 op2 E2 ...
9336 which we represent on a stack. On the stack, the precedence
9337 levels are strictly increasing. When a new operator is
9338 encountered of higher precedence than that at the top of the
9339 stack, it is pushed; its LHS is the top expression, and its RHS
9340 is everything parsed until it is popped. When a new operator is
9341 encountered with precedence less than or equal to that at the top
9342 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
9343 by the result of the operation until the operator at the top of
9344 the stack has lower precedence than the new operator or there is
9345 only one element on the stack; then the top expression is the LHS
9346 of the new operator. In the case of logical AND and OR
9347 expressions, we also need to adjust c_inhibit_evaluation_warnings
9348 as appropriate when the operators are pushed and popped. */
9350 struct {
9351 /* The expression at this stack level. */
9352 struct c_expr expr;
9353 /* The precedence of the operator on its left, PREC_NONE at the
9354 bottom of the stack. */
9355 enum c_parser_prec prec;
9356 /* The operation on its left. */
9357 enum tree_code op;
9358 /* The source location of this operation. */
9359 location_t loc;
9360 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
9361 tree sizeof_arg;
9362 } stack[NUM_PRECS];
9363 int sp;
9364 /* Location of the binary operator. */
9365 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
9366 #define POP \
9367 do { \
9368 switch (stack[sp].op) \
9370 case TRUTH_ANDIF_EXPR: \
9371 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9372 == truthvalue_false_node); \
9373 break; \
9374 case TRUTH_ORIF_EXPR: \
9375 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9376 == truthvalue_true_node); \
9377 break; \
9378 case TRUNC_DIV_EXPR: \
9379 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
9380 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
9381 && (stack[sp].expr.original_code == SIZEOF_EXPR \
9382 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
9384 tree type0 = stack[sp - 1].sizeof_arg; \
9385 tree type1 = stack[sp].sizeof_arg; \
9386 tree first_arg = type0; \
9387 if (!TYPE_P (type0)) \
9388 type0 = TREE_TYPE (type0); \
9389 if (!TYPE_P (type1)) \
9390 type1 = TREE_TYPE (type1); \
9391 if (POINTER_TYPE_P (type0) \
9392 && comptypes (TREE_TYPE (type0), type1) \
9393 && !(TREE_CODE (first_arg) == PARM_DECL \
9394 && C_ARRAY_PARAMETER (first_arg) \
9395 && warn_sizeof_array_argument)) \
9397 auto_diagnostic_group d; \
9398 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
9399 "division %<sizeof (%T) / sizeof (%T)%> " \
9400 "does not compute the number of array " \
9401 "elements", \
9402 type0, type1)) \
9403 if (DECL_P (first_arg)) \
9404 inform (DECL_SOURCE_LOCATION (first_arg), \
9405 "first %<sizeof%> operand was declared here"); \
9407 else if (TREE_CODE (type0) == ARRAY_TYPE \
9408 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
9409 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
9410 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
9411 stack[sp].sizeof_arg, type1); \
9413 break; \
9414 default: \
9415 break; \
9417 stack[sp - 1].expr \
9418 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
9419 stack[sp - 1].expr, true, true); \
9420 stack[sp].expr \
9421 = convert_lvalue_to_rvalue (stack[sp].loc, \
9422 stack[sp].expr, true, true); \
9423 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
9424 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
9425 && ((1 << stack[sp].prec) \
9426 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
9427 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
9428 | (1 << PREC_ADD) | (1 << PREC_MULT) \
9429 | (1 << PREC_EQ)))) \
9430 || ((c_parser_next_token_is (parser, CPP_QUERY) \
9431 || (omp_atomic_lhs == void_list_node \
9432 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
9433 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
9434 && stack[sp].op != TRUNC_MOD_EXPR \
9435 && stack[sp].op != GE_EXPR \
9436 && stack[sp].op != LE_EXPR \
9437 && stack[sp].op != NE_EXPR \
9438 && stack[0].expr.value != error_mark_node \
9439 && stack[1].expr.value != error_mark_node \
9440 && (omp_atomic_lhs == void_list_node \
9441 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
9442 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
9443 || (stack[sp].op == EQ_EXPR \
9444 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
9446 tree t = make_node (stack[1].op); \
9447 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
9448 TREE_OPERAND (t, 0) = stack[0].expr.value; \
9449 TREE_OPERAND (t, 1) = stack[1].expr.value; \
9450 stack[0].expr.value = t; \
9451 stack[0].expr.m_decimal = 0; \
9453 else \
9454 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
9455 stack[sp].op, \
9456 stack[sp - 1].expr, \
9457 stack[sp].expr); \
9458 sp--; \
9459 } while (0)
9460 gcc_assert (!after || c_dialect_objc ());
9461 stack[0].loc = c_parser_peek_token (parser)->location;
9462 stack[0].expr = c_parser_cast_expression (parser, after);
9463 stack[0].prec = PREC_NONE;
9464 stack[0].sizeof_arg = c_last_sizeof_arg;
9465 sp = 0;
9466 while (true)
9468 enum c_parser_prec oprec;
9469 enum tree_code ocode;
9470 source_range src_range;
9471 if (parser->error)
9472 goto out;
9473 switch (c_parser_peek_token (parser)->type)
9475 case CPP_MULT:
9476 oprec = PREC_MULT;
9477 ocode = MULT_EXPR;
9478 break;
9479 case CPP_DIV:
9480 oprec = PREC_MULT;
9481 ocode = TRUNC_DIV_EXPR;
9482 break;
9483 case CPP_MOD:
9484 oprec = PREC_MULT;
9485 ocode = TRUNC_MOD_EXPR;
9486 break;
9487 case CPP_PLUS:
9488 oprec = PREC_ADD;
9489 ocode = PLUS_EXPR;
9490 break;
9491 case CPP_MINUS:
9492 oprec = PREC_ADD;
9493 ocode = MINUS_EXPR;
9494 break;
9495 case CPP_LSHIFT:
9496 oprec = PREC_SHIFT;
9497 ocode = LSHIFT_EXPR;
9498 break;
9499 case CPP_RSHIFT:
9500 oprec = PREC_SHIFT;
9501 ocode = RSHIFT_EXPR;
9502 break;
9503 case CPP_LESS:
9504 oprec = PREC_REL;
9505 ocode = LT_EXPR;
9506 break;
9507 case CPP_GREATER:
9508 oprec = PREC_REL;
9509 ocode = GT_EXPR;
9510 break;
9511 case CPP_LESS_EQ:
9512 oprec = PREC_REL;
9513 ocode = LE_EXPR;
9514 break;
9515 case CPP_GREATER_EQ:
9516 oprec = PREC_REL;
9517 ocode = GE_EXPR;
9518 break;
9519 case CPP_EQ_EQ:
9520 oprec = PREC_EQ;
9521 ocode = EQ_EXPR;
9522 break;
9523 case CPP_NOT_EQ:
9524 oprec = PREC_EQ;
9525 ocode = NE_EXPR;
9526 break;
9527 case CPP_AND:
9528 oprec = PREC_BITAND;
9529 ocode = BIT_AND_EXPR;
9530 break;
9531 case CPP_XOR:
9532 oprec = PREC_BITXOR;
9533 ocode = BIT_XOR_EXPR;
9534 break;
9535 case CPP_OR:
9536 oprec = PREC_BITOR;
9537 ocode = BIT_IOR_EXPR;
9538 break;
9539 case CPP_AND_AND:
9540 oprec = PREC_LOGAND;
9541 ocode = TRUTH_ANDIF_EXPR;
9542 break;
9543 case CPP_OR_OR:
9544 oprec = PREC_LOGOR;
9545 ocode = TRUTH_ORIF_EXPR;
9546 break;
9547 default:
9548 /* Not a binary operator, so end of the binary
9549 expression. */
9550 goto out;
9552 binary_loc = c_parser_peek_token (parser)->location;
9553 while (oprec <= stack[sp].prec)
9554 POP;
9555 c_parser_consume_token (parser);
9556 switch (ocode)
9558 case TRUTH_ANDIF_EXPR:
9559 src_range = stack[sp].expr.src_range;
9560 stack[sp].expr
9561 = convert_lvalue_to_rvalue (stack[sp].loc,
9562 stack[sp].expr, true, true);
9563 stack[sp].expr.value = c_objc_common_truthvalue_conversion
9564 (stack[sp].loc, default_conversion (stack[sp].expr.value));
9565 c_inhibit_evaluation_warnings += (stack[sp].expr.value
9566 == truthvalue_false_node);
9567 set_c_expr_source_range (&stack[sp].expr, src_range);
9568 break;
9569 case TRUTH_ORIF_EXPR:
9570 src_range = stack[sp].expr.src_range;
9571 stack[sp].expr
9572 = convert_lvalue_to_rvalue (stack[sp].loc,
9573 stack[sp].expr, true, true);
9574 stack[sp].expr.value = c_objc_common_truthvalue_conversion
9575 (stack[sp].loc, default_conversion (stack[sp].expr.value));
9576 c_inhibit_evaluation_warnings += (stack[sp].expr.value
9577 == truthvalue_true_node);
9578 set_c_expr_source_range (&stack[sp].expr, src_range);
9579 break;
9580 default:
9581 break;
9583 sp++;
9584 stack[sp].loc = binary_loc;
9585 stack[sp].expr = c_parser_cast_expression (parser, NULL);
9586 stack[sp].prec = oprec;
9587 stack[sp].op = ocode;
9588 stack[sp].sizeof_arg = c_last_sizeof_arg;
9590 out:
9591 while (sp > 0)
9592 POP;
9593 return stack[0].expr;
9594 #undef POP
9597 /* Parse any storage class specifiers after an open parenthesis in a
9598 context where a compound literal is permitted. */
9600 static struct c_declspecs *
9601 c_parser_compound_literal_scspecs (c_parser *parser)
9603 bool seen_scspec = false;
9604 struct c_declspecs *specs = build_null_declspecs ();
9605 while (c_parser_next_token_is (parser, CPP_KEYWORD))
9607 switch (c_parser_peek_token (parser)->keyword)
9609 case RID_CONSTEXPR:
9610 case RID_REGISTER:
9611 case RID_STATIC:
9612 case RID_THREAD:
9613 seen_scspec = true;
9614 declspecs_add_scspec (c_parser_peek_token (parser)->location,
9615 specs, c_parser_peek_token (parser)->value);
9616 c_parser_consume_token (parser);
9617 break;
9618 default:
9619 goto out;
9622 out:
9623 return seen_scspec ? specs : NULL;
9626 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
9627 is not NULL then it is an Objective-C message expression which is the
9628 primary-expression starting the expression as an initializer.
9630 cast-expression:
9631 unary-expression
9632 ( type-name ) unary-expression
9635 static struct c_expr
9636 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
9638 location_t cast_loc = c_parser_peek_token (parser)->location;
9639 gcc_assert (!after || c_dialect_objc ());
9640 if (after)
9641 return c_parser_postfix_expression_after_primary (parser,
9642 cast_loc, *after);
9643 /* If the expression begins with a parenthesized type name, it may
9644 be either a cast or a compound literal; we need to see whether
9645 the next character is '{' to tell the difference. If not, it is
9646 an unary expression. Full detection of unknown typenames here
9647 would require a 3-token lookahead. */
9648 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9649 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9651 struct c_declspecs *scspecs;
9652 struct c_type_name *type_name;
9653 struct c_expr ret;
9654 struct c_expr expr;
9655 matching_parens parens;
9656 parens.consume_open (parser);
9657 scspecs = c_parser_compound_literal_scspecs (parser);
9658 type_name = c_parser_type_name (parser, true);
9659 parens.skip_until_found_close (parser);
9660 if (type_name == NULL)
9662 ret.set_error ();
9663 ret.original_code = ERROR_MARK;
9664 ret.original_type = NULL;
9665 return ret;
9668 /* Save casted types in the function's used types hash table. */
9669 used_types_insert (type_name->specs->type);
9671 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9672 return c_parser_postfix_expression_after_paren_type (parser, scspecs,
9673 type_name,
9674 cast_loc);
9675 if (scspecs)
9676 error_at (cast_loc, "storage class specifier in cast");
9677 if (type_name->specs->alignas_p)
9678 error_at (type_name->specs->locations[cdw_alignas],
9679 "alignment specified for type name in cast");
9681 location_t expr_loc = c_parser_peek_token (parser)->location;
9682 expr = c_parser_cast_expression (parser, NULL);
9683 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
9685 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
9686 if (ret.value && expr.value)
9687 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
9688 ret.original_code = ERROR_MARK;
9689 ret.original_type = NULL;
9690 ret.m_decimal = 0;
9691 return ret;
9693 else
9694 return c_parser_unary_expression (parser);
9697 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
9699 unary-expression:
9700 postfix-expression
9701 ++ unary-expression
9702 -- unary-expression
9703 unary-operator cast-expression
9704 sizeof unary-expression
9705 sizeof ( type-name )
9707 unary-operator: one of
9708 & * + - ~ !
9710 GNU extensions:
9712 unary-expression:
9713 __alignof__ unary-expression
9714 __alignof__ ( type-name )
9715 && identifier
9717 (C11 permits _Alignof with type names only.)
9719 unary-operator: one of
9720 __extension__ __real__ __imag__
9722 Transactional Memory:
9724 unary-expression:
9725 transaction-expression
9727 In addition, the GNU syntax treats ++ and -- as unary operators, so
9728 they may be applied to cast expressions with errors for non-lvalues
9729 given later. */
9731 static struct c_expr
9732 c_parser_unary_expression (c_parser *parser)
9734 int ext;
9735 struct c_expr ret, op;
9736 location_t op_loc = c_parser_peek_token (parser)->location;
9737 location_t exp_loc;
9738 location_t finish;
9739 ret.original_code = ERROR_MARK;
9740 ret.original_type = NULL;
9741 switch (c_parser_peek_token (parser)->type)
9743 case CPP_PLUS_PLUS:
9744 c_parser_consume_token (parser);
9745 exp_loc = c_parser_peek_token (parser)->location;
9746 op = c_parser_cast_expression (parser, NULL);
9748 op = default_function_array_read_conversion (exp_loc, op);
9749 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
9750 case CPP_MINUS_MINUS:
9751 c_parser_consume_token (parser);
9752 exp_loc = c_parser_peek_token (parser)->location;
9753 op = c_parser_cast_expression (parser, NULL);
9755 op = default_function_array_read_conversion (exp_loc, op);
9756 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
9757 case CPP_AND:
9758 c_parser_consume_token (parser);
9759 op = c_parser_cast_expression (parser, NULL);
9760 mark_exp_read (op.value);
9761 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
9762 case CPP_MULT:
9764 c_parser_consume_token (parser);
9765 exp_loc = c_parser_peek_token (parser)->location;
9766 op = c_parser_cast_expression (parser, NULL);
9767 finish = op.get_finish ();
9768 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9769 location_t combined_loc = make_location (op_loc, op_loc, finish);
9770 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
9771 ret.src_range.m_start = op_loc;
9772 ret.src_range.m_finish = finish;
9773 ret.m_decimal = 0;
9774 return ret;
9776 case CPP_PLUS:
9777 if (!c_dialect_objc () && !in_system_header_at (input_location))
9778 warning_at (op_loc,
9779 OPT_Wtraditional,
9780 "traditional C rejects the unary plus operator");
9781 c_parser_consume_token (parser);
9782 exp_loc = c_parser_peek_token (parser)->location;
9783 op = c_parser_cast_expression (parser, NULL);
9784 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9785 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
9786 case CPP_MINUS:
9787 c_parser_consume_token (parser);
9788 exp_loc = c_parser_peek_token (parser)->location;
9789 op = c_parser_cast_expression (parser, NULL);
9790 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9791 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
9792 case CPP_COMPL:
9793 c_parser_consume_token (parser);
9794 exp_loc = c_parser_peek_token (parser)->location;
9795 op = c_parser_cast_expression (parser, NULL);
9796 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9797 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
9798 case CPP_NOT:
9799 c_parser_consume_token (parser);
9800 exp_loc = c_parser_peek_token (parser)->location;
9801 op = c_parser_cast_expression (parser, NULL);
9802 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9803 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
9804 case CPP_AND_AND:
9805 /* Refer to the address of a label as a pointer. */
9806 c_parser_consume_token (parser);
9807 if (c_parser_next_token_is (parser, CPP_NAME))
9809 ret.value = finish_label_address_expr
9810 (c_parser_peek_token (parser)->value, op_loc);
9811 set_c_expr_source_range (&ret, op_loc,
9812 c_parser_peek_token (parser)->get_finish ());
9813 c_parser_consume_token (parser);
9815 else
9817 c_parser_error (parser, "expected identifier");
9818 ret.set_error ();
9820 return ret;
9821 case CPP_KEYWORD:
9822 switch (c_parser_peek_token (parser)->keyword)
9824 case RID_SIZEOF:
9825 return c_parser_sizeof_expression (parser);
9826 case RID_ALIGNOF:
9827 return c_parser_alignof_expression (parser);
9828 case RID_BUILTIN_HAS_ATTRIBUTE:
9829 return c_parser_has_attribute_expression (parser);
9830 case RID_EXTENSION:
9831 c_parser_consume_token (parser);
9832 ext = disable_extension_diagnostics ();
9833 ret = c_parser_cast_expression (parser, NULL);
9834 restore_extension_diagnostics (ext);
9835 return ret;
9836 case RID_REALPART:
9837 c_parser_consume_token (parser);
9838 exp_loc = c_parser_peek_token (parser)->location;
9839 op = c_parser_cast_expression (parser, NULL);
9840 op = default_function_array_conversion (exp_loc, op);
9841 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
9842 case RID_IMAGPART:
9843 c_parser_consume_token (parser);
9844 exp_loc = c_parser_peek_token (parser)->location;
9845 op = c_parser_cast_expression (parser, NULL);
9846 op = default_function_array_conversion (exp_loc, op);
9847 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
9848 case RID_TRANSACTION_ATOMIC:
9849 case RID_TRANSACTION_RELAXED:
9850 return c_parser_transaction_expression (parser,
9851 c_parser_peek_token (parser)->keyword);
9852 default:
9853 return c_parser_postfix_expression (parser);
9855 default:
9856 return c_parser_postfix_expression (parser);
9860 /* Parse a sizeof expression. */
9862 static struct c_expr
9863 c_parser_sizeof_expression (c_parser *parser)
9865 struct c_expr expr;
9866 struct c_expr result;
9867 location_t expr_loc;
9868 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
9870 location_t start;
9871 location_t finish = UNKNOWN_LOCATION;
9873 start = c_parser_peek_token (parser)->location;
9875 c_parser_consume_token (parser);
9876 c_inhibit_evaluation_warnings++;
9877 in_sizeof++;
9878 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9879 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9881 /* Either sizeof ( type-name ) or sizeof unary-expression
9882 starting with a compound literal. */
9883 struct c_declspecs *scspecs;
9884 struct c_type_name *type_name;
9885 matching_parens parens;
9886 parens.consume_open (parser);
9887 expr_loc = c_parser_peek_token (parser)->location;
9888 scspecs = c_parser_compound_literal_scspecs (parser);
9889 type_name = c_parser_type_name (parser, true);
9890 parens.skip_until_found_close (parser);
9891 finish = parser->tokens_buf[0].location;
9892 if (type_name == NULL)
9894 struct c_expr ret;
9895 c_inhibit_evaluation_warnings--;
9896 in_sizeof--;
9897 ret.set_error ();
9898 ret.original_code = ERROR_MARK;
9899 ret.original_type = NULL;
9900 return ret;
9902 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9904 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
9905 type_name,
9906 expr_loc);
9907 finish = expr.get_finish ();
9908 goto sizeof_expr;
9910 /* sizeof ( type-name ). */
9911 if (scspecs)
9912 error_at (expr_loc, "storage class specifier in %<sizeof%>");
9913 if (type_name->specs->alignas_p)
9914 error_at (type_name->specs->locations[cdw_alignas],
9915 "alignment specified for type name in %<sizeof%>");
9916 c_inhibit_evaluation_warnings--;
9917 in_sizeof--;
9918 result = c_expr_sizeof_type (expr_loc, type_name);
9920 else
9922 expr_loc = c_parser_peek_token (parser)->location;
9923 expr = c_parser_unary_expression (parser);
9924 finish = expr.get_finish ();
9925 sizeof_expr:
9926 c_inhibit_evaluation_warnings--;
9927 in_sizeof--;
9928 mark_exp_read (expr.value);
9929 if (TREE_CODE (expr.value) == COMPONENT_REF
9930 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
9931 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
9932 result = c_expr_sizeof_expr (expr_loc, expr);
9934 if (finish == UNKNOWN_LOCATION)
9935 finish = start;
9936 set_c_expr_source_range (&result, start, finish);
9937 return result;
9940 /* Parse an alignof expression. */
9942 static struct c_expr
9943 c_parser_alignof_expression (c_parser *parser)
9945 struct c_expr expr;
9946 location_t start_loc = c_parser_peek_token (parser)->location;
9947 location_t end_loc;
9948 tree alignof_spelling = c_parser_peek_token (parser)->value;
9949 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
9950 bool is_c11_alignof = (strcmp (IDENTIFIER_POINTER (alignof_spelling),
9951 "_Alignof") == 0
9952 || strcmp (IDENTIFIER_POINTER (alignof_spelling),
9953 "alignof") == 0);
9954 /* A diagnostic is not required for the use of this identifier in
9955 the implementation namespace; only diagnose it for the C11 or C23
9956 spelling because of existing code using the other spellings. */
9957 if (is_c11_alignof)
9959 if (flag_isoc99)
9960 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
9961 alignof_spelling);
9962 else
9963 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
9964 alignof_spelling);
9966 c_parser_consume_token (parser);
9967 c_inhibit_evaluation_warnings++;
9968 in_alignof++;
9969 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9970 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9972 /* Either __alignof__ ( type-name ) or __alignof__
9973 unary-expression starting with a compound literal. */
9974 location_t loc;
9975 struct c_declspecs *scspecs;
9976 struct c_type_name *type_name;
9977 struct c_expr ret;
9978 matching_parens parens;
9979 parens.consume_open (parser);
9980 loc = c_parser_peek_token (parser)->location;
9981 scspecs = c_parser_compound_literal_scspecs (parser);
9982 type_name = c_parser_type_name (parser, true);
9983 end_loc = c_parser_peek_token (parser)->location;
9984 parens.skip_until_found_close (parser);
9985 if (type_name == NULL)
9987 struct c_expr ret;
9988 c_inhibit_evaluation_warnings--;
9989 in_alignof--;
9990 ret.set_error ();
9991 ret.original_code = ERROR_MARK;
9992 ret.original_type = NULL;
9993 return ret;
9995 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9997 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
9998 type_name,
9999 loc);
10000 goto alignof_expr;
10002 /* alignof ( type-name ). */
10003 if (scspecs)
10004 error_at (loc, "storage class specifier in %qE", alignof_spelling);
10005 if (type_name->specs->alignas_p)
10006 error_at (type_name->specs->locations[cdw_alignas],
10007 "alignment specified for type name in %qE",
10008 alignof_spelling);
10009 c_inhibit_evaluation_warnings--;
10010 in_alignof--;
10011 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
10012 NULL, NULL),
10013 false, is_c11_alignof, 1);
10014 ret.original_code = ERROR_MARK;
10015 ret.original_type = NULL;
10016 set_c_expr_source_range (&ret, start_loc, end_loc);
10017 ret.m_decimal = 0;
10018 return ret;
10020 else
10022 struct c_expr ret;
10023 expr = c_parser_unary_expression (parser);
10024 end_loc = expr.src_range.m_finish;
10025 alignof_expr:
10026 mark_exp_read (expr.value);
10027 c_inhibit_evaluation_warnings--;
10028 in_alignof--;
10029 if (is_c11_alignof)
10030 pedwarn (start_loc,
10031 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
10032 alignof_spelling);
10033 ret.value = c_alignof_expr (start_loc, expr.value);
10034 ret.original_code = ERROR_MARK;
10035 ret.original_type = NULL;
10036 set_c_expr_source_range (&ret, start_loc, end_loc);
10037 ret.m_decimal = 0;
10038 return ret;
10042 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
10043 expression. */
10045 static struct c_expr
10046 c_parser_has_attribute_expression (c_parser *parser)
10048 gcc_assert (c_parser_next_token_is_keyword (parser,
10049 RID_BUILTIN_HAS_ATTRIBUTE));
10050 location_t start = c_parser_peek_token (parser)->location;
10051 c_parser_consume_token (parser);
10053 c_inhibit_evaluation_warnings++;
10055 matching_parens parens;
10056 if (!parens.require_open (parser))
10058 c_inhibit_evaluation_warnings--;
10059 in_typeof--;
10061 struct c_expr result;
10062 result.set_error ();
10063 result.original_code = ERROR_MARK;
10064 result.original_type = NULL;
10065 return result;
10068 /* Treat the type argument the same way as in typeof for the purposes
10069 of warnings. FIXME: Generalize this so the warning refers to
10070 __builtin_has_attribute rather than typeof. */
10071 in_typeof++;
10073 /* The first operand: one of DECL, EXPR, or TYPE. */
10074 tree oper = NULL_TREE;
10075 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
10077 struct c_type_name *tname = c_parser_type_name (parser);
10078 in_typeof--;
10079 if (tname)
10081 oper = groktypename (tname, NULL, NULL);
10082 pop_maybe_used (c_type_variably_modified_p (oper));
10085 else
10087 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
10088 c_inhibit_evaluation_warnings--;
10089 in_typeof--;
10090 if (cexpr.value != error_mark_node)
10092 mark_exp_read (cexpr.value);
10093 oper = cexpr.value;
10094 tree etype = TREE_TYPE (oper);
10095 bool was_vm = c_type_variably_modified_p (etype);
10096 /* This is returned with the type so that when the type is
10097 evaluated, this can be evaluated. */
10098 if (was_vm)
10099 oper = c_fully_fold (oper, false, NULL);
10100 pop_maybe_used (was_vm);
10104 struct c_expr result;
10105 result.original_code = ERROR_MARK;
10106 result.original_type = NULL;
10108 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10110 /* Consume the closing parenthesis if that's the next token
10111 in the likely case the built-in was invoked with fewer
10112 than two arguments. */
10113 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10114 c_parser_consume_token (parser);
10115 c_inhibit_evaluation_warnings--;
10116 result.set_error ();
10117 return result;
10120 bool save_translate_strings_p = parser->translate_strings_p;
10122 location_t atloc = c_parser_peek_token (parser)->location;
10123 /* Parse a single attribute. Require no leading comma and do not
10124 allow empty attributes. */
10125 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
10127 parser->translate_strings_p = save_translate_strings_p;
10129 location_t finish = c_parser_peek_token (parser)->location;
10130 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10131 c_parser_consume_token (parser);
10132 else
10134 c_parser_error (parser, "expected identifier");
10135 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10137 result.set_error ();
10138 return result;
10141 if (!attr)
10143 error_at (atloc, "expected identifier");
10144 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10145 "expected %<)%>");
10146 result.set_error ();
10147 return result;
10150 result.original_code = INTEGER_CST;
10151 result.original_type = boolean_type_node;
10153 if (has_attribute (atloc, oper, attr, default_conversion))
10154 result.value = boolean_true_node;
10155 else
10156 result.value = boolean_false_node;
10158 set_c_expr_source_range (&result, start, finish);
10159 result.m_decimal = 0;
10160 return result;
10163 /* Helper function to read arguments of builtins which are interfaces
10164 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
10165 others. The name of the builtin is passed using BNAME parameter.
10166 Function returns true if there were no errors while parsing and
10167 stores the arguments in CEXPR_LIST. If it returns true,
10168 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
10169 parenthesis. */
10170 static bool
10171 c_parser_get_builtin_args (c_parser *parser, const char *bname,
10172 vec<c_expr_t, va_gc> **ret_cexpr_list,
10173 bool choose_expr_p,
10174 location_t *out_close_paren_loc)
10176 location_t loc = c_parser_peek_token (parser)->location;
10177 vec<c_expr_t, va_gc> *cexpr_list;
10178 c_expr_t expr;
10179 bool saved_force_folding_builtin_constant_p;
10181 *ret_cexpr_list = NULL;
10182 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
10184 error_at (loc, "cannot take address of %qs", bname);
10185 return false;
10188 c_parser_consume_token (parser);
10190 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10192 *out_close_paren_loc = c_parser_peek_token (parser)->location;
10193 c_parser_consume_token (parser);
10194 return true;
10197 saved_force_folding_builtin_constant_p
10198 = force_folding_builtin_constant_p;
10199 force_folding_builtin_constant_p |= choose_expr_p;
10200 expr = c_parser_expr_no_commas (parser, NULL);
10201 force_folding_builtin_constant_p
10202 = saved_force_folding_builtin_constant_p;
10203 vec_alloc (cexpr_list, 1);
10204 vec_safe_push (cexpr_list, expr);
10205 while (c_parser_next_token_is (parser, CPP_COMMA))
10207 c_parser_consume_token (parser);
10208 expr = c_parser_expr_no_commas (parser, NULL);
10209 vec_safe_push (cexpr_list, expr);
10212 *out_close_paren_loc = c_parser_peek_token (parser)->location;
10213 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
10214 return false;
10216 *ret_cexpr_list = cexpr_list;
10217 return true;
10220 /* This represents a single generic-association. */
10222 struct c_generic_association
10224 /* The location of the starting token of the type. */
10225 location_t type_location;
10226 /* The association's type, or NULL_TREE for 'default'. */
10227 tree type;
10228 /* The association's expression. */
10229 struct c_expr expression;
10232 /* Parse a generic-selection. (C11 6.5.1.1).
10234 generic-selection:
10235 _Generic ( assignment-expression , generic-assoc-list )
10237 generic-assoc-list:
10238 generic-association
10239 generic-assoc-list , generic-association
10241 generic-association:
10242 type-name : assignment-expression
10243 default : assignment-expression
10246 static struct c_expr
10247 c_parser_generic_selection (c_parser *parser)
10249 struct c_expr selector, error_expr;
10250 tree selector_type;
10251 struct c_generic_association matched_assoc;
10252 int match_found = -1;
10253 location_t generic_loc, selector_loc;
10255 error_expr.original_code = ERROR_MARK;
10256 error_expr.original_type = NULL;
10257 error_expr.set_error ();
10258 matched_assoc.type_location = UNKNOWN_LOCATION;
10259 matched_assoc.type = NULL_TREE;
10260 matched_assoc.expression = error_expr;
10262 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
10263 generic_loc = c_parser_peek_token (parser)->location;
10264 c_parser_consume_token (parser);
10265 if (flag_isoc99)
10266 pedwarn_c99 (generic_loc, OPT_Wpedantic,
10267 "ISO C99 does not support %<_Generic%>");
10268 else
10269 pedwarn_c99 (generic_loc, OPT_Wpedantic,
10270 "ISO C90 does not support %<_Generic%>");
10272 matching_parens parens;
10273 if (!parens.require_open (parser))
10274 return error_expr;
10276 c_inhibit_evaluation_warnings++;
10277 selector_loc = c_parser_peek_token (parser)->location;
10278 selector = c_parser_expr_no_commas (parser, NULL);
10279 selector = default_function_array_conversion (selector_loc, selector);
10280 c_inhibit_evaluation_warnings--;
10282 if (selector.value == error_mark_node)
10284 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10285 return selector;
10287 mark_exp_read (selector.value);
10288 selector_type = TREE_TYPE (selector.value);
10289 /* In ISO C terms, rvalues (including the controlling expression of
10290 _Generic) do not have qualified types. */
10291 if (TREE_CODE (selector_type) != ARRAY_TYPE)
10292 selector_type = TYPE_MAIN_VARIANT (selector_type);
10293 /* In ISO C terms, _Noreturn is not part of the type of expressions
10294 such as &abort, but in GCC it is represented internally as a type
10295 qualifier. */
10296 if (FUNCTION_POINTER_TYPE_P (selector_type)
10297 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
10298 selector_type
10299 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
10301 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10303 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10304 return error_expr;
10307 auto_vec<c_generic_association> associations;
10308 while (1)
10310 struct c_generic_association assoc, *iter;
10311 unsigned int ix;
10312 c_token *token = c_parser_peek_token (parser);
10314 assoc.type_location = token->location;
10315 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
10317 c_parser_consume_token (parser);
10318 assoc.type = NULL_TREE;
10320 else
10322 struct c_type_name *type_name;
10324 type_name = c_parser_type_name (parser);
10325 if (type_name == NULL)
10327 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10328 return error_expr;
10330 assoc.type = groktypename (type_name, NULL, NULL);
10331 if (assoc.type == error_mark_node)
10333 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10334 return error_expr;
10337 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
10338 error_at (assoc.type_location,
10339 "%<_Generic%> association has function type");
10340 else if (!COMPLETE_TYPE_P (assoc.type))
10341 error_at (assoc.type_location,
10342 "%<_Generic%> association has incomplete type");
10344 if (c_type_variably_modified_p (assoc.type))
10345 error_at (assoc.type_location,
10346 "%<_Generic%> association has "
10347 "variable length type");
10350 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
10352 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10353 return error_expr;
10356 bool match = assoc.type == NULL_TREE
10357 || comptypes (assoc.type, selector_type);
10359 if (!match)
10360 c_inhibit_evaluation_warnings++;
10362 assoc.expression = c_parser_expr_no_commas (parser, NULL);
10364 if (!match)
10365 c_inhibit_evaluation_warnings--;
10367 if (assoc.expression.value == error_mark_node)
10369 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10370 return error_expr;
10373 for (ix = 0; associations.iterate (ix, &iter); ++ix)
10375 if (assoc.type == NULL_TREE)
10377 if (iter->type == NULL_TREE)
10379 error_at (assoc.type_location,
10380 "duplicate %<default%> case in %<_Generic%>");
10381 inform (iter->type_location, "original %<default%> is here");
10384 else if (iter->type != NULL_TREE)
10386 if (comptypes (assoc.type, iter->type))
10388 error_at (assoc.type_location,
10389 "%<_Generic%> specifies two compatible types");
10390 inform (iter->type_location, "compatible type is here");
10395 if (assoc.type == NULL_TREE)
10397 if (match_found < 0)
10399 matched_assoc = assoc;
10400 match_found = associations.length ();
10403 else if (match)
10405 if (match_found < 0 || matched_assoc.type == NULL_TREE)
10407 matched_assoc = assoc;
10408 match_found = associations.length ();
10410 else
10412 error_at (assoc.type_location,
10413 "%<_Generic%> selector matches multiple associations");
10414 inform (matched_assoc.type_location,
10415 "other match is here");
10419 associations.safe_push (assoc);
10421 if (c_parser_peek_token (parser)->type != CPP_COMMA)
10422 break;
10423 c_parser_consume_token (parser);
10426 unsigned int ix;
10427 struct c_generic_association *iter;
10428 FOR_EACH_VEC_ELT (associations, ix, iter)
10429 if (ix != (unsigned) match_found)
10430 mark_exp_read (iter->expression.value);
10432 if (!parens.require_close (parser))
10434 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10435 return error_expr;
10438 if (match_found < 0)
10440 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
10441 "compatible with any association",
10442 selector_type);
10443 return error_expr;
10446 return matched_assoc.expression;
10449 /* Check the validity of a function pointer argument *EXPR (argument
10450 position POS) to __builtin_tgmath. Return the number of function
10451 arguments if possibly valid; return 0 having reported an error if
10452 not valid. */
10454 static unsigned int
10455 check_tgmath_function (c_expr *expr, unsigned int pos)
10457 tree type = TREE_TYPE (expr->value);
10458 if (!FUNCTION_POINTER_TYPE_P (type))
10460 error_at (expr->get_location (),
10461 "argument %u of %<__builtin_tgmath%> is not a function pointer",
10462 pos);
10463 return 0;
10465 type = TREE_TYPE (type);
10466 if (!prototype_p (type))
10468 error_at (expr->get_location (),
10469 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
10470 return 0;
10472 if (stdarg_p (type))
10474 error_at (expr->get_location (),
10475 "argument %u of %<__builtin_tgmath%> has variable arguments",
10476 pos);
10477 return 0;
10479 unsigned int nargs = 0;
10480 function_args_iterator iter;
10481 tree t;
10482 FOREACH_FUNCTION_ARGS (type, t, iter)
10484 if (t == void_type_node)
10485 break;
10486 nargs++;
10488 if (nargs == 0)
10490 error_at (expr->get_location (),
10491 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
10492 return 0;
10494 return nargs;
10497 /* Ways in which a parameter or return value of a type-generic macro
10498 may vary between the different functions the macro may call. */
10499 enum tgmath_parm_kind
10501 tgmath_fixed, tgmath_real, tgmath_complex
10504 /* Helper function for c_parser_postfix_expression. Parse predefined
10505 identifiers. */
10507 static struct c_expr
10508 c_parser_predefined_identifier (c_parser *parser)
10510 location_t loc = c_parser_peek_token (parser)->location;
10511 switch (c_parser_peek_token (parser)->keyword)
10513 case RID_FUNCTION_NAME:
10514 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
10515 "identifier", "__FUNCTION__");
10516 break;
10517 case RID_PRETTY_FUNCTION_NAME:
10518 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
10519 "identifier", "__PRETTY_FUNCTION__");
10520 break;
10521 case RID_C99_FUNCTION_NAME:
10522 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
10523 "%<__func__%> predefined identifier");
10524 break;
10525 default:
10526 gcc_unreachable ();
10529 struct c_expr expr;
10530 expr.original_code = ERROR_MARK;
10531 expr.original_type = NULL;
10532 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
10533 c_parser_peek_token (parser)->value);
10534 set_c_expr_source_range (&expr, loc, loc);
10535 expr.m_decimal = 0;
10536 c_parser_consume_token (parser);
10537 return expr;
10540 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
10541 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
10542 call c_parser_postfix_expression_after_paren_type on encountering them.
10544 postfix-expression:
10545 primary-expression
10546 postfix-expression [ expression ]
10547 postfix-expression ( argument-expression-list[opt] )
10548 postfix-expression . identifier
10549 postfix-expression -> identifier
10550 postfix-expression ++
10551 postfix-expression --
10552 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
10553 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
10555 argument-expression-list:
10556 argument-expression
10557 argument-expression-list , argument-expression
10559 primary-expression:
10560 identifier
10561 constant
10562 string-literal
10563 ( expression )
10564 generic-selection
10566 GNU extensions:
10568 primary-expression:
10569 __func__
10570 (treated as a keyword in GNU C)
10571 __FUNCTION__
10572 __PRETTY_FUNCTION__
10573 ( compound-statement )
10574 __builtin_va_arg ( assignment-expression , type-name )
10575 __builtin_offsetof ( type-name , offsetof-member-designator )
10576 __builtin_choose_expr ( assignment-expression ,
10577 assignment-expression ,
10578 assignment-expression )
10579 __builtin_types_compatible_p ( type-name , type-name )
10580 __builtin_tgmath ( expr-list )
10581 __builtin_complex ( assignment-expression , assignment-expression )
10582 __builtin_shuffle ( assignment-expression , assignment-expression )
10583 __builtin_shuffle ( assignment-expression ,
10584 assignment-expression ,
10585 assignment-expression, )
10586 __builtin_convertvector ( assignment-expression , type-name )
10587 __builtin_assoc_barrier ( assignment-expression )
10589 offsetof-member-designator:
10590 identifier
10591 offsetof-member-designator . identifier
10592 offsetof-member-designator [ expression ]
10594 Objective-C:
10596 primary-expression:
10597 [ objc-receiver objc-message-args ]
10598 @selector ( objc-selector-arg )
10599 @protocol ( identifier )
10600 @encode ( type-name )
10601 objc-string-literal
10602 Classname . identifier
10605 static struct c_expr
10606 c_parser_postfix_expression (c_parser *parser)
10608 struct c_expr expr, e1;
10609 struct c_type_name *t1, *t2;
10610 location_t loc = c_parser_peek_token (parser)->location;
10611 source_range tok_range = c_parser_peek_token (parser)->get_range ();
10612 expr.original_code = ERROR_MARK;
10613 expr.original_type = NULL;
10614 expr.m_decimal = 0;
10615 switch (c_parser_peek_token (parser)->type)
10617 case CPP_NUMBER:
10618 expr.value = c_parser_peek_token (parser)->value;
10619 set_c_expr_source_range (&expr, tok_range);
10620 loc = c_parser_peek_token (parser)->location;
10621 expr.m_decimal = c_parser_peek_token (parser)->flags & DECIMAL_INT;
10622 c_parser_consume_token (parser);
10623 if (TREE_CODE (expr.value) == FIXED_CST
10624 && !targetm.fixed_point_supported_p ())
10626 error_at (loc, "fixed-point types not supported for this target");
10627 expr.set_error ();
10629 break;
10630 case CPP_CHAR:
10631 case CPP_CHAR16:
10632 case CPP_CHAR32:
10633 case CPP_UTF8CHAR:
10634 case CPP_WCHAR:
10635 expr.value = c_parser_peek_token (parser)->value;
10636 /* For the purpose of warning when a pointer is compared with
10637 a zero character constant. */
10638 expr.original_type = char_type_node;
10639 set_c_expr_source_range (&expr, tok_range);
10640 c_parser_consume_token (parser);
10641 break;
10642 case CPP_STRING:
10643 case CPP_STRING16:
10644 case CPP_STRING32:
10645 case CPP_WSTRING:
10646 case CPP_UTF8STRING:
10647 expr = c_parser_string_literal (parser, parser->translate_strings_p,
10648 true);
10649 break;
10650 case CPP_OBJC_STRING:
10651 gcc_assert (c_dialect_objc ());
10652 expr.value
10653 = objc_build_string_object (c_parser_peek_token (parser)->value);
10654 set_c_expr_source_range (&expr, tok_range);
10655 c_parser_consume_token (parser);
10656 break;
10657 case CPP_NAME:
10658 switch (c_parser_peek_token (parser)->id_kind)
10660 case C_ID_ID:
10662 tree id = c_parser_peek_token (parser)->value;
10663 c_parser_consume_token (parser);
10664 expr.value = build_external_ref (loc, id,
10665 (c_parser_peek_token (parser)->type
10666 == CPP_OPEN_PAREN),
10667 &expr.original_type);
10668 set_c_expr_source_range (&expr, tok_range);
10669 break;
10671 case C_ID_CLASSNAME:
10673 /* Here we parse the Objective-C 2.0 Class.name dot
10674 syntax. */
10675 tree class_name = c_parser_peek_token (parser)->value;
10676 tree component;
10677 c_parser_consume_token (parser);
10678 gcc_assert (c_dialect_objc ());
10679 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
10681 expr.set_error ();
10682 break;
10684 if (c_parser_next_token_is_not (parser, CPP_NAME))
10686 c_parser_error (parser, "expected identifier");
10687 expr.set_error ();
10688 break;
10690 c_token *component_tok = c_parser_peek_token (parser);
10691 component = component_tok->value;
10692 location_t end_loc = component_tok->get_finish ();
10693 c_parser_consume_token (parser);
10694 expr.value = objc_build_class_component_ref (class_name,
10695 component);
10696 set_c_expr_source_range (&expr, loc, end_loc);
10697 break;
10699 default:
10700 c_parser_error (parser, "expected expression");
10701 expr.set_error ();
10702 break;
10704 break;
10705 case CPP_OPEN_PAREN:
10706 /* A parenthesized expression, statement expression or compound
10707 literal. */
10708 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
10710 /* A statement expression. */
10711 tree stmt;
10712 location_t brace_loc;
10713 bool save_c_omp_array_section_p = c_omp_array_section_p;
10714 c_parser_consume_token (parser);
10715 brace_loc = c_parser_peek_token (parser)->location;
10716 c_parser_consume_token (parser);
10717 /* If we've not yet started the current function's statement list,
10718 or we're in the parameter scope of an old-style function
10719 declaration, statement expressions are not allowed. */
10720 if (!building_stmt_list_p () || old_style_parameter_scope ())
10722 error_at (loc, "braced-group within expression allowed "
10723 "only inside a function");
10724 parser->error = true;
10725 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
10726 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10727 expr.set_error ();
10728 break;
10730 c_omp_array_section_p = false;
10731 stmt = c_begin_stmt_expr ();
10732 c_parser_compound_statement_nostart (parser);
10733 location_t close_loc = c_parser_peek_token (parser)->location;
10734 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10735 "expected %<)%>");
10736 pedwarn (loc, OPT_Wpedantic,
10737 "ISO C forbids braced-groups within expressions");
10738 expr.value = c_finish_stmt_expr (brace_loc, stmt);
10739 set_c_expr_source_range (&expr, loc, close_loc);
10740 mark_exp_read (expr.value);
10741 c_omp_array_section_p = save_c_omp_array_section_p;
10743 else
10745 /* A parenthesized expression. */
10746 location_t loc_open_paren = c_parser_peek_token (parser)->location;
10747 c_parser_consume_token (parser);
10748 expr = c_parser_expression (parser);
10749 if (TREE_CODE (expr.value) == MODIFY_EXPR)
10750 suppress_warning (expr.value, OPT_Wparentheses);
10751 if (expr.original_code != C_MAYBE_CONST_EXPR
10752 && expr.original_code != SIZEOF_EXPR)
10753 expr.original_code = ERROR_MARK;
10754 /* Remember that we saw ( ) around the sizeof. */
10755 if (expr.original_code == SIZEOF_EXPR)
10756 expr.original_code = PAREN_SIZEOF_EXPR;
10757 /* Don't change EXPR.ORIGINAL_TYPE. */
10758 location_t loc_close_paren = c_parser_peek_token (parser)->location;
10759 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
10760 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10761 "expected %<)%>", loc_open_paren);
10763 break;
10764 case CPP_KEYWORD:
10765 switch (c_parser_peek_token (parser)->keyword)
10767 case RID_FUNCTION_NAME:
10768 case RID_PRETTY_FUNCTION_NAME:
10769 case RID_C99_FUNCTION_NAME:
10770 expr = c_parser_predefined_identifier (parser);
10771 break;
10772 case RID_VA_ARG:
10774 location_t start_loc = loc;
10775 c_parser_consume_token (parser);
10776 matching_parens parens;
10777 if (!parens.require_open (parser))
10779 expr.set_error ();
10780 break;
10782 e1 = c_parser_expr_no_commas (parser, NULL);
10783 mark_exp_read (e1.value);
10784 e1.value = c_fully_fold (e1.value, false, NULL);
10785 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10787 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10788 expr.set_error ();
10789 break;
10791 loc = c_parser_peek_token (parser)->location;
10792 t1 = c_parser_type_name (parser);
10793 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10794 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10795 "expected %<)%>");
10796 if (t1 == NULL)
10798 expr.set_error ();
10800 else
10802 tree type_expr = NULL_TREE;
10803 expr.value = c_build_va_arg (start_loc, e1.value, loc,
10804 groktypename (t1, &type_expr, NULL));
10805 if (type_expr)
10807 expr.value = build2 (C_MAYBE_CONST_EXPR,
10808 TREE_TYPE (expr.value), type_expr,
10809 expr.value);
10810 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
10812 set_c_expr_source_range (&expr, start_loc, end_loc);
10815 break;
10816 case RID_OFFSETOF:
10818 c_parser_consume_token (parser);
10819 matching_parens parens;
10820 if (!parens.require_open (parser))
10822 expr.set_error ();
10823 break;
10825 t1 = c_parser_type_name (parser);
10826 if (t1 == NULL)
10827 parser->error = true;
10828 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10829 gcc_assert (parser->error);
10830 if (parser->error)
10832 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10833 expr.set_error ();
10834 break;
10836 tree type = groktypename (t1, NULL, NULL);
10837 tree offsetof_ref;
10838 if (type == error_mark_node)
10839 offsetof_ref = error_mark_node;
10840 else
10842 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
10843 SET_EXPR_LOCATION (offsetof_ref, loc);
10845 /* Parse the second argument to __builtin_offsetof. We
10846 must have one identifier, and beyond that we want to
10847 accept sub structure and sub array references. */
10848 if (c_parser_next_token_is (parser, CPP_NAME))
10850 c_token *comp_tok = c_parser_peek_token (parser);
10851 offsetof_ref
10852 = build_component_ref (loc, offsetof_ref, comp_tok->value,
10853 comp_tok->location, UNKNOWN_LOCATION);
10854 c_parser_consume_token (parser);
10855 while (c_parser_next_token_is (parser, CPP_DOT)
10856 || c_parser_next_token_is (parser,
10857 CPP_OPEN_SQUARE)
10858 || c_parser_next_token_is (parser,
10859 CPP_DEREF))
10861 if (c_parser_next_token_is (parser, CPP_DEREF))
10863 loc = c_parser_peek_token (parser)->location;
10864 offsetof_ref = build_array_ref (loc,
10865 offsetof_ref,
10866 integer_zero_node);
10867 goto do_dot;
10869 else if (c_parser_next_token_is (parser, CPP_DOT))
10871 do_dot:
10872 c_parser_consume_token (parser);
10873 if (c_parser_next_token_is_not (parser,
10874 CPP_NAME))
10876 c_parser_error (parser, "expected identifier");
10877 break;
10879 c_token *comp_tok = c_parser_peek_token (parser);
10880 offsetof_ref
10881 = build_component_ref (loc, offsetof_ref,
10882 comp_tok->value,
10883 comp_tok->location,
10884 UNKNOWN_LOCATION);
10885 c_parser_consume_token (parser);
10887 else
10889 struct c_expr ce;
10890 tree idx;
10891 loc = c_parser_peek_token (parser)->location;
10892 c_parser_consume_token (parser);
10893 ce = c_parser_expression (parser);
10894 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
10895 idx = ce.value;
10896 idx = c_fully_fold (idx, false, NULL);
10897 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10898 "expected %<]%>");
10899 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
10903 else
10904 c_parser_error (parser, "expected identifier");
10905 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10906 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10907 "expected %<)%>");
10908 expr.value = fold_offsetof (offsetof_ref);
10909 set_c_expr_source_range (&expr, loc, end_loc);
10911 break;
10912 case RID_CHOOSE_EXPR:
10914 vec<c_expr_t, va_gc> *cexpr_list;
10915 c_expr_t *e1_p, *e2_p, *e3_p;
10916 tree c;
10917 location_t close_paren_loc;
10919 c_parser_consume_token (parser);
10920 if (!c_parser_get_builtin_args (parser,
10921 "__builtin_choose_expr",
10922 &cexpr_list, true,
10923 &close_paren_loc))
10925 expr.set_error ();
10926 break;
10929 if (vec_safe_length (cexpr_list) != 3)
10931 error_at (loc, "wrong number of arguments to "
10932 "%<__builtin_choose_expr%>");
10933 expr.set_error ();
10934 break;
10937 e1_p = &(*cexpr_list)[0];
10938 e2_p = &(*cexpr_list)[1];
10939 e3_p = &(*cexpr_list)[2];
10941 c = e1_p->value;
10942 mark_exp_read (e2_p->value);
10943 mark_exp_read (e3_p->value);
10944 if (TREE_CODE (c) != INTEGER_CST
10945 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
10946 error_at (loc,
10947 "first argument to %<__builtin_choose_expr%> not"
10948 " a constant");
10949 constant_expression_warning (c);
10950 expr = integer_zerop (c) ? *e3_p : *e2_p;
10951 set_c_expr_source_range (&expr, loc, close_paren_loc);
10952 break;
10954 case RID_TYPES_COMPATIBLE_P:
10956 c_parser_consume_token (parser);
10957 matching_parens parens;
10958 if (!parens.require_open (parser))
10960 expr.set_error ();
10961 break;
10963 t1 = c_parser_type_name (parser);
10964 if (t1 == NULL)
10966 expr.set_error ();
10967 break;
10969 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10971 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10972 expr.set_error ();
10973 break;
10975 t2 = c_parser_type_name (parser);
10976 if (t2 == NULL)
10978 expr.set_error ();
10979 break;
10981 location_t close_paren_loc = c_parser_peek_token (parser)->location;
10982 parens.skip_until_found_close (parser);
10983 tree e1, e2;
10984 e1 = groktypename (t1, NULL, NULL);
10985 e2 = groktypename (t2, NULL, NULL);
10986 if (e1 == error_mark_node || e2 == error_mark_node)
10988 expr.set_error ();
10989 break;
10992 e1 = TYPE_MAIN_VARIANT (e1);
10993 e2 = TYPE_MAIN_VARIANT (e2);
10995 expr.value
10996 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
10997 set_c_expr_source_range (&expr, loc, close_paren_loc);
10999 break;
11000 case RID_BUILTIN_TGMATH:
11002 vec<c_expr_t, va_gc> *cexpr_list;
11003 location_t close_paren_loc;
11005 c_parser_consume_token (parser);
11006 if (!c_parser_get_builtin_args (parser,
11007 "__builtin_tgmath",
11008 &cexpr_list, false,
11009 &close_paren_loc))
11011 expr.set_error ();
11012 break;
11015 if (vec_safe_length (cexpr_list) < 3)
11017 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11018 expr.set_error ();
11019 break;
11022 unsigned int i;
11023 c_expr_t *p;
11024 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
11025 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11026 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
11027 if (nargs == 0)
11029 expr.set_error ();
11030 break;
11032 if (vec_safe_length (cexpr_list) < nargs)
11034 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11035 expr.set_error ();
11036 break;
11038 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
11039 if (num_functions < 2)
11041 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11042 expr.set_error ();
11043 break;
11046 /* The first NUM_FUNCTIONS expressions are the function
11047 pointers. The remaining NARGS expressions are the
11048 arguments that are to be passed to one of those
11049 functions, chosen following <tgmath.h> rules. */
11050 for (unsigned int j = 1; j < num_functions; j++)
11052 unsigned int this_nargs
11053 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
11054 if (this_nargs == 0)
11056 expr.set_error ();
11057 goto out;
11059 if (this_nargs != nargs)
11061 error_at ((*cexpr_list)[j].get_location (),
11062 "argument %u of %<__builtin_tgmath%> has "
11063 "wrong number of arguments", j + 1);
11064 expr.set_error ();
11065 goto out;
11069 /* The functions all have the same number of arguments.
11070 Determine whether arguments and return types vary in
11071 ways permitted for <tgmath.h> functions. */
11072 /* The first entry in each of these vectors is for the
11073 return type, subsequent entries for parameter
11074 types. */
11075 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
11076 auto_vec<tree> parm_first (nargs + 1);
11077 auto_vec<bool> parm_complex (nargs + 1);
11078 auto_vec<bool> parm_varies (nargs + 1);
11079 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
11080 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
11081 parm_first.quick_push (first_ret);
11082 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
11083 parm_varies.quick_push (false);
11084 function_args_iterator iter;
11085 tree t;
11086 unsigned int argpos;
11087 FOREACH_FUNCTION_ARGS (first_type, t, iter)
11089 if (t == void_type_node)
11090 break;
11091 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
11092 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
11093 parm_varies.quick_push (false);
11095 for (unsigned int j = 1; j < num_functions; j++)
11097 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11098 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
11099 if (ret != parm_first[0])
11101 parm_varies[0] = true;
11102 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
11103 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
11105 error_at ((*cexpr_list)[0].get_location (),
11106 "invalid type-generic return type for "
11107 "argument %u of %<__builtin_tgmath%>",
11109 expr.set_error ();
11110 goto out;
11112 if (!SCALAR_FLOAT_TYPE_P (ret)
11113 && !COMPLEX_FLOAT_TYPE_P (ret))
11115 error_at ((*cexpr_list)[j].get_location (),
11116 "invalid type-generic return type for "
11117 "argument %u of %<__builtin_tgmath%>",
11118 j + 1);
11119 expr.set_error ();
11120 goto out;
11123 if (TREE_CODE (ret) == COMPLEX_TYPE)
11124 parm_complex[0] = true;
11125 argpos = 1;
11126 FOREACH_FUNCTION_ARGS (type, t, iter)
11128 if (t == void_type_node)
11129 break;
11130 t = TYPE_MAIN_VARIANT (t);
11131 if (t != parm_first[argpos])
11133 parm_varies[argpos] = true;
11134 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
11135 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
11137 error_at ((*cexpr_list)[0].get_location (),
11138 "invalid type-generic type for "
11139 "argument %u of argument %u of "
11140 "%<__builtin_tgmath%>", argpos, 1);
11141 expr.set_error ();
11142 goto out;
11144 if (!SCALAR_FLOAT_TYPE_P (t)
11145 && !COMPLEX_FLOAT_TYPE_P (t))
11147 error_at ((*cexpr_list)[j].get_location (),
11148 "invalid type-generic type for "
11149 "argument %u of argument %u of "
11150 "%<__builtin_tgmath%>", argpos, j + 1);
11151 expr.set_error ();
11152 goto out;
11155 if (TREE_CODE (t) == COMPLEX_TYPE)
11156 parm_complex[argpos] = true;
11157 argpos++;
11160 enum tgmath_parm_kind max_variation = tgmath_fixed;
11161 for (unsigned int j = 0; j <= nargs; j++)
11163 enum tgmath_parm_kind this_kind;
11164 if (parm_varies[j])
11166 if (parm_complex[j])
11167 max_variation = this_kind = tgmath_complex;
11168 else
11170 this_kind = tgmath_real;
11171 if (max_variation != tgmath_complex)
11172 max_variation = tgmath_real;
11175 else
11176 this_kind = tgmath_fixed;
11177 parm_kind.quick_push (this_kind);
11179 if (max_variation == tgmath_fixed)
11181 error_at (loc, "function arguments of %<__builtin_tgmath%> "
11182 "all have the same type");
11183 expr.set_error ();
11184 break;
11187 /* Identify a parameter (not the return type) that varies,
11188 including with complex types if any variation includes
11189 complex types; there must be at least one such
11190 parameter. */
11191 unsigned int tgarg = 0;
11192 for (unsigned int j = 1; j <= nargs; j++)
11193 if (parm_kind[j] == max_variation)
11195 tgarg = j;
11196 break;
11198 if (tgarg == 0)
11200 error_at (loc, "function arguments of %<__builtin_tgmath%> "
11201 "lack type-generic parameter");
11202 expr.set_error ();
11203 break;
11206 /* Determine the type of the relevant parameter for each
11207 function. */
11208 auto_vec<tree> tg_type (num_functions);
11209 for (unsigned int j = 0; j < num_functions; j++)
11211 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11212 argpos = 1;
11213 FOREACH_FUNCTION_ARGS (type, t, iter)
11215 if (argpos == tgarg)
11217 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
11218 break;
11220 argpos++;
11224 /* Verify that the corresponding types are different for
11225 all the listed functions. Also determine whether all
11226 the types are complex, whether all the types are
11227 standard or binary, and whether all the types are
11228 decimal. */
11229 bool all_complex = true;
11230 bool all_binary = true;
11231 bool all_decimal = true;
11232 hash_set<tree> tg_types;
11233 FOR_EACH_VEC_ELT (tg_type, i, t)
11235 if (TREE_CODE (t) == COMPLEX_TYPE)
11236 all_decimal = false;
11237 else
11239 all_complex = false;
11240 if (DECIMAL_FLOAT_TYPE_P (t))
11241 all_binary = false;
11242 else
11243 all_decimal = false;
11245 if (tg_types.add (t))
11247 error_at ((*cexpr_list)[i].get_location (),
11248 "duplicate type-generic parameter type for "
11249 "function argument %u of %<__builtin_tgmath%>",
11250 i + 1);
11251 expr.set_error ();
11252 goto out;
11256 /* Verify that other parameters and the return type whose
11257 types vary have their types varying in the correct
11258 way. */
11259 for (unsigned int j = 0; j < num_functions; j++)
11261 tree exp_type = tg_type[j];
11262 tree exp_real_type = exp_type;
11263 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
11264 exp_real_type = TREE_TYPE (exp_type);
11265 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11266 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
11267 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
11268 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
11270 error_at ((*cexpr_list)[j].get_location (),
11271 "bad return type for function argument %u "
11272 "of %<__builtin_tgmath%>", j + 1);
11273 expr.set_error ();
11274 goto out;
11276 argpos = 1;
11277 FOREACH_FUNCTION_ARGS (type, t, iter)
11279 if (t == void_type_node)
11280 break;
11281 t = TYPE_MAIN_VARIANT (t);
11282 if ((parm_kind[argpos] == tgmath_complex
11283 && t != exp_type)
11284 || (parm_kind[argpos] == tgmath_real
11285 && t != exp_real_type))
11287 error_at ((*cexpr_list)[j].get_location (),
11288 "bad type for argument %u of "
11289 "function argument %u of "
11290 "%<__builtin_tgmath%>", argpos, j + 1);
11291 expr.set_error ();
11292 goto out;
11294 argpos++;
11298 /* The functions listed are a valid set of functions for a
11299 <tgmath.h> macro to select between. Identify the
11300 matching function, if any. First, the argument types
11301 must be combined following <tgmath.h> rules. Integer
11302 types are treated as _Decimal64 if any type-generic
11303 argument is decimal, or if the only alternatives for
11304 type-generic arguments are of decimal types, and are
11305 otherwise treated as _Float32x (or _Complex _Float32x
11306 for complex integer types) if any type-generic argument
11307 has _FloatNx type, otherwise as double (or _Complex
11308 double for complex integer types). After that
11309 adjustment, types are combined following the usual
11310 arithmetic conversions. If the function only accepts
11311 complex arguments, a complex type is produced. */
11312 bool arg_complex = all_complex;
11313 bool arg_binary = all_binary;
11314 bool arg_int_decimal = all_decimal;
11315 bool arg_int_floatnx = false;
11316 for (unsigned int j = 1; j <= nargs; j++)
11318 if (parm_kind[j] == tgmath_fixed)
11319 continue;
11320 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
11321 tree type = TREE_TYPE (ce->value);
11322 if (!INTEGRAL_TYPE_P (type)
11323 && !SCALAR_FLOAT_TYPE_P (type)
11324 && TREE_CODE (type) != COMPLEX_TYPE)
11326 error_at (ce->get_location (),
11327 "invalid type of argument %u of type-generic "
11328 "function", j);
11329 expr.set_error ();
11330 goto out;
11332 if (DECIMAL_FLOAT_TYPE_P (type))
11334 arg_int_decimal = true;
11335 if (all_complex)
11337 error_at (ce->get_location (),
11338 "decimal floating-point argument %u to "
11339 "complex-only type-generic function", j);
11340 expr.set_error ();
11341 goto out;
11343 else if (all_binary)
11345 error_at (ce->get_location (),
11346 "decimal floating-point argument %u to "
11347 "binary-only type-generic function", j);
11348 expr.set_error ();
11349 goto out;
11351 else if (arg_complex)
11353 error_at (ce->get_location (),
11354 "both complex and decimal floating-point "
11355 "arguments to type-generic function");
11356 expr.set_error ();
11357 goto out;
11359 else if (arg_binary)
11361 error_at (ce->get_location (),
11362 "both binary and decimal floating-point "
11363 "arguments to type-generic function");
11364 expr.set_error ();
11365 goto out;
11368 else if (TREE_CODE (type) == COMPLEX_TYPE)
11370 arg_complex = true;
11371 if (COMPLEX_FLOAT_TYPE_P (type))
11372 arg_binary = true;
11373 if (all_decimal)
11375 error_at (ce->get_location (),
11376 "complex argument %u to "
11377 "decimal-only type-generic function", j);
11378 expr.set_error ();
11379 goto out;
11381 else if (arg_int_decimal)
11383 error_at (ce->get_location (),
11384 "both complex and decimal floating-point "
11385 "arguments to type-generic function");
11386 expr.set_error ();
11387 goto out;
11390 else if (SCALAR_FLOAT_TYPE_P (type))
11392 arg_binary = true;
11393 if (all_decimal)
11395 error_at (ce->get_location (),
11396 "binary argument %u to "
11397 "decimal-only type-generic function", j);
11398 expr.set_error ();
11399 goto out;
11401 else if (arg_int_decimal)
11403 error_at (ce->get_location (),
11404 "both binary and decimal floating-point "
11405 "arguments to type-generic function");
11406 expr.set_error ();
11407 goto out;
11410 tree rtype = TYPE_MAIN_VARIANT (type);
11411 if (TREE_CODE (rtype) == COMPLEX_TYPE)
11412 rtype = TREE_TYPE (rtype);
11413 if (SCALAR_FLOAT_TYPE_P (rtype))
11414 for (unsigned int j = 0; j < NUM_FLOATNX_TYPES; j++)
11415 if (rtype == FLOATNX_TYPE_NODE (j))
11417 arg_int_floatnx = true;
11418 break;
11421 tree arg_real = NULL_TREE;
11422 for (unsigned int j = 1; j <= nargs; j++)
11424 if (parm_kind[j] == tgmath_fixed)
11425 continue;
11426 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
11427 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
11428 if (TREE_CODE (type) == COMPLEX_TYPE)
11429 type = TREE_TYPE (type);
11430 if (INTEGRAL_TYPE_P (type))
11431 type = (arg_int_decimal
11432 ? dfloat64_type_node
11433 : arg_int_floatnx
11434 ? float32x_type_node
11435 : double_type_node);
11436 if (arg_real == NULL_TREE)
11437 arg_real = type;
11438 else
11439 arg_real = common_type (arg_real, type);
11440 if (arg_real == error_mark_node)
11442 expr.set_error ();
11443 goto out;
11446 tree arg_type = (arg_complex
11447 ? build_complex_type (arg_real)
11448 : arg_real);
11450 /* Look for a function to call with type-generic parameter
11451 type ARG_TYPE. */
11452 c_expr_t *fn = NULL;
11453 for (unsigned int j = 0; j < num_functions; j++)
11455 if (tg_type[j] == arg_type)
11457 fn = &(*cexpr_list)[j];
11458 break;
11461 if (fn == NULL
11462 && parm_kind[0] == tgmath_fixed
11463 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
11465 /* Presume this is a macro that rounds its result to a
11466 narrower type, and look for the first function with
11467 at least the range and precision of the argument
11468 type. */
11469 for (unsigned int j = 0; j < num_functions; j++)
11471 if (arg_complex
11472 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
11473 continue;
11474 tree real_tg_type = (arg_complex
11475 ? TREE_TYPE (tg_type[j])
11476 : tg_type[j]);
11477 if (DECIMAL_FLOAT_TYPE_P (arg_real)
11478 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
11479 continue;
11480 scalar_float_mode arg_mode
11481 = SCALAR_FLOAT_TYPE_MODE (arg_real);
11482 scalar_float_mode tg_mode
11483 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
11484 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
11485 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
11486 if (arg_fmt->b == tg_fmt->b
11487 && arg_fmt->p <= tg_fmt->p
11488 && arg_fmt->emax <= tg_fmt->emax
11489 && (arg_fmt->emin - arg_fmt->p
11490 >= tg_fmt->emin - tg_fmt->p))
11492 fn = &(*cexpr_list)[j];
11493 break;
11497 if (fn == NULL)
11499 error_at (loc, "no matching function for type-generic call");
11500 expr.set_error ();
11501 break;
11504 /* Construct a call to FN. */
11505 vec<tree, va_gc> *args;
11506 vec_alloc (args, nargs);
11507 vec<tree, va_gc> *origtypes;
11508 vec_alloc (origtypes, nargs);
11509 auto_vec<location_t> arg_loc (nargs);
11510 for (unsigned int j = 0; j < nargs; j++)
11512 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
11513 args->quick_push (ce->value);
11514 arg_loc.quick_push (ce->get_location ());
11515 origtypes->quick_push (ce->original_type);
11517 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
11518 args, origtypes);
11519 set_c_expr_source_range (&expr, loc, close_paren_loc);
11520 break;
11522 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
11524 vec<c_expr_t, va_gc> *cexpr_list;
11525 c_expr_t *e2_p;
11526 tree chain_value;
11527 location_t close_paren_loc;
11529 c_parser_consume_token (parser);
11530 if (!c_parser_get_builtin_args (parser,
11531 "__builtin_call_with_static_chain",
11532 &cexpr_list, false,
11533 &close_paren_loc))
11535 expr.set_error ();
11536 break;
11538 if (vec_safe_length (cexpr_list) != 2)
11540 error_at (loc, "wrong number of arguments to "
11541 "%<__builtin_call_with_static_chain%>");
11542 expr.set_error ();
11543 break;
11546 expr = (*cexpr_list)[0];
11547 e2_p = &(*cexpr_list)[1];
11548 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
11549 chain_value = e2_p->value;
11550 mark_exp_read (chain_value);
11552 if (TREE_CODE (expr.value) != CALL_EXPR)
11553 error_at (loc, "first argument to "
11554 "%<__builtin_call_with_static_chain%> "
11555 "must be a call expression");
11556 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
11557 error_at (loc, "second argument to "
11558 "%<__builtin_call_with_static_chain%> "
11559 "must be a pointer type");
11560 else
11561 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
11562 set_c_expr_source_range (&expr, loc, close_paren_loc);
11563 break;
11565 case RID_BUILTIN_COMPLEX:
11567 vec<c_expr_t, va_gc> *cexpr_list;
11568 c_expr_t *e1_p, *e2_p;
11569 location_t close_paren_loc;
11571 c_parser_consume_token (parser);
11572 if (!c_parser_get_builtin_args (parser,
11573 "__builtin_complex",
11574 &cexpr_list, false,
11575 &close_paren_loc))
11577 expr.set_error ();
11578 break;
11581 if (vec_safe_length (cexpr_list) != 2)
11583 error_at (loc, "wrong number of arguments to "
11584 "%<__builtin_complex%>");
11585 expr.set_error ();
11586 break;
11589 e1_p = &(*cexpr_list)[0];
11590 e2_p = &(*cexpr_list)[1];
11592 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
11593 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
11594 e1_p->value = convert (TREE_TYPE (e1_p->value),
11595 TREE_OPERAND (e1_p->value, 0));
11596 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
11597 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
11598 e2_p->value = convert (TREE_TYPE (e2_p->value),
11599 TREE_OPERAND (e2_p->value, 0));
11600 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
11601 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
11602 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
11603 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
11605 error_at (loc, "%<__builtin_complex%> operand "
11606 "not of real binary floating-point type");
11607 expr.set_error ();
11608 break;
11610 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
11611 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
11613 error_at (loc,
11614 "%<__builtin_complex%> operands of different types");
11615 expr.set_error ();
11616 break;
11618 pedwarn_c90 (loc, OPT_Wpedantic,
11619 "ISO C90 does not support complex types");
11620 expr.value = build2_loc (loc, COMPLEX_EXPR,
11621 build_complex_type
11622 (TYPE_MAIN_VARIANT
11623 (TREE_TYPE (e1_p->value))),
11624 e1_p->value, e2_p->value);
11625 set_c_expr_source_range (&expr, loc, close_paren_loc);
11626 break;
11628 case RID_BUILTIN_SHUFFLE:
11630 vec<c_expr_t, va_gc> *cexpr_list;
11631 unsigned int i;
11632 c_expr_t *p;
11633 location_t close_paren_loc;
11635 c_parser_consume_token (parser);
11636 if (!c_parser_get_builtin_args (parser,
11637 "__builtin_shuffle",
11638 &cexpr_list, false,
11639 &close_paren_loc))
11641 expr.set_error ();
11642 break;
11645 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
11646 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11648 if (vec_safe_length (cexpr_list) == 2)
11649 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
11650 NULL_TREE,
11651 (*cexpr_list)[1].value);
11653 else if (vec_safe_length (cexpr_list) == 3)
11654 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
11655 (*cexpr_list)[1].value,
11656 (*cexpr_list)[2].value);
11657 else
11659 error_at (loc, "wrong number of arguments to "
11660 "%<__builtin_shuffle%>");
11661 expr.set_error ();
11663 set_c_expr_source_range (&expr, loc, close_paren_loc);
11664 break;
11666 case RID_BUILTIN_SHUFFLEVECTOR:
11668 vec<c_expr_t, va_gc> *cexpr_list;
11669 unsigned int i;
11670 c_expr_t *p;
11671 location_t close_paren_loc;
11673 c_parser_consume_token (parser);
11674 if (!c_parser_get_builtin_args (parser,
11675 "__builtin_shufflevector",
11676 &cexpr_list, false,
11677 &close_paren_loc))
11679 expr.set_error ();
11680 break;
11683 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
11684 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11686 if (vec_safe_length (cexpr_list) < 3)
11688 error_at (loc, "wrong number of arguments to "
11689 "%<__builtin_shuffle%>");
11690 expr.set_error ();
11692 else
11694 auto_vec<tree, 16> mask;
11695 for (i = 2; i < cexpr_list->length (); ++i)
11696 mask.safe_push ((*cexpr_list)[i].value);
11697 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
11698 (*cexpr_list)[1].value,
11699 mask);
11701 set_c_expr_source_range (&expr, loc, close_paren_loc);
11702 break;
11704 case RID_BUILTIN_CONVERTVECTOR:
11706 location_t start_loc = loc;
11707 c_parser_consume_token (parser);
11708 matching_parens parens;
11709 if (!parens.require_open (parser))
11711 expr.set_error ();
11712 break;
11714 e1 = c_parser_expr_no_commas (parser, NULL);
11715 mark_exp_read (e1.value);
11716 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
11718 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
11719 expr.set_error ();
11720 break;
11722 loc = c_parser_peek_token (parser)->location;
11723 t1 = c_parser_type_name (parser);
11724 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
11725 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11726 "expected %<)%>");
11727 if (t1 == NULL)
11728 expr.set_error ();
11729 else
11731 tree type_expr = NULL_TREE;
11732 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
11733 groktypename (t1, &type_expr,
11734 NULL));
11735 set_c_expr_source_range (&expr, start_loc, end_loc);
11738 break;
11739 case RID_BUILTIN_ASSOC_BARRIER:
11741 location_t start_loc = loc;
11742 c_parser_consume_token (parser);
11743 matching_parens parens;
11744 if (!parens.require_open (parser))
11746 expr.set_error ();
11747 break;
11749 e1 = c_parser_expr_no_commas (parser, NULL);
11750 mark_exp_read (e1.value);
11751 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
11752 parens.skip_until_found_close (parser);
11753 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
11754 set_c_expr_source_range (&expr, start_loc, end_loc);
11756 break;
11757 case RID_BUILTIN_STDC:
11759 vec<c_expr_t, va_gc> *cexpr_list;
11760 c_expr_t *arg_p;
11761 location_t close_paren_loc;
11762 enum c_builtin_stdc {
11763 C_BUILTIN_STDC_BIT_CEIL,
11764 C_BUILTIN_STDC_BIT_FLOOR,
11765 C_BUILTIN_STDC_BIT_WIDTH,
11766 C_BUILTIN_STDC_COUNT_ONES,
11767 C_BUILTIN_STDC_COUNT_ZEROS,
11768 C_BUILTIN_STDC_FIRST_LEADING_ONE,
11769 C_BUILTIN_STDC_FIRST_LEADING_ZERO,
11770 C_BUILTIN_STDC_FIRST_TRAILING_ONE,
11771 C_BUILTIN_STDC_FIRST_TRAILING_ZERO,
11772 C_BUILTIN_STDC_HAS_SINGLE_BIT,
11773 C_BUILTIN_STDC_LEADING_ONES,
11774 C_BUILTIN_STDC_LEADING_ZEROS,
11775 C_BUILTIN_STDC_TRAILING_ONES,
11776 C_BUILTIN_STDC_TRAILING_ZEROS,
11777 C_BUILTIN_STDC_MAX
11778 } stdc_rid = C_BUILTIN_STDC_MAX;
11779 const char *name
11780 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
11781 switch (name[sizeof ("__builtin_stdc_") - 1])
11783 case 'b':
11784 switch (name[sizeof ("__builtin_stdc_bit_") - 1])
11786 case 'c':
11787 stdc_rid = C_BUILTIN_STDC_BIT_CEIL;
11788 break;
11789 case 'f':
11790 stdc_rid = C_BUILTIN_STDC_BIT_FLOOR;
11791 break;
11792 default:
11793 stdc_rid = C_BUILTIN_STDC_BIT_WIDTH;
11794 break;
11796 break;
11797 case 'c':
11798 if (name[sizeof ("__builtin_stdc_count_") - 1] == 'o')
11799 stdc_rid = C_BUILTIN_STDC_COUNT_ONES;
11800 else
11801 stdc_rid = C_BUILTIN_STDC_COUNT_ZEROS;
11802 break;
11803 case 'f':
11804 switch (name[sizeof ("__builtin_stdc_first_trailing_") - 1])
11806 case 'n':
11807 stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ONE;
11808 break;
11809 case 'e':
11810 stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ZERO;
11811 break;
11812 case 'o':
11813 stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ONE;
11814 break;
11815 default:
11816 stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ZERO;
11817 break;
11819 break;
11820 case 'h':
11821 stdc_rid = C_BUILTIN_STDC_HAS_SINGLE_BIT;
11822 break;
11823 case 'l':
11824 if (name[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
11825 stdc_rid = C_BUILTIN_STDC_LEADING_ONES;
11826 else
11827 stdc_rid = C_BUILTIN_STDC_LEADING_ZEROS;
11828 break;
11829 case 't':
11830 if (name[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
11831 stdc_rid = C_BUILTIN_STDC_TRAILING_ONES;
11832 else
11833 stdc_rid = C_BUILTIN_STDC_TRAILING_ZEROS;
11834 break;
11836 gcc_checking_assert (stdc_rid != C_BUILTIN_STDC_MAX);
11838 c_parser_consume_token (parser);
11839 if (!c_parser_get_builtin_args (parser, name,
11840 &cexpr_list, false,
11841 &close_paren_loc))
11843 expr.set_error ();
11844 break;
11847 if (vec_safe_length (cexpr_list) != 1)
11849 error_at (loc, "wrong number of arguments to %qs", name);
11850 expr.set_error ();
11851 break;
11854 arg_p = &(*cexpr_list)[0];
11855 *arg_p = convert_lvalue_to_rvalue (loc, *arg_p, true, true);
11856 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p->value)))
11858 error_at (loc, "%qs operand not an integral type", name);
11859 expr.set_error ();
11860 break;
11862 if (TREE_CODE (TREE_TYPE (arg_p->value)) == ENUMERAL_TYPE)
11864 error_at (loc, "argument %u in call to function "
11865 "%qs has enumerated type", 1, name);
11866 expr.set_error ();
11867 break;
11869 if (TREE_CODE (TREE_TYPE (arg_p->value)) == BOOLEAN_TYPE)
11871 error_at (loc, "argument %u in call to function "
11872 "%qs has boolean type", 1, name);
11873 expr.set_error ();
11874 break;
11876 if (!TYPE_UNSIGNED (TREE_TYPE (arg_p->value)))
11878 error_at (loc, "argument 1 in call to function "
11879 "%qs has signed type", name);
11880 expr.set_error ();
11881 break;
11883 tree arg = arg_p->value;
11884 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
11885 /* Expand:
11886 __builtin_stdc_leading_zeros (arg) as
11887 (unsigned int) __builtin_clzg (arg, prec)
11888 __builtin_stdc_leading_ones (arg) as
11889 (unsigned int) __builtin_clzg ((type) ~arg, prec)
11890 __builtin_stdc_trailing_zeros (arg) as
11891 (unsigned int) __builtin_ctzg (arg, prec)
11892 __builtin_stdc_trailing_ones (arg) as
11893 (unsigned int) __builtin_ctzg ((type) ~arg, prec)
11894 __builtin_stdc_first_leading_zero (arg) as
11895 __builtin_clzg ((type) ~arg, -1) + 1U
11896 __builtin_stdc_first_leading_one (arg) as
11897 __builtin_clzg (arg, -1) + 1U
11898 __builtin_stdc_first_trailing_zero (arg) as
11899 __builtin_ctzg ((type) ~arg, -1) + 1U
11900 __builtin_stdc_first_trailing_one (arg) as
11901 __builtin_ctzg (arg, -1) + 1U
11902 __builtin_stdc_count_zeros (arg) as
11903 (unsigned int) __builtin_popcountg ((type) ~arg)
11904 __builtin_stdc_count_ones (arg) as
11905 (unsigned int) __builtin_popcountg (arg)
11906 __builtin_stdc_has_single_bit (arg) as
11907 (_Bool) (__builtin_popcountg (arg) == 1)
11908 __builtin_stdc_bit_width (arg) as
11909 (unsigned int) (prec - __builtin_clzg (arg, prec))
11910 __builtin_stdc_bit_floor (arg) as
11911 arg == 0 ? (type) 0
11912 : (type) 1 << (prec - 1 - __builtin_clzg (arg))
11913 __builtin_stdc_bit_ceil (arg) as
11914 arg <= 1 ? (type) 1
11915 : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
11916 without evaluating arg multiple times, type being
11917 __typeof (arg) and prec __builtin_popcountg ((type) ~0)). */
11918 int prec = TYPE_PRECISION (type);
11919 tree barg1 = arg;
11920 switch (stdc_rid)
11922 case C_BUILTIN_STDC_BIT_CEIL:
11923 arg = save_expr (arg);
11924 barg1 = build2_loc (loc, PLUS_EXPR, type, arg,
11925 build_int_cst (type, -1));
11926 break;
11927 case C_BUILTIN_STDC_BIT_FLOOR:
11928 barg1 = arg = save_expr (arg);
11929 break;
11930 case C_BUILTIN_STDC_COUNT_ZEROS:
11931 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
11932 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
11933 case C_BUILTIN_STDC_LEADING_ONES:
11934 case C_BUILTIN_STDC_TRAILING_ONES:
11935 barg1 = build1_loc (loc, BIT_NOT_EXPR, type, arg);
11936 break;
11937 default:
11938 break;
11940 tree barg2 = NULL_TREE;
11941 switch (stdc_rid)
11943 case C_BUILTIN_STDC_BIT_WIDTH:
11944 case C_BUILTIN_STDC_LEADING_ONES:
11945 case C_BUILTIN_STDC_LEADING_ZEROS:
11946 case C_BUILTIN_STDC_TRAILING_ONES:
11947 case C_BUILTIN_STDC_TRAILING_ZEROS:
11948 barg2 = build_int_cst (integer_type_node, prec);
11949 break;
11950 case C_BUILTIN_STDC_FIRST_LEADING_ONE:
11951 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
11952 case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
11953 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
11954 barg2 = integer_minus_one_node;
11955 break;
11956 default:
11957 break;
11959 tree fndecl = NULL_TREE;
11960 switch (stdc_rid)
11962 case C_BUILTIN_STDC_BIT_CEIL:
11963 case C_BUILTIN_STDC_BIT_FLOOR:
11964 case C_BUILTIN_STDC_BIT_WIDTH:
11965 case C_BUILTIN_STDC_FIRST_LEADING_ONE:
11966 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
11967 case C_BUILTIN_STDC_LEADING_ONES:
11968 case C_BUILTIN_STDC_LEADING_ZEROS:
11969 fndecl = builtin_decl_explicit (BUILT_IN_CLZG);
11970 break;
11971 case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
11972 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
11973 case C_BUILTIN_STDC_TRAILING_ONES:
11974 case C_BUILTIN_STDC_TRAILING_ZEROS:
11975 fndecl = builtin_decl_explicit (BUILT_IN_CTZG);
11976 break;
11977 case C_BUILTIN_STDC_COUNT_ONES:
11978 case C_BUILTIN_STDC_COUNT_ZEROS:
11979 case C_BUILTIN_STDC_HAS_SINGLE_BIT:
11980 fndecl = builtin_decl_explicit (BUILT_IN_POPCOUNTG);
11981 break;
11982 default:
11983 gcc_unreachable ();
11985 /* Construct a call to __builtin_{clz,ctz,popcount}g. */
11986 int nargs = barg2 != NULL_TREE ? 2 : 1;
11987 vec<tree, va_gc> *args;
11988 vec_alloc (args, nargs);
11989 vec<tree, va_gc> *origtypes;
11990 vec_alloc (origtypes, nargs);
11991 auto_vec<location_t> arg_loc (nargs);
11992 args->quick_push (barg1);
11993 arg_loc.quick_push (arg_p->get_location ());
11994 origtypes->quick_push (arg_p->original_type);
11995 if (nargs == 2)
11997 args->quick_push (barg2);
11998 arg_loc.quick_push (loc);
11999 origtypes->quick_push (integer_type_node);
12001 expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
12002 args, origtypes);
12003 set_c_expr_source_range (&expr, loc, close_paren_loc);
12004 if (expr.value == error_mark_node)
12005 break;
12006 switch (stdc_rid)
12008 case C_BUILTIN_STDC_BIT_CEIL:
12009 case C_BUILTIN_STDC_BIT_FLOOR:
12010 --prec;
12011 /* FALLTHRU */
12012 case C_BUILTIN_STDC_BIT_WIDTH:
12013 expr.value = build2_loc (loc, MINUS_EXPR, integer_type_node,
12014 build_int_cst (integer_type_node,
12015 prec), expr.value);
12016 break;
12017 case C_BUILTIN_STDC_FIRST_LEADING_ONE:
12018 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
12019 case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
12020 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
12021 expr.value = build2_loc (loc, PLUS_EXPR, integer_type_node,
12022 expr.value, integer_one_node);
12023 break;
12024 case C_BUILTIN_STDC_HAS_SINGLE_BIT:
12025 expr.value = build2_loc (loc, EQ_EXPR, boolean_type_node,
12026 expr.value, integer_one_node);
12027 break;
12028 default:
12029 break;
12032 if (stdc_rid != C_BUILTIN_STDC_BIT_CEIL
12033 && stdc_rid != C_BUILTIN_STDC_BIT_FLOOR)
12035 if (stdc_rid != C_BUILTIN_STDC_HAS_SINGLE_BIT)
12036 expr.value = fold_convert_loc (loc, unsigned_type_node,
12037 expr.value);
12038 break;
12040 /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
12041 or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
12042 warnings. The LSHIFT_EXPR is in dead code in that case. */
12043 if (integer_zerop (arg)
12044 || (stdc_rid == C_BUILTIN_STDC_BIT_CEIL && integer_onep (arg)))
12045 expr.value = build_int_cst (type, 0);
12046 else
12047 expr.value
12048 = build2_loc (loc, LSHIFT_EXPR, type,
12049 build_int_cst (type,
12050 (stdc_rid
12051 == C_BUILTIN_STDC_BIT_CEIL
12052 ? 2 : 1)), expr.value);
12053 if (stdc_rid == C_BUILTIN_STDC_BIT_CEIL)
12054 expr.value = build3_loc (loc, COND_EXPR, type,
12055 build2_loc (loc, LE_EXPR,
12056 boolean_type_node, arg,
12057 build_int_cst (type, 1)),
12058 build_int_cst (type, 1),
12059 expr.value);
12060 else
12061 expr.value = build3_loc (loc, COND_EXPR, type,
12062 build2_loc (loc, EQ_EXPR,
12063 boolean_type_node, arg,
12064 build_int_cst (type, 0)),
12065 build_int_cst (type, 0),
12066 expr.value);
12067 break;
12069 case RID_AT_SELECTOR:
12071 gcc_assert (c_dialect_objc ());
12072 c_parser_consume_token (parser);
12073 matching_parens parens;
12074 if (!parens.require_open (parser))
12076 expr.set_error ();
12077 break;
12079 tree sel = c_parser_objc_selector_arg (parser);
12080 location_t close_loc = c_parser_peek_token (parser)->location;
12081 parens.skip_until_found_close (parser);
12082 expr.value = objc_build_selector_expr (loc, sel);
12083 set_c_expr_source_range (&expr, loc, close_loc);
12085 break;
12086 case RID_AT_PROTOCOL:
12088 gcc_assert (c_dialect_objc ());
12089 c_parser_consume_token (parser);
12090 matching_parens parens;
12091 if (!parens.require_open (parser))
12093 expr.set_error ();
12094 break;
12096 if (c_parser_next_token_is_not (parser, CPP_NAME))
12098 c_parser_error (parser, "expected identifier");
12099 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
12100 expr.set_error ();
12101 break;
12103 tree id = c_parser_peek_token (parser)->value;
12104 c_parser_consume_token (parser);
12105 location_t close_loc = c_parser_peek_token (parser)->location;
12106 parens.skip_until_found_close (parser);
12107 expr.value = objc_build_protocol_expr (id);
12108 set_c_expr_source_range (&expr, loc, close_loc);
12110 break;
12111 case RID_AT_ENCODE:
12113 /* Extension to support C-structures in the archiver. */
12114 gcc_assert (c_dialect_objc ());
12115 c_parser_consume_token (parser);
12116 matching_parens parens;
12117 if (!parens.require_open (parser))
12119 expr.set_error ();
12120 break;
12122 t1 = c_parser_type_name (parser);
12123 if (t1 == NULL)
12125 expr.set_error ();
12126 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
12127 break;
12129 location_t close_loc = c_parser_peek_token (parser)->location;
12130 parens.skip_until_found_close (parser);
12131 tree type = groktypename (t1, NULL, NULL);
12132 expr.value = objc_build_encode_expr (type);
12133 set_c_expr_source_range (&expr, loc, close_loc);
12135 break;
12136 case RID_GENERIC:
12137 expr = c_parser_generic_selection (parser);
12138 break;
12139 case RID_OMP_ALL_MEMORY:
12140 gcc_assert (flag_openmp);
12141 c_parser_consume_token (parser);
12142 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
12143 "%<depend%> clause");
12144 expr.set_error ();
12145 break;
12146 /* C23 'nullptr' literal. */
12147 case RID_NULLPTR:
12148 c_parser_consume_token (parser);
12149 expr.value = nullptr_node;
12150 set_c_expr_source_range (&expr, tok_range);
12151 pedwarn_c11 (loc, OPT_Wpedantic,
12152 "ISO C does not support %qs before C23", "nullptr");
12153 break;
12154 case RID_TRUE:
12155 c_parser_consume_token (parser);
12156 expr.value = boolean_true_node;
12157 set_c_expr_source_range (&expr, tok_range);
12158 break;
12159 case RID_FALSE:
12160 c_parser_consume_token (parser);
12161 expr.value = boolean_false_node;
12162 set_c_expr_source_range (&expr, tok_range);
12163 break;
12164 default:
12165 c_parser_error (parser, "expected expression");
12166 expr.set_error ();
12167 break;
12169 break;
12170 case CPP_OPEN_SQUARE:
12171 if (c_dialect_objc ())
12173 tree receiver, args;
12174 c_parser_consume_token (parser);
12175 receiver = c_parser_objc_receiver (parser);
12176 args = c_parser_objc_message_args (parser);
12177 location_t close_loc = c_parser_peek_token (parser)->location;
12178 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
12179 "expected %<]%>");
12180 expr.value = objc_build_message_expr (receiver, args);
12181 set_c_expr_source_range (&expr, loc, close_loc);
12182 break;
12184 /* Else fall through to report error. */
12185 /* FALLTHRU */
12186 default:
12187 c_parser_error (parser, "expected expression");
12188 expr.set_error ();
12189 break;
12191 out:
12192 return c_parser_postfix_expression_after_primary
12193 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
12196 /* Parse a postfix expression after a parenthesized type name: the
12197 brace-enclosed initializer of a compound literal, possibly followed
12198 by some postfix operators. This is separate because it is not
12199 possible to tell until after the type name whether a cast
12200 expression has a cast or a compound literal, or whether the operand
12201 of sizeof is a parenthesized type name or starts with a compound
12202 literal. TYPE_LOC is the location where TYPE_NAME starts--the
12203 location of the first token after the parentheses around the type
12204 name. */
12206 static struct c_expr
12207 c_parser_postfix_expression_after_paren_type (c_parser *parser,
12208 struct c_declspecs *scspecs,
12209 struct c_type_name *type_name,
12210 location_t type_loc)
12212 tree type;
12213 struct c_expr init;
12214 bool non_const;
12215 struct c_expr expr;
12216 location_t start_loc;
12217 tree type_expr = NULL_TREE;
12218 bool type_expr_const = true;
12219 bool constexpr_p = scspecs ? scspecs->constexpr_p : false;
12220 unsigned int underspec_state = 0;
12221 check_compound_literal_type (type_loc, type_name);
12222 rich_location richloc (line_table, type_loc);
12223 start_loc = c_parser_peek_token (parser)->location;
12224 if (constexpr_p)
12226 underspec_state = start_underspecified_init (start_loc, NULL_TREE);
12227 /* A constexpr compound literal is subject to the constraints on
12228 underspecified declarations, which may not declare tags or
12229 members or structures or unions; it is undefined behavior to
12230 declare the members of an enumeration. Where the structure,
12231 union or enumeration type is declared within the compound
12232 literal initializer, this is diagnosed elsewhere as a result
12233 of the above call to start_underspecified_init. Diagnose
12234 here the case of declaring such a type in the type specifiers
12235 of the compound literal. */
12236 switch (type_name->specs->typespec_kind)
12238 case ctsk_tagfirstref:
12239 case ctsk_tagfirstref_attrs:
12240 error_at (type_loc, "%qT declared in %<constexpr%> compound literal",
12241 type_name->specs->type);
12242 break;
12244 case ctsk_tagdef:
12245 error_at (type_loc, "%qT defined in %<constexpr%> compound literal",
12246 type_name->specs->type);
12247 break;
12249 default:
12250 break;
12253 start_init (NULL_TREE, NULL,
12254 (global_bindings_p ()
12255 || (scspecs && scspecs->storage_class == csc_static)
12256 || constexpr_p), constexpr_p, &richloc);
12257 type = groktypename (type_name, &type_expr, &type_expr_const);
12258 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
12260 error_at (type_loc, "compound literal has variable size");
12261 type = error_mark_node;
12263 else if (TREE_CODE (type) == FUNCTION_TYPE)
12265 error_at (type_loc, "compound literal has function type");
12266 type = error_mark_node;
12268 if (constexpr_p && type != error_mark_node)
12270 tree type_no_array = strip_array_types (type);
12271 /* The type of a constexpr object must not be variably modified
12272 (which applies to all compound literals), volatile, atomic or
12273 restrict qualified or have a member with such a qualifier.
12274 const qualification is implicitly added. */
12275 if (TYPE_QUALS (type_no_array)
12276 & (TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC))
12277 error_at (type_loc, "invalid qualifiers for %<constexpr%> object");
12278 else if (RECORD_OR_UNION_TYPE_P (type_no_array)
12279 && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array))
12280 error_at (type_loc, "invalid qualifiers for field of "
12281 "%<constexpr%> object");
12282 type = c_build_qualified_type (type,
12283 (TYPE_QUALS (type_no_array)
12284 | TYPE_QUAL_CONST));
12286 init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
12287 if (constexpr_p)
12288 finish_underspecified_init (NULL_TREE, underspec_state);
12289 finish_init ();
12290 maybe_warn_string_init (type_loc, type, init);
12292 if (type != error_mark_node
12293 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
12294 && current_function_decl)
12296 error ("compound literal qualified by address-space qualifier");
12297 type = error_mark_node;
12300 if (!pedwarn_c90 (start_loc, OPT_Wpedantic,
12301 "ISO C90 forbids compound literals") && scspecs)
12302 pedwarn_c11 (start_loc, OPT_Wpedantic,
12303 "ISO C forbids storage class specifiers in compound literals "
12304 "before C23");
12305 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
12306 ? CONSTRUCTOR_NON_CONST (init.value)
12307 : init.original_code == C_MAYBE_CONST_EXPR);
12308 non_const |= !type_expr_const;
12309 unsigned int alignas_align = 0;
12310 if (type != error_mark_node
12311 && type_name->specs->align_log != -1)
12313 alignas_align = 1U << type_name->specs->align_log;
12314 if (alignas_align < min_align_of_type (type))
12316 error_at (type_name->specs->locations[cdw_alignas],
12317 "%<_Alignas%> specifiers cannot reduce "
12318 "alignment of compound literal");
12319 alignas_align = 0;
12322 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
12323 alignas_align, scspecs);
12324 set_c_expr_source_range (&expr, init.src_range);
12325 expr.m_decimal = 0;
12326 expr.original_code = ERROR_MARK;
12327 expr.original_type = NULL;
12328 if (type != error_mark_node
12329 && expr.value != error_mark_node
12330 && type_expr)
12332 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
12334 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
12335 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
12337 else
12339 gcc_assert (!non_const);
12340 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
12341 type_expr, expr.value);
12344 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
12347 /* Callback function for sizeof_pointer_memaccess_warning to compare
12348 types. */
12350 static bool
12351 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
12353 return comptypes (type1, type2) == 1;
12356 /* Warn for patterns where abs-like function appears to be used incorrectly,
12357 gracefully ignore any non-abs-like function. The warning location should
12358 be LOC. FNDECL is the declaration of called function, it must be a
12359 BUILT_IN_NORMAL function. ARG is the first and only argument of the
12360 call. */
12362 static void
12363 warn_for_abs (location_t loc, tree fndecl, tree arg)
12365 /* Avoid warning in unreachable subexpressions. */
12366 if (c_inhibit_evaluation_warnings)
12367 return;
12369 tree atype = TREE_TYPE (arg);
12371 /* Casts from pointers (and thus arrays and fndecls) will generate
12372 -Wint-conversion warnings. Most other wrong types hopefully lead to type
12373 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
12374 types and possibly other exotic types. */
12375 if (!INTEGRAL_TYPE_P (atype)
12376 && !SCALAR_FLOAT_TYPE_P (atype)
12377 && TREE_CODE (atype) != COMPLEX_TYPE)
12378 return;
12380 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
12382 switch (fcode)
12384 case BUILT_IN_ABS:
12385 case BUILT_IN_LABS:
12386 case BUILT_IN_LLABS:
12387 case BUILT_IN_IMAXABS:
12388 if (!INTEGRAL_TYPE_P (atype))
12390 if (SCALAR_FLOAT_TYPE_P (atype))
12391 warning_at (loc, OPT_Wabsolute_value,
12392 "using integer absolute value function %qD when "
12393 "argument is of floating-point type %qT",
12394 fndecl, atype);
12395 else if (TREE_CODE (atype) == COMPLEX_TYPE)
12396 warning_at (loc, OPT_Wabsolute_value,
12397 "using integer absolute value function %qD when "
12398 "argument is of complex type %qT", fndecl, atype);
12399 else
12400 gcc_unreachable ();
12401 return;
12403 if (TYPE_UNSIGNED (atype))
12404 warning_at (loc, OPT_Wabsolute_value,
12405 "taking the absolute value of unsigned type %qT "
12406 "has no effect", atype);
12407 break;
12409 CASE_FLT_FN (BUILT_IN_FABS):
12410 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
12411 if (!SCALAR_FLOAT_TYPE_P (atype)
12412 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
12414 if (INTEGRAL_TYPE_P (atype))
12415 warning_at (loc, OPT_Wabsolute_value,
12416 "using floating-point absolute value function %qD "
12417 "when argument is of integer type %qT", fndecl, atype);
12418 else if (DECIMAL_FLOAT_TYPE_P (atype))
12419 warning_at (loc, OPT_Wabsolute_value,
12420 "using floating-point absolute value function %qD "
12421 "when argument is of decimal floating-point type %qT",
12422 fndecl, atype);
12423 else if (TREE_CODE (atype) == COMPLEX_TYPE)
12424 warning_at (loc, OPT_Wabsolute_value,
12425 "using floating-point absolute value function %qD when "
12426 "argument is of complex type %qT", fndecl, atype);
12427 else
12428 gcc_unreachable ();
12429 return;
12431 break;
12433 CASE_FLT_FN (BUILT_IN_CABS):
12434 if (TREE_CODE (atype) != COMPLEX_TYPE)
12436 if (INTEGRAL_TYPE_P (atype))
12437 warning_at (loc, OPT_Wabsolute_value,
12438 "using complex absolute value function %qD when "
12439 "argument is of integer type %qT", fndecl, atype);
12440 else if (SCALAR_FLOAT_TYPE_P (atype))
12441 warning_at (loc, OPT_Wabsolute_value,
12442 "using complex absolute value function %qD when "
12443 "argument is of floating-point type %qT",
12444 fndecl, atype);
12445 else
12446 gcc_unreachable ();
12448 return;
12450 break;
12452 case BUILT_IN_FABSD32:
12453 case BUILT_IN_FABSD64:
12454 case BUILT_IN_FABSD128:
12455 if (!DECIMAL_FLOAT_TYPE_P (atype))
12457 if (INTEGRAL_TYPE_P (atype))
12458 warning_at (loc, OPT_Wabsolute_value,
12459 "using decimal floating-point absolute value "
12460 "function %qD when argument is of integer type %qT",
12461 fndecl, atype);
12462 else if (SCALAR_FLOAT_TYPE_P (atype))
12463 warning_at (loc, OPT_Wabsolute_value,
12464 "using decimal floating-point absolute value "
12465 "function %qD when argument is of floating-point "
12466 "type %qT", fndecl, atype);
12467 else if (TREE_CODE (atype) == COMPLEX_TYPE)
12468 warning_at (loc, OPT_Wabsolute_value,
12469 "using decimal floating-point absolute value "
12470 "function %qD when argument is of complex type %qT",
12471 fndecl, atype);
12472 else
12473 gcc_unreachable ();
12474 return;
12476 break;
12478 default:
12479 return;
12482 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
12483 return;
12485 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
12486 if (TREE_CODE (atype) == COMPLEX_TYPE)
12488 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
12489 atype = TREE_TYPE (atype);
12490 ftype = TREE_TYPE (ftype);
12493 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
12494 warning_at (loc, OPT_Wabsolute_value,
12495 "absolute value function %qD given an argument of type %qT "
12496 "but has parameter of type %qT which may cause truncation "
12497 "of value", fndecl, atype, ftype);
12501 /* Parse a postfix expression after the initial primary or compound
12502 literal; that is, parse a series of postfix operators.
12504 EXPR_LOC is the location of the primary expression. */
12506 static struct c_expr
12507 c_parser_postfix_expression_after_primary (c_parser *parser,
12508 location_t expr_loc,
12509 struct c_expr expr)
12511 struct c_expr orig_expr;
12512 tree ident, idx, len;
12513 location_t sizeof_arg_loc[6], comp_loc;
12514 tree sizeof_arg[6];
12515 unsigned int literal_zero_mask;
12516 unsigned int i;
12517 vec<tree, va_gc> *exprlist;
12518 vec<tree, va_gc> *origtypes = NULL;
12519 vec<location_t> arg_loc = vNULL;
12520 location_t start;
12521 location_t finish;
12523 while (true)
12525 location_t op_loc = c_parser_peek_token (parser)->location;
12526 switch (c_parser_peek_token (parser)->type)
12528 case CPP_OPEN_SQUARE:
12529 /* Array reference. */
12530 c_parser_consume_token (parser);
12531 idx = len = NULL_TREE;
12532 if (!c_omp_array_section_p
12533 || c_parser_next_token_is_not (parser, CPP_COLON))
12534 idx = c_parser_expression (parser).value;
12536 if (c_omp_array_section_p
12537 && c_parser_next_token_is (parser, CPP_COLON))
12539 c_parser_consume_token (parser);
12540 if (c_parser_next_token_is_not (parser, CPP_CLOSE_SQUARE))
12541 len = c_parser_expression (parser).value;
12543 expr.value = build_omp_array_section (op_loc, expr.value, idx,
12544 len);
12546 else
12547 expr.value = build_array_ref (op_loc, expr.value, idx);
12549 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
12550 "expected %<]%>");
12552 start = expr.get_start ();
12553 finish = parser->tokens_buf[0].location;
12554 set_c_expr_source_range (&expr, start, finish);
12555 expr.original_code = ERROR_MARK;
12556 expr.original_type = NULL;
12557 expr.m_decimal = 0;
12558 break;
12559 case CPP_OPEN_PAREN:
12560 /* Function call. */
12562 matching_parens parens;
12563 parens.consume_open (parser);
12564 for (i = 0; i < 6; i++)
12566 sizeof_arg[i] = NULL_TREE;
12567 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
12569 literal_zero_mask = 0;
12570 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12571 exprlist = NULL;
12572 else if (TREE_CODE (expr.value) == FUNCTION_DECL
12573 && fndecl_built_in_p (expr.value, BUILT_IN_CLASSIFY_TYPE)
12574 && c_parser_next_tokens_start_typename (parser,
12575 cla_prefer_id))
12577 /* __builtin_classify_type (type) */
12578 c_inhibit_evaluation_warnings++;
12579 in_alignof++;
12580 struct c_type_name *type = c_parser_type_name (parser);
12581 c_inhibit_evaluation_warnings--;
12582 in_alignof--;
12583 struct c_typespec ret;
12584 ret.expr = NULL_TREE;
12585 ret.spec = error_mark_node;
12586 ret.expr_const_operands = false;
12587 if (type != NULL)
12588 ret.spec = groktypename (type, &ret.expr,
12589 &ret.expr_const_operands);
12590 parens.skip_until_found_close (parser);
12591 expr.value = build_int_cst (integer_type_node,
12592 type_to_class (ret.spec));
12593 break;
12595 else
12596 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
12597 sizeof_arg_loc, sizeof_arg,
12598 &arg_loc, &literal_zero_mask);
12599 parens.skip_until_found_close (parser);
12601 orig_expr = expr;
12602 mark_exp_read (expr.value);
12603 if (warn_sizeof_pointer_memaccess)
12604 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
12605 expr.value, exprlist,
12606 sizeof_arg,
12607 sizeof_ptr_memacc_comptypes);
12608 if (TREE_CODE (expr.value) == FUNCTION_DECL)
12610 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
12611 && vec_safe_length (exprlist) == 3)
12613 tree arg0 = (*exprlist)[0];
12614 tree arg2 = (*exprlist)[2];
12615 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
12617 if (warn_absolute_value
12618 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
12619 && vec_safe_length (exprlist) == 1)
12620 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
12621 if (parser->omp_for_parse_state
12622 && parser->omp_for_parse_state->in_intervening_code
12623 && omp_runtime_api_call (expr.value))
12625 error_at (expr_loc, "calls to the OpenMP runtime API are "
12626 "not permitted in intervening code");
12627 parser->omp_for_parse_state->fail = true;
12629 if (warn_calloc_transposed_args)
12630 if (tree attr = lookup_attribute ("alloc_size",
12631 TYPE_ATTRIBUTES
12632 (TREE_TYPE (expr.value))))
12633 if (TREE_VALUE (attr) && TREE_CHAIN (TREE_VALUE (attr)))
12634 warn_for_calloc (sizeof_arg_loc, expr.value, exprlist,
12635 sizeof_arg, attr);
12638 start = expr.get_start ();
12639 finish = parser->tokens_buf[0].get_finish ();
12640 expr.value
12641 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
12642 exprlist, origtypes);
12643 set_c_expr_source_range (&expr, start, finish);
12644 expr.m_decimal = 0;
12646 expr.original_code = ERROR_MARK;
12647 if (TREE_CODE (expr.value) == INTEGER_CST
12648 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
12649 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
12650 expr.original_code = C_MAYBE_CONST_EXPR;
12651 expr.original_type = NULL;
12652 if (exprlist)
12654 release_tree_vector (exprlist);
12655 release_tree_vector (origtypes);
12657 arg_loc.release ();
12658 break;
12659 case CPP_DOT:
12660 /* Structure element reference. */
12661 c_parser_consume_token (parser);
12662 expr = default_function_array_conversion (expr_loc, expr);
12663 if (c_parser_next_token_is (parser, CPP_NAME))
12665 c_token *comp_tok = c_parser_peek_token (parser);
12666 ident = comp_tok->value;
12667 comp_loc = comp_tok->location;
12669 else
12671 c_parser_error (parser, "expected identifier");
12672 expr.set_error ();
12673 expr.original_code = ERROR_MARK;
12674 expr.original_type = NULL;
12675 return expr;
12677 start = expr.get_start ();
12678 finish = c_parser_peek_token (parser)->get_finish ();
12679 c_parser_consume_token (parser);
12680 expr.value = build_component_ref (op_loc, expr.value, ident,
12681 comp_loc, UNKNOWN_LOCATION);
12682 set_c_expr_source_range (&expr, start, finish);
12683 expr.original_code = ERROR_MARK;
12684 if (TREE_CODE (expr.value) != COMPONENT_REF)
12685 expr.original_type = NULL;
12686 else
12688 /* Remember the original type of a bitfield. */
12689 tree field = TREE_OPERAND (expr.value, 1);
12690 if (TREE_CODE (field) != FIELD_DECL)
12691 expr.original_type = NULL;
12692 else
12693 expr.original_type = DECL_BIT_FIELD_TYPE (field);
12695 expr.m_decimal = 0;
12696 break;
12697 case CPP_DEREF:
12698 /* Structure element reference. */
12699 c_parser_consume_token (parser);
12700 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
12701 if (c_parser_next_token_is (parser, CPP_NAME))
12703 c_token *comp_tok = c_parser_peek_token (parser);
12704 ident = comp_tok->value;
12705 comp_loc = comp_tok->location;
12707 else
12709 c_parser_error (parser, "expected identifier");
12710 expr.set_error ();
12711 expr.original_code = ERROR_MARK;
12712 expr.original_type = NULL;
12713 return expr;
12715 start = expr.get_start ();
12716 finish = c_parser_peek_token (parser)->get_finish ();
12717 c_parser_consume_token (parser);
12718 expr.value = build_component_ref (op_loc,
12719 build_indirect_ref (op_loc,
12720 expr.value,
12721 RO_ARROW),
12722 ident, comp_loc,
12723 expr.get_location ());
12724 set_c_expr_source_range (&expr, start, finish);
12725 expr.original_code = ERROR_MARK;
12726 if (TREE_CODE (expr.value) != COMPONENT_REF)
12727 expr.original_type = NULL;
12728 else
12730 /* Remember the original type of a bitfield. */
12731 tree field = TREE_OPERAND (expr.value, 1);
12732 if (TREE_CODE (field) != FIELD_DECL)
12733 expr.original_type = NULL;
12734 else
12735 expr.original_type = DECL_BIT_FIELD_TYPE (field);
12737 expr.m_decimal = 0;
12738 break;
12739 case CPP_PLUS_PLUS:
12740 /* Postincrement. */
12741 start = expr.get_start ();
12742 finish = c_parser_peek_token (parser)->get_finish ();
12743 c_parser_consume_token (parser);
12744 expr = default_function_array_read_conversion (expr_loc, expr);
12745 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
12746 expr.value, false);
12747 set_c_expr_source_range (&expr, start, finish);
12748 expr.original_code = ERROR_MARK;
12749 expr.original_type = NULL;
12750 break;
12751 case CPP_MINUS_MINUS:
12752 /* Postdecrement. */
12753 start = expr.get_start ();
12754 finish = c_parser_peek_token (parser)->get_finish ();
12755 c_parser_consume_token (parser);
12756 expr = default_function_array_read_conversion (expr_loc, expr);
12757 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
12758 expr.value, false);
12759 set_c_expr_source_range (&expr, start, finish);
12760 expr.original_code = ERROR_MARK;
12761 expr.original_type = NULL;
12762 break;
12763 default:
12764 return expr;
12769 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
12771 expression:
12772 assignment-expression
12773 expression , assignment-expression
12776 static struct c_expr
12777 c_parser_expression (c_parser *parser)
12779 location_t tloc = c_parser_peek_token (parser)->location;
12780 struct c_expr expr;
12781 expr = c_parser_expr_no_commas (parser, NULL);
12782 if (c_parser_next_token_is (parser, CPP_COMMA))
12783 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
12784 while (c_parser_next_token_is (parser, CPP_COMMA))
12786 struct c_expr next;
12787 tree lhsval;
12788 location_t loc = c_parser_peek_token (parser)->location;
12789 location_t expr_loc;
12790 c_parser_consume_token (parser);
12791 expr_loc = c_parser_peek_token (parser)->location;
12792 lhsval = expr.value;
12793 while (TREE_CODE (lhsval) == COMPOUND_EXPR
12794 || TREE_CODE (lhsval) == NOP_EXPR)
12796 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
12797 lhsval = TREE_OPERAND (lhsval, 1);
12798 else
12799 lhsval = TREE_OPERAND (lhsval, 0);
12801 if (DECL_P (lhsval) || handled_component_p (lhsval))
12802 mark_exp_read (lhsval);
12803 next = c_parser_expr_no_commas (parser, NULL);
12804 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
12805 expr.value = build_compound_expr (loc, expr.value, next.value);
12806 expr.original_code = COMPOUND_EXPR;
12807 expr.original_type = next.original_type;
12808 expr.m_decimal = 0;
12810 return expr;
12813 /* Parse an expression and convert functions or arrays to pointers and
12814 lvalues to rvalues. */
12816 static struct c_expr
12817 c_parser_expression_conv (c_parser *parser)
12819 struct c_expr expr;
12820 location_t loc = c_parser_peek_token (parser)->location;
12821 expr = c_parser_expression (parser);
12822 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
12823 return expr;
12826 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
12827 argument is a literal zero alone and if so, set it in literal_zero_mask. */
12829 static inline void
12830 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
12831 unsigned int idx)
12833 if (idx >= HOST_BITS_PER_INT)
12834 return;
12836 c_token *tok = c_parser_peek_token (parser);
12837 switch (tok->type)
12839 case CPP_NUMBER:
12840 case CPP_CHAR:
12841 case CPP_WCHAR:
12842 case CPP_CHAR16:
12843 case CPP_CHAR32:
12844 case CPP_UTF8CHAR:
12845 /* If a parameter is literal zero alone, remember it
12846 for -Wmemset-transposed-args warning. */
12847 if (integer_zerop (tok->value)
12848 && !TREE_OVERFLOW (tok->value)
12849 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
12850 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
12851 *literal_zero_mask |= 1U << idx;
12852 default:
12853 break;
12857 /* Parse a non-empty list of expressions. If CONVERT_P, convert
12858 functions and arrays to pointers and lvalues to rvalues. If
12859 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
12860 locations of function arguments into this vector.
12862 nonempty-expr-list:
12863 assignment-expression
12864 nonempty-expr-list , assignment-expression
12867 static vec<tree, va_gc> *
12868 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
12869 vec<tree, va_gc> **p_orig_types,
12870 location_t *sizeof_arg_loc, tree *sizeof_arg,
12871 vec<location_t> *locations,
12872 unsigned int *literal_zero_mask)
12874 vec<tree, va_gc> *ret;
12875 vec<tree, va_gc> *orig_types;
12876 struct c_expr expr;
12877 unsigned int idx = 0;
12878 bool save_c_omp_array_section_p = c_omp_array_section_p;
12879 c_omp_array_section_p = false;
12881 ret = make_tree_vector ();
12882 if (p_orig_types == NULL)
12883 orig_types = NULL;
12884 else
12885 orig_types = make_tree_vector ();
12887 if (literal_zero_mask)
12888 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
12889 expr = c_parser_expr_no_commas (parser, NULL);
12890 if (convert_p)
12891 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
12892 if (fold_p)
12893 expr.value = c_fully_fold (expr.value, false, NULL);
12894 ret->quick_push (expr.value);
12895 if (orig_types)
12896 orig_types->quick_push (expr.original_type);
12897 if (locations)
12898 locations->safe_push (expr.get_location ());
12899 if (sizeof_arg != NULL
12900 && (expr.original_code == SIZEOF_EXPR
12901 || expr.original_code == PAREN_SIZEOF_EXPR))
12903 sizeof_arg[0] = c_last_sizeof_arg;
12904 sizeof_arg_loc[0] = c_last_sizeof_loc;
12906 while (c_parser_next_token_is (parser, CPP_COMMA))
12908 c_parser_consume_token (parser);
12909 if (literal_zero_mask)
12910 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
12911 expr = c_parser_expr_no_commas (parser, NULL);
12912 if (convert_p)
12913 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
12914 true);
12915 if (fold_p)
12916 expr.value = c_fully_fold (expr.value, false, NULL);
12917 vec_safe_push (ret, expr.value);
12918 if (orig_types)
12919 vec_safe_push (orig_types, expr.original_type);
12920 if (locations)
12921 locations->safe_push (expr.get_location ());
12922 if (++idx < 6
12923 && sizeof_arg != NULL
12924 && (expr.original_code == SIZEOF_EXPR
12925 || expr.original_code == PAREN_SIZEOF_EXPR))
12927 sizeof_arg[idx] = c_last_sizeof_arg;
12928 sizeof_arg_loc[idx] = c_last_sizeof_loc;
12931 if (orig_types)
12932 *p_orig_types = orig_types;
12933 c_omp_array_section_p = save_c_omp_array_section_p;
12934 return ret;
12937 /* Parse Objective-C-specific constructs. */
12939 /* Parse an objc-class-definition.
12941 objc-class-definition:
12942 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
12943 objc-class-instance-variables[opt] objc-methodprotolist @end
12944 @implementation identifier objc-superclass[opt]
12945 objc-class-instance-variables[opt]
12946 @interface identifier ( identifier ) objc-protocol-refs[opt]
12947 objc-methodprotolist @end
12948 @interface identifier ( ) objc-protocol-refs[opt]
12949 objc-methodprotolist @end
12950 @implementation identifier ( identifier )
12952 objc-superclass:
12953 : identifier
12955 "@interface identifier (" must start "@interface identifier (
12956 identifier ) ...": objc-methodprotolist in the first production may
12957 not start with a parenthesized identifier as a declarator of a data
12958 definition with no declaration specifiers if the objc-superclass,
12959 objc-protocol-refs and objc-class-instance-variables are omitted. */
12961 static void
12962 c_parser_objc_class_definition (c_parser *parser, tree attributes)
12964 bool iface_p;
12965 tree id1;
12966 tree superclass;
12967 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
12968 iface_p = true;
12969 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
12970 iface_p = false;
12971 else
12972 gcc_unreachable ();
12974 c_parser_consume_token (parser);
12975 if (c_parser_next_token_is_not (parser, CPP_NAME))
12977 c_parser_error (parser, "expected identifier");
12978 return;
12980 id1 = c_parser_peek_token (parser)->value;
12981 location_t loc1 = c_parser_peek_token (parser)->location;
12982 c_parser_consume_token (parser);
12983 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12985 /* We have a category or class extension. */
12986 tree id2;
12987 tree proto = NULL_TREE;
12988 matching_parens parens;
12989 parens.consume_open (parser);
12990 if (c_parser_next_token_is_not (parser, CPP_NAME))
12992 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12994 /* We have a class extension. */
12995 id2 = NULL_TREE;
12997 else
12999 c_parser_error (parser, "expected identifier or %<)%>");
13000 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
13001 return;
13004 else
13006 id2 = c_parser_peek_token (parser)->value;
13007 c_parser_consume_token (parser);
13009 parens.skip_until_found_close (parser);
13010 if (!iface_p)
13012 objc_start_category_implementation (id1, id2);
13013 return;
13015 if (c_parser_next_token_is (parser, CPP_LESS))
13016 proto = c_parser_objc_protocol_refs (parser);
13017 objc_start_category_interface (id1, id2, proto, attributes);
13018 c_parser_objc_methodprotolist (parser);
13019 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13020 objc_finish_interface ();
13021 return;
13023 if (c_parser_next_token_is (parser, CPP_COLON))
13025 c_parser_consume_token (parser);
13026 if (c_parser_next_token_is_not (parser, CPP_NAME))
13028 c_parser_error (parser, "expected identifier");
13029 return;
13031 superclass = c_parser_peek_token (parser)->value;
13032 c_parser_consume_token (parser);
13034 else
13035 superclass = NULL_TREE;
13036 if (iface_p)
13038 tree proto = NULL_TREE;
13039 if (c_parser_next_token_is (parser, CPP_LESS))
13040 proto = c_parser_objc_protocol_refs (parser);
13041 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
13043 else
13044 objc_start_class_implementation (id1, superclass);
13045 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13046 c_parser_objc_class_instance_variables (parser);
13047 if (iface_p)
13049 objc_continue_interface ();
13050 c_parser_objc_methodprotolist (parser);
13051 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13052 objc_finish_interface ();
13054 else
13056 objc_continue_implementation ();
13057 return;
13061 /* Parse objc-class-instance-variables.
13063 objc-class-instance-variables:
13064 { objc-instance-variable-decl-list[opt] }
13066 objc-instance-variable-decl-list:
13067 objc-visibility-spec
13068 objc-instance-variable-decl ;
13070 objc-instance-variable-decl-list objc-visibility-spec
13071 objc-instance-variable-decl-list objc-instance-variable-decl ;
13072 objc-instance-variable-decl-list ;
13074 objc-visibility-spec:
13075 @private
13076 @protected
13077 @public
13079 objc-instance-variable-decl:
13080 struct-declaration
13083 static void
13084 c_parser_objc_class_instance_variables (c_parser *parser)
13086 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
13087 c_parser_consume_token (parser);
13088 while (c_parser_next_token_is_not (parser, CPP_EOF))
13090 tree decls;
13091 /* Parse any stray semicolon. */
13092 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
13094 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13095 "extra semicolon");
13096 c_parser_consume_token (parser);
13097 continue;
13099 /* Stop if at the end of the instance variables. */
13100 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
13102 c_parser_consume_token (parser);
13103 break;
13105 /* Parse any objc-visibility-spec. */
13106 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
13108 c_parser_consume_token (parser);
13109 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
13110 continue;
13112 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
13114 c_parser_consume_token (parser);
13115 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
13116 continue;
13118 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
13120 c_parser_consume_token (parser);
13121 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
13122 continue;
13124 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
13126 c_parser_consume_token (parser);
13127 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
13128 continue;
13130 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
13132 c_parser_pragma (parser, pragma_external, NULL);
13133 continue;
13136 /* Parse some comma-separated declarations. */
13137 decls = c_parser_struct_declaration (parser, NULL);
13138 if (decls == NULL)
13140 /* There is a syntax error. We want to skip the offending
13141 tokens up to the next ';' (included) or '}'
13142 (excluded). */
13144 /* First, skip manually a ')' or ']'. This is because they
13145 reduce the nesting level, so c_parser_skip_until_found()
13146 wouldn't be able to skip past them. */
13147 c_token *token = c_parser_peek_token (parser);
13148 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
13149 c_parser_consume_token (parser);
13151 /* Then, do the standard skipping. */
13152 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13154 /* We hopefully recovered. Start normal parsing again. */
13155 parser->error = false;
13156 continue;
13158 else
13160 /* Comma-separated instance variables are chained together
13161 in reverse order; add them one by one. */
13162 tree ivar = nreverse (decls);
13163 for (; ivar; ivar = DECL_CHAIN (ivar))
13164 objc_add_instance_variable (copy_node (ivar));
13166 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13170 /* Parse an objc-class-declaration.
13172 objc-class-declaration:
13173 @class identifier-list ;
13176 static void
13177 c_parser_objc_class_declaration (c_parser *parser)
13179 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
13180 c_parser_consume_token (parser);
13181 /* Any identifiers, including those declared as type names, are OK
13182 here. */
13183 while (true)
13185 tree id;
13186 if (c_parser_next_token_is_not (parser, CPP_NAME))
13188 c_parser_error (parser, "expected identifier");
13189 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13190 parser->error = false;
13191 return;
13193 id = c_parser_peek_token (parser)->value;
13194 objc_declare_class (id);
13195 c_parser_consume_token (parser);
13196 if (c_parser_next_token_is (parser, CPP_COMMA))
13197 c_parser_consume_token (parser);
13198 else
13199 break;
13201 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13204 /* Parse an objc-alias-declaration.
13206 objc-alias-declaration:
13207 @compatibility_alias identifier identifier ;
13210 static void
13211 c_parser_objc_alias_declaration (c_parser *parser)
13213 tree id1, id2;
13214 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
13215 c_parser_consume_token (parser);
13216 if (c_parser_next_token_is_not (parser, CPP_NAME))
13218 c_parser_error (parser, "expected identifier");
13219 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13220 return;
13222 id1 = c_parser_peek_token (parser)->value;
13223 c_parser_consume_token (parser);
13224 if (c_parser_next_token_is_not (parser, CPP_NAME))
13226 c_parser_error (parser, "expected identifier");
13227 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13228 return;
13230 id2 = c_parser_peek_token (parser)->value;
13231 c_parser_consume_token (parser);
13232 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13233 objc_declare_alias (id1, id2);
13236 /* Parse an objc-protocol-definition.
13238 objc-protocol-definition:
13239 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
13240 @protocol identifier-list ;
13242 "@protocol identifier ;" should be resolved as "@protocol
13243 identifier-list ;": objc-methodprotolist may not start with a
13244 semicolon in the first alternative if objc-protocol-refs are
13245 omitted. */
13247 static void
13248 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
13250 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
13252 c_parser_consume_token (parser);
13253 if (c_parser_next_token_is_not (parser, CPP_NAME))
13255 c_parser_error (parser, "expected identifier");
13256 return;
13258 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13259 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
13261 /* Any identifiers, including those declared as type names, are
13262 OK here. */
13263 while (true)
13265 tree id;
13266 if (c_parser_next_token_is_not (parser, CPP_NAME))
13268 c_parser_error (parser, "expected identifier");
13269 break;
13271 id = c_parser_peek_token (parser)->value;
13272 objc_declare_protocol (id, attributes);
13273 c_parser_consume_token (parser);
13274 if (c_parser_next_token_is (parser, CPP_COMMA))
13275 c_parser_consume_token (parser);
13276 else
13277 break;
13279 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13281 else
13283 tree id = c_parser_peek_token (parser)->value;
13284 tree proto = NULL_TREE;
13285 c_parser_consume_token (parser);
13286 if (c_parser_next_token_is (parser, CPP_LESS))
13287 proto = c_parser_objc_protocol_refs (parser);
13288 parser->objc_pq_context = true;
13289 objc_start_protocol (id, proto, attributes);
13290 c_parser_objc_methodprotolist (parser);
13291 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13292 parser->objc_pq_context = false;
13293 objc_finish_interface ();
13297 /* Parse an objc-method-type.
13299 objc-method-type:
13303 Return true if it is a class method (+) and false if it is
13304 an instance method (-).
13306 static inline bool
13307 c_parser_objc_method_type (c_parser *parser)
13309 switch (c_parser_peek_token (parser)->type)
13311 case CPP_PLUS:
13312 c_parser_consume_token (parser);
13313 return true;
13314 case CPP_MINUS:
13315 c_parser_consume_token (parser);
13316 return false;
13317 default:
13318 gcc_unreachable ();
13322 /* Parse an objc-method-definition.
13324 objc-method-definition:
13325 objc-method-type objc-method-decl ;[opt] compound-statement
13328 static void
13329 c_parser_objc_method_definition (c_parser *parser)
13331 bool is_class_method = c_parser_objc_method_type (parser);
13332 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
13333 parser->objc_pq_context = true;
13334 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
13335 &expr);
13336 if (decl == error_mark_node)
13337 return; /* Bail here. */
13339 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
13341 c_parser_consume_token (parser);
13342 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13343 "extra semicolon in method definition specified");
13346 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13348 c_parser_error (parser, "expected %<{%>");
13349 return;
13352 parser->objc_pq_context = false;
13353 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
13355 add_stmt (c_parser_compound_statement (parser));
13356 objc_finish_method_definition (current_function_decl);
13358 else
13360 /* This code is executed when we find a method definition
13361 outside of an @implementation context (or invalid for other
13362 reasons). Parse the method (to keep going) but do not emit
13363 any code.
13365 c_parser_compound_statement (parser);
13369 /* Parse an objc-methodprotolist.
13371 objc-methodprotolist:
13372 empty
13373 objc-methodprotolist objc-methodproto
13374 objc-methodprotolist declaration
13375 objc-methodprotolist ;
13376 @optional
13377 @required
13379 The declaration is a data definition, which may be missing
13380 declaration specifiers under the same rules and diagnostics as
13381 other data definitions outside functions, and the stray semicolon
13382 is diagnosed the same way as a stray semicolon outside a
13383 function. */
13385 static void
13386 c_parser_objc_methodprotolist (c_parser *parser)
13388 while (true)
13390 /* The list is terminated by @end. */
13391 switch (c_parser_peek_token (parser)->type)
13393 case CPP_SEMICOLON:
13394 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13395 "ISO C does not allow extra %<;%> outside of a function");
13396 c_parser_consume_token (parser);
13397 break;
13398 case CPP_PLUS:
13399 case CPP_MINUS:
13400 c_parser_objc_methodproto (parser);
13401 break;
13402 case CPP_PRAGMA:
13403 c_parser_pragma (parser, pragma_external, NULL);
13404 break;
13405 case CPP_EOF:
13406 return;
13407 default:
13408 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
13409 return;
13410 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
13411 c_parser_objc_at_property_declaration (parser);
13412 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
13414 objc_set_method_opt (true);
13415 c_parser_consume_token (parser);
13417 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
13419 objc_set_method_opt (false);
13420 c_parser_consume_token (parser);
13422 else
13423 c_parser_declaration_or_fndef (parser, false, false, true,
13424 false, true);
13425 break;
13430 /* Parse an objc-methodproto.
13432 objc-methodproto:
13433 objc-method-type objc-method-decl ;
13436 static void
13437 c_parser_objc_methodproto (c_parser *parser)
13439 bool is_class_method = c_parser_objc_method_type (parser);
13440 tree decl, attributes = NULL_TREE;
13442 /* Remember protocol qualifiers in prototypes. */
13443 parser->objc_pq_context = true;
13444 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
13445 NULL);
13446 /* Forget protocol qualifiers now. */
13447 parser->objc_pq_context = false;
13449 /* Do not allow the presence of attributes to hide an erroneous
13450 method implementation in the interface section. */
13451 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
13453 c_parser_error (parser, "expected %<;%>");
13454 return;
13457 if (decl != error_mark_node)
13458 objc_add_method_declaration (is_class_method, decl, attributes);
13460 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13463 /* If we are at a position that method attributes may be present, check that
13464 there are not any parsed already (a syntax error) and then collect any
13465 specified at the current location. Finally, if new attributes were present,
13466 check that the next token is legal ( ';' for decls and '{' for defs). */
13468 static bool
13469 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
13471 bool bad = false;
13472 if (*attributes)
13474 c_parser_error (parser,
13475 "method attributes must be specified at the end only");
13476 *attributes = NULL_TREE;
13477 bad = true;
13480 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
13481 *attributes = c_parser_gnu_attributes (parser);
13483 /* If there were no attributes here, just report any earlier error. */
13484 if (*attributes == NULL_TREE || bad)
13485 return bad;
13487 /* If the attributes are followed by a ; or {, then just report any earlier
13488 error. */
13489 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
13490 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13491 return bad;
13493 /* We've got attributes, but not at the end. */
13494 c_parser_error (parser,
13495 "expected %<;%> or %<{%> after method attribute definition");
13496 return true;
13499 /* Parse an objc-method-decl.
13501 objc-method-decl:
13502 ( objc-type-name ) objc-selector
13503 objc-selector
13504 ( objc-type-name ) objc-keyword-selector objc-optparmlist
13505 objc-keyword-selector objc-optparmlist
13506 gnu-attributes
13508 objc-keyword-selector:
13509 objc-keyword-decl
13510 objc-keyword-selector objc-keyword-decl
13512 objc-keyword-decl:
13513 objc-selector : ( objc-type-name ) identifier
13514 objc-selector : identifier
13515 : ( objc-type-name ) identifier
13516 : identifier
13518 objc-optparmlist:
13519 objc-optparms objc-optellipsis
13521 objc-optparms:
13522 empty
13523 objc-opt-parms , parameter-declaration
13525 objc-optellipsis:
13526 empty
13527 , ...
13530 static tree
13531 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
13532 tree *attributes, tree *expr)
13534 tree type = NULL_TREE;
13535 tree sel;
13536 tree parms = NULL_TREE;
13537 bool ellipsis = false;
13538 bool attr_err = false;
13540 *attributes = NULL_TREE;
13541 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13543 matching_parens parens;
13544 parens.consume_open (parser);
13545 type = c_parser_objc_type_name (parser);
13546 parens.skip_until_found_close (parser);
13548 sel = c_parser_objc_selector (parser);
13549 /* If there is no selector, or a colon follows, we have an
13550 objc-keyword-selector. If there is a selector, and a colon does
13551 not follow, that selector ends the objc-method-decl. */
13552 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
13554 tree tsel = sel;
13555 tree list = NULL_TREE;
13556 while (true)
13558 tree atype = NULL_TREE, id, keyworddecl;
13559 tree param_attr = NULL_TREE;
13560 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13561 break;
13562 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13564 c_parser_consume_token (parser);
13565 atype = c_parser_objc_type_name (parser);
13566 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
13567 "expected %<)%>");
13569 /* New ObjC allows attributes on method parameters. */
13570 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
13571 param_attr = c_parser_gnu_attributes (parser);
13572 if (c_parser_next_token_is_not (parser, CPP_NAME))
13574 c_parser_error (parser, "expected identifier");
13575 return error_mark_node;
13577 id = c_parser_peek_token (parser)->value;
13578 c_parser_consume_token (parser);
13579 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
13580 list = chainon (list, keyworddecl);
13581 tsel = c_parser_objc_selector (parser);
13582 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
13583 break;
13586 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
13588 /* Parse the optional parameter list. Optional Objective-C
13589 method parameters follow the C syntax, and may include '...'
13590 to denote a variable number of arguments. */
13591 parms = make_node (TREE_LIST);
13592 while (c_parser_next_token_is (parser, CPP_COMMA))
13594 struct c_parm *parm;
13595 c_parser_consume_token (parser);
13596 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
13598 ellipsis = true;
13599 c_parser_consume_token (parser);
13600 attr_err |= c_parser_objc_maybe_method_attributes
13601 (parser, attributes) ;
13602 break;
13604 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
13605 if (parm == NULL)
13606 break;
13607 parms = chainon (parms,
13608 build_tree_list (NULL_TREE, grokparm (parm, expr)));
13610 sel = list;
13612 else
13613 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
13615 if (sel == NULL)
13617 c_parser_error (parser, "objective-c method declaration is expected");
13618 return error_mark_node;
13621 if (attr_err)
13622 return error_mark_node;
13624 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
13627 /* Parse an objc-type-name.
13629 objc-type-name:
13630 objc-type-qualifiers[opt] type-name
13631 objc-type-qualifiers[opt]
13633 objc-type-qualifiers:
13634 objc-type-qualifier
13635 objc-type-qualifiers objc-type-qualifier
13637 objc-type-qualifier: one of
13638 in out inout bycopy byref oneway
13641 static tree
13642 c_parser_objc_type_name (c_parser *parser)
13644 tree quals = NULL_TREE;
13645 struct c_type_name *type_name = NULL;
13646 tree type = NULL_TREE;
13647 while (true)
13649 c_token *token = c_parser_peek_token (parser);
13650 if (token->type == CPP_KEYWORD
13651 && (token->keyword == RID_IN
13652 || token->keyword == RID_OUT
13653 || token->keyword == RID_INOUT
13654 || token->keyword == RID_BYCOPY
13655 || token->keyword == RID_BYREF
13656 || token->keyword == RID_ONEWAY))
13658 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
13659 c_parser_consume_token (parser);
13661 else
13662 break;
13664 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
13665 type_name = c_parser_type_name (parser);
13666 if (type_name)
13667 type = groktypename (type_name, NULL, NULL);
13669 /* If the type is unknown, and error has already been produced and
13670 we need to recover from the error. In that case, use NULL_TREE
13671 for the type, as if no type had been specified; this will use the
13672 default type ('id') which is good for error recovery. */
13673 if (type == error_mark_node)
13674 type = NULL_TREE;
13676 return build_tree_list (quals, type);
13679 /* Parse objc-protocol-refs.
13681 objc-protocol-refs:
13682 < identifier-list >
13685 static tree
13686 c_parser_objc_protocol_refs (c_parser *parser)
13688 tree list = NULL_TREE;
13689 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
13690 c_parser_consume_token (parser);
13691 /* Any identifiers, including those declared as type names, are OK
13692 here. */
13693 while (true)
13695 tree id;
13696 if (c_parser_next_token_is_not (parser, CPP_NAME))
13698 c_parser_error (parser, "expected identifier");
13699 break;
13701 id = c_parser_peek_token (parser)->value;
13702 list = chainon (list, build_tree_list (NULL_TREE, id));
13703 c_parser_consume_token (parser);
13704 if (c_parser_next_token_is (parser, CPP_COMMA))
13705 c_parser_consume_token (parser);
13706 else
13707 break;
13709 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
13710 return list;
13713 /* Parse an objc-try-catch-finally-statement.
13715 objc-try-catch-finally-statement:
13716 @try compound-statement objc-catch-list[opt]
13717 @try compound-statement objc-catch-list[opt] @finally compound-statement
13719 objc-catch-list:
13720 @catch ( objc-catch-parameter-declaration ) compound-statement
13721 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
13723 objc-catch-parameter-declaration:
13724 parameter-declaration
13725 '...'
13727 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
13729 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
13730 for C++. Keep them in sync. */
13732 static void
13733 c_parser_objc_try_catch_finally_statement (c_parser *parser)
13735 location_t location;
13736 tree stmt;
13738 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
13739 c_parser_consume_token (parser);
13740 location = c_parser_peek_token (parser)->location;
13741 objc_maybe_warn_exceptions (location);
13742 stmt = c_parser_compound_statement (parser);
13743 objc_begin_try_stmt (location, stmt);
13745 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
13747 struct c_parm *parm;
13748 tree parameter_declaration = error_mark_node;
13749 bool seen_open_paren = false;
13751 c_parser_consume_token (parser);
13752 matching_parens parens;
13753 if (!parens.require_open (parser))
13754 seen_open_paren = true;
13755 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
13757 /* We have "@catch (...)" (where the '...' are literally
13758 what is in the code). Skip the '...'.
13759 parameter_declaration is set to NULL_TREE, and
13760 objc_being_catch_clauses() knows that that means
13761 '...'. */
13762 c_parser_consume_token (parser);
13763 parameter_declaration = NULL_TREE;
13765 else
13767 /* We have "@catch (NSException *exception)" or something
13768 like that. Parse the parameter declaration. */
13769 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
13770 if (parm == NULL)
13771 parameter_declaration = error_mark_node;
13772 else
13773 parameter_declaration = grokparm (parm, NULL);
13775 if (seen_open_paren)
13776 parens.require_close (parser);
13777 else
13779 /* If there was no open parenthesis, we are recovering from
13780 an error, and we are trying to figure out what mistake
13781 the user has made. */
13783 /* If there is an immediate closing parenthesis, the user
13784 probably forgot the opening one (ie, they typed "@catch
13785 NSException *e)". Parse the closing parenthesis and keep
13786 going. */
13787 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
13788 c_parser_consume_token (parser);
13790 /* If these is no immediate closing parenthesis, the user
13791 probably doesn't know that parenthesis are required at
13792 all (ie, they typed "@catch NSException *e"). So, just
13793 forget about the closing parenthesis and keep going. */
13795 objc_begin_catch_clause (parameter_declaration);
13796 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
13797 c_parser_compound_statement_nostart (parser);
13798 objc_finish_catch_clause ();
13800 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
13802 c_parser_consume_token (parser);
13803 location = c_parser_peek_token (parser)->location;
13804 stmt = c_parser_compound_statement (parser);
13805 objc_build_finally_clause (location, stmt);
13807 objc_finish_try_stmt ();
13810 /* Parse an objc-synchronized-statement.
13812 objc-synchronized-statement:
13813 @synchronized ( expression ) compound-statement
13816 static void
13817 c_parser_objc_synchronized_statement (c_parser *parser)
13819 location_t loc;
13820 tree expr, stmt;
13821 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
13822 c_parser_consume_token (parser);
13823 loc = c_parser_peek_token (parser)->location;
13824 objc_maybe_warn_exceptions (loc);
13825 matching_parens parens;
13826 if (parens.require_open (parser))
13828 struct c_expr ce = c_parser_expression (parser);
13829 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
13830 expr = ce.value;
13831 expr = c_fully_fold (expr, false, NULL);
13832 parens.skip_until_found_close (parser);
13834 else
13835 expr = error_mark_node;
13836 stmt = c_parser_compound_statement (parser);
13837 objc_build_synchronized (loc, expr, stmt);
13840 /* Parse an objc-selector; return NULL_TREE without an error if the
13841 next token is not an objc-selector.
13843 objc-selector:
13844 identifier
13845 one of
13846 enum struct union if else while do for switch case default
13847 break continue return goto asm sizeof typeof typeof_unqual __alignof
13848 unsigned long const short volatile signed restrict _Complex
13849 in out inout bycopy byref oneway int char float double void _Bool
13850 _Atomic
13852 ??? Why this selection of keywords but not, for example, storage
13853 class specifiers? */
13855 static tree
13856 c_parser_objc_selector (c_parser *parser)
13858 c_token *token = c_parser_peek_token (parser);
13859 tree value = token->value;
13860 if (token->type == CPP_NAME)
13862 c_parser_consume_token (parser);
13863 return value;
13865 if (token->type != CPP_KEYWORD)
13866 return NULL_TREE;
13867 switch (token->keyword)
13869 case RID_ENUM:
13870 case RID_STRUCT:
13871 case RID_UNION:
13872 case RID_IF:
13873 case RID_ELSE:
13874 case RID_WHILE:
13875 case RID_DO:
13876 case RID_FOR:
13877 case RID_SWITCH:
13878 case RID_CASE:
13879 case RID_DEFAULT:
13880 case RID_BREAK:
13881 case RID_CONTINUE:
13882 case RID_RETURN:
13883 case RID_GOTO:
13884 case RID_ASM:
13885 case RID_SIZEOF:
13886 case RID_TYPEOF:
13887 case RID_TYPEOF_UNQUAL:
13888 case RID_ALIGNOF:
13889 case RID_UNSIGNED:
13890 case RID_LONG:
13891 case RID_CONST:
13892 case RID_SHORT:
13893 case RID_VOLATILE:
13894 case RID_SIGNED:
13895 case RID_RESTRICT:
13896 case RID_COMPLEX:
13897 case RID_IN:
13898 case RID_OUT:
13899 case RID_INOUT:
13900 case RID_BYCOPY:
13901 case RID_BYREF:
13902 case RID_ONEWAY:
13903 case RID_INT:
13904 case RID_CHAR:
13905 case RID_FLOAT:
13906 case RID_DOUBLE:
13907 CASE_RID_FLOATN_NX:
13908 case RID_VOID:
13909 case RID_BOOL:
13910 case RID_ATOMIC:
13911 case RID_AUTO_TYPE:
13912 case RID_INT_N_0:
13913 case RID_INT_N_1:
13914 case RID_INT_N_2:
13915 case RID_INT_N_3:
13916 c_parser_consume_token (parser);
13917 return value;
13918 default:
13919 return NULL_TREE;
13923 /* Parse an objc-selector-arg.
13925 objc-selector-arg:
13926 objc-selector
13927 objc-keywordname-list
13929 objc-keywordname-list:
13930 objc-keywordname
13931 objc-keywordname-list objc-keywordname
13933 objc-keywordname:
13934 objc-selector :
13938 static tree
13939 c_parser_objc_selector_arg (c_parser *parser)
13941 tree sel = c_parser_objc_selector (parser);
13942 tree list = NULL_TREE;
13943 if (sel
13944 && c_parser_next_token_is_not (parser, CPP_COLON)
13945 && c_parser_next_token_is_not (parser, CPP_SCOPE))
13946 return sel;
13947 while (true)
13949 if (c_parser_next_token_is (parser, CPP_SCOPE))
13951 c_parser_consume_token (parser);
13952 list = chainon (list, build_tree_list (sel, NULL_TREE));
13953 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
13955 else
13957 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13958 return list;
13959 list = chainon (list, build_tree_list (sel, NULL_TREE));
13961 sel = c_parser_objc_selector (parser);
13962 if (!sel
13963 && c_parser_next_token_is_not (parser, CPP_COLON)
13964 && c_parser_next_token_is_not (parser, CPP_SCOPE))
13965 break;
13967 return list;
13970 /* Parse an objc-receiver.
13972 objc-receiver:
13973 expression
13974 class-name
13975 type-name
13978 static tree
13979 c_parser_objc_receiver (c_parser *parser)
13981 location_t loc = c_parser_peek_token (parser)->location;
13983 if (c_parser_peek_token (parser)->type == CPP_NAME
13984 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
13985 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
13987 tree id = c_parser_peek_token (parser)->value;
13988 c_parser_consume_token (parser);
13989 return objc_get_class_reference (id);
13991 struct c_expr ce = c_parser_expression (parser);
13992 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
13993 return c_fully_fold (ce.value, false, NULL);
13996 /* Parse objc-message-args.
13998 objc-message-args:
13999 objc-selector
14000 objc-keywordarg-list
14002 objc-keywordarg-list:
14003 objc-keywordarg
14004 objc-keywordarg-list objc-keywordarg
14006 objc-keywordarg:
14007 objc-selector : objc-keywordexpr
14008 : objc-keywordexpr
14011 static tree
14012 c_parser_objc_message_args (c_parser *parser)
14014 tree sel = c_parser_objc_selector (parser);
14015 tree list = NULL_TREE;
14016 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
14017 return sel;
14018 while (true)
14020 tree keywordexpr;
14021 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14022 return error_mark_node;
14023 keywordexpr = c_parser_objc_keywordexpr (parser);
14024 list = chainon (list, build_tree_list (sel, keywordexpr));
14025 sel = c_parser_objc_selector (parser);
14026 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
14027 break;
14029 return list;
14032 /* Parse an objc-keywordexpr.
14034 objc-keywordexpr:
14035 nonempty-expr-list
14038 static tree
14039 c_parser_objc_keywordexpr (c_parser *parser)
14041 tree ret;
14042 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
14043 NULL, NULL, NULL, NULL);
14044 if (vec_safe_length (expr_list) == 1)
14046 /* Just return the expression, remove a level of
14047 indirection. */
14048 ret = (*expr_list)[0];
14050 else
14052 /* We have a comma expression, we will collapse later. */
14053 ret = build_tree_list_vec (expr_list);
14055 release_tree_vector (expr_list);
14056 return ret;
14059 /* A check, needed in several places, that ObjC interface, implementation or
14060 method definitions are not prefixed by incorrect items. */
14061 static bool
14062 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
14063 struct c_declspecs *specs)
14065 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
14066 || specs->typespec_kind != ctsk_none)
14068 c_parser_error (parser,
14069 "no type or storage class may be specified here,");
14070 c_parser_skip_to_end_of_block_or_statement (parser);
14071 return true;
14073 return false;
14076 /* Parse an Objective-C @property declaration. The syntax is:
14078 objc-property-declaration:
14079 '@property' objc-property-attributes[opt] struct-declaration ;
14081 objc-property-attributes:
14082 '(' objc-property-attribute-list ')'
14084 objc-property-attribute-list:
14085 objc-property-attribute
14086 objc-property-attribute-list, objc-property-attribute
14088 objc-property-attribute
14089 'getter' = identifier
14090 'setter' = identifier
14091 'readonly'
14092 'readwrite'
14093 'assign'
14094 'retain'
14095 'copy'
14096 'nonatomic'
14098 For example:
14099 @property NSString *name;
14100 @property (readonly) id object;
14101 @property (retain, nonatomic, getter=getTheName) id name;
14102 @property int a, b, c;
14104 PS: This function is identical to cp_parser_objc_at_propery_declaration
14105 for C++. Keep them in sync. */
14106 static void
14107 c_parser_objc_at_property_declaration (c_parser *parser)
14109 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
14110 location_t loc = c_parser_peek_token (parser)->location;
14111 c_parser_consume_token (parser); /* Eat '@property'. */
14113 /* Parse the optional attribute list.
14115 A list of parsed, but not verified, attributes. */
14116 vec<property_attribute_info *> prop_attr_list = vNULL;
14118 bool syntax_error = false;
14119 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14121 matching_parens parens;
14123 location_t attr_start = c_parser_peek_token (parser)->location;
14124 /* Eat the '(' */
14125 parens.consume_open (parser);
14127 /* Property attribute keywords are valid now. */
14128 parser->objc_property_attr_context = true;
14130 /* Allow @property (), with a warning. */
14131 location_t attr_end = c_parser_peek_token (parser)->location;
14133 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14135 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
14136 warning_at (attr_comb, OPT_Wattributes,
14137 "empty property attribute list");
14139 else
14140 while (true)
14142 c_token *token = c_parser_peek_token (parser);
14143 attr_start = token->location;
14144 attr_end = get_finish (token->location);
14145 location_t attr_comb = make_location (attr_start, attr_start,
14146 attr_end);
14148 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
14150 warning_at (attr_comb, OPT_Wattributes,
14151 "missing property attribute");
14152 if (token->type == CPP_CLOSE_PAREN)
14153 break;
14154 c_parser_consume_token (parser);
14155 continue;
14158 tree attr_name = NULL_TREE;
14159 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
14160 bool add_at = false;
14161 if (token->type == CPP_KEYWORD)
14163 keyword = token->keyword;
14164 if (OBJC_IS_AT_KEYWORD (keyword))
14166 /* For '@' keywords the token value has the keyword,
14167 prepend the '@' for diagnostics. */
14168 attr_name = token->value;
14169 add_at = true;
14171 else
14172 attr_name = ridpointers[(int)keyword];
14174 else if (token->type == CPP_NAME)
14175 attr_name = token->value;
14176 c_parser_consume_token (parser);
14178 enum objc_property_attribute_kind prop_kind
14179 = objc_prop_attr_kind_for_rid (keyword);
14180 property_attribute_info *prop
14181 = new property_attribute_info (attr_name, attr_comb, prop_kind);
14182 prop_attr_list.safe_push (prop);
14184 tree meth_name;
14185 switch (prop->prop_kind)
14187 default: break;
14188 case OBJC_PROPERTY_ATTR_UNKNOWN:
14189 if (attr_name)
14190 error_at (attr_comb, "unknown property attribute %<%s%s%>",
14191 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
14192 else
14193 error_at (attr_comb, "unknown property attribute");
14194 prop->parse_error = syntax_error = true;
14195 break;
14197 case OBJC_PROPERTY_ATTR_GETTER:
14198 case OBJC_PROPERTY_ATTR_SETTER:
14199 if (c_parser_next_token_is_not (parser, CPP_EQ))
14201 attr_comb = make_location (attr_end, attr_start, attr_end);
14202 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
14203 attr_name);
14204 prop->parse_error = syntax_error = true;
14205 break;
14207 token = c_parser_peek_token (parser);
14208 attr_end = token->location;
14209 c_parser_consume_token (parser); /* eat the = */
14210 if (c_parser_next_token_is_not (parser, CPP_NAME))
14212 attr_comb = make_location (attr_end, attr_start, attr_end);
14213 error_at (attr_comb, "expected %qE selector name",
14214 attr_name);
14215 prop->parse_error = syntax_error = true;
14216 break;
14218 /* Get the end of the method name, and consume the name. */
14219 token = c_parser_peek_token (parser);
14220 attr_end = get_finish (token->location);
14221 meth_name = token->value;
14222 c_parser_consume_token (parser);
14223 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
14225 if (c_parser_next_token_is_not (parser, CPP_COLON))
14227 attr_comb = make_location (attr_end, attr_start,
14228 attr_end);
14229 error_at (attr_comb, "setter method names must"
14230 " terminate with %<:%>");
14231 prop->parse_error = syntax_error = true;
14233 else
14235 attr_end = get_finish (c_parser_peek_token
14236 (parser)->location);
14237 c_parser_consume_token (parser);
14239 attr_comb = make_location (attr_start, attr_start,
14240 attr_end);
14242 else
14243 attr_comb = make_location (attr_start, attr_start,
14244 attr_end);
14245 prop->ident = meth_name;
14246 /* Updated location including all that was successfully
14247 parsed. */
14248 prop->prop_loc = attr_comb;
14249 break;
14252 /* If we see a comma here, then keep going - even if we already
14253 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
14254 this makes a more useful output and avoid spurious warnings about
14255 missing attributes that are, in fact, specified after the one with
14256 the syntax error. */
14257 if (c_parser_next_token_is (parser, CPP_COMMA))
14258 c_parser_consume_token (parser);
14259 else
14260 break;
14262 parser->objc_property_attr_context = false;
14264 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
14265 /* We don't really want to chew the whole of the file looking for a
14266 matching closing parenthesis, so we will try to read the decl and
14267 let the error handling for that close out the statement. */
14269 else
14270 syntax_error = false, parens.skip_until_found_close (parser);
14273 /* 'properties' is the list of properties that we read. Usually a
14274 single one, but maybe more (eg, in "@property int a, b, c;" there
14275 are three). */
14276 tree properties = c_parser_struct_declaration (parser, NULL);
14278 if (properties == error_mark_node)
14279 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14280 else
14282 if (properties == NULL_TREE)
14283 c_parser_error (parser, "expected identifier");
14284 else
14286 /* Comma-separated properties are chained together in reverse order;
14287 add them one by one. */
14288 properties = nreverse (properties);
14289 for (; properties; properties = TREE_CHAIN (properties))
14290 objc_add_property_declaration (loc, copy_node (properties),
14291 prop_attr_list);
14293 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14296 while (!prop_attr_list.is_empty())
14297 delete prop_attr_list.pop ();
14298 prop_attr_list.release ();
14299 parser->error = false;
14302 /* Parse an Objective-C @synthesize declaration. The syntax is:
14304 objc-synthesize-declaration:
14305 @synthesize objc-synthesize-identifier-list ;
14307 objc-synthesize-identifier-list:
14308 objc-synthesize-identifier
14309 objc-synthesize-identifier-list, objc-synthesize-identifier
14311 objc-synthesize-identifier
14312 identifier
14313 identifier = identifier
14315 For example:
14316 @synthesize MyProperty;
14317 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
14319 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
14320 for C++. Keep them in sync.
14322 static void
14323 c_parser_objc_at_synthesize_declaration (c_parser *parser)
14325 tree list = NULL_TREE;
14326 location_t loc;
14327 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
14328 loc = c_parser_peek_token (parser)->location;
14330 c_parser_consume_token (parser);
14331 while (true)
14333 tree property, ivar;
14334 if (c_parser_next_token_is_not (parser, CPP_NAME))
14336 c_parser_error (parser, "expected identifier");
14337 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14338 /* Once we find the semicolon, we can resume normal parsing.
14339 We have to reset parser->error manually because
14340 c_parser_skip_until_found() won't reset it for us if the
14341 next token is precisely a semicolon. */
14342 parser->error = false;
14343 return;
14345 property = c_parser_peek_token (parser)->value;
14346 c_parser_consume_token (parser);
14347 if (c_parser_next_token_is (parser, CPP_EQ))
14349 c_parser_consume_token (parser);
14350 if (c_parser_next_token_is_not (parser, CPP_NAME))
14352 c_parser_error (parser, "expected identifier");
14353 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14354 parser->error = false;
14355 return;
14357 ivar = c_parser_peek_token (parser)->value;
14358 c_parser_consume_token (parser);
14360 else
14361 ivar = NULL_TREE;
14362 list = chainon (list, build_tree_list (ivar, property));
14363 if (c_parser_next_token_is (parser, CPP_COMMA))
14364 c_parser_consume_token (parser);
14365 else
14366 break;
14368 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14369 objc_add_synthesize_declaration (loc, list);
14372 /* Parse an Objective-C @dynamic declaration. The syntax is:
14374 objc-dynamic-declaration:
14375 @dynamic identifier-list ;
14377 For example:
14378 @dynamic MyProperty;
14379 @dynamic MyProperty, AnotherProperty;
14381 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
14382 for C++. Keep them in sync.
14384 static void
14385 c_parser_objc_at_dynamic_declaration (c_parser *parser)
14387 tree list = NULL_TREE;
14388 location_t loc;
14389 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
14390 loc = c_parser_peek_token (parser)->location;
14392 c_parser_consume_token (parser);
14393 while (true)
14395 tree property;
14396 if (c_parser_next_token_is_not (parser, CPP_NAME))
14398 c_parser_error (parser, "expected identifier");
14399 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14400 parser->error = false;
14401 return;
14403 property = c_parser_peek_token (parser)->value;
14404 list = chainon (list, build_tree_list (NULL_TREE, property));
14405 c_parser_consume_token (parser);
14406 if (c_parser_next_token_is (parser, CPP_COMMA))
14407 c_parser_consume_token (parser);
14408 else
14409 break;
14411 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14412 objc_add_dynamic_declaration (loc, list);
14416 /* Parse a pragma GCC ivdep. */
14418 static bool
14419 c_parse_pragma_ivdep (c_parser *parser)
14421 c_parser_consume_pragma (parser);
14422 c_parser_skip_to_pragma_eol (parser);
14423 return true;
14426 /* Parse a pragma GCC novector. */
14428 static bool
14429 c_parse_pragma_novector (c_parser *parser)
14431 c_parser_consume_pragma (parser);
14432 c_parser_skip_to_pragma_eol (parser);
14433 return true;
14436 /* Parse a pragma GCC unroll. */
14438 static unsigned short
14439 c_parser_pragma_unroll (c_parser *parser)
14441 unsigned short unroll;
14442 c_parser_consume_pragma (parser);
14443 location_t location = c_parser_peek_token (parser)->location;
14444 tree expr = c_parser_expr_no_commas (parser, NULL).value;
14445 mark_exp_read (expr);
14446 expr = c_fully_fold (expr, false, NULL);
14447 HOST_WIDE_INT lunroll = 0;
14448 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14449 || TREE_CODE (expr) != INTEGER_CST
14450 || (lunroll = tree_to_shwi (expr)) < 0
14451 || lunroll >= USHRT_MAX)
14453 error_at (location, "%<#pragma GCC unroll%> requires an"
14454 " assignment-expression that evaluates to a non-negative"
14455 " integral constant less than %u", USHRT_MAX);
14456 unroll = 0;
14458 else
14460 unroll = (unsigned short)lunroll;
14461 if (unroll == 0)
14462 unroll = 1;
14465 c_parser_skip_to_pragma_eol (parser);
14466 return unroll;
14469 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
14470 should be considered, statements. ALLOW_STMT is true if we're within
14471 the context of a function and such pragmas are to be allowed. Returns
14472 true if we actually parsed such a pragma. */
14474 static bool
14475 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
14477 unsigned int id;
14478 const char *construct = NULL;
14480 input_location = c_parser_peek_token (parser)->location;
14481 id = c_parser_peek_token (parser)->pragma_kind;
14482 gcc_assert (id != PRAGMA_NONE);
14483 if (parser->omp_for_parse_state
14484 && parser->omp_for_parse_state->in_intervening_code
14485 && id >= PRAGMA_OMP__START_
14486 && id <= PRAGMA_OMP__LAST_)
14488 error_at (input_location,
14489 "intervening code must not contain OpenMP directives");
14490 parser->omp_for_parse_state->fail = true;
14491 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14492 return false;
14495 switch (id)
14497 case PRAGMA_OACC_DECLARE:
14498 c_parser_oacc_declare (parser);
14499 return false;
14501 case PRAGMA_OACC_ENTER_DATA:
14502 if (context != pragma_compound)
14504 construct = "acc enter data";
14505 in_compound:
14506 if (context == pragma_stmt)
14508 error_at (c_parser_peek_token (parser)->location,
14509 "%<#pragma %s%> may only be used in compound "
14510 "statements", construct);
14511 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14512 return true;
14514 goto bad_stmt;
14516 c_parser_oacc_enter_exit_data (parser, true);
14517 return false;
14519 case PRAGMA_OACC_EXIT_DATA:
14520 if (context != pragma_compound)
14522 construct = "acc exit data";
14523 goto in_compound;
14525 c_parser_oacc_enter_exit_data (parser, false);
14526 return false;
14528 case PRAGMA_OACC_ROUTINE:
14529 if (context != pragma_external)
14531 error_at (c_parser_peek_token (parser)->location,
14532 "%<#pragma acc routine%> must be at file scope");
14533 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14534 return false;
14536 c_parser_oacc_routine (parser, context);
14537 return false;
14539 case PRAGMA_OACC_UPDATE:
14540 if (context != pragma_compound)
14542 construct = "acc update";
14543 goto in_compound;
14545 c_parser_oacc_update (parser);
14546 return false;
14548 case PRAGMA_OMP_BARRIER:
14549 if (context != pragma_compound)
14551 construct = "omp barrier";
14552 goto in_compound;
14554 c_parser_omp_barrier (parser);
14555 return false;
14557 case PRAGMA_OMP_DEPOBJ:
14558 if (context != pragma_compound)
14560 construct = "omp depobj";
14561 goto in_compound;
14563 c_parser_omp_depobj (parser);
14564 return false;
14566 case PRAGMA_OMP_FLUSH:
14567 if (context != pragma_compound)
14569 construct = "omp flush";
14570 goto in_compound;
14572 c_parser_omp_flush (parser);
14573 return false;
14575 case PRAGMA_OMP_TASKWAIT:
14576 if (context != pragma_compound)
14578 construct = "omp taskwait";
14579 goto in_compound;
14581 c_parser_omp_taskwait (parser);
14582 return false;
14584 case PRAGMA_OMP_TASKYIELD:
14585 if (context != pragma_compound)
14587 construct = "omp taskyield";
14588 goto in_compound;
14590 c_parser_omp_taskyield (parser);
14591 return false;
14593 case PRAGMA_OMP_CANCEL:
14594 if (context != pragma_compound)
14596 construct = "omp cancel";
14597 goto in_compound;
14599 c_parser_omp_cancel (parser);
14600 return false;
14602 case PRAGMA_OMP_CANCELLATION_POINT:
14603 return c_parser_omp_cancellation_point (parser, context);
14605 case PRAGMA_OMP_THREADPRIVATE:
14606 c_parser_omp_threadprivate (parser);
14607 return false;
14609 case PRAGMA_OMP_TARGET:
14610 return c_parser_omp_target (parser, context, if_p);
14612 case PRAGMA_OMP_BEGIN:
14613 c_parser_omp_begin (parser);
14614 return false;
14616 case PRAGMA_OMP_END:
14617 c_parser_omp_end (parser);
14618 return false;
14620 case PRAGMA_OMP_SCAN:
14621 error_at (c_parser_peek_token (parser)->location,
14622 "%<#pragma omp scan%> may only be used in "
14623 "a loop construct with %<inscan%> %<reduction%> clause");
14624 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14625 return false;
14627 case PRAGMA_OMP_SECTION:
14628 error_at (c_parser_peek_token (parser)->location,
14629 "%<#pragma omp section%> may only be used in "
14630 "%<#pragma omp sections%> construct");
14631 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14632 return false;
14634 case PRAGMA_OMP_DECLARE:
14635 return c_parser_omp_declare (parser, context);
14637 case PRAGMA_OMP_REQUIRES:
14638 if (context != pragma_external)
14640 error_at (c_parser_peek_token (parser)->location,
14641 "%<#pragma %s%> may only be used at file scope",
14642 "omp requires");
14643 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14644 return false;
14646 c_parser_omp_requires (parser);
14647 return false;
14649 case PRAGMA_OMP_ALLOCATE:
14650 c_parser_omp_allocate (parser);
14651 return false;
14653 case PRAGMA_OMP_ASSUMES:
14654 if (context != pragma_external)
14656 error_at (c_parser_peek_token (parser)->location,
14657 "%<#pragma %s%> may only be used at file scope",
14658 "omp assumes");
14659 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14660 return false;
14662 c_parser_omp_assumes (parser);
14663 return false;
14665 case PRAGMA_OMP_NOTHING:
14666 c_parser_omp_nothing (parser);
14667 return false;
14669 case PRAGMA_OMP_ERROR:
14670 return c_parser_omp_error (parser, context);
14672 case PRAGMA_OMP_ORDERED:
14673 return c_parser_omp_ordered (parser, context, if_p);
14675 case PRAGMA_NOVECTOR:
14676 case PRAGMA_UNROLL:
14677 case PRAGMA_IVDEP:
14679 bool novector = false;
14680 unsigned short unroll = 0;
14681 bool ivdep = false;
14683 switch (id)
14685 case PRAGMA_NOVECTOR:
14686 novector = c_parse_pragma_novector (parser);
14687 break;
14688 case PRAGMA_UNROLL:
14689 unroll = c_parser_pragma_unroll (parser);
14690 break;
14691 case PRAGMA_IVDEP:
14692 ivdep = c_parse_pragma_ivdep (parser);
14693 break;
14694 default:
14695 gcc_unreachable ();
14698 c_token *tok = c_parser_peek_token (parser);
14699 bool has_more = tok->type == CPP_PRAGMA;
14700 while (has_more)
14702 switch (tok->pragma_kind)
14704 case PRAGMA_IVDEP:
14705 ivdep = c_parse_pragma_ivdep (parser);
14706 break;
14707 case PRAGMA_UNROLL:
14708 unroll = c_parser_pragma_unroll (parser);
14709 break;
14710 case PRAGMA_NOVECTOR:
14711 novector = c_parse_pragma_novector (parser);
14712 break;
14713 default:
14714 has_more = false;
14715 break;
14717 tok = c_parser_peek_token (parser);
14718 has_more = has_more && tok->type == CPP_PRAGMA;
14720 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
14721 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
14722 && !c_parser_next_token_is_keyword (parser, RID_DO))
14724 c_parser_error (parser, "for, while or do statement expected");
14725 return false;
14727 if (c_parser_next_token_is_keyword (parser, RID_FOR))
14728 c_parser_for_statement (parser, ivdep, unroll, novector, if_p);
14729 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
14730 c_parser_while_statement (parser, ivdep, unroll, novector, if_p);
14731 else
14732 c_parser_do_statement (parser, ivdep, unroll, novector);
14734 return true;
14736 case PRAGMA_GCC_PCH_PREPROCESS:
14737 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
14738 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14739 return false;
14741 case PRAGMA_OACC_WAIT:
14742 if (context != pragma_compound)
14744 construct = "acc wait";
14745 goto in_compound;
14747 /* FALL THROUGH. */
14749 default:
14750 if (id < PRAGMA_FIRST_EXTERNAL)
14752 if (context != pragma_stmt && context != pragma_compound)
14754 bad_stmt:
14755 c_parser_error (parser, "expected declaration specifiers");
14756 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14757 return false;
14759 c_parser_omp_construct (parser, if_p);
14760 return true;
14762 break;
14765 c_parser_consume_pragma (parser);
14766 c_invoke_pragma_handler (id);
14768 /* Skip to EOL, but suppress any error message. Those will have been
14769 generated by the handler routine through calling error, as opposed
14770 to calling c_parser_error. */
14771 parser->error = true;
14772 c_parser_skip_to_pragma_eol (parser);
14774 return false;
14777 /* The interface the pragma parsers have to the lexer. */
14779 enum cpp_ttype
14780 pragma_lex (tree *value, location_t *loc)
14782 c_token *tok = c_parser_peek_token (the_parser);
14783 enum cpp_ttype ret = tok->type;
14785 *value = tok->value;
14786 if (loc)
14787 *loc = tok->location;
14789 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
14790 ret = CPP_EOF;
14791 else if (ret == CPP_STRING)
14792 *value = c_parser_string_literal (the_parser, false, false).value;
14793 else
14795 if (ret == CPP_KEYWORD)
14796 ret = CPP_NAME;
14797 c_parser_consume_token (the_parser);
14800 return ret;
14803 void
14804 pragma_lex_discard_to_eol ()
14806 cpp_ttype type;
14809 type = c_parser_peek_token (the_parser)->type;
14810 gcc_assert (type != CPP_EOF);
14811 c_parser_consume_token (the_parser);
14812 } while (type != CPP_PRAGMA_EOL);
14815 static void
14816 c_parser_pragma_pch_preprocess (c_parser *parser)
14818 tree name = NULL;
14820 parser->lex_joined_string = true;
14821 c_parser_consume_pragma (parser);
14822 if (c_parser_next_token_is (parser, CPP_STRING))
14824 name = c_parser_peek_token (parser)->value;
14825 c_parser_consume_token (parser);
14827 else
14828 c_parser_error (parser, "expected string literal");
14829 c_parser_skip_to_pragma_eol (parser);
14830 parser->lex_joined_string = false;
14832 if (name)
14833 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
14836 /* OpenACC and OpenMP parsing routines. */
14838 /* Returns name of the next clause.
14839 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
14840 the token is not consumed. Otherwise appropriate pragma_omp_clause is
14841 returned and the token is consumed. */
14843 static pragma_omp_clause
14844 c_parser_omp_clause_name (c_parser *parser)
14846 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
14848 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14849 result = PRAGMA_OACC_CLAUSE_AUTO;
14850 else if (c_parser_next_token_is_keyword (parser, RID_IF))
14851 result = PRAGMA_OMP_CLAUSE_IF;
14852 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14853 result = PRAGMA_OMP_CLAUSE_DEFAULT;
14854 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
14855 result = PRAGMA_OMP_CLAUSE_FOR;
14856 else if (c_parser_next_token_is (parser, CPP_NAME))
14858 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14860 switch (p[0])
14862 case 'a':
14863 if (!strcmp ("affinity", p))
14864 result = PRAGMA_OMP_CLAUSE_AFFINITY;
14865 else if (!strcmp ("aligned", p))
14866 result = PRAGMA_OMP_CLAUSE_ALIGNED;
14867 else if (!strcmp ("allocate", p))
14868 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
14869 else if (!strcmp ("async", p))
14870 result = PRAGMA_OACC_CLAUSE_ASYNC;
14871 else if (!strcmp ("attach", p))
14872 result = PRAGMA_OACC_CLAUSE_ATTACH;
14873 break;
14874 case 'b':
14875 if (!strcmp ("bind", p))
14876 result = PRAGMA_OMP_CLAUSE_BIND;
14877 break;
14878 case 'c':
14879 if (!strcmp ("collapse", p))
14880 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
14881 else if (!strcmp ("copy", p))
14882 result = PRAGMA_OACC_CLAUSE_COPY;
14883 else if (!strcmp ("copyin", p))
14884 result = PRAGMA_OMP_CLAUSE_COPYIN;
14885 else if (!strcmp ("copyout", p))
14886 result = PRAGMA_OACC_CLAUSE_COPYOUT;
14887 else if (!strcmp ("copyprivate", p))
14888 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
14889 else if (!strcmp ("create", p))
14890 result = PRAGMA_OACC_CLAUSE_CREATE;
14891 break;
14892 case 'd':
14893 if (!strcmp ("defaultmap", p))
14894 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
14895 else if (!strcmp ("delete", p))
14896 result = PRAGMA_OACC_CLAUSE_DELETE;
14897 else if (!strcmp ("depend", p))
14898 result = PRAGMA_OMP_CLAUSE_DEPEND;
14899 else if (!strcmp ("detach", p))
14900 result = PRAGMA_OACC_CLAUSE_DETACH;
14901 else if (!strcmp ("device", p))
14902 result = PRAGMA_OMP_CLAUSE_DEVICE;
14903 else if (!strcmp ("deviceptr", p))
14904 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
14905 else if (!strcmp ("device_resident", p))
14906 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
14907 else if (!strcmp ("device_type", p))
14908 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
14909 else if (!strcmp ("dist_schedule", p))
14910 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
14911 else if (!strcmp ("doacross", p))
14912 result = PRAGMA_OMP_CLAUSE_DOACROSS;
14913 break;
14914 case 'e':
14915 if (!strcmp ("enter", p))
14916 result = PRAGMA_OMP_CLAUSE_ENTER;
14917 break;
14918 case 'f':
14919 if (!strcmp ("filter", p))
14920 result = PRAGMA_OMP_CLAUSE_FILTER;
14921 else if (!strcmp ("final", p))
14922 result = PRAGMA_OMP_CLAUSE_FINAL;
14923 else if (!strcmp ("finalize", p))
14924 result = PRAGMA_OACC_CLAUSE_FINALIZE;
14925 else if (!strcmp ("firstprivate", p))
14926 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
14927 else if (!strcmp ("from", p))
14928 result = PRAGMA_OMP_CLAUSE_FROM;
14929 break;
14930 case 'g':
14931 if (!strcmp ("gang", p))
14932 result = PRAGMA_OACC_CLAUSE_GANG;
14933 else if (!strcmp ("grainsize", p))
14934 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
14935 break;
14936 case 'h':
14937 if (!strcmp ("has_device_addr", p))
14938 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
14939 else if (!strcmp ("hint", p))
14940 result = PRAGMA_OMP_CLAUSE_HINT;
14941 else if (!strcmp ("host", p))
14942 result = PRAGMA_OACC_CLAUSE_HOST;
14943 break;
14944 case 'i':
14945 if (!strcmp ("if_present", p))
14946 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
14947 else if (!strcmp ("in_reduction", p))
14948 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
14949 else if (!strcmp ("inbranch", p))
14950 result = PRAGMA_OMP_CLAUSE_INBRANCH;
14951 else if (!strcmp ("independent", p))
14952 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
14953 else if (!strcmp ("indirect", p))
14954 result = PRAGMA_OMP_CLAUSE_INDIRECT;
14955 else if (!strcmp ("is_device_ptr", p))
14956 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
14957 break;
14958 case 'l':
14959 if (!strcmp ("lastprivate", p))
14960 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
14961 else if (!strcmp ("linear", p))
14962 result = PRAGMA_OMP_CLAUSE_LINEAR;
14963 else if (!strcmp ("link", p))
14964 result = PRAGMA_OMP_CLAUSE_LINK;
14965 break;
14966 case 'm':
14967 if (!strcmp ("map", p))
14968 result = PRAGMA_OMP_CLAUSE_MAP;
14969 else if (!strcmp ("mergeable", p))
14970 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
14971 break;
14972 case 'n':
14973 if (!strcmp ("no_create", p))
14974 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
14975 else if (!strcmp ("nogroup", p))
14976 result = PRAGMA_OMP_CLAUSE_NOGROUP;
14977 else if (!strcmp ("nohost", p))
14978 result = PRAGMA_OACC_CLAUSE_NOHOST;
14979 else if (!strcmp ("nontemporal", p))
14980 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
14981 else if (!strcmp ("notinbranch", p))
14982 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
14983 else if (!strcmp ("nowait", p))
14984 result = PRAGMA_OMP_CLAUSE_NOWAIT;
14985 else if (!strcmp ("num_gangs", p))
14986 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
14987 else if (!strcmp ("num_tasks", p))
14988 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
14989 else if (!strcmp ("num_teams", p))
14990 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
14991 else if (!strcmp ("num_threads", p))
14992 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
14993 else if (!strcmp ("num_workers", p))
14994 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
14995 break;
14996 case 'o':
14997 if (!strcmp ("ordered", p))
14998 result = PRAGMA_OMP_CLAUSE_ORDERED;
14999 else if (!strcmp ("order", p))
15000 result = PRAGMA_OMP_CLAUSE_ORDER;
15001 break;
15002 case 'p':
15003 if (!strcmp ("parallel", p))
15004 result = PRAGMA_OMP_CLAUSE_PARALLEL;
15005 else if (!strcmp ("present", p))
15006 result = PRAGMA_OACC_CLAUSE_PRESENT;
15007 /* As of OpenACC 2.5, these are now aliases of the non-present_or
15008 clauses. */
15009 else if (!strcmp ("present_or_copy", p)
15010 || !strcmp ("pcopy", p))
15011 result = PRAGMA_OACC_CLAUSE_COPY;
15012 else if (!strcmp ("present_or_copyin", p)
15013 || !strcmp ("pcopyin", p))
15014 result = PRAGMA_OACC_CLAUSE_COPYIN;
15015 else if (!strcmp ("present_or_copyout", p)
15016 || !strcmp ("pcopyout", p))
15017 result = PRAGMA_OACC_CLAUSE_COPYOUT;
15018 else if (!strcmp ("present_or_create", p)
15019 || !strcmp ("pcreate", p))
15020 result = PRAGMA_OACC_CLAUSE_CREATE;
15021 else if (!strcmp ("priority", p))
15022 result = PRAGMA_OMP_CLAUSE_PRIORITY;
15023 else if (!strcmp ("private", p))
15024 result = PRAGMA_OMP_CLAUSE_PRIVATE;
15025 else if (!strcmp ("proc_bind", p))
15026 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
15027 break;
15028 case 'r':
15029 if (!strcmp ("reduction", p))
15030 result = PRAGMA_OMP_CLAUSE_REDUCTION;
15031 break;
15032 case 's':
15033 if (!strcmp ("safelen", p))
15034 result = PRAGMA_OMP_CLAUSE_SAFELEN;
15035 else if (!strcmp ("schedule", p))
15036 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
15037 else if (!strcmp ("sections", p))
15038 result = PRAGMA_OMP_CLAUSE_SECTIONS;
15039 else if (!strcmp ("self", p))
15040 result = PRAGMA_OACC_CLAUSE_SELF;
15041 else if (!strcmp ("seq", p))
15042 result = PRAGMA_OACC_CLAUSE_SEQ;
15043 else if (!strcmp ("shared", p))
15044 result = PRAGMA_OMP_CLAUSE_SHARED;
15045 else if (!strcmp ("simd", p))
15046 result = PRAGMA_OMP_CLAUSE_SIMD;
15047 else if (!strcmp ("simdlen", p))
15048 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
15049 break;
15050 case 't':
15051 if (!strcmp ("task_reduction", p))
15052 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
15053 else if (!strcmp ("taskgroup", p))
15054 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
15055 else if (!strcmp ("thread_limit", p))
15056 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
15057 else if (!strcmp ("threads", p))
15058 result = PRAGMA_OMP_CLAUSE_THREADS;
15059 else if (!strcmp ("tile", p))
15060 result = PRAGMA_OACC_CLAUSE_TILE;
15061 else if (!strcmp ("to", p))
15062 result = PRAGMA_OMP_CLAUSE_TO;
15063 break;
15064 case 'u':
15065 if (!strcmp ("uniform", p))
15066 result = PRAGMA_OMP_CLAUSE_UNIFORM;
15067 else if (!strcmp ("untied", p))
15068 result = PRAGMA_OMP_CLAUSE_UNTIED;
15069 else if (!strcmp ("use_device", p))
15070 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
15071 else if (!strcmp ("use_device_addr", p))
15072 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
15073 else if (!strcmp ("use_device_ptr", p))
15074 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
15075 break;
15076 case 'v':
15077 if (!strcmp ("vector", p))
15078 result = PRAGMA_OACC_CLAUSE_VECTOR;
15079 else if (!strcmp ("vector_length", p))
15080 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
15081 break;
15082 case 'w':
15083 if (!strcmp ("wait", p))
15084 result = PRAGMA_OACC_CLAUSE_WAIT;
15085 else if (!strcmp ("worker", p))
15086 result = PRAGMA_OACC_CLAUSE_WORKER;
15087 break;
15091 if (result != PRAGMA_OMP_CLAUSE_NONE)
15092 c_parser_consume_token (parser);
15094 return result;
15097 /* Validate that a clause of the given type does not already exist. */
15099 static void
15100 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
15101 const char *name)
15103 if (tree c = omp_find_clause (clauses, code))
15104 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
15107 /* OpenACC 2.0
15108 Parse wait clause or wait directive parameters. */
15110 static tree
15111 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
15113 vec<tree, va_gc> *args;
15114 tree t, args_tree;
15116 matching_parens parens;
15117 if (!parens.require_open (parser))
15118 return list;
15120 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
15121 args_tree = build_tree_list_vec (args);
15123 for (t = args_tree; t; t = TREE_CHAIN (t))
15125 tree targ = TREE_VALUE (t);
15127 if (targ != error_mark_node)
15129 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
15131 c_parser_error (parser, "expression must be integral");
15132 targ = error_mark_node;
15134 else
15136 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
15138 OMP_CLAUSE_DECL (c) = targ;
15139 OMP_CLAUSE_CHAIN (c) = list;
15140 list = c;
15145 release_tree_vector (args);
15146 parens.require_close (parser);
15147 return list;
15150 /* OpenACC 2.0, OpenMP 2.5:
15151 variable-list:
15152 identifier
15153 variable-list , identifier
15155 If KIND is nonzero, create the appropriate node and install the
15156 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
15157 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
15159 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
15160 return the list created.
15162 The optional ALLOW_DEREF argument is true if list items can use the deref
15163 (->) operator. */
15165 struct omp_dim
15167 tree low_bound, length;
15168 location_t loc;
15169 bool no_colon;
15170 omp_dim (tree lb, tree len, location_t lo, bool nc)
15171 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
15174 static tree
15175 c_parser_omp_variable_list (c_parser *parser,
15176 location_t clause_loc,
15177 enum omp_clause_code kind, tree list,
15178 bool map_lvalue = false)
15180 auto_vec<omp_dim> dims;
15181 bool array_section_p;
15182 auto_vec<c_token> tokens;
15183 unsigned int tokens_avail = 0;
15184 c_token *saved_tokens = NULL;
15185 bool first = true;
15187 while (1)
15189 tree t = NULL_TREE;
15191 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15193 if (c_parser_next_token_is_not (parser, CPP_NAME)
15194 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15196 struct c_expr expr;
15197 if (kind == OMP_CLAUSE_DEPEND
15198 && c_parser_next_token_is_keyword (parser,
15199 RID_OMP_ALL_MEMORY)
15200 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
15201 || (c_parser_peek_2nd_token (parser)->type
15202 == CPP_CLOSE_PAREN)))
15204 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
15205 c_parser_consume_token (parser);
15207 else
15208 expr = c_parser_expr_no_commas (parser, NULL);
15209 if (expr.value != error_mark_node)
15211 tree u = build_omp_clause (clause_loc, kind);
15212 OMP_CLAUSE_DECL (u) = expr.value;
15213 OMP_CLAUSE_CHAIN (u) = list;
15214 list = u;
15217 if (c_parser_next_token_is_not (parser, CPP_COMMA))
15218 break;
15220 c_parser_consume_token (parser);
15221 first = false;
15222 continue;
15225 tokens.truncate (0);
15226 unsigned int nesting_depth = 0;
15227 while (1)
15229 c_token *token = c_parser_peek_token (parser);
15230 switch (token->type)
15232 case CPP_EOF:
15233 case CPP_PRAGMA_EOL:
15234 break;
15235 case CPP_OPEN_BRACE:
15236 case CPP_OPEN_PAREN:
15237 case CPP_OPEN_SQUARE:
15238 ++nesting_depth;
15239 goto add;
15240 case CPP_CLOSE_BRACE:
15241 case CPP_CLOSE_PAREN:
15242 case CPP_CLOSE_SQUARE:
15243 if (nesting_depth-- == 0)
15244 break;
15245 goto add;
15246 case CPP_COMMA:
15247 if (nesting_depth == 0)
15248 break;
15249 goto add;
15250 default:
15251 add:
15252 tokens.safe_push (*token);
15253 c_parser_consume_token (parser);
15254 continue;
15256 break;
15259 /* Make sure nothing tries to read past the end of the tokens. */
15260 c_token eof_token;
15261 memset (&eof_token, 0, sizeof (eof_token));
15262 eof_token.type = CPP_EOF;
15263 tokens.safe_push (eof_token);
15264 tokens.safe_push (eof_token);
15266 saved_tokens = parser->tokens;
15267 tokens_avail = parser->tokens_avail;
15268 parser->tokens = tokens.address ();
15269 parser->tokens_avail = tokens.length ();
15271 else if (map_lvalue
15272 && (kind == OMP_CLAUSE_MAP
15273 || kind == OMP_CLAUSE_TO
15274 || kind == OMP_CLAUSE_FROM))
15276 location_t loc = c_parser_peek_token (parser)->location;
15277 bool save_c_omp_array_section_p = c_omp_array_section_p;
15278 c_omp_array_section_p = true;
15279 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15280 if (expr.value != error_mark_node)
15281 mark_exp_read (expr.value);
15282 c_omp_array_section_p = save_c_omp_array_section_p;
15283 tree decl = expr.value;
15285 /* This code rewrites a parsed expression containing various tree
15286 codes used to represent array accesses into a more uniform nest of
15287 OMP_ARRAY_SECTION nodes before it is processed by
15288 c-typeck.cc:handle_omp_array_sections_1. It might be more
15289 efficient to move this logic to that function instead, analysing
15290 the parsed expression directly rather than this preprocessed
15291 form. (See also equivalent code in cp/parser.cc,
15292 cp/semantics.cc). */
15293 dims.truncate (0);
15294 if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
15296 while (TREE_CODE (decl) == OMP_ARRAY_SECTION)
15298 tree low_bound = TREE_OPERAND (decl, 1);
15299 tree length = TREE_OPERAND (decl, 2);
15300 dims.safe_push (omp_dim (low_bound, length, loc, false));
15301 decl = TREE_OPERAND (decl, 0);
15304 while (TREE_CODE (decl) == ARRAY_REF
15305 || TREE_CODE (decl) == INDIRECT_REF
15306 || TREE_CODE (decl) == COMPOUND_EXPR)
15308 if (TREE_CODE (decl) == COMPOUND_EXPR)
15310 decl = TREE_OPERAND (decl, 1);
15311 STRIP_NOPS (decl);
15313 else if (TREE_CODE (decl) == INDIRECT_REF)
15315 dims.safe_push (omp_dim (integer_zero_node,
15316 integer_one_node, loc, true));
15317 decl = TREE_OPERAND (decl, 0);
15319 else /* ARRAY_REF. */
15321 tree index = TREE_OPERAND (decl, 1);
15322 dims.safe_push (omp_dim (index, integer_one_node, loc,
15323 true));
15324 decl = TREE_OPERAND (decl, 0);
15328 for (int i = dims.length () - 1; i >= 0; i--)
15329 decl = build_omp_array_section (loc, decl, dims[i].low_bound,
15330 dims[i].length);
15332 else if (TREE_CODE (decl) == INDIRECT_REF)
15334 /* Turn indirection of a pointer "*foo" into "foo[0:1]". */
15335 decl = TREE_OPERAND (decl, 0);
15336 STRIP_NOPS (decl);
15338 decl = build_omp_array_section (loc, decl, integer_zero_node,
15339 integer_one_node);
15341 else if (TREE_CODE (decl) == ARRAY_REF)
15343 tree idx = TREE_OPERAND (decl, 1);
15345 decl = TREE_OPERAND (decl, 0);
15346 STRIP_NOPS (decl);
15348 decl = build_omp_array_section (loc, decl, idx, integer_one_node);
15350 else if (TREE_CODE (decl) == NON_LVALUE_EXPR
15351 || CONVERT_EXPR_P (decl))
15352 decl = TREE_OPERAND (decl, 0);
15354 tree u = build_omp_clause (clause_loc, kind);
15355 OMP_CLAUSE_DECL (u) = decl;
15356 OMP_CLAUSE_CHAIN (u) = list;
15357 list = u;
15359 goto next_item;
15362 if (c_parser_next_token_is (parser, CPP_NAME)
15363 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15365 t = lookup_name (c_parser_peek_token (parser)->value);
15367 if (t == NULL_TREE)
15369 undeclared_variable (c_parser_peek_token (parser)->location,
15370 c_parser_peek_token (parser)->value);
15371 t = error_mark_node;
15374 c_parser_consume_token (parser);
15376 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
15377 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
15378 || (c_parser_peek_token (parser)->keyword
15379 == RID_PRETTY_FUNCTION_NAME)
15380 || (c_parser_peek_token (parser)->keyword
15381 == RID_C99_FUNCTION_NAME)))
15382 t = c_parser_predefined_identifier (parser).value;
15383 else
15385 if (first)
15386 c_parser_error (parser, "expected identifier");
15387 break;
15390 if (t == error_mark_node)
15392 else if (kind != 0)
15394 switch (kind)
15396 case OMP_CLAUSE__CACHE_:
15397 /* The OpenACC cache directive explicitly only allows "array
15398 elements or subarrays". */
15399 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
15401 c_parser_error (parser, "expected %<[%>");
15402 t = error_mark_node;
15403 break;
15405 /* FALLTHROUGH */
15406 case OMP_CLAUSE_MAP:
15407 case OMP_CLAUSE_FROM:
15408 case OMP_CLAUSE_TO:
15409 start_component_ref:
15410 while (c_parser_next_token_is (parser, CPP_DOT)
15411 || c_parser_next_token_is (parser, CPP_DEREF))
15413 location_t op_loc = c_parser_peek_token (parser)->location;
15414 location_t arrow_loc = UNKNOWN_LOCATION;
15415 if (c_parser_next_token_is (parser, CPP_DEREF))
15417 c_expr t_expr;
15418 t_expr.value = t;
15419 t_expr.original_code = ERROR_MARK;
15420 t_expr.original_type = NULL;
15421 set_c_expr_source_range (&t_expr, op_loc, op_loc);
15422 t_expr.m_decimal = 0;
15423 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
15424 true, false);
15425 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
15426 arrow_loc = t_expr.get_location ();
15428 c_parser_consume_token (parser);
15429 if (!c_parser_next_token_is (parser, CPP_NAME))
15431 c_parser_error (parser, "expected identifier");
15432 t = error_mark_node;
15433 break;
15436 c_token *comp_tok = c_parser_peek_token (parser);
15437 tree ident = comp_tok->value;
15438 location_t comp_loc = comp_tok->location;
15439 c_parser_consume_token (parser);
15440 t = build_component_ref (op_loc, t, ident, comp_loc,
15441 arrow_loc);
15443 /* FALLTHROUGH */
15444 case OMP_CLAUSE_AFFINITY:
15445 case OMP_CLAUSE_DEPEND:
15446 case OMP_CLAUSE_REDUCTION:
15447 case OMP_CLAUSE_IN_REDUCTION:
15448 case OMP_CLAUSE_TASK_REDUCTION:
15449 case OMP_CLAUSE_HAS_DEVICE_ADDR:
15450 array_section_p = false;
15451 dims.truncate (0);
15452 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
15454 location_t loc = UNKNOWN_LOCATION;
15455 tree low_bound = NULL_TREE, length = NULL_TREE;
15456 bool no_colon = false;
15458 c_parser_consume_token (parser);
15459 if (!c_parser_next_token_is (parser, CPP_COLON))
15461 location_t expr_loc
15462 = c_parser_peek_token (parser)->location;
15463 c_expr expr = c_parser_expression (parser);
15464 expr = convert_lvalue_to_rvalue (expr_loc, expr,
15465 false, true);
15466 low_bound = expr.value;
15467 loc = expr_loc;
15469 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
15471 length = integer_one_node;
15472 no_colon = true;
15474 else
15476 /* Look for `:'. */
15477 if (!c_parser_require (parser, CPP_COLON,
15478 "expected %<:%>"))
15480 t = error_mark_node;
15481 break;
15483 array_section_p = true;
15484 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
15486 location_t expr_loc
15487 = c_parser_peek_token (parser)->location;
15488 c_expr expr = c_parser_expression (parser);
15489 expr = convert_lvalue_to_rvalue (expr_loc, expr,
15490 false, true);
15491 length = expr.value;
15494 /* Look for the closing `]'. */
15495 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
15496 "expected %<]%>"))
15498 t = error_mark_node;
15499 break;
15502 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
15505 if (t != error_mark_node)
15507 if ((kind == OMP_CLAUSE_MAP
15508 || kind == OMP_CLAUSE_FROM
15509 || kind == OMP_CLAUSE_TO)
15510 && !array_section_p
15511 && (c_parser_next_token_is (parser, CPP_DOT)
15512 || c_parser_next_token_is (parser, CPP_DEREF)))
15514 for (unsigned i = 0; i < dims.length (); i++)
15516 gcc_assert (dims[i].length == integer_one_node);
15517 t = build_array_ref (dims[i].loc,
15518 t, dims[i].low_bound);
15520 goto start_component_ref;
15522 else
15523 for (unsigned i = 0; i < dims.length (); i++)
15524 t = build_omp_array_section (clause_loc, t,
15525 dims[i].low_bound,
15526 dims[i].length);
15529 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15530 && t != error_mark_node
15531 && parser->tokens_avail != 2)
15533 if (array_section_p)
15535 error_at (c_parser_peek_token (parser)->location,
15536 "expected %<)%> or %<,%>");
15537 t = error_mark_node;
15539 else
15541 parser->tokens = tokens.address ();
15542 parser->tokens_avail = tokens.length ();
15544 t = c_parser_expr_no_commas (parser, NULL).value;
15545 if (t != error_mark_node && parser->tokens_avail != 2)
15547 error_at (c_parser_peek_token (parser)->location,
15548 "expected %<)%> or %<,%>");
15549 t = error_mark_node;
15553 break;
15554 default:
15555 break;
15558 if (t != error_mark_node)
15560 tree u = build_omp_clause (clause_loc, kind);
15561 OMP_CLAUSE_DECL (u) = t;
15562 OMP_CLAUSE_CHAIN (u) = list;
15563 list = u;
15566 else
15567 list = tree_cons (t, NULL_TREE, list);
15569 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15571 parser->tokens = saved_tokens;
15572 parser->tokens_avail = tokens_avail;
15575 next_item:
15576 if (c_parser_next_token_is_not (parser, CPP_COMMA))
15577 break;
15579 c_parser_consume_token (parser);
15580 first = false;
15583 return list;
15586 /* Similarly, but expect leading and trailing parenthesis. This is a very
15587 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
15588 argument is true if list items can use the deref (->) operator. */
15590 static tree
15591 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
15592 tree list, bool map_lvalue = false)
15594 /* The clauses location. */
15595 location_t loc = c_parser_peek_token (parser)->location;
15597 if (parser->in_omp_decl_attribute)
15599 if (kind)
15601 tree u = build_omp_clause (loc, kind);
15602 OMP_CLAUSE_DECL (u) = parser->in_omp_decl_attribute;
15603 OMP_CLAUSE_CHAIN (u) = list;
15604 return u;
15606 else
15607 return tree_cons (parser->in_omp_decl_attribute, NULL_TREE, list);
15610 matching_parens parens;
15611 if (parens.require_open (parser))
15613 list = c_parser_omp_variable_list (parser, loc, kind, list, map_lvalue);
15614 parens.skip_until_found_close (parser);
15616 return list;
15619 /* OpenACC 2.0:
15620 copy ( variable-list )
15621 copyin ( variable-list )
15622 copyout ( variable-list )
15623 create ( variable-list )
15624 delete ( variable-list )
15625 present ( variable-list )
15627 OpenACC 2.6:
15628 no_create ( variable-list )
15629 attach ( variable-list )
15630 detach ( variable-list ) */
15632 static tree
15633 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
15634 tree list)
15636 enum gomp_map_kind kind;
15637 switch (c_kind)
15639 case PRAGMA_OACC_CLAUSE_ATTACH:
15640 kind = GOMP_MAP_ATTACH;
15641 break;
15642 case PRAGMA_OACC_CLAUSE_COPY:
15643 kind = GOMP_MAP_TOFROM;
15644 break;
15645 case PRAGMA_OACC_CLAUSE_COPYIN:
15646 kind = GOMP_MAP_TO;
15647 break;
15648 case PRAGMA_OACC_CLAUSE_COPYOUT:
15649 kind = GOMP_MAP_FROM;
15650 break;
15651 case PRAGMA_OACC_CLAUSE_CREATE:
15652 kind = GOMP_MAP_ALLOC;
15653 break;
15654 case PRAGMA_OACC_CLAUSE_DELETE:
15655 kind = GOMP_MAP_RELEASE;
15656 break;
15657 case PRAGMA_OACC_CLAUSE_DETACH:
15658 kind = GOMP_MAP_DETACH;
15659 break;
15660 case PRAGMA_OACC_CLAUSE_DEVICE:
15661 kind = GOMP_MAP_FORCE_TO;
15662 break;
15663 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
15664 kind = GOMP_MAP_DEVICE_RESIDENT;
15665 break;
15666 case PRAGMA_OACC_CLAUSE_LINK:
15667 kind = GOMP_MAP_LINK;
15668 break;
15669 case PRAGMA_OACC_CLAUSE_NO_CREATE:
15670 kind = GOMP_MAP_IF_PRESENT;
15671 break;
15672 case PRAGMA_OACC_CLAUSE_PRESENT:
15673 kind = GOMP_MAP_FORCE_PRESENT;
15674 break;
15675 case PRAGMA_OACC_CLAUSE_SELF:
15676 /* "The 'host' clause is a synonym for the 'self' clause." */
15677 case PRAGMA_OACC_CLAUSE_HOST:
15678 kind = GOMP_MAP_FORCE_FROM;
15679 break;
15680 default:
15681 gcc_unreachable ();
15683 tree nl, c;
15684 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, false);
15686 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15687 OMP_CLAUSE_SET_MAP_KIND (c, kind);
15689 return nl;
15692 /* OpenACC 2.0:
15693 deviceptr ( variable-list ) */
15695 static tree
15696 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
15698 location_t loc = c_parser_peek_token (parser)->location;
15699 tree vars, t;
15701 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
15702 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
15703 variable-list must only allow for pointer variables. */
15704 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
15705 for (t = vars; t && t; t = TREE_CHAIN (t))
15707 tree v = TREE_PURPOSE (t);
15709 /* FIXME diagnostics: Ideally we should keep individual
15710 locations for all the variables in the var list to make the
15711 following errors more precise. Perhaps
15712 c_parser_omp_var_list_parens() should construct a list of
15713 locations to go along with the var list. */
15715 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
15716 error_at (loc, "%qD is not a variable", v);
15717 else if (TREE_TYPE (v) == error_mark_node)
15719 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
15720 error_at (loc, "%qD is not a pointer variable", v);
15722 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
15723 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
15724 OMP_CLAUSE_DECL (u) = v;
15725 OMP_CLAUSE_CHAIN (u) = list;
15726 list = u;
15729 return list;
15732 /* OpenACC 2.0, OpenMP 3.0:
15733 collapse ( constant-expression ) */
15735 static tree
15736 c_parser_omp_clause_collapse (c_parser *parser, tree list)
15738 tree c, num = error_mark_node;
15739 HOST_WIDE_INT n;
15740 location_t loc;
15742 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
15743 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
15745 loc = c_parser_peek_token (parser)->location;
15746 matching_parens parens;
15747 if (parens.require_open (parser))
15749 num = c_parser_expr_no_commas (parser, NULL).value;
15750 parens.skip_until_found_close (parser);
15752 if (num == error_mark_node)
15753 return list;
15754 mark_exp_read (num);
15755 num = c_fully_fold (num, false, NULL);
15756 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
15757 || !tree_fits_shwi_p (num)
15758 || (n = tree_to_shwi (num)) <= 0
15759 || (int) n != n)
15761 error_at (loc,
15762 "collapse argument needs positive constant integer expression");
15763 return list;
15765 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
15766 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
15767 OMP_CLAUSE_CHAIN (c) = list;
15768 return c;
15771 /* OpenMP 2.5:
15772 copyin ( variable-list ) */
15774 static tree
15775 c_parser_omp_clause_copyin (c_parser *parser, tree list)
15777 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
15780 /* OpenMP 2.5:
15781 copyprivate ( variable-list ) */
15783 static tree
15784 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
15786 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
15789 /* OpenMP 2.5:
15790 default ( none | shared )
15792 OpenMP 5.1:
15793 default ( private | firstprivate )
15795 OpenACC:
15796 default ( none | present ) */
15798 static tree
15799 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
15801 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
15802 location_t loc = c_parser_peek_token (parser)->location;
15803 tree c;
15805 matching_parens parens;
15806 if (!parens.require_open (parser))
15807 return list;
15808 if (c_parser_next_token_is (parser, CPP_NAME))
15810 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15812 switch (p[0])
15814 case 'n':
15815 if (strcmp ("none", p) != 0)
15816 goto invalid_kind;
15817 kind = OMP_CLAUSE_DEFAULT_NONE;
15818 break;
15820 case 'p':
15821 if (is_oacc)
15823 if (strcmp ("present", p) != 0)
15824 goto invalid_kind;
15825 kind = OMP_CLAUSE_DEFAULT_PRESENT;
15827 else
15829 if (strcmp ("private", p) != 0)
15830 goto invalid_kind;
15831 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
15833 break;
15835 case 'f':
15836 if (strcmp ("firstprivate", p) != 0 || is_oacc)
15837 goto invalid_kind;
15838 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
15839 break;
15841 case 's':
15842 if (strcmp ("shared", p) != 0 || is_oacc)
15843 goto invalid_kind;
15844 kind = OMP_CLAUSE_DEFAULT_SHARED;
15845 break;
15847 default:
15848 goto invalid_kind;
15851 c_parser_consume_token (parser);
15853 else
15855 invalid_kind:
15856 if (is_oacc)
15857 c_parser_error (parser, "expected %<none%> or %<present%>");
15858 else
15859 c_parser_error (parser, "expected %<none%>, %<shared%>, "
15860 "%<private%> or %<firstprivate%>");
15862 parens.skip_until_found_close (parser);
15864 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
15865 return list;
15867 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
15868 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
15869 OMP_CLAUSE_CHAIN (c) = list;
15870 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
15872 return c;
15875 /* OpenMP 2.5:
15876 firstprivate ( variable-list ) */
15878 static tree
15879 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
15881 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
15884 /* OpenMP 3.1:
15885 final ( expression ) */
15887 static tree
15888 c_parser_omp_clause_final (c_parser *parser, tree list)
15890 location_t loc = c_parser_peek_token (parser)->location;
15891 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
15893 matching_parens parens;
15894 tree t, c;
15895 if (!parens.require_open (parser))
15896 t = error_mark_node;
15897 else
15899 location_t eloc = c_parser_peek_token (parser)->location;
15900 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15901 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
15902 t = c_objc_common_truthvalue_conversion (eloc, t);
15903 t = c_fully_fold (t, false, NULL);
15904 parens.skip_until_found_close (parser);
15907 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
15909 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
15910 OMP_CLAUSE_FINAL_EXPR (c) = t;
15911 OMP_CLAUSE_CHAIN (c) = list;
15912 list = c;
15914 else
15915 c_parser_error (parser, "expected %<(%>");
15917 return list;
15920 /* OpenMP 5.1:
15921 indirect [( expression )]
15924 static tree
15925 c_parser_omp_clause_indirect (c_parser *parser, tree list)
15927 location_t location = c_parser_peek_token (parser)->location;
15928 tree t;
15930 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
15932 matching_parens parens;
15933 if (!parens.require_open (parser))
15934 return list;
15936 location_t loc = c_parser_peek_token (parser)->location;
15937 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15938 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
15939 t = c_objc_common_truthvalue_conversion (loc, expr.value);
15940 t = c_fully_fold (t, false, NULL);
15941 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
15942 || TREE_CODE (t) != INTEGER_CST)
15944 c_parser_error (parser, "expected constant logical expression");
15945 return list;
15947 parens.skip_until_found_close (parser);
15949 else
15950 t = integer_one_node;
15952 check_no_duplicate_clause (list, OMP_CLAUSE_INDIRECT, "indirect");
15954 tree c = build_omp_clause (location, OMP_CLAUSE_INDIRECT);
15955 OMP_CLAUSE_INDIRECT_EXPR (c) = t;
15956 OMP_CLAUSE_CHAIN (c) = list;
15958 return c;
15961 /* OpenACC, OpenMP 2.5:
15962 if ( expression )
15964 OpenMP 4.5:
15965 if ( directive-name-modifier : expression )
15967 directive-name-modifier:
15968 parallel | task | taskloop | target data | target | target update
15969 | target enter data | target exit data
15971 OpenMP 5.0:
15972 directive-name-modifier:
15973 ... | simd | cancel */
15975 static tree
15976 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
15978 location_t location = c_parser_peek_token (parser)->location;
15979 enum tree_code if_modifier = ERROR_MARK;
15981 matching_parens parens;
15982 if (!parens.require_open (parser))
15983 return list;
15985 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
15987 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15988 int n = 2;
15989 if (strcmp (p, "cancel") == 0)
15990 if_modifier = VOID_CST;
15991 else if (strcmp (p, "parallel") == 0)
15992 if_modifier = OMP_PARALLEL;
15993 else if (strcmp (p, "simd") == 0)
15994 if_modifier = OMP_SIMD;
15995 else if (strcmp (p, "task") == 0)
15996 if_modifier = OMP_TASK;
15997 else if (strcmp (p, "taskloop") == 0)
15998 if_modifier = OMP_TASKLOOP;
15999 else if (strcmp (p, "target") == 0)
16001 if_modifier = OMP_TARGET;
16002 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
16004 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
16005 if (strcmp ("data", p) == 0)
16006 if_modifier = OMP_TARGET_DATA;
16007 else if (strcmp ("update", p) == 0)
16008 if_modifier = OMP_TARGET_UPDATE;
16009 else if (strcmp ("enter", p) == 0)
16010 if_modifier = OMP_TARGET_ENTER_DATA;
16011 else if (strcmp ("exit", p) == 0)
16012 if_modifier = OMP_TARGET_EXIT_DATA;
16013 if (if_modifier != OMP_TARGET)
16015 n = 3;
16016 c_parser_consume_token (parser);
16018 else
16020 location_t loc = c_parser_peek_2nd_token (parser)->location;
16021 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
16022 "or %<exit%>");
16023 if_modifier = ERROR_MARK;
16025 if (if_modifier == OMP_TARGET_ENTER_DATA
16026 || if_modifier == OMP_TARGET_EXIT_DATA)
16028 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
16030 p = IDENTIFIER_POINTER
16031 (c_parser_peek_2nd_token (parser)->value);
16032 if (strcmp ("data", p) == 0)
16033 n = 4;
16035 if (n == 4)
16036 c_parser_consume_token (parser);
16037 else
16039 location_t loc
16040 = c_parser_peek_2nd_token (parser)->location;
16041 error_at (loc, "expected %<data%>");
16042 if_modifier = ERROR_MARK;
16047 if (if_modifier != ERROR_MARK)
16049 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16051 c_parser_consume_token (parser);
16052 c_parser_consume_token (parser);
16054 else
16056 if (n > 2)
16058 location_t loc = c_parser_peek_2nd_token (parser)->location;
16059 error_at (loc, "expected %<:%>");
16061 if_modifier = ERROR_MARK;
16066 location_t loc = c_parser_peek_token (parser)->location;
16067 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16068 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
16069 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
16070 t = c_fully_fold (t, false, NULL);
16071 parens.skip_until_found_close (parser);
16073 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
16074 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
16076 if (if_modifier != ERROR_MARK
16077 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
16079 const char *p = NULL;
16080 switch (if_modifier)
16082 case VOID_CST: p = "cancel"; break;
16083 case OMP_PARALLEL: p = "parallel"; break;
16084 case OMP_SIMD: p = "simd"; break;
16085 case OMP_TASK: p = "task"; break;
16086 case OMP_TASKLOOP: p = "taskloop"; break;
16087 case OMP_TARGET_DATA: p = "target data"; break;
16088 case OMP_TARGET: p = "target"; break;
16089 case OMP_TARGET_UPDATE: p = "target update"; break;
16090 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
16091 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
16092 default: gcc_unreachable ();
16094 error_at (location, "too many %<if%> clauses with %qs modifier",
16096 return list;
16098 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
16100 if (!is_omp)
16101 error_at (location, "too many %<if%> clauses");
16102 else
16103 error_at (location, "too many %<if%> clauses without modifier");
16104 return list;
16106 else if (if_modifier == ERROR_MARK
16107 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
16109 error_at (location, "if any %<if%> clause has modifier, then all "
16110 "%<if%> clauses have to use modifier");
16111 return list;
16115 c = build_omp_clause (location, OMP_CLAUSE_IF);
16116 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
16117 OMP_CLAUSE_IF_EXPR (c) = t;
16118 OMP_CLAUSE_CHAIN (c) = list;
16119 return c;
16122 /* OpenMP 2.5:
16123 lastprivate ( variable-list )
16125 OpenMP 5.0:
16126 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
16128 static tree
16129 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
16131 /* The clauses location. */
16132 location_t loc = c_parser_peek_token (parser)->location;
16134 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
16136 bool conditional = false;
16137 if (c_parser_next_token_is (parser, CPP_NAME)
16138 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16140 const char *p
16141 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16142 if (strcmp (p, "conditional") == 0)
16144 conditional = true;
16145 c_parser_consume_token (parser);
16146 c_parser_consume_token (parser);
16149 tree nlist = c_parser_omp_variable_list (parser, loc,
16150 OMP_CLAUSE_LASTPRIVATE, list);
16151 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
16152 if (conditional)
16153 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
16154 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
16155 return nlist;
16157 return list;
16160 /* OpenMP 3.1:
16161 mergeable */
16163 static tree
16164 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
16166 tree c;
16168 /* FIXME: Should we allow duplicates? */
16169 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
16171 c = build_omp_clause (c_parser_peek_token (parser)->location,
16172 OMP_CLAUSE_MERGEABLE);
16173 OMP_CLAUSE_CHAIN (c) = list;
16175 return c;
16178 /* OpenMP 2.5:
16179 nowait */
16181 static tree
16182 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
16184 tree c;
16185 location_t loc = c_parser_peek_token (parser)->location;
16187 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
16189 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
16190 OMP_CLAUSE_CHAIN (c) = list;
16191 return c;
16194 /* OpenMP 2.5:
16195 num_threads ( expression ) */
16197 static tree
16198 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
16200 location_t num_threads_loc = c_parser_peek_token (parser)->location;
16201 matching_parens parens;
16202 if (parens.require_open (parser))
16204 location_t expr_loc = c_parser_peek_token (parser)->location;
16205 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16206 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16207 tree c, t = expr.value;
16208 t = c_fully_fold (t, false, NULL);
16210 parens.skip_until_found_close (parser);
16212 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16214 c_parser_error (parser, "expected integer expression");
16215 return list;
16218 /* Attempt to statically determine when the number isn't positive. */
16219 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16220 build_int_cst (TREE_TYPE (t), 0));
16221 protected_set_expr_location (c, expr_loc);
16222 if (c == boolean_true_node)
16224 warning_at (expr_loc, OPT_Wopenmp,
16225 "%<num_threads%> value must be positive");
16226 t = integer_one_node;
16229 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
16231 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
16232 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
16233 OMP_CLAUSE_CHAIN (c) = list;
16234 list = c;
16237 return list;
16240 /* OpenMP 4.5:
16241 num_tasks ( expression )
16243 OpenMP 5.1:
16244 num_tasks ( strict : expression ) */
16246 static tree
16247 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
16249 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
16250 matching_parens parens;
16251 if (parens.require_open (parser))
16253 bool strict = false;
16254 if (c_parser_next_token_is (parser, CPP_NAME)
16255 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
16256 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16257 "strict") == 0)
16259 strict = true;
16260 c_parser_consume_token (parser);
16261 c_parser_consume_token (parser);
16264 location_t expr_loc = c_parser_peek_token (parser)->location;
16265 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16266 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16267 tree c, t = expr.value;
16268 t = c_fully_fold (t, false, NULL);
16270 parens.skip_until_found_close (parser);
16272 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16274 c_parser_error (parser, "expected integer expression");
16275 return list;
16278 /* Attempt to statically determine when the number isn't positive. */
16279 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16280 build_int_cst (TREE_TYPE (t), 0));
16281 if (CAN_HAVE_LOCATION_P (c))
16282 SET_EXPR_LOCATION (c, expr_loc);
16283 if (c == boolean_true_node)
16285 warning_at (expr_loc, OPT_Wopenmp,
16286 "%<num_tasks%> value must be positive");
16287 t = integer_one_node;
16290 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
16292 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
16293 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
16294 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
16295 OMP_CLAUSE_CHAIN (c) = list;
16296 list = c;
16299 return list;
16302 /* OpenMP 4.5:
16303 grainsize ( expression )
16305 OpenMP 5.1:
16306 grainsize ( strict : expression ) */
16308 static tree
16309 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
16311 location_t grainsize_loc = c_parser_peek_token (parser)->location;
16312 matching_parens parens;
16313 if (parens.require_open (parser))
16315 bool strict = false;
16316 if (c_parser_next_token_is (parser, CPP_NAME)
16317 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
16318 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16319 "strict") == 0)
16321 strict = true;
16322 c_parser_consume_token (parser);
16323 c_parser_consume_token (parser);
16326 location_t expr_loc = c_parser_peek_token (parser)->location;
16327 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16328 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16329 tree c, t = expr.value;
16330 t = c_fully_fold (t, false, NULL);
16332 parens.skip_until_found_close (parser);
16334 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16336 c_parser_error (parser, "expected integer expression");
16337 return list;
16340 /* Attempt to statically determine when the number isn't positive. */
16341 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16342 build_int_cst (TREE_TYPE (t), 0));
16343 if (CAN_HAVE_LOCATION_P (c))
16344 SET_EXPR_LOCATION (c, expr_loc);
16345 if (c == boolean_true_node)
16347 warning_at (expr_loc, OPT_Wopenmp,
16348 "%<grainsize%> value must be positive");
16349 t = integer_one_node;
16352 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
16354 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
16355 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
16356 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
16357 OMP_CLAUSE_CHAIN (c) = list;
16358 list = c;
16361 return list;
16364 /* OpenMP 4.5:
16365 priority ( expression ) */
16367 static tree
16368 c_parser_omp_clause_priority (c_parser *parser, tree list)
16370 location_t priority_loc = c_parser_peek_token (parser)->location;
16371 matching_parens parens;
16372 if (parens.require_open (parser))
16374 location_t expr_loc = c_parser_peek_token (parser)->location;
16375 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16376 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16377 tree c, t = expr.value;
16378 t = c_fully_fold (t, false, NULL);
16380 parens.skip_until_found_close (parser);
16382 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16384 c_parser_error (parser, "expected integer expression");
16385 return list;
16388 /* Attempt to statically determine when the number isn't
16389 non-negative. */
16390 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
16391 build_int_cst (TREE_TYPE (t), 0));
16392 if (CAN_HAVE_LOCATION_P (c))
16393 SET_EXPR_LOCATION (c, expr_loc);
16394 if (c == boolean_true_node)
16396 warning_at (expr_loc, OPT_Wopenmp,
16397 "%<priority%> value must be non-negative");
16398 t = integer_one_node;
16401 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
16403 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
16404 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
16405 OMP_CLAUSE_CHAIN (c) = list;
16406 list = c;
16409 return list;
16412 /* OpenMP 4.5:
16413 hint ( expression ) */
16415 static tree
16416 c_parser_omp_clause_hint (c_parser *parser, tree list)
16418 location_t hint_loc = c_parser_peek_token (parser)->location;
16419 matching_parens parens;
16420 if (parens.require_open (parser))
16422 location_t expr_loc = c_parser_peek_token (parser)->location;
16423 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16424 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16425 tree c, t = expr.value;
16426 t = c_fully_fold (t, false, NULL);
16427 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
16428 || TREE_CODE (t) != INTEGER_CST
16429 || tree_int_cst_sgn (t) == -1)
16431 c_parser_error (parser, "expected constant integer expression "
16432 "with valid sync-hint value");
16433 return list;
16435 parens.skip_until_found_close (parser);
16436 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
16438 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
16439 OMP_CLAUSE_HINT_EXPR (c) = t;
16440 OMP_CLAUSE_CHAIN (c) = list;
16441 list = c;
16444 return list;
16447 /* OpenMP 5.1:
16448 filter ( integer-expression ) */
16450 static tree
16451 c_parser_omp_clause_filter (c_parser *parser, tree list)
16453 location_t hint_loc = c_parser_peek_token (parser)->location;
16454 matching_parens parens;
16455 if (parens.require_open (parser))
16457 location_t expr_loc = c_parser_peek_token (parser)->location;
16458 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16459 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16460 tree c, t = expr.value;
16461 t = c_fully_fold (t, false, NULL);
16462 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16464 c_parser_error (parser, "expected integer expression");
16465 return list;
16467 parens.skip_until_found_close (parser);
16468 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
16470 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
16471 OMP_CLAUSE_FILTER_EXPR (c) = t;
16472 OMP_CLAUSE_CHAIN (c) = list;
16473 list = c;
16476 return list;
16479 /* OpenMP 4.5:
16480 defaultmap ( tofrom : scalar )
16482 OpenMP 5.0:
16483 defaultmap ( implicit-behavior [ : variable-category ] ) */
16485 static tree
16486 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
16488 location_t loc = c_parser_peek_token (parser)->location;
16489 tree c;
16490 const char *p;
16491 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
16492 enum omp_clause_defaultmap_kind category
16493 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
16495 matching_parens parens;
16496 if (!parens.require_open (parser))
16497 return list;
16498 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
16499 p = "default";
16500 else if (!c_parser_next_token_is (parser, CPP_NAME))
16502 invalid_behavior:
16503 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
16504 "%<tofrom%>, %<firstprivate%>, %<none%> "
16505 "or %<default%>");
16506 goto out_err;
16508 else
16509 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16511 switch (p[0])
16513 case 'a':
16514 if (strcmp ("alloc", p) == 0)
16515 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
16516 else
16517 goto invalid_behavior;
16518 break;
16520 case 'd':
16521 if (strcmp ("default", p) == 0)
16522 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
16523 else
16524 goto invalid_behavior;
16525 break;
16527 case 'f':
16528 if (strcmp ("firstprivate", p) == 0)
16529 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
16530 else if (strcmp ("from", p) == 0)
16531 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
16532 else
16533 goto invalid_behavior;
16534 break;
16536 case 'n':
16537 if (strcmp ("none", p) == 0)
16538 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
16539 else
16540 goto invalid_behavior;
16541 break;
16543 case 'p':
16544 if (strcmp ("present", p) == 0)
16545 behavior = OMP_CLAUSE_DEFAULTMAP_PRESENT;
16546 else
16547 goto invalid_behavior;
16548 break;
16550 case 't':
16551 if (strcmp ("tofrom", p) == 0)
16552 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
16553 else if (strcmp ("to", p) == 0)
16554 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
16555 else
16556 goto invalid_behavior;
16557 break;
16559 default:
16560 goto invalid_behavior;
16562 c_parser_consume_token (parser);
16564 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16566 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16567 goto out_err;
16568 if (!c_parser_next_token_is (parser, CPP_NAME))
16570 invalid_category:
16571 c_parser_error (parser, "expected %<scalar%>, %<aggregate%>, "
16572 "%<pointer%> or %<all%>");
16573 goto out_err;
16575 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16576 switch (p[0])
16578 case 'a':
16579 if (strcmp ("aggregate", p) == 0)
16580 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
16581 else if (strcmp ("all", p) == 0)
16582 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
16583 else
16584 goto invalid_category;
16585 break;
16587 case 'p':
16588 if (strcmp ("pointer", p) == 0)
16589 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
16590 else
16591 goto invalid_category;
16592 break;
16594 case 's':
16595 if (strcmp ("scalar", p) == 0)
16596 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
16597 else
16598 goto invalid_category;
16599 break;
16601 default:
16602 goto invalid_category;
16605 c_parser_consume_token (parser);
16607 parens.skip_until_found_close (parser);
16609 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
16610 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
16611 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16612 || category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16613 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
16614 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16615 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
16616 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16617 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL)))
16619 enum omp_clause_defaultmap_kind cat = category;
16620 location_t loc = OMP_CLAUSE_LOCATION (c);
16621 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16622 || (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16623 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16624 != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
16625 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
16626 p = NULL;
16627 switch (cat)
16629 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
16630 p = NULL;
16631 break;
16632 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
16633 p = "all";
16634 break;
16635 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
16636 p = "aggregate";
16637 break;
16638 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
16639 p = "pointer";
16640 break;
16641 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
16642 p = "scalar";
16643 break;
16644 default:
16645 gcc_unreachable ();
16647 if (p)
16648 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
16650 else
16651 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
16652 "category");
16653 break;
16656 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
16657 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
16658 OMP_CLAUSE_CHAIN (c) = list;
16659 return c;
16661 out_err:
16662 parens.skip_until_found_close (parser);
16663 return list;
16666 /* OpenACC 2.0:
16667 use_device ( variable-list )
16669 OpenMP 4.5:
16670 use_device_ptr ( variable-list ) */
16672 static tree
16673 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
16675 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
16676 list);
16679 /* OpenMP 5.0:
16680 use_device_addr ( variable-list ) */
16682 static tree
16683 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
16685 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
16686 list);
16689 /* OpenMP 5.1:
16690 has_device_addr ( variable-list ) */
16692 static tree
16693 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
16695 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
16696 list);
16699 /* OpenMP 4.5:
16700 is_device_ptr ( variable-list ) */
16702 static tree
16703 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
16705 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
16708 /* OpenACC:
16709 num_gangs ( expression )
16710 num_workers ( expression )
16711 vector_length ( expression ) */
16713 static tree
16714 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
16715 tree list)
16717 location_t loc = c_parser_peek_token (parser)->location;
16719 matching_parens parens;
16720 if (!parens.require_open (parser))
16721 return list;
16723 location_t expr_loc = c_parser_peek_token (parser)->location;
16724 c_expr expr = c_parser_expression (parser);
16725 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16726 tree c, t = expr.value;
16727 t = c_fully_fold (t, false, NULL);
16729 parens.skip_until_found_close (parser);
16731 if (t == error_mark_node)
16732 return list;
16733 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16735 error_at (expr_loc, "%qs expression must be integral",
16736 omp_clause_code_name[code]);
16737 return list;
16740 /* Attempt to statically determine when the number isn't positive. */
16741 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16742 build_int_cst (TREE_TYPE (t), 0));
16743 protected_set_expr_location (c, expr_loc);
16744 if (c == boolean_true_node)
16746 warning_at (expr_loc, 0,
16747 "%qs value must be positive",
16748 omp_clause_code_name[code]);
16749 t = integer_one_node;
16752 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
16754 c = build_omp_clause (loc, code);
16755 OMP_CLAUSE_OPERAND (c, 0) = t;
16756 OMP_CLAUSE_CHAIN (c) = list;
16757 return c;
16760 /* OpenACC:
16762 gang [( gang-arg-list )]
16763 worker [( [num:] int-expr )]
16764 vector [( [length:] int-expr )]
16766 where gang-arg is one of:
16768 [num:] int-expr
16769 static: size-expr
16771 and size-expr may be:
16774 int-expr
16777 static tree
16778 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
16779 omp_clause_code kind,
16780 const char *str, tree list)
16782 const char *id = "num";
16783 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
16785 if (kind == OMP_CLAUSE_VECTOR)
16786 id = "length";
16788 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
16790 c_parser_consume_token (parser);
16794 c_token *next = c_parser_peek_token (parser);
16795 int idx = 0;
16797 /* Gang static argument. */
16798 if (kind == OMP_CLAUSE_GANG
16799 && c_parser_next_token_is_keyword (parser, RID_STATIC))
16801 c_parser_consume_token (parser);
16803 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16804 goto cleanup_error;
16806 idx = 1;
16807 if (ops[idx] != NULL_TREE)
16809 c_parser_error (parser, "too many %<static%> arguments");
16810 goto cleanup_error;
16813 /* Check for the '*' argument. */
16814 if (c_parser_next_token_is (parser, CPP_MULT)
16815 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
16816 || c_parser_peek_2nd_token (parser)->type
16817 == CPP_CLOSE_PAREN))
16819 c_parser_consume_token (parser);
16820 ops[idx] = integer_minus_one_node;
16822 if (c_parser_next_token_is (parser, CPP_COMMA))
16824 c_parser_consume_token (parser);
16825 continue;
16827 else
16828 break;
16831 /* Worker num: argument and vector length: arguments. */
16832 else if (c_parser_next_token_is (parser, CPP_NAME)
16833 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
16834 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16836 c_parser_consume_token (parser); /* id */
16837 c_parser_consume_token (parser); /* ':' */
16840 /* Now collect the actual argument. */
16841 if (ops[idx] != NULL_TREE)
16843 c_parser_error (parser, "unexpected argument");
16844 goto cleanup_error;
16847 location_t expr_loc = c_parser_peek_token (parser)->location;
16848 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
16849 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
16850 tree expr = cexpr.value;
16851 if (expr == error_mark_node)
16852 goto cleanup_error;
16854 expr = c_fully_fold (expr, false, NULL);
16856 /* Attempt to statically determine when the number isn't a
16857 positive integer. */
16859 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
16861 c_parser_error (parser, "expected integer expression");
16862 return list;
16865 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
16866 build_int_cst (TREE_TYPE (expr), 0));
16867 if (c == boolean_true_node)
16869 warning_at (loc, 0,
16870 "%qs value must be positive", str);
16871 expr = integer_one_node;
16874 ops[idx] = expr;
16876 if (kind == OMP_CLAUSE_GANG
16877 && c_parser_next_token_is (parser, CPP_COMMA))
16879 c_parser_consume_token (parser);
16880 continue;
16882 break;
16884 while (1);
16886 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
16887 goto cleanup_error;
16890 check_no_duplicate_clause (list, kind, str);
16892 c = build_omp_clause (loc, kind);
16894 if (ops[1])
16895 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
16897 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
16898 OMP_CLAUSE_CHAIN (c) = list;
16900 return c;
16902 cleanup_error:
16903 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
16904 return list;
16907 /* OpenACC 2.5:
16908 auto
16909 finalize
16910 independent
16911 nohost
16912 seq */
16914 static tree
16915 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
16916 tree list)
16918 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
16920 tree c = build_omp_clause (loc, code);
16921 OMP_CLAUSE_CHAIN (c) = list;
16923 return c;
16926 /* OpenACC:
16927 async [( int-expr )] */
16929 static tree
16930 c_parser_oacc_clause_async (c_parser *parser, tree list)
16932 tree c, t;
16933 location_t loc = c_parser_peek_token (parser)->location;
16935 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
16937 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
16939 c_parser_consume_token (parser);
16941 t = c_parser_expr_no_commas (parser, NULL).value;
16942 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16943 c_parser_error (parser, "expected integer expression");
16944 else if (t == error_mark_node
16945 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
16946 return list;
16948 else
16949 t = c_fully_fold (t, false, NULL);
16951 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
16953 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
16954 OMP_CLAUSE_ASYNC_EXPR (c) = t;
16955 OMP_CLAUSE_CHAIN (c) = list;
16956 list = c;
16958 return list;
16961 /* OpenACC 2.0:
16962 tile ( size-expr-list ) */
16964 static tree
16965 c_parser_oacc_clause_tile (c_parser *parser, tree list)
16967 tree c, expr = error_mark_node;
16968 location_t loc;
16969 tree tile = NULL_TREE;
16971 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
16972 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
16974 loc = c_parser_peek_token (parser)->location;
16975 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
16976 return list;
16980 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
16981 return list;
16983 if (c_parser_next_token_is (parser, CPP_MULT)
16984 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
16985 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
16987 c_parser_consume_token (parser);
16988 expr = integer_zero_node;
16990 else
16992 location_t expr_loc = c_parser_peek_token (parser)->location;
16993 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
16994 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
16995 expr = cexpr.value;
16997 if (expr == error_mark_node)
16999 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17000 "expected %<)%>");
17001 return list;
17004 expr = c_fully_fold (expr, false, NULL);
17006 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
17007 || !tree_fits_shwi_p (expr)
17008 || tree_to_shwi (expr) <= 0)
17010 error_at (expr_loc, "%<tile%> argument needs positive"
17011 " integral constant");
17012 expr = integer_zero_node;
17016 tile = tree_cons (NULL_TREE, expr, tile);
17018 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
17020 /* Consume the trailing ')'. */
17021 c_parser_consume_token (parser);
17023 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
17024 tile = nreverse (tile);
17025 OMP_CLAUSE_TILE_LIST (c) = tile;
17026 OMP_CLAUSE_CHAIN (c) = list;
17027 return c;
17030 /* OpenACC:
17031 wait [( int-expr-list )] */
17033 static tree
17034 c_parser_oacc_clause_wait (c_parser *parser, tree list)
17036 location_t clause_loc = c_parser_peek_token (parser)->location;
17038 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17039 list = c_parser_oacc_wait_list (parser, clause_loc, list);
17040 else
17042 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
17044 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
17045 OMP_CLAUSE_CHAIN (c) = list;
17046 list = c;
17049 return list;
17052 /* OpenACC 2.7:
17053 self [( expression )] */
17055 static tree
17056 c_parser_oacc_compute_clause_self (c_parser *parser, tree list)
17058 tree t;
17059 location_t location = c_parser_peek_token (parser)->location;
17060 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17062 matching_parens parens;
17063 parens.consume_open (parser);
17065 location_t loc = c_parser_peek_token (parser)->location;
17066 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17067 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
17068 t = c_objc_common_truthvalue_conversion (loc, expr.value);
17069 t = c_fully_fold (t, false, NULL);
17070 parens.skip_until_found_close (parser);
17072 else
17073 t = truthvalue_true_node;
17075 for (tree c = list; c; c = OMP_CLAUSE_CHAIN (c))
17076 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
17078 error_at (location, "too many %<self%> clauses");
17079 return list;
17082 tree c = build_omp_clause (location, OMP_CLAUSE_SELF);
17083 OMP_CLAUSE_SELF_EXPR (c) = t;
17084 OMP_CLAUSE_CHAIN (c) = list;
17085 return c;
17088 /* OpenMP 5.0:
17089 order ( concurrent )
17091 OpenMP 5.1:
17092 order ( order-modifier : concurrent )
17094 order-modifier:
17095 reproducible
17096 unconstrained */
17098 static tree
17099 c_parser_omp_clause_order (c_parser *parser, tree list)
17101 location_t loc = c_parser_peek_token (parser)->location;
17102 tree c;
17103 const char *p;
17104 bool unconstrained = false;
17105 bool reproducible = false;
17107 matching_parens parens;
17108 if (!parens.require_open (parser))
17109 return list;
17110 if (c_parser_next_token_is (parser, CPP_NAME)
17111 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
17113 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17114 if (strcmp (p, "unconstrained") == 0)
17115 unconstrained = true;
17116 else if (strcmp (p, "reproducible") == 0)
17117 reproducible = true;
17118 else
17120 c_parser_error (parser, "expected %<reproducible%> or "
17121 "%<unconstrained%>");
17122 goto out_err;
17124 c_parser_consume_token (parser);
17125 c_parser_consume_token (parser);
17127 if (!c_parser_next_token_is (parser, CPP_NAME))
17129 c_parser_error (parser, "expected %<concurrent%>");
17130 goto out_err;
17132 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17133 if (strcmp (p, "concurrent") != 0)
17135 c_parser_error (parser, "expected %<concurrent%>");
17136 goto out_err;
17138 c_parser_consume_token (parser);
17139 parens.skip_until_found_close (parser);
17140 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
17141 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
17142 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
17143 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
17144 OMP_CLAUSE_CHAIN (c) = list;
17145 return c;
17147 out_err:
17148 parens.skip_until_found_close (parser);
17149 return list;
17153 /* OpenMP 5.0:
17154 bind ( teams | parallel | thread ) */
17156 static tree
17157 c_parser_omp_clause_bind (c_parser *parser, tree list)
17159 location_t loc = c_parser_peek_token (parser)->location;
17160 tree c;
17161 const char *p;
17162 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
17164 matching_parens parens;
17165 if (!parens.require_open (parser))
17166 return list;
17167 if (!c_parser_next_token_is (parser, CPP_NAME))
17169 invalid:
17170 c_parser_error (parser,
17171 "expected %<teams%>, %<parallel%> or %<thread%>");
17172 parens.skip_until_found_close (parser);
17173 return list;
17175 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17176 if (strcmp (p, "teams") == 0)
17177 kind = OMP_CLAUSE_BIND_TEAMS;
17178 else if (strcmp (p, "parallel") == 0)
17179 kind = OMP_CLAUSE_BIND_PARALLEL;
17180 else if (strcmp (p, "thread") != 0)
17181 goto invalid;
17182 c_parser_consume_token (parser);
17183 parens.skip_until_found_close (parser);
17184 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
17185 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
17186 OMP_CLAUSE_BIND_KIND (c) = kind;
17187 OMP_CLAUSE_CHAIN (c) = list;
17188 return c;
17192 /* OpenMP 2.5:
17193 ordered
17195 OpenMP 4.5:
17196 ordered ( constant-expression ) */
17198 static tree
17199 c_parser_omp_clause_ordered (c_parser *parser, tree list)
17201 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
17203 tree c, num = NULL_TREE;
17204 HOST_WIDE_INT n;
17205 location_t loc = c_parser_peek_token (parser)->location;
17206 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17208 matching_parens parens;
17209 parens.consume_open (parser);
17210 num = c_parser_expr_no_commas (parser, NULL).value;
17211 parens.skip_until_found_close (parser);
17213 if (num == error_mark_node)
17214 return list;
17215 if (num)
17217 mark_exp_read (num);
17218 num = c_fully_fold (num, false, NULL);
17219 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
17220 || !tree_fits_shwi_p (num)
17221 || (n = tree_to_shwi (num)) <= 0
17222 || (int) n != n)
17224 error_at (loc, "ordered argument needs positive "
17225 "constant integer expression");
17226 return list;
17229 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
17230 OMP_CLAUSE_ORDERED_EXPR (c) = num;
17231 OMP_CLAUSE_CHAIN (c) = list;
17232 return c;
17235 /* OpenMP 2.5:
17236 private ( variable-list ) */
17238 static tree
17239 c_parser_omp_clause_private (c_parser *parser, tree list)
17241 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
17244 /* OpenMP 2.5:
17245 reduction ( reduction-operator : variable-list )
17247 reduction-operator:
17248 One of: + * - & ^ | && ||
17250 OpenMP 3.1:
17252 reduction-operator:
17253 One of: + * - & ^ | && || max min
17255 OpenMP 4.0:
17257 reduction-operator:
17258 One of: + * - & ^ | && ||
17259 identifier
17261 OpenMP 5.0:
17262 reduction ( reduction-modifier, reduction-operator : variable-list )
17263 in_reduction ( reduction-operator : variable-list )
17264 task_reduction ( reduction-operator : variable-list ) */
17266 static tree
17267 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
17268 bool is_omp, tree list)
17270 location_t clause_loc = c_parser_peek_token (parser)->location;
17271 matching_parens parens;
17272 if (parens.require_open (parser))
17274 bool task = false;
17275 bool inscan = false;
17276 enum tree_code code = ERROR_MARK;
17277 tree reduc_id = NULL_TREE;
17279 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
17281 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
17282 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
17284 c_parser_consume_token (parser);
17285 c_parser_consume_token (parser);
17287 else if (c_parser_next_token_is (parser, CPP_NAME)
17288 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
17290 const char *p
17291 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17292 if (strcmp (p, "task") == 0)
17293 task = true;
17294 else if (strcmp (p, "inscan") == 0)
17295 inscan = true;
17296 if (task || inscan)
17298 c_parser_consume_token (parser);
17299 c_parser_consume_token (parser);
17304 switch (c_parser_peek_token (parser)->type)
17306 case CPP_PLUS:
17307 code = PLUS_EXPR;
17308 break;
17309 case CPP_MULT:
17310 code = MULT_EXPR;
17311 break;
17312 case CPP_MINUS:
17313 code = MINUS_EXPR;
17314 break;
17315 case CPP_AND:
17316 code = BIT_AND_EXPR;
17317 break;
17318 case CPP_XOR:
17319 code = BIT_XOR_EXPR;
17320 break;
17321 case CPP_OR:
17322 code = BIT_IOR_EXPR;
17323 break;
17324 case CPP_AND_AND:
17325 code = TRUTH_ANDIF_EXPR;
17326 break;
17327 case CPP_OR_OR:
17328 code = TRUTH_ORIF_EXPR;
17329 break;
17330 case CPP_NAME:
17332 const char *p
17333 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17334 if (strcmp (p, "min") == 0)
17336 code = MIN_EXPR;
17337 break;
17339 if (strcmp (p, "max") == 0)
17341 code = MAX_EXPR;
17342 break;
17344 reduc_id = c_parser_peek_token (parser)->value;
17345 break;
17347 default:
17348 c_parser_error (parser,
17349 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
17350 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
17351 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
17352 return list;
17354 c_parser_consume_token (parser);
17355 reduc_id = c_omp_reduction_id (code, reduc_id);
17356 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
17358 tree nl, c;
17360 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
17361 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17363 tree d = OMP_CLAUSE_DECL (c), type;
17364 if (TREE_CODE (d) != OMP_ARRAY_SECTION)
17365 type = TREE_TYPE (d);
17366 else
17368 int cnt = 0;
17369 tree t;
17370 for (t = d;
17371 TREE_CODE (t) == OMP_ARRAY_SECTION;
17372 t = TREE_OPERAND (t, 0))
17373 cnt++;
17374 type = TREE_TYPE (t);
17375 while (cnt > 0)
17377 if (TREE_CODE (type) != POINTER_TYPE
17378 && TREE_CODE (type) != ARRAY_TYPE)
17379 break;
17380 type = TREE_TYPE (type);
17381 cnt--;
17384 while (TREE_CODE (type) == ARRAY_TYPE)
17385 type = TREE_TYPE (type);
17386 OMP_CLAUSE_REDUCTION_CODE (c) = code;
17387 if (task)
17388 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
17389 else if (inscan)
17390 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
17391 if (code == ERROR_MARK
17392 || !(INTEGRAL_TYPE_P (type)
17393 || SCALAR_FLOAT_TYPE_P (type)
17394 || TREE_CODE (type) == COMPLEX_TYPE))
17395 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
17396 = c_omp_reduction_lookup (reduc_id,
17397 TYPE_MAIN_VARIANT (type));
17400 list = nl;
17402 parens.skip_until_found_close (parser);
17404 return list;
17407 /* OpenMP 2.5:
17408 schedule ( schedule-kind )
17409 schedule ( schedule-kind , expression )
17411 schedule-kind:
17412 static | dynamic | guided | runtime | auto
17414 OpenMP 4.5:
17415 schedule ( schedule-modifier : schedule-kind )
17416 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
17418 schedule-modifier:
17419 simd
17420 monotonic
17421 nonmonotonic */
17423 static tree
17424 c_parser_omp_clause_schedule (c_parser *parser, tree list)
17426 tree c, t;
17427 location_t loc = c_parser_peek_token (parser)->location;
17428 int modifiers = 0, nmodifiers = 0;
17430 matching_parens parens;
17431 if (!parens.require_open (parser))
17432 return list;
17434 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
17436 location_t comma = UNKNOWN_LOCATION;
17437 while (c_parser_next_token_is (parser, CPP_NAME))
17439 tree kind = c_parser_peek_token (parser)->value;
17440 const char *p = IDENTIFIER_POINTER (kind);
17441 if (strcmp ("simd", p) == 0)
17442 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
17443 else if (strcmp ("monotonic", p) == 0)
17444 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
17445 else if (strcmp ("nonmonotonic", p) == 0)
17446 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
17447 else
17448 break;
17449 comma = UNKNOWN_LOCATION;
17450 c_parser_consume_token (parser);
17451 if (nmodifiers++ == 0
17452 && c_parser_next_token_is (parser, CPP_COMMA))
17454 comma = c_parser_peek_token (parser)->location;
17455 c_parser_consume_token (parser);
17457 else
17459 c_parser_require (parser, CPP_COLON, "expected %<:%>");
17460 break;
17463 if (comma != UNKNOWN_LOCATION)
17464 error_at (comma, "expected %<:%>");
17466 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
17467 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
17468 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
17469 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
17471 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
17472 "specified");
17473 modifiers = 0;
17476 if (c_parser_next_token_is (parser, CPP_NAME))
17478 tree kind = c_parser_peek_token (parser)->value;
17479 const char *p = IDENTIFIER_POINTER (kind);
17481 switch (p[0])
17483 case 'd':
17484 if (strcmp ("dynamic", p) != 0)
17485 goto invalid_kind;
17486 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
17487 break;
17489 case 'g':
17490 if (strcmp ("guided", p) != 0)
17491 goto invalid_kind;
17492 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
17493 break;
17495 case 'r':
17496 if (strcmp ("runtime", p) != 0)
17497 goto invalid_kind;
17498 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
17499 break;
17501 default:
17502 goto invalid_kind;
17505 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
17506 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
17507 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
17508 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
17509 else
17510 goto invalid_kind;
17512 c_parser_consume_token (parser);
17513 if (c_parser_next_token_is (parser, CPP_COMMA))
17515 location_t here;
17516 c_parser_consume_token (parser);
17518 here = c_parser_peek_token (parser)->location;
17519 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17520 expr = convert_lvalue_to_rvalue (here, expr, false, true);
17521 t = expr.value;
17522 t = c_fully_fold (t, false, NULL);
17524 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
17525 error_at (here, "schedule %<runtime%> does not take "
17526 "a %<chunk_size%> parameter");
17527 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
17528 error_at (here,
17529 "schedule %<auto%> does not take "
17530 "a %<chunk_size%> parameter");
17531 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
17532 || TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE)
17534 /* Attempt to statically determine when the number isn't
17535 positive. */
17536 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
17537 build_int_cst (TREE_TYPE (t), 0));
17538 protected_set_expr_location (s, loc);
17539 if (s == boolean_true_node)
17541 warning_at (loc, OPT_Wopenmp,
17542 "chunk size value must be positive");
17543 t = integer_one_node;
17545 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
17547 else
17548 c_parser_error (parser, "expected integer expression");
17550 parens.skip_until_found_close (parser);
17552 else
17553 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17554 "expected %<,%> or %<)%>");
17556 OMP_CLAUSE_SCHEDULE_KIND (c)
17557 = (enum omp_clause_schedule_kind)
17558 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
17560 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
17561 OMP_CLAUSE_CHAIN (c) = list;
17562 return c;
17564 invalid_kind:
17565 c_parser_error (parser, "invalid schedule kind");
17566 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
17567 return list;
17570 /* OpenMP 2.5:
17571 shared ( variable-list ) */
17573 static tree
17574 c_parser_omp_clause_shared (c_parser *parser, tree list)
17576 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
17579 /* OpenMP 3.0:
17580 untied */
17582 static tree
17583 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
17585 tree c;
17587 /* FIXME: Should we allow duplicates? */
17588 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
17590 c = build_omp_clause (c_parser_peek_token (parser)->location,
17591 OMP_CLAUSE_UNTIED);
17592 OMP_CLAUSE_CHAIN (c) = list;
17594 return c;
17597 /* OpenMP 4.0:
17598 inbranch
17599 notinbranch */
17601 static tree
17602 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
17603 enum omp_clause_code code, tree list)
17605 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
17607 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17608 OMP_CLAUSE_CHAIN (c) = list;
17610 return c;
17613 /* OpenMP 4.0:
17614 parallel
17616 sections
17617 taskgroup */
17619 static tree
17620 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
17621 enum omp_clause_code code, tree list)
17623 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17624 OMP_CLAUSE_CHAIN (c) = list;
17626 return c;
17629 /* OpenMP 4.5:
17630 nogroup */
17632 static tree
17633 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
17635 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
17636 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
17637 OMP_CLAUSE_NOGROUP);
17638 OMP_CLAUSE_CHAIN (c) = list;
17639 return c;
17642 /* OpenMP 4.5:
17643 simd
17644 threads */
17646 static tree
17647 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
17648 enum omp_clause_code code, tree list)
17650 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
17651 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17652 OMP_CLAUSE_CHAIN (c) = list;
17653 return c;
17656 /* OpenMP 4.0:
17657 num_teams ( expression )
17659 OpenMP 5.1:
17660 num_teams ( expression : expression ) */
17662 static tree
17663 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
17665 location_t num_teams_loc = c_parser_peek_token (parser)->location;
17666 matching_parens parens;
17667 if (parens.require_open (parser))
17669 location_t upper_loc = c_parser_peek_token (parser)->location;
17670 location_t lower_loc = UNKNOWN_LOCATION;
17671 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17672 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
17673 tree c, upper = expr.value, lower = NULL_TREE;
17674 upper = c_fully_fold (upper, false, NULL);
17676 if (c_parser_next_token_is (parser, CPP_COLON))
17678 c_parser_consume_token (parser);
17679 lower_loc = upper_loc;
17680 lower = upper;
17681 upper_loc = c_parser_peek_token (parser)->location;
17682 expr = c_parser_expr_no_commas (parser, NULL);
17683 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
17684 upper = expr.value;
17685 upper = c_fully_fold (upper, false, NULL);
17688 parens.skip_until_found_close (parser);
17690 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
17691 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
17693 c_parser_error (parser, "expected integer expression");
17694 return list;
17697 /* Attempt to statically determine when the number isn't positive. */
17698 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
17699 build_int_cst (TREE_TYPE (upper), 0));
17700 protected_set_expr_location (c, upper_loc);
17701 if (c == boolean_true_node)
17703 warning_at (upper_loc, OPT_Wopenmp,
17704 "%<num_teams%> value must be positive");
17705 upper = integer_one_node;
17707 if (lower)
17709 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
17710 build_int_cst (TREE_TYPE (lower), 0));
17711 protected_set_expr_location (c, lower_loc);
17712 if (c == boolean_true_node)
17714 warning_at (lower_loc, OPT_Wopenmp,
17715 "%<num_teams%> value must be positive");
17716 lower = NULL_TREE;
17718 else if (TREE_CODE (lower) == INTEGER_CST
17719 && TREE_CODE (upper) == INTEGER_CST
17720 && tree_int_cst_lt (upper, lower))
17722 warning_at (lower_loc, OPT_Wopenmp,
17723 "%<num_teams%> lower bound %qE bigger than upper "
17724 "bound %qE", lower, upper);
17725 lower = NULL_TREE;
17729 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
17731 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
17732 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
17733 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
17734 OMP_CLAUSE_CHAIN (c) = list;
17735 list = c;
17738 return list;
17741 /* OpenMP 4.0:
17742 thread_limit ( expression ) */
17744 static tree
17745 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
17747 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
17748 matching_parens parens;
17749 if (parens.require_open (parser))
17751 location_t expr_loc = c_parser_peek_token (parser)->location;
17752 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17753 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17754 tree c, t = expr.value;
17755 t = c_fully_fold (t, false, NULL);
17757 parens.skip_until_found_close (parser);
17759 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
17761 c_parser_error (parser, "expected integer expression");
17762 return list;
17765 /* Attempt to statically determine when the number isn't positive. */
17766 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
17767 build_int_cst (TREE_TYPE (t), 0));
17768 protected_set_expr_location (c, expr_loc);
17769 if (c == boolean_true_node)
17771 warning_at (expr_loc, OPT_Wopenmp,
17772 "%<thread_limit%> value must be positive");
17773 t = integer_one_node;
17776 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
17777 "thread_limit");
17779 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
17780 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
17781 OMP_CLAUSE_CHAIN (c) = list;
17782 list = c;
17785 return list;
17788 /* OpenMP 4.0:
17789 aligned ( variable-list )
17790 aligned ( variable-list : constant-expression ) */
17792 static tree
17793 c_parser_omp_clause_aligned (c_parser *parser, tree list)
17795 location_t clause_loc = c_parser_peek_token (parser)->location;
17796 tree nl, c;
17798 matching_parens parens;
17799 if (!parens.require_open (parser))
17800 return list;
17802 nl = c_parser_omp_variable_list (parser, clause_loc,
17803 OMP_CLAUSE_ALIGNED, list);
17805 if (c_parser_next_token_is (parser, CPP_COLON))
17807 c_parser_consume_token (parser);
17808 location_t expr_loc = c_parser_peek_token (parser)->location;
17809 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17810 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17811 tree alignment = expr.value;
17812 alignment = c_fully_fold (alignment, false, NULL);
17813 if (TREE_CODE (alignment) != INTEGER_CST
17814 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
17815 || tree_int_cst_sgn (alignment) != 1)
17817 error_at (clause_loc, "%<aligned%> clause alignment expression must "
17818 "be positive constant integer expression");
17819 alignment = NULL_TREE;
17822 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17823 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
17826 parens.skip_until_found_close (parser);
17827 return nl;
17830 /* OpenMP 5.0:
17831 allocate ( variable-list )
17832 allocate ( expression : variable-list )
17834 OpenMP 5.1:
17835 allocate ( allocator-modifier : variable-list )
17836 allocate ( allocator-modifier , allocator-modifier : variable-list )
17838 allocator-modifier:
17839 allocator ( expression )
17840 align ( expression ) */
17842 static tree
17843 c_parser_omp_clause_allocate (c_parser *parser, tree list)
17845 location_t clause_loc = c_parser_peek_token (parser)->location;
17846 tree nl, c;
17847 tree allocator = NULL_TREE;
17848 tree align = NULL_TREE;
17850 matching_parens parens;
17851 if (!parens.require_open (parser))
17852 return list;
17854 if ((c_parser_next_token_is_not (parser, CPP_NAME)
17855 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
17856 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
17857 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
17859 bool has_modifiers = false;
17860 tree orig_type = NULL_TREE;
17861 if (c_parser_next_token_is (parser, CPP_NAME)
17862 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
17864 unsigned int n = 3;
17865 const char *p
17866 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17867 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
17868 && c_parser_check_balanced_raw_token_sequence (parser, &n)
17869 && (c_parser_peek_nth_token_raw (parser, n)->type
17870 == CPP_CLOSE_PAREN))
17872 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
17873 == CPP_COLON)
17874 has_modifiers = true;
17875 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
17876 == CPP_COMMA
17877 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
17878 == CPP_NAME)
17879 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
17880 == CPP_OPEN_PAREN))
17882 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
17883 const char *q = IDENTIFIER_POINTER (tok->value);
17884 n += 4;
17885 if ((strcmp (q, "allocator") == 0
17886 || strcmp (q, "align") == 0)
17887 && c_parser_check_balanced_raw_token_sequence (parser,
17889 && (c_parser_peek_nth_token_raw (parser, n)->type
17890 == CPP_CLOSE_PAREN)
17891 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
17892 == CPP_COLON))
17893 has_modifiers = true;
17896 if (has_modifiers)
17898 c_parser_consume_token (parser);
17899 matching_parens parens2;;
17900 parens2.require_open (parser);
17901 location_t expr_loc = c_parser_peek_token (parser)->location;
17902 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17903 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17904 if (expr.value == error_mark_node)
17906 else if (strcmp (p, "allocator") == 0)
17908 allocator = expr.value;
17909 allocator = c_fully_fold (allocator, false, NULL);
17910 orig_type = expr.original_type
17911 ? expr.original_type : TREE_TYPE (allocator);
17912 orig_type = TYPE_MAIN_VARIANT (orig_type);
17914 else
17916 align = expr.value;
17917 align = c_fully_fold (align, false, NULL);
17919 parens2.skip_until_found_close (parser);
17920 if (c_parser_next_token_is (parser, CPP_COMMA))
17922 c_parser_consume_token (parser);
17923 c_token *tok = c_parser_peek_token (parser);
17924 const char *q = "";
17925 if (c_parser_next_token_is (parser, CPP_NAME))
17926 q = IDENTIFIER_POINTER (tok->value);
17927 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
17929 c_parser_error (parser, "expected %<allocator%> or "
17930 "%<align%>");
17931 parens.skip_until_found_close (parser);
17932 return list;
17934 else if (strcmp (p, q) == 0)
17936 error_at (tok->location, "duplicate %qs modifier", p);
17937 parens.skip_until_found_close (parser);
17938 return list;
17940 c_parser_consume_token (parser);
17941 if (!parens2.require_open (parser))
17943 parens.skip_until_found_close (parser);
17944 return list;
17946 expr_loc = c_parser_peek_token (parser)->location;
17947 expr = c_parser_expr_no_commas (parser, NULL);
17948 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
17949 true);
17950 if (strcmp (q, "allocator") == 0)
17952 allocator = expr.value;
17953 allocator = c_fully_fold (allocator, false, NULL);
17954 orig_type = expr.original_type
17955 ? expr.original_type : TREE_TYPE (allocator);
17956 orig_type = TYPE_MAIN_VARIANT (orig_type);
17958 else
17960 align = expr.value;
17961 align = c_fully_fold (align, false, NULL);
17963 parens2.skip_until_found_close (parser);
17967 if (!has_modifiers)
17969 location_t expr_loc = c_parser_peek_token (parser)->location;
17970 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17971 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17972 allocator = expr.value;
17973 allocator = c_fully_fold (allocator, false, NULL);
17974 orig_type = expr.original_type
17975 ? expr.original_type : TREE_TYPE (allocator);
17976 orig_type = TYPE_MAIN_VARIANT (orig_type);
17978 if (allocator
17979 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
17980 || TREE_CODE (orig_type) != ENUMERAL_TYPE
17981 || (TYPE_NAME (orig_type)
17982 != get_identifier ("omp_allocator_handle_t"))))
17984 error_at (clause_loc, "%<allocate%> clause allocator expression "
17985 "has type %qT rather than "
17986 "%<omp_allocator_handle_t%>",
17987 TREE_TYPE (allocator));
17988 allocator = NULL_TREE;
17990 if (align
17991 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
17992 || !tree_fits_uhwi_p (align)
17993 || !integer_pow2p (align)))
17995 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
17996 "argument needs to be positive constant "
17997 "power of two integer expression");
17998 align = NULL_TREE;
18000 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18002 parens.skip_until_found_close (parser);
18003 return list;
18007 nl = c_parser_omp_variable_list (parser, clause_loc,
18008 OMP_CLAUSE_ALLOCATE, list);
18010 if (allocator || align)
18011 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18013 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18014 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
18017 parens.skip_until_found_close (parser);
18018 return nl;
18021 /* OpenMP 4.0:
18022 linear ( variable-list )
18023 linear ( variable-list : expression )
18025 OpenMP 4.5:
18026 linear ( modifier ( variable-list ) )
18027 linear ( modifier ( variable-list ) : expression )
18029 modifier:
18032 OpenMP 5.2:
18033 linear ( variable-list : modifiers-list )
18035 modifiers:
18037 step ( expression ) */
18039 static tree
18040 c_parser_omp_clause_linear (c_parser *parser, tree list)
18042 location_t clause_loc = c_parser_peek_token (parser)->location;
18043 tree nl, c, step;
18044 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
18045 bool old_linear_modifier = false;
18047 matching_parens parens;
18048 if (!parens.require_open (parser))
18049 return list;
18051 if (c_parser_next_token_is (parser, CPP_NAME))
18053 c_token *tok = c_parser_peek_token (parser);
18054 const char *p = IDENTIFIER_POINTER (tok->value);
18055 if (strcmp ("val", p) == 0)
18056 kind = OMP_CLAUSE_LINEAR_VAL;
18057 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
18058 kind = OMP_CLAUSE_LINEAR_DEFAULT;
18059 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18061 old_linear_modifier = true;
18062 c_parser_consume_token (parser);
18063 c_parser_consume_token (parser);
18067 nl = c_parser_omp_variable_list (parser, clause_loc,
18068 OMP_CLAUSE_LINEAR, list);
18070 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18071 parens.skip_until_found_close (parser);
18073 if (c_parser_next_token_is (parser, CPP_COLON))
18075 c_parser_consume_token (parser);
18076 location_t expr_loc = c_parser_peek_token (parser)->location;
18077 bool has_modifiers = false;
18078 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
18079 && c_parser_next_token_is (parser, CPP_NAME))
18081 c_token *tok = c_parser_peek_token (parser);
18082 const char *p = IDENTIFIER_POINTER (tok->value);
18083 unsigned int pos = 0;
18084 if (strcmp ("val", p) == 0)
18085 pos = 2;
18086 else if (strcmp ("step", p) == 0
18087 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
18089 pos = 3;
18090 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
18091 && (c_parser_peek_nth_token_raw (parser, pos)->type
18092 == CPP_CLOSE_PAREN))
18093 ++pos;
18094 else
18095 pos = 0;
18097 if (pos)
18099 tok = c_parser_peek_nth_token_raw (parser, pos);
18100 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
18101 has_modifiers = true;
18104 if (has_modifiers)
18106 step = NULL_TREE;
18107 while (c_parser_next_token_is (parser, CPP_NAME))
18109 c_token *tok = c_parser_peek_token (parser);
18110 const char *p = IDENTIFIER_POINTER (tok->value);
18111 if (strcmp ("val", p) == 0)
18113 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18114 error_at (tok->location, "multiple linear modifiers");
18115 kind = OMP_CLAUSE_LINEAR_DEFAULT;
18116 c_parser_consume_token (parser);
18118 else if (strcmp ("step", p) == 0)
18120 c_parser_consume_token (parser);
18121 matching_parens parens2;
18122 if (parens2.require_open (parser))
18124 if (step)
18125 error_at (tok->location,
18126 "multiple %<step%> modifiers");
18127 expr_loc = c_parser_peek_token (parser)->location;
18128 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18129 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
18130 true);
18131 step = c_fully_fold (expr.value, false, NULL);
18132 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
18134 error_at (clause_loc, "%<linear%> clause step "
18135 "expression must be integral");
18136 step = integer_one_node;
18138 parens2.skip_until_found_close (parser);
18140 else
18141 break;
18143 else
18144 break;
18145 if (c_parser_next_token_is (parser, CPP_COMMA))
18147 c_parser_consume_token (parser);
18148 continue;
18150 break;
18152 if (!step)
18153 step = integer_one_node;
18155 else
18157 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18158 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18159 step = c_fully_fold (expr.value, false, NULL);
18160 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
18162 error_at (clause_loc, "%<linear%> clause step expression must "
18163 "be integral");
18164 step = integer_one_node;
18169 else
18170 step = integer_one_node;
18172 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18174 OMP_CLAUSE_LINEAR_STEP (c) = step;
18175 OMP_CLAUSE_LINEAR_KIND (c) = kind;
18176 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
18179 parens.skip_until_found_close (parser);
18180 return nl;
18183 /* OpenMP 5.0:
18184 nontemporal ( variable-list ) */
18186 static tree
18187 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
18189 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
18192 /* OpenMP 4.0:
18193 safelen ( constant-expression ) */
18195 static tree
18196 c_parser_omp_clause_safelen (c_parser *parser, tree list)
18198 location_t clause_loc = c_parser_peek_token (parser)->location;
18199 tree c, t;
18201 matching_parens parens;
18202 if (!parens.require_open (parser))
18203 return list;
18205 location_t expr_loc = c_parser_peek_token (parser)->location;
18206 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18207 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18208 t = expr.value;
18209 t = c_fully_fold (t, false, NULL);
18210 if (TREE_CODE (t) != INTEGER_CST
18211 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
18212 || tree_int_cst_sgn (t) != 1)
18214 error_at (clause_loc, "%<safelen%> clause expression must "
18215 "be positive constant integer expression");
18216 t = NULL_TREE;
18219 parens.skip_until_found_close (parser);
18220 if (t == NULL_TREE || t == error_mark_node)
18221 return list;
18223 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
18225 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
18226 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
18227 OMP_CLAUSE_CHAIN (c) = list;
18228 return c;
18231 /* OpenMP 4.0:
18232 simdlen ( constant-expression ) */
18234 static tree
18235 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
18237 location_t clause_loc = c_parser_peek_token (parser)->location;
18238 tree c, t;
18240 matching_parens parens;
18241 if (!parens.require_open (parser))
18242 return list;
18244 location_t expr_loc = c_parser_peek_token (parser)->location;
18245 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18246 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18247 t = expr.value;
18248 t = c_fully_fold (t, false, NULL);
18249 if (TREE_CODE (t) != INTEGER_CST
18250 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
18251 || tree_int_cst_sgn (t) != 1)
18253 error_at (clause_loc, "%<simdlen%> clause expression must "
18254 "be positive constant integer expression");
18255 t = NULL_TREE;
18258 parens.skip_until_found_close (parser);
18259 if (t == NULL_TREE || t == error_mark_node)
18260 return list;
18262 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
18264 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
18265 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
18266 OMP_CLAUSE_CHAIN (c) = list;
18267 return c;
18270 /* OpenMP 4.5:
18271 vec:
18272 identifier [+/- integer]
18273 vec , identifier [+/- integer]
18276 static tree
18277 c_parser_omp_clause_doacross_sink (c_parser *parser, location_t clause_loc,
18278 tree list, bool depend_p)
18280 tree vec = NULL;
18281 if (c_parser_next_token_is_not (parser, CPP_NAME)
18282 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
18284 c_parser_error (parser, "expected identifier");
18285 return list;
18288 if (!depend_p)
18290 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18291 if (strcmp (p, "omp_cur_iteration") == 0
18292 && c_parser_peek_2nd_token (parser)->type == CPP_MINUS
18293 && c_parser_peek_nth_token (parser, 3)->type == CPP_NUMBER
18294 && c_parser_peek_nth_token (parser, 4)->type == CPP_CLOSE_PAREN)
18296 tree val = c_parser_peek_nth_token (parser, 3)->value;
18297 if (integer_onep (val))
18299 c_parser_consume_token (parser);
18300 c_parser_consume_token (parser);
18301 c_parser_consume_token (parser);
18302 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18303 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
18304 OMP_CLAUSE_CHAIN (u) = list;
18305 return u;
18312 while (c_parser_next_token_is (parser, CPP_NAME)
18313 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
18315 tree t = lookup_name (c_parser_peek_token (parser)->value);
18316 tree addend = NULL;
18318 if (t == NULL_TREE)
18320 undeclared_variable (c_parser_peek_token (parser)->location,
18321 c_parser_peek_token (parser)->value);
18322 t = error_mark_node;
18325 c_parser_consume_token (parser);
18327 bool neg = false;
18328 if (c_parser_next_token_is (parser, CPP_MINUS))
18329 neg = true;
18330 else if (!c_parser_next_token_is (parser, CPP_PLUS))
18332 addend = integer_zero_node;
18333 neg = false;
18334 goto add_to_vector;
18336 c_parser_consume_token (parser);
18338 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
18340 c_parser_error (parser, "expected integer");
18341 return list;
18344 addend = c_parser_peek_token (parser)->value;
18345 if (TREE_CODE (addend) != INTEGER_CST)
18347 c_parser_error (parser, "expected integer");
18348 return list;
18350 c_parser_consume_token (parser);
18352 add_to_vector:
18353 if (t != error_mark_node)
18355 vec = tree_cons (addend, t, vec);
18356 if (neg)
18357 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
18360 if (c_parser_next_token_is_not (parser, CPP_COMMA)
18361 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
18362 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
18363 break;
18365 c_parser_consume_token (parser);
18368 if (vec == NULL_TREE)
18369 return list;
18371 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18372 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
18373 OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
18374 OMP_CLAUSE_DECL (u) = nreverse (vec);
18375 OMP_CLAUSE_CHAIN (u) = list;
18376 return u;
18379 /* OpenMP 5.0:
18380 iterators ( iterators-definition )
18382 iterators-definition:
18383 iterator-specifier
18384 iterator-specifier , iterators-definition
18386 iterator-specifier:
18387 identifier = range-specification
18388 iterator-type identifier = range-specification
18390 range-specification:
18391 begin : end
18392 begin : end : step */
18394 static tree
18395 c_parser_omp_iterators (c_parser *parser)
18397 tree ret = NULL_TREE, *last = &ret;
18398 c_parser_consume_token (parser);
18400 push_scope ();
18402 matching_parens parens;
18403 if (!parens.require_open (parser))
18404 return error_mark_node;
18408 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
18409 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
18411 struct c_type_name *type = c_parser_type_name (parser);
18412 if (type != NULL)
18413 iter_type = groktypename (type, &type_expr, NULL);
18415 if (iter_type == NULL_TREE)
18416 iter_type = integer_type_node;
18418 location_t loc = c_parser_peek_token (parser)->location;
18419 if (!c_parser_next_token_is (parser, CPP_NAME))
18421 c_parser_error (parser, "expected identifier");
18422 break;
18425 tree id = c_parser_peek_token (parser)->value;
18426 c_parser_consume_token (parser);
18428 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18429 break;
18431 location_t eloc = c_parser_peek_token (parser)->location;
18432 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18433 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18434 tree begin = expr.value;
18436 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18437 break;
18439 eloc = c_parser_peek_token (parser)->location;
18440 expr = c_parser_expr_no_commas (parser, NULL);
18441 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18442 tree end = expr.value;
18444 tree step = integer_one_node;
18445 if (c_parser_next_token_is (parser, CPP_COLON))
18447 c_parser_consume_token (parser);
18448 eloc = c_parser_peek_token (parser)->location;
18449 expr = c_parser_expr_no_commas (parser, NULL);
18450 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18451 step = expr.value;
18454 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
18455 DECL_ARTIFICIAL (iter_var) = 1;
18456 DECL_CONTEXT (iter_var) = current_function_decl;
18457 pushdecl (iter_var);
18459 *last = make_tree_vec (6);
18460 TREE_VEC_ELT (*last, 0) = iter_var;
18461 TREE_VEC_ELT (*last, 1) = begin;
18462 TREE_VEC_ELT (*last, 2) = end;
18463 TREE_VEC_ELT (*last, 3) = step;
18464 last = &TREE_CHAIN (*last);
18466 if (c_parser_next_token_is (parser, CPP_COMMA))
18468 c_parser_consume_token (parser);
18469 continue;
18471 break;
18473 while (1);
18475 parens.skip_until_found_close (parser);
18476 return ret ? ret : error_mark_node;
18479 /* OpenMP 5.0:
18480 affinity ( [aff-modifier :] variable-list )
18481 aff-modifier:
18482 iterator ( iterators-definition ) */
18484 static tree
18485 c_parser_omp_clause_affinity (c_parser *parser, tree list)
18487 location_t clause_loc = c_parser_peek_token (parser)->location;
18488 tree nl, iterators = NULL_TREE;
18490 matching_parens parens;
18491 if (!parens.require_open (parser))
18492 return list;
18494 if (c_parser_next_token_is (parser, CPP_NAME))
18496 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18497 bool parse_iter = ((strcmp ("iterator", p) == 0)
18498 && (c_parser_peek_2nd_token (parser)->type
18499 == CPP_OPEN_PAREN));
18500 if (parse_iter)
18502 unsigned n = 3;
18503 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
18504 && (c_parser_peek_nth_token_raw (parser, n)->type
18505 == CPP_CLOSE_PAREN)
18506 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
18507 == CPP_COLON));
18509 if (parse_iter)
18511 iterators = c_parser_omp_iterators (parser);
18512 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18514 if (iterators)
18515 pop_scope ();
18516 parens.skip_until_found_close (parser);
18517 return list;
18521 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
18522 list);
18523 if (iterators)
18525 tree block = pop_scope ();
18526 if (iterators != error_mark_node)
18528 TREE_VEC_ELT (iterators, 5) = block;
18529 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18530 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
18531 OMP_CLAUSE_DECL (c));
18535 parens.skip_until_found_close (parser);
18536 return nl;
18540 /* OpenMP 4.0:
18541 depend ( depend-kind: variable-list )
18543 depend-kind:
18544 in | out | inout
18546 OpenMP 4.5:
18547 depend ( source )
18549 depend ( sink : vec )
18551 OpenMP 5.0:
18552 depend ( depend-modifier , depend-kind: variable-list )
18554 depend-kind:
18555 in | out | inout | mutexinoutset | depobj | inoutset
18557 depend-modifier:
18558 iterator ( iterators-definition ) */
18560 static tree
18561 c_parser_omp_clause_depend (c_parser *parser, tree list)
18563 location_t clause_loc = c_parser_peek_token (parser)->location;
18564 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
18565 enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
18566 tree nl, c, iterators = NULL_TREE;
18568 matching_parens parens;
18569 if (!parens.require_open (parser))
18570 return list;
18574 if (c_parser_next_token_is_not (parser, CPP_NAME))
18575 goto invalid_kind;
18577 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18578 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
18580 iterators = c_parser_omp_iterators (parser);
18581 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
18582 continue;
18584 if (strcmp ("in", p) == 0)
18585 kind = OMP_CLAUSE_DEPEND_IN;
18586 else if (strcmp ("inout", p) == 0)
18587 kind = OMP_CLAUSE_DEPEND_INOUT;
18588 else if (strcmp ("inoutset", p) == 0)
18589 kind = OMP_CLAUSE_DEPEND_INOUTSET;
18590 else if (strcmp ("mutexinoutset", p) == 0)
18591 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
18592 else if (strcmp ("out", p) == 0)
18593 kind = OMP_CLAUSE_DEPEND_OUT;
18594 else if (strcmp ("depobj", p) == 0)
18595 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
18596 else if (strcmp ("sink", p) == 0)
18597 dkind = OMP_CLAUSE_DOACROSS_SINK;
18598 else if (strcmp ("source", p) == 0)
18599 dkind = OMP_CLAUSE_DOACROSS_SOURCE;
18600 else
18601 goto invalid_kind;
18602 break;
18604 while (1);
18606 c_parser_consume_token (parser);
18608 if (iterators
18609 && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
18610 || dkind == OMP_CLAUSE_DOACROSS_SINK))
18612 pop_scope ();
18613 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
18614 dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
18615 iterators = NULL_TREE;
18618 if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
18620 c = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18621 OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
18622 OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
18623 OMP_CLAUSE_DECL (c) = NULL_TREE;
18624 OMP_CLAUSE_CHAIN (c) = list;
18625 parens.skip_until_found_close (parser);
18626 return c;
18629 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18630 goto resync_fail;
18632 if (dkind == OMP_CLAUSE_DOACROSS_SINK)
18633 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, true);
18634 else
18636 nl = c_parser_omp_variable_list (parser, clause_loc,
18637 OMP_CLAUSE_DEPEND, list);
18639 if (iterators)
18641 tree block = pop_scope ();
18642 if (iterators == error_mark_node)
18643 iterators = NULL_TREE;
18644 else
18645 TREE_VEC_ELT (iterators, 5) = block;
18648 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18650 OMP_CLAUSE_DEPEND_KIND (c) = kind;
18651 if (iterators)
18652 OMP_CLAUSE_DECL (c)
18653 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
18657 parens.skip_until_found_close (parser);
18658 return nl;
18660 invalid_kind:
18661 c_parser_error (parser, "invalid depend kind");
18662 resync_fail:
18663 parens.skip_until_found_close (parser);
18664 if (iterators)
18665 pop_scope ();
18666 return list;
18669 /* OpenMP 5.2:
18670 doacross ( source : )
18671 doacross ( source : omp_cur_iteration )
18673 doacross ( sink : vec )
18674 doacross ( sink : omp_cur_iteration - logical_iteration ) */
18676 static tree
18677 c_parser_omp_clause_doacross (c_parser *parser, tree list)
18679 location_t clause_loc = c_parser_peek_token (parser)->location;
18680 enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
18681 tree nl;
18682 const char *p;
18684 matching_parens parens;
18685 if (!parens.require_open (parser))
18686 return list;
18688 if (c_parser_next_token_is_not (parser, CPP_NAME))
18689 goto invalid_kind;
18691 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18692 if (strcmp ("sink", p) == 0)
18693 kind = OMP_CLAUSE_DOACROSS_SINK;
18694 else if (strcmp ("source", p) == 0)
18695 kind = OMP_CLAUSE_DOACROSS_SOURCE;
18696 else
18697 goto invalid_kind;
18699 c_parser_consume_token (parser);
18701 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18702 goto resync_fail;
18704 if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
18706 if (c_parser_next_token_is (parser, CPP_NAME)
18707 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
18708 "omp_cur_iteration") == 0)
18709 c_parser_consume_token (parser);
18710 nl = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18711 OMP_CLAUSE_DOACROSS_KIND (nl) = OMP_CLAUSE_DOACROSS_SOURCE;
18712 OMP_CLAUSE_DECL (nl) = NULL_TREE;
18713 OMP_CLAUSE_CHAIN (nl) = list;
18715 else
18716 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, false);
18718 parens.skip_until_found_close (parser);
18719 return nl;
18721 invalid_kind:
18722 c_parser_error (parser, "invalid doacross kind");
18723 resync_fail:
18724 parens.skip_until_found_close (parser);
18725 return list;
18728 /* OpenMP 4.0:
18729 map ( map-kind: variable-list )
18730 map ( variable-list )
18732 map-kind:
18733 alloc | to | from | tofrom
18735 OpenMP 4.5:
18736 map-kind:
18737 alloc | to | from | tofrom | release | delete
18739 map ( always [,] map-kind: variable-list )
18741 OpenMP 5.0:
18742 map ( [map-type-modifier[,] ...] map-kind: variable-list )
18744 map-type-modifier:
18745 always | close */
18747 static tree
18748 c_parser_omp_clause_map (c_parser *parser, tree list)
18750 location_t clause_loc = c_parser_peek_token (parser)->location;
18751 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
18752 tree nl, c;
18754 matching_parens parens;
18755 if (!parens.require_open (parser))
18756 return list;
18758 int pos = 1;
18759 int map_kind_pos = 0;
18760 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
18762 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
18764 map_kind_pos = pos;
18765 break;
18768 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
18769 pos++;
18770 pos++;
18773 int always_modifier = 0;
18774 int close_modifier = 0;
18775 int present_modifier = 0;
18776 for (int pos = 1; pos < map_kind_pos; ++pos)
18778 c_token *tok = c_parser_peek_token (parser);
18780 if (tok->type == CPP_COMMA)
18782 c_parser_consume_token (parser);
18783 continue;
18786 const char *p = IDENTIFIER_POINTER (tok->value);
18787 if (strcmp ("always", p) == 0)
18789 if (always_modifier)
18791 c_parser_error (parser, "too many %<always%> modifiers");
18792 parens.skip_until_found_close (parser);
18793 return list;
18795 always_modifier++;
18797 else if (strcmp ("close", p) == 0)
18799 if (close_modifier)
18801 c_parser_error (parser, "too many %<close%> modifiers");
18802 parens.skip_until_found_close (parser);
18803 return list;
18805 close_modifier++;
18807 else if (strcmp ("present", p) == 0)
18809 if (present_modifier)
18811 c_parser_error (parser, "too many %<present%> modifiers");
18812 parens.skip_until_found_close (parser);
18813 return list;
18815 present_modifier++;
18817 else
18819 c_parser_error (parser, "%<map%> clause with map-type modifier other "
18820 "than %<always%>, %<close%> or %<present%>");
18821 parens.skip_until_found_close (parser);
18822 return list;
18825 c_parser_consume_token (parser);
18828 if (c_parser_next_token_is (parser, CPP_NAME)
18829 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
18831 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18832 int always_present_modifier = always_modifier && present_modifier;
18834 if (strcmp ("alloc", p) == 0)
18835 kind = present_modifier ? GOMP_MAP_PRESENT_ALLOC : GOMP_MAP_ALLOC;
18836 else if (strcmp ("to", p) == 0)
18837 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TO
18838 : present_modifier ? GOMP_MAP_PRESENT_TO
18839 : always_modifier ? GOMP_MAP_ALWAYS_TO
18840 : GOMP_MAP_TO);
18841 else if (strcmp ("from", p) == 0)
18842 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_FROM
18843 : present_modifier ? GOMP_MAP_PRESENT_FROM
18844 : always_modifier ? GOMP_MAP_ALWAYS_FROM
18845 : GOMP_MAP_FROM);
18846 else if (strcmp ("tofrom", p) == 0)
18847 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TOFROM
18848 : present_modifier ? GOMP_MAP_PRESENT_TOFROM
18849 : always_modifier ? GOMP_MAP_ALWAYS_TOFROM
18850 : GOMP_MAP_TOFROM);
18851 else if (strcmp ("release", p) == 0)
18852 kind = GOMP_MAP_RELEASE;
18853 else if (strcmp ("delete", p) == 0)
18854 kind = GOMP_MAP_DELETE;
18855 else
18857 c_parser_error (parser, "invalid map kind");
18858 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18859 "expected %<)%>");
18860 return list;
18862 c_parser_consume_token (parser);
18863 c_parser_consume_token (parser);
18866 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
18867 true);
18869 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18870 OMP_CLAUSE_SET_MAP_KIND (c, kind);
18872 parens.skip_until_found_close (parser);
18873 return nl;
18876 /* OpenMP 4.0:
18877 device ( expression )
18879 OpenMP 5.0:
18880 device ( [device-modifier :] integer-expression )
18882 device-modifier:
18883 ancestor | device_num */
18885 static tree
18886 c_parser_omp_clause_device (c_parser *parser, tree list)
18888 location_t clause_loc = c_parser_peek_token (parser)->location;
18889 location_t expr_loc;
18890 c_expr expr;
18891 tree c, t;
18892 bool ancestor = false;
18894 matching_parens parens;
18895 if (!parens.require_open (parser))
18896 return list;
18898 if (c_parser_next_token_is (parser, CPP_NAME)
18899 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
18901 c_token *tok = c_parser_peek_token (parser);
18902 const char *p = IDENTIFIER_POINTER (tok->value);
18903 if (strcmp ("ancestor", p) == 0)
18905 /* A requires directive with the reverse_offload clause must be
18906 specified. */
18907 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
18909 error_at (tok->location, "%<ancestor%> device modifier not "
18910 "preceded by %<requires%> directive "
18911 "with %<reverse_offload%> clause");
18912 parens.skip_until_found_close (parser);
18913 return list;
18915 ancestor = true;
18917 else if (strcmp ("device_num", p) == 0)
18919 else
18921 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
18922 parens.skip_until_found_close (parser);
18923 return list;
18925 c_parser_consume_token (parser);
18926 c_parser_consume_token (parser);
18929 expr_loc = c_parser_peek_token (parser)->location;
18930 expr = c_parser_expr_no_commas (parser, NULL);
18931 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18932 t = expr.value;
18933 t = c_fully_fold (t, false, NULL);
18935 parens.skip_until_found_close (parser);
18937 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
18939 c_parser_error (parser, "expected integer expression");
18940 return list;
18942 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
18944 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
18945 "%<1%>");
18946 return list;
18949 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
18951 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
18953 OMP_CLAUSE_DEVICE_ID (c) = t;
18954 OMP_CLAUSE_CHAIN (c) = list;
18955 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
18957 list = c;
18958 return list;
18961 /* OpenMP 4.0:
18962 dist_schedule ( static )
18963 dist_schedule ( static , expression ) */
18965 static tree
18966 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
18968 tree c, t = NULL_TREE;
18969 location_t loc = c_parser_peek_token (parser)->location;
18971 matching_parens parens;
18972 if (!parens.require_open (parser))
18973 return list;
18975 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
18977 c_parser_error (parser, "invalid dist_schedule kind");
18978 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18979 "expected %<)%>");
18980 return list;
18983 c_parser_consume_token (parser);
18984 if (c_parser_next_token_is (parser, CPP_COMMA))
18986 c_parser_consume_token (parser);
18988 location_t expr_loc = c_parser_peek_token (parser)->location;
18989 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18990 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18991 t = expr.value;
18992 t = c_fully_fold (t, false, NULL);
18993 parens.skip_until_found_close (parser);
18995 else
18996 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18997 "expected %<,%> or %<)%>");
18999 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
19000 "dist_schedule"); */
19001 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
19002 warning_at (loc, OPT_Wopenmp, "too many %qs clauses", "dist_schedule");
19003 if (t == error_mark_node)
19004 return list;
19006 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
19007 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
19008 OMP_CLAUSE_CHAIN (c) = list;
19009 return c;
19012 /* OpenMP 4.0:
19013 proc_bind ( proc-bind-kind )
19015 proc-bind-kind:
19016 primary | master | close | spread
19017 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
19019 static tree
19020 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
19022 location_t clause_loc = c_parser_peek_token (parser)->location;
19023 enum omp_clause_proc_bind_kind kind;
19024 tree c;
19026 matching_parens parens;
19027 if (!parens.require_open (parser))
19028 return list;
19030 if (c_parser_next_token_is (parser, CPP_NAME))
19032 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19033 if (strcmp ("primary", p) == 0)
19034 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
19035 else if (strcmp ("master", p) == 0)
19036 kind = OMP_CLAUSE_PROC_BIND_MASTER;
19037 else if (strcmp ("close", p) == 0)
19038 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
19039 else if (strcmp ("spread", p) == 0)
19040 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
19041 else
19042 goto invalid_kind;
19044 else
19045 goto invalid_kind;
19047 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
19048 c_parser_consume_token (parser);
19049 parens.skip_until_found_close (parser);
19050 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
19051 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
19052 OMP_CLAUSE_CHAIN (c) = list;
19053 return c;
19055 invalid_kind:
19056 c_parser_error (parser, "invalid proc_bind kind");
19057 parens.skip_until_found_close (parser);
19058 return list;
19061 /* OpenMP 5.0:
19062 device_type ( host | nohost | any ) */
19064 static tree
19065 c_parser_omp_clause_device_type (c_parser *parser, tree list)
19067 location_t clause_loc = c_parser_peek_token (parser)->location;
19068 enum omp_clause_device_type_kind kind;
19069 tree c;
19071 matching_parens parens;
19072 if (!parens.require_open (parser))
19073 return list;
19075 if (c_parser_next_token_is (parser, CPP_NAME))
19077 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19078 if (strcmp ("host", p) == 0)
19079 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
19080 else if (strcmp ("nohost", p) == 0)
19081 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
19082 else if (strcmp ("any", p) == 0)
19083 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
19084 else
19085 goto invalid_kind;
19087 else
19088 goto invalid_kind;
19090 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
19091 "device_type");
19092 c_parser_consume_token (parser);
19093 parens.skip_until_found_close (parser);
19094 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
19095 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
19096 OMP_CLAUSE_CHAIN (c) = list;
19097 return c;
19099 invalid_kind:
19100 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
19101 parens.skip_until_found_close (parser);
19102 return list;
19105 /* OpenMP 4.0:
19106 from ( variable-list )
19107 to ( variable-list )
19109 OpenMP 5.1:
19110 from ( [present :] variable-list )
19111 to ( [present :] variable-list ) */
19113 static tree
19114 c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
19115 tree list)
19117 location_t loc = c_parser_peek_token (parser)->location;
19118 matching_parens parens;
19119 if (!parens.require_open (parser))
19120 return list;
19122 bool present = false;
19123 c_token *token = c_parser_peek_token (parser);
19125 if (token->type == CPP_NAME
19126 && strcmp (IDENTIFIER_POINTER (token->value), "present") == 0
19127 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
19129 present = true;
19130 c_parser_consume_token (parser);
19131 c_parser_consume_token (parser);
19134 tree nl = c_parser_omp_variable_list (parser, loc, kind, list);
19135 parens.skip_until_found_close (parser);
19137 if (present)
19138 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
19139 OMP_CLAUSE_MOTION_PRESENT (c) = 1;
19141 return nl;
19144 /* OpenMP 4.0:
19145 uniform ( variable-list ) */
19147 static tree
19148 c_parser_omp_clause_uniform (c_parser *parser, tree list)
19150 /* The clauses location. */
19151 location_t loc = c_parser_peek_token (parser)->location;
19153 matching_parens parens;
19154 if (parens.require_open (parser))
19156 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
19157 list);
19158 parens.skip_until_found_close (parser);
19160 return list;
19163 /* OpenMP 5.0:
19164 detach ( event-handle ) */
19166 static tree
19167 c_parser_omp_clause_detach (c_parser *parser, tree list)
19169 matching_parens parens;
19170 location_t clause_loc = c_parser_peek_token (parser)->location;
19172 if (!parens.require_open (parser))
19173 return list;
19175 if (c_parser_next_token_is_not (parser, CPP_NAME)
19176 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
19178 c_parser_error (parser, "expected identifier");
19179 parens.skip_until_found_close (parser);
19180 return list;
19183 tree t = lookup_name (c_parser_peek_token (parser)->value);
19184 if (t == NULL_TREE)
19186 undeclared_variable (c_parser_peek_token (parser)->location,
19187 c_parser_peek_token (parser)->value);
19188 parens.skip_until_found_close (parser);
19189 return list;
19191 c_parser_consume_token (parser);
19193 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
19194 if (!INTEGRAL_TYPE_P (type)
19195 || TREE_CODE (type) != ENUMERAL_TYPE
19196 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
19198 error_at (clause_loc, "%<detach%> clause event handle "
19199 "has type %qT rather than "
19200 "%<omp_event_handle_t%>",
19201 type);
19202 parens.skip_until_found_close (parser);
19203 return list;
19206 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
19207 OMP_CLAUSE_DECL (u) = t;
19208 OMP_CLAUSE_CHAIN (u) = list;
19209 parens.skip_until_found_close (parser);
19210 return u;
19213 /* Parse all OpenACC clauses. The set clauses allowed by the directive
19214 is a bitmask in MASK. Return the list of clauses found. */
19216 static tree
19217 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
19218 const char *where, bool finish_p = true,
19219 bool target_p = false)
19221 tree clauses = NULL;
19222 bool first = true;
19224 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19226 location_t here;
19227 pragma_omp_clause c_kind;
19228 const char *c_name;
19229 tree prev = clauses;
19231 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
19232 c_parser_consume_token (parser);
19234 here = c_parser_peek_token (parser)->location;
19235 c_kind = c_parser_omp_clause_name (parser);
19237 switch (c_kind)
19239 case PRAGMA_OACC_CLAUSE_ASYNC:
19240 clauses = c_parser_oacc_clause_async (parser, clauses);
19241 c_name = "async";
19242 break;
19243 case PRAGMA_OACC_CLAUSE_AUTO:
19244 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
19245 clauses);
19246 c_name = "auto";
19247 break;
19248 case PRAGMA_OACC_CLAUSE_ATTACH:
19249 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19250 c_name = "attach";
19251 break;
19252 case PRAGMA_OACC_CLAUSE_COLLAPSE:
19253 clauses = c_parser_omp_clause_collapse (parser, clauses);
19254 c_name = "collapse";
19255 break;
19256 case PRAGMA_OACC_CLAUSE_COPY:
19257 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19258 c_name = "copy";
19259 break;
19260 case PRAGMA_OACC_CLAUSE_COPYIN:
19261 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19262 c_name = "copyin";
19263 break;
19264 case PRAGMA_OACC_CLAUSE_COPYOUT:
19265 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19266 c_name = "copyout";
19267 break;
19268 case PRAGMA_OACC_CLAUSE_CREATE:
19269 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19270 c_name = "create";
19271 break;
19272 case PRAGMA_OACC_CLAUSE_DELETE:
19273 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19274 c_name = "delete";
19275 break;
19276 case PRAGMA_OMP_CLAUSE_DEFAULT:
19277 clauses = c_parser_omp_clause_default (parser, clauses, true);
19278 c_name = "default";
19279 break;
19280 case PRAGMA_OACC_CLAUSE_DETACH:
19281 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19282 c_name = "detach";
19283 break;
19284 case PRAGMA_OACC_CLAUSE_DEVICE:
19285 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19286 c_name = "device";
19287 break;
19288 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
19289 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
19290 c_name = "deviceptr";
19291 break;
19292 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
19293 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19294 c_name = "device_resident";
19295 break;
19296 case PRAGMA_OACC_CLAUSE_FINALIZE:
19297 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
19298 clauses);
19299 c_name = "finalize";
19300 break;
19301 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
19302 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
19303 c_name = "firstprivate";
19304 break;
19305 case PRAGMA_OACC_CLAUSE_GANG:
19306 c_name = "gang";
19307 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
19308 c_name, clauses);
19309 break;
19310 case PRAGMA_OACC_CLAUSE_HOST:
19311 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19312 c_name = "host";
19313 break;
19314 case PRAGMA_OACC_CLAUSE_IF:
19315 clauses = c_parser_omp_clause_if (parser, clauses, false);
19316 c_name = "if";
19317 break;
19318 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
19319 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
19320 clauses);
19321 c_name = "if_present";
19322 break;
19323 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
19324 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
19325 clauses);
19326 c_name = "independent";
19327 break;
19328 case PRAGMA_OACC_CLAUSE_LINK:
19329 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19330 c_name = "link";
19331 break;
19332 case PRAGMA_OACC_CLAUSE_NO_CREATE:
19333 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19334 c_name = "no_create";
19335 break;
19336 case PRAGMA_OACC_CLAUSE_NOHOST:
19337 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
19338 clauses);
19339 c_name = "nohost";
19340 break;
19341 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
19342 clauses = c_parser_oacc_single_int_clause (parser,
19343 OMP_CLAUSE_NUM_GANGS,
19344 clauses);
19345 c_name = "num_gangs";
19346 break;
19347 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
19348 clauses = c_parser_oacc_single_int_clause (parser,
19349 OMP_CLAUSE_NUM_WORKERS,
19350 clauses);
19351 c_name = "num_workers";
19352 break;
19353 case PRAGMA_OACC_CLAUSE_PRESENT:
19354 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19355 c_name = "present";
19356 break;
19357 case PRAGMA_OACC_CLAUSE_PRIVATE:
19358 clauses = c_parser_omp_clause_private (parser, clauses);
19359 c_name = "private";
19360 break;
19361 case PRAGMA_OACC_CLAUSE_REDUCTION:
19362 clauses
19363 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
19364 false, clauses);
19365 c_name = "reduction";
19366 break;
19367 case PRAGMA_OACC_CLAUSE_SELF:
19368 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)) == 0)
19369 /* OpenACC compute construct */
19370 clauses = c_parser_oacc_compute_clause_self (parser, clauses);
19371 else
19372 /* OpenACC 'update' directive */
19373 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19374 c_name = "self";
19375 break;
19376 case PRAGMA_OACC_CLAUSE_SEQ:
19377 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
19378 clauses);
19379 c_name = "seq";
19380 break;
19381 case PRAGMA_OACC_CLAUSE_TILE:
19382 clauses = c_parser_oacc_clause_tile (parser, clauses);
19383 c_name = "tile";
19384 break;
19385 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
19386 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
19387 c_name = "use_device";
19388 break;
19389 case PRAGMA_OACC_CLAUSE_VECTOR:
19390 c_name = "vector";
19391 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
19392 c_name, clauses);
19393 break;
19394 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
19395 clauses = c_parser_oacc_single_int_clause (parser,
19396 OMP_CLAUSE_VECTOR_LENGTH,
19397 clauses);
19398 c_name = "vector_length";
19399 break;
19400 case PRAGMA_OACC_CLAUSE_WAIT:
19401 clauses = c_parser_oacc_clause_wait (parser, clauses);
19402 c_name = "wait";
19403 break;
19404 case PRAGMA_OACC_CLAUSE_WORKER:
19405 c_name = "worker";
19406 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
19407 c_name, clauses);
19408 break;
19409 default:
19410 c_parser_error (parser, "expected an OpenACC clause");
19411 goto saw_error;
19414 first = false;
19416 if (((mask >> c_kind) & 1) == 0)
19418 /* Remove the invalid clause(s) from the list to avoid
19419 confusing the rest of the compiler. */
19420 clauses = prev;
19421 error_at (here, "%qs is not valid for %qs", c_name, where);
19425 saw_error:
19426 c_parser_skip_to_pragma_eol (parser);
19428 if (finish_p)
19429 return c_finish_omp_clauses (clauses, target_p ? C_ORT_ACC_TARGET
19430 : C_ORT_ACC);
19432 return clauses;
19435 /* Parse all OpenMP clauses. The set clauses allowed by the directive
19436 is a bitmask in MASK. Return the list of clauses found.
19437 FINISH_P set if c_finish_omp_clauses should be called.
19438 NESTED non-zero if clauses should be terminated by closing paren instead
19439 of end of pragma. If it is 2, additionally commas are required in between
19440 the clauses. */
19442 static tree
19443 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
19444 const char *where, bool finish_p = true,
19445 int nested = 0)
19447 tree clauses = NULL;
19448 bool first = true;
19450 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19452 location_t here;
19453 pragma_omp_clause c_kind;
19454 const char *c_name;
19455 tree prev = clauses;
19457 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
19458 break;
19460 if (!first || nested != 2)
19462 if (c_parser_next_token_is (parser, CPP_COMMA))
19463 c_parser_consume_token (parser);
19464 else if (nested == 2)
19465 error_at (c_parser_peek_token (parser)->location,
19466 "clauses in %<simd%> trait should be separated "
19467 "by %<,%>");
19470 here = c_parser_peek_token (parser)->location;
19471 c_kind = c_parser_omp_clause_name (parser);
19473 switch (c_kind)
19475 case PRAGMA_OMP_CLAUSE_BIND:
19476 clauses = c_parser_omp_clause_bind (parser, clauses);
19477 c_name = "bind";
19478 break;
19479 case PRAGMA_OMP_CLAUSE_COLLAPSE:
19480 clauses = c_parser_omp_clause_collapse (parser, clauses);
19481 c_name = "collapse";
19482 break;
19483 case PRAGMA_OMP_CLAUSE_COPYIN:
19484 clauses = c_parser_omp_clause_copyin (parser, clauses);
19485 c_name = "copyin";
19486 break;
19487 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
19488 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
19489 c_name = "copyprivate";
19490 break;
19491 case PRAGMA_OMP_CLAUSE_DEFAULT:
19492 clauses = c_parser_omp_clause_default (parser, clauses, false);
19493 c_name = "default";
19494 break;
19495 case PRAGMA_OMP_CLAUSE_DETACH:
19496 clauses = c_parser_omp_clause_detach (parser, clauses);
19497 c_name = "detach";
19498 break;
19499 case PRAGMA_OMP_CLAUSE_FILTER:
19500 clauses = c_parser_omp_clause_filter (parser, clauses);
19501 c_name = "filter";
19502 break;
19503 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
19504 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
19505 c_name = "firstprivate";
19506 break;
19507 case PRAGMA_OMP_CLAUSE_FINAL:
19508 clauses = c_parser_omp_clause_final (parser, clauses);
19509 c_name = "final";
19510 break;
19511 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
19512 clauses = c_parser_omp_clause_grainsize (parser, clauses);
19513 c_name = "grainsize";
19514 break;
19515 case PRAGMA_OMP_CLAUSE_HINT:
19516 clauses = c_parser_omp_clause_hint (parser, clauses);
19517 c_name = "hint";
19518 break;
19519 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
19520 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
19521 c_name = "defaultmap";
19522 break;
19523 case PRAGMA_OMP_CLAUSE_IF:
19524 clauses = c_parser_omp_clause_if (parser, clauses, true);
19525 c_name = "if";
19526 break;
19527 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
19528 clauses
19529 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
19530 true, clauses);
19531 c_name = "in_reduction";
19532 break;
19533 case PRAGMA_OMP_CLAUSE_INDIRECT:
19534 clauses = c_parser_omp_clause_indirect (parser, clauses);
19535 c_name = "indirect";
19536 break;
19537 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
19538 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
19539 c_name = "lastprivate";
19540 break;
19541 case PRAGMA_OMP_CLAUSE_MERGEABLE:
19542 clauses = c_parser_omp_clause_mergeable (parser, clauses);
19543 c_name = "mergeable";
19544 break;
19545 case PRAGMA_OMP_CLAUSE_NOWAIT:
19546 clauses = c_parser_omp_clause_nowait (parser, clauses);
19547 c_name = "nowait";
19548 break;
19549 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
19550 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
19551 c_name = "num_tasks";
19552 break;
19553 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
19554 clauses = c_parser_omp_clause_num_threads (parser, clauses);
19555 c_name = "num_threads";
19556 break;
19557 case PRAGMA_OMP_CLAUSE_ORDER:
19558 clauses = c_parser_omp_clause_order (parser, clauses);
19559 c_name = "order";
19560 break;
19561 case PRAGMA_OMP_CLAUSE_ORDERED:
19562 clauses = c_parser_omp_clause_ordered (parser, clauses);
19563 c_name = "ordered";
19564 break;
19565 case PRAGMA_OMP_CLAUSE_PRIORITY:
19566 clauses = c_parser_omp_clause_priority (parser, clauses);
19567 c_name = "priority";
19568 break;
19569 case PRAGMA_OMP_CLAUSE_PRIVATE:
19570 clauses = c_parser_omp_clause_private (parser, clauses);
19571 c_name = "private";
19572 break;
19573 case PRAGMA_OMP_CLAUSE_REDUCTION:
19574 clauses
19575 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
19576 true, clauses);
19577 c_name = "reduction";
19578 break;
19579 case PRAGMA_OMP_CLAUSE_SCHEDULE:
19580 clauses = c_parser_omp_clause_schedule (parser, clauses);
19581 c_name = "schedule";
19582 break;
19583 case PRAGMA_OMP_CLAUSE_SHARED:
19584 clauses = c_parser_omp_clause_shared (parser, clauses);
19585 c_name = "shared";
19586 break;
19587 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
19588 clauses
19589 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
19590 true, clauses);
19591 c_name = "task_reduction";
19592 break;
19593 case PRAGMA_OMP_CLAUSE_UNTIED:
19594 clauses = c_parser_omp_clause_untied (parser, clauses);
19595 c_name = "untied";
19596 break;
19597 case PRAGMA_OMP_CLAUSE_INBRANCH:
19598 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
19599 clauses);
19600 c_name = "inbranch";
19601 break;
19602 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
19603 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
19604 c_name = "nontemporal";
19605 break;
19606 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
19607 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
19608 clauses);
19609 c_name = "notinbranch";
19610 break;
19611 case PRAGMA_OMP_CLAUSE_PARALLEL:
19612 clauses
19613 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
19614 clauses);
19615 c_name = "parallel";
19616 if (!first)
19618 clause_not_first:
19619 error_at (here, "%qs must be the first clause of %qs",
19620 c_name, where);
19621 clauses = prev;
19623 break;
19624 case PRAGMA_OMP_CLAUSE_FOR:
19625 clauses
19626 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
19627 clauses);
19628 c_name = "for";
19629 if (!first)
19630 goto clause_not_first;
19631 break;
19632 case PRAGMA_OMP_CLAUSE_SECTIONS:
19633 clauses
19634 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
19635 clauses);
19636 c_name = "sections";
19637 if (!first)
19638 goto clause_not_first;
19639 break;
19640 case PRAGMA_OMP_CLAUSE_TASKGROUP:
19641 clauses
19642 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
19643 clauses);
19644 c_name = "taskgroup";
19645 if (!first)
19646 goto clause_not_first;
19647 break;
19648 case PRAGMA_OMP_CLAUSE_LINK:
19649 clauses
19650 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
19651 c_name = "link";
19652 break;
19653 case PRAGMA_OMP_CLAUSE_TO:
19654 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
19656 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
19657 clauses);
19658 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
19659 OMP_CLAUSE_ENTER_TO (c) = 1;
19660 clauses = nl;
19662 else
19663 clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_TO,
19664 clauses);
19665 c_name = "to";
19666 break;
19667 case PRAGMA_OMP_CLAUSE_FROM:
19668 clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_FROM,
19669 clauses);
19670 c_name = "from";
19671 break;
19672 case PRAGMA_OMP_CLAUSE_UNIFORM:
19673 clauses = c_parser_omp_clause_uniform (parser, clauses);
19674 c_name = "uniform";
19675 break;
19676 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
19677 clauses = c_parser_omp_clause_num_teams (parser, clauses);
19678 c_name = "num_teams";
19679 break;
19680 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
19681 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
19682 c_name = "thread_limit";
19683 break;
19684 case PRAGMA_OMP_CLAUSE_ALIGNED:
19685 clauses = c_parser_omp_clause_aligned (parser, clauses);
19686 c_name = "aligned";
19687 break;
19688 case PRAGMA_OMP_CLAUSE_ALLOCATE:
19689 clauses = c_parser_omp_clause_allocate (parser, clauses);
19690 c_name = "allocate";
19691 break;
19692 case PRAGMA_OMP_CLAUSE_LINEAR:
19693 clauses = c_parser_omp_clause_linear (parser, clauses);
19694 c_name = "linear";
19695 break;
19696 case PRAGMA_OMP_CLAUSE_AFFINITY:
19697 clauses = c_parser_omp_clause_affinity (parser, clauses);
19698 c_name = "affinity";
19699 break;
19700 case PRAGMA_OMP_CLAUSE_DEPEND:
19701 clauses = c_parser_omp_clause_depend (parser, clauses);
19702 c_name = "depend";
19703 break;
19704 case PRAGMA_OMP_CLAUSE_DOACROSS:
19705 clauses = c_parser_omp_clause_doacross (parser, clauses);
19706 c_name = "doacross";
19707 break;
19708 case PRAGMA_OMP_CLAUSE_MAP:
19709 clauses = c_parser_omp_clause_map (parser, clauses);
19710 c_name = "map";
19711 break;
19712 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
19713 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
19714 c_name = "use_device_ptr";
19715 break;
19716 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
19717 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
19718 c_name = "use_device_addr";
19719 break;
19720 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
19721 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
19722 c_name = "has_device_addr";
19723 break;
19724 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
19725 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
19726 c_name = "is_device_ptr";
19727 break;
19728 case PRAGMA_OMP_CLAUSE_DEVICE:
19729 clauses = c_parser_omp_clause_device (parser, clauses);
19730 c_name = "device";
19731 break;
19732 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
19733 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
19734 c_name = "dist_schedule";
19735 break;
19736 case PRAGMA_OMP_CLAUSE_PROC_BIND:
19737 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
19738 c_name = "proc_bind";
19739 break;
19740 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
19741 clauses = c_parser_omp_clause_device_type (parser, clauses);
19742 c_name = "device_type";
19743 break;
19744 case PRAGMA_OMP_CLAUSE_SAFELEN:
19745 clauses = c_parser_omp_clause_safelen (parser, clauses);
19746 c_name = "safelen";
19747 break;
19748 case PRAGMA_OMP_CLAUSE_SIMDLEN:
19749 clauses = c_parser_omp_clause_simdlen (parser, clauses);
19750 c_name = "simdlen";
19751 break;
19752 case PRAGMA_OMP_CLAUSE_NOGROUP:
19753 clauses = c_parser_omp_clause_nogroup (parser, clauses);
19754 c_name = "nogroup";
19755 break;
19756 case PRAGMA_OMP_CLAUSE_THREADS:
19757 clauses
19758 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
19759 clauses);
19760 c_name = "threads";
19761 break;
19762 case PRAGMA_OMP_CLAUSE_SIMD:
19763 clauses
19764 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
19765 clauses);
19766 c_name = "simd";
19767 break;
19768 case PRAGMA_OMP_CLAUSE_ENTER:
19769 clauses
19770 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
19771 clauses);
19772 c_name = "enter";
19773 break;
19774 default:
19775 c_parser_error (parser, "expected an OpenMP clause");
19776 goto saw_error;
19779 first = false;
19781 if (((mask >> c_kind) & 1) == 0)
19783 /* Remove the invalid clause(s) from the list to avoid
19784 confusing the rest of the compiler. */
19785 clauses = prev;
19786 error_at (here, "%qs is not valid for %qs", c_name, where);
19790 saw_error:
19791 if (!nested)
19792 c_parser_skip_to_pragma_eol (parser);
19794 if (finish_p)
19796 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
19797 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
19798 return c_finish_omp_clauses (clauses, C_ORT_OMP);
19801 return clauses;
19804 /* OpenACC 2.0, OpenMP 2.5:
19805 structured-block:
19806 statement
19808 In practice, we're also interested in adding the statement to an
19809 outer node. So it is convenient if we work around the fact that
19810 c_parser_statement calls add_stmt. */
19812 static tree
19813 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
19815 tree stmt = push_stmt_list ();
19816 parser->omp_attrs_forbidden_p = true;
19817 c_parser_statement (parser, if_p);
19818 return pop_stmt_list (stmt);
19821 /* OpenACC 2.0:
19822 # pragma acc cache (variable-list) new-line
19824 LOC is the location of the #pragma token.
19827 static tree
19828 c_parser_oacc_cache (location_t loc, c_parser *parser)
19830 tree stmt, clauses;
19832 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
19833 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
19835 c_parser_skip_to_pragma_eol (parser);
19837 stmt = make_node (OACC_CACHE);
19838 TREE_TYPE (stmt) = void_type_node;
19839 OACC_CACHE_CLAUSES (stmt) = clauses;
19840 SET_EXPR_LOCATION (stmt, loc);
19841 add_stmt (stmt);
19843 return stmt;
19846 /* OpenACC 2.0:
19847 # pragma acc data oacc-data-clause[optseq] new-line
19848 structured-block
19850 LOC is the location of the #pragma token.
19853 #define OACC_DATA_CLAUSE_MASK \
19854 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19858 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
19860 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
19863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19865 static tree
19866 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
19868 tree stmt, clauses, block;
19870 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
19871 "#pragma acc data");
19873 block = c_begin_omp_parallel ();
19874 add_stmt (c_parser_omp_structured_block (parser, if_p));
19876 stmt = c_finish_oacc_data (loc, clauses, block);
19878 return stmt;
19881 /* OpenACC 2.0:
19882 # pragma acc declare oacc-data-clause[optseq] new-line
19885 #define OACC_DECLARE_CLAUSE_MASK \
19886 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
19892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
19893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19895 static void
19896 c_parser_oacc_declare (c_parser *parser)
19898 location_t pragma_loc = c_parser_peek_token (parser)->location;
19899 tree clauses, stmt, t, decl;
19901 bool error = false;
19903 c_parser_consume_pragma (parser);
19905 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
19906 "#pragma acc declare");
19907 if (!clauses)
19909 error_at (pragma_loc,
19910 "no valid clauses specified in %<#pragma acc declare%>");
19911 return;
19914 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
19916 location_t loc = OMP_CLAUSE_LOCATION (t);
19917 decl = OMP_CLAUSE_DECL (t);
19918 if (!DECL_P (decl))
19920 error_at (loc, "array section in %<#pragma acc declare%>");
19921 error = true;
19922 continue;
19925 switch (OMP_CLAUSE_MAP_KIND (t))
19927 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19928 case GOMP_MAP_ALLOC:
19929 case GOMP_MAP_TO:
19930 case GOMP_MAP_FORCE_DEVICEPTR:
19931 case GOMP_MAP_DEVICE_RESIDENT:
19932 break;
19934 case GOMP_MAP_LINK:
19935 if (!global_bindings_p ()
19936 && (TREE_STATIC (decl)
19937 || !DECL_EXTERNAL (decl)))
19939 error_at (loc,
19940 "%qD must be a global variable in "
19941 "%<#pragma acc declare link%>",
19942 decl);
19943 error = true;
19944 continue;
19946 break;
19948 default:
19949 if (global_bindings_p ())
19951 error_at (loc, "invalid OpenACC clause at file scope");
19952 error = true;
19953 continue;
19955 if (DECL_EXTERNAL (decl))
19957 error_at (loc,
19958 "invalid use of %<extern%> variable %qD "
19959 "in %<#pragma acc declare%>", decl);
19960 error = true;
19961 continue;
19963 else if (TREE_PUBLIC (decl))
19965 error_at (loc,
19966 "invalid use of %<global%> variable %qD "
19967 "in %<#pragma acc declare%>", decl);
19968 error = true;
19969 continue;
19971 break;
19974 if (!c_check_in_current_scope (decl))
19976 error_at (loc,
19977 "%qD must be a variable declared in the same scope as "
19978 "%<#pragma acc declare%>", decl);
19979 error = true;
19980 continue;
19983 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
19984 || lookup_attribute ("omp declare target link",
19985 DECL_ATTRIBUTES (decl)))
19987 error_at (loc, "variable %qD used more than once with "
19988 "%<#pragma acc declare%>", decl);
19989 error = true;
19990 continue;
19993 if (!error)
19995 tree id;
19997 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
19998 id = get_identifier ("omp declare target link");
19999 else
20000 id = get_identifier ("omp declare target");
20002 DECL_ATTRIBUTES (decl)
20003 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
20005 if (global_bindings_p ())
20007 symtab_node *node = symtab_node::get (decl);
20008 if (node != NULL)
20010 node->offloadable = 1;
20011 if (ENABLE_OFFLOADING)
20013 g->have_offload = true;
20014 if (is_a <varpool_node *> (node))
20015 vec_safe_push (offload_vars, decl);
20022 if (error || global_bindings_p ())
20023 return;
20025 stmt = make_node (OACC_DECLARE);
20026 TREE_TYPE (stmt) = void_type_node;
20027 OACC_DECLARE_CLAUSES (stmt) = clauses;
20028 SET_EXPR_LOCATION (stmt, pragma_loc);
20030 add_stmt (stmt);
20032 return;
20035 /* OpenACC 2.0:
20036 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
20040 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
20043 LOC is the location of the #pragma token.
20046 #define OACC_ENTER_DATA_CLAUSE_MASK \
20047 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20051 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20054 #define OACC_EXIT_DATA_CLAUSE_MASK \
20055 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
20059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
20060 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
20061 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20063 static void
20064 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
20066 location_t loc = c_parser_peek_token (parser)->location;
20067 tree clauses, stmt;
20068 const char *p = "";
20070 c_parser_consume_pragma (parser);
20072 if (c_parser_next_token_is (parser, CPP_NAME))
20074 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20075 c_parser_consume_token (parser);
20078 if (strcmp (p, "data") != 0)
20080 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
20081 enter ? "enter" : "exit");
20082 parser->error = true;
20083 c_parser_skip_to_pragma_eol (parser);
20084 return;
20087 if (enter)
20088 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
20089 "#pragma acc enter data");
20090 else
20091 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
20092 "#pragma acc exit data");
20094 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
20096 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
20097 enter ? "enter" : "exit");
20098 return;
20101 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
20102 TREE_TYPE (stmt) = void_type_node;
20103 OMP_STANDALONE_CLAUSES (stmt) = clauses;
20104 SET_EXPR_LOCATION (stmt, loc);
20105 add_stmt (stmt);
20109 /* OpenACC 2.0:
20110 # pragma acc host_data oacc-data-clause[optseq] new-line
20111 structured-block
20114 #define OACC_HOST_DATA_CLAUSE_MASK \
20115 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
20116 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20117 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
20119 static tree
20120 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
20122 tree stmt, clauses, block;
20124 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
20125 "#pragma acc host_data", false);
20126 if (!omp_find_clause (clauses, OMP_CLAUSE_USE_DEVICE_PTR))
20128 error_at (loc, "%<host_data%> construct requires %<use_device%> clause");
20129 return error_mark_node;
20131 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
20132 block = c_begin_omp_parallel ();
20133 add_stmt (c_parser_omp_structured_block (parser, if_p));
20134 stmt = c_finish_oacc_host_data (loc, clauses, block);
20135 return stmt;
20139 /* OpenACC 2.0:
20141 # pragma acc loop oacc-loop-clause[optseq] new-line
20142 structured-block
20144 LOC is the location of the #pragma token.
20147 #define OACC_LOOP_CLAUSE_MASK \
20148 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
20149 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20150 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
20155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
20156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
20158 static tree
20159 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
20160 omp_clause_mask mask, tree *cclauses, bool *if_p)
20162 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
20164 strcat (p_name, " loop");
20165 mask |= OACC_LOOP_CLAUSE_MASK;
20167 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
20168 /*finish_p=*/cclauses == NULL,
20169 /*target=*/is_parallel);
20170 if (cclauses)
20172 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
20173 if (*cclauses)
20174 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC_TARGET);
20175 if (clauses)
20176 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
20179 tree block = c_begin_compound_stmt (true);
20180 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
20181 if_p);
20182 block = c_end_compound_stmt (loc, block, true);
20183 add_stmt (block);
20185 return stmt;
20188 /* OpenACC 2.0:
20189 # pragma acc kernels oacc-kernels-clause[optseq] new-line
20190 structured-block
20194 # pragma acc parallel oacc-parallel-clause[optseq] new-line
20195 structured-block
20197 OpenACC 2.6:
20199 # pragma acc serial oacc-serial-clause[optseq] new-line
20200 structured-block
20202 LOC is the location of the #pragma token.
20205 #define OACC_KERNELS_CLAUSE_MASK \
20206 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20207 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20209 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20210 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20211 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20214 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20215 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20216 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20217 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20218 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20219 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20220 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20221 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20223 #define OACC_PARALLEL_CLAUSE_MASK \
20224 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20225 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20226 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20227 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20228 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20229 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20230 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20231 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20232 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20233 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20235 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20236 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20244 #define OACC_SERIAL_CLAUSE_MASK \
20245 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20250 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20251 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20252 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20253 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20254 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20255 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20256 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20257 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20258 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20259 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20260 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20262 static tree
20263 c_parser_oacc_compute (location_t loc, c_parser *parser,
20264 enum pragma_kind p_kind, char *p_name, bool *if_p)
20266 omp_clause_mask mask;
20267 enum tree_code code;
20268 switch (p_kind)
20270 case PRAGMA_OACC_KERNELS:
20271 strcat (p_name, " kernels");
20272 mask = OACC_KERNELS_CLAUSE_MASK;
20273 code = OACC_KERNELS;
20274 break;
20275 case PRAGMA_OACC_PARALLEL:
20276 strcat (p_name, " parallel");
20277 mask = OACC_PARALLEL_CLAUSE_MASK;
20278 code = OACC_PARALLEL;
20279 break;
20280 case PRAGMA_OACC_SERIAL:
20281 strcat (p_name, " serial");
20282 mask = OACC_SERIAL_CLAUSE_MASK;
20283 code = OACC_SERIAL;
20284 break;
20285 default:
20286 gcc_unreachable ();
20289 if (c_parser_next_token_is (parser, CPP_NAME))
20291 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20292 if (strcmp (p, "loop") == 0)
20294 c_parser_consume_token (parser);
20295 tree block = c_begin_omp_parallel ();
20296 tree clauses;
20297 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
20298 return c_finish_omp_construct (loc, code, block, clauses);
20302 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
20303 /*finish_p=*/true,
20304 /*target=*/true);
20306 tree block = c_begin_omp_parallel ();
20307 add_stmt (c_parser_omp_structured_block (parser, if_p));
20309 return c_finish_omp_construct (loc, code, block, clauses);
20312 /* OpenACC 2.0:
20313 # pragma acc routine oacc-routine-clause[optseq] new-line
20314 function-definition
20316 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
20319 #define OACC_ROUTINE_CLAUSE_MASK \
20320 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20321 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20322 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20323 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20324 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
20326 /* Parse an OpenACC routine directive. For named directives, we apply
20327 immediately to the named function. For unnamed ones we then parse
20328 a declaration or definition, which must be for a function. */
20330 static void
20331 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
20333 gcc_checking_assert (context == pragma_external);
20335 oacc_routine_data data;
20336 data.error_seen = false;
20337 data.fndecl_seen = false;
20338 data.loc = c_parser_peek_token (parser)->location;
20340 c_parser_consume_pragma (parser);
20342 /* Look for optional '( name )'. */
20343 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20345 c_parser_consume_token (parser); /* '(' */
20347 tree decl = NULL_TREE;
20348 c_token *name_token = c_parser_peek_token (parser);
20349 location_t name_loc = name_token->location;
20350 if (name_token->type == CPP_NAME
20351 && (name_token->id_kind == C_ID_ID
20352 || name_token->id_kind == C_ID_TYPENAME))
20354 decl = lookup_name (name_token->value);
20355 if (!decl)
20356 error_at (name_loc,
20357 "%qE has not been declared", name_token->value);
20358 c_parser_consume_token (parser);
20360 else
20361 c_parser_error (parser, "expected function name");
20363 if (!decl
20364 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20366 c_parser_skip_to_pragma_eol (parser, false);
20367 return;
20370 data.clauses
20371 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
20372 "#pragma acc routine");
20373 /* The clauses are in reverse order; fix that to make later diagnostic
20374 emission easier. */
20375 data.clauses = nreverse (data.clauses);
20377 if (TREE_CODE (decl) != FUNCTION_DECL)
20379 error_at (name_loc, "%qD does not refer to a function", decl);
20380 return;
20383 c_finish_oacc_routine (&data, decl, false);
20385 else /* No optional '( name )'. */
20387 data.clauses
20388 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
20389 "#pragma acc routine");
20390 /* The clauses are in reverse order; fix that to make later diagnostic
20391 emission easier. */
20392 data.clauses = nreverse (data.clauses);
20394 /* Emit a helpful diagnostic if there's another pragma following this
20395 one. Also don't allow a static assertion declaration, as in the
20396 following we'll just parse a *single* "declaration or function
20397 definition", and the static assertion counts an one. */
20398 if (c_parser_next_token_is (parser, CPP_PRAGMA)
20399 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
20401 error_at (data.loc,
20402 "%<#pragma acc routine%> not immediately followed by"
20403 " function declaration or definition");
20404 /* ..., and then just keep going. */
20405 return;
20408 /* We only have to consider the pragma_external case here. */
20409 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20410 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20412 int ext = disable_extension_diagnostics ();
20414 c_parser_consume_token (parser);
20415 while (c_parser_next_token_is (parser, CPP_KEYWORD)
20416 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20417 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20418 NULL, NULL, false, NULL, &data);
20419 restore_extension_diagnostics (ext);
20421 else
20422 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20423 NULL, NULL, false, NULL, &data);
20427 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
20428 IS_DEFN is true if we're applying it to the definition. */
20430 static void
20431 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
20432 bool is_defn)
20434 /* Keep going if we're in error reporting mode. */
20435 if (data->error_seen
20436 || fndecl == error_mark_node)
20437 return;
20439 if (data->fndecl_seen)
20441 error_at (data->loc,
20442 "%<#pragma acc routine%> not immediately followed by"
20443 " a single function declaration or definition");
20444 data->error_seen = true;
20445 return;
20447 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
20449 error_at (data->loc,
20450 "%<#pragma acc routine%> not immediately followed by"
20451 " function declaration or definition");
20452 data->error_seen = true;
20453 return;
20456 int compatible
20457 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
20458 "#pragma acc routine");
20459 if (compatible < 0)
20461 data->error_seen = true;
20462 return;
20464 if (compatible > 0)
20467 else
20469 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
20471 error_at (data->loc,
20472 TREE_USED (fndecl)
20473 ? G_("%<#pragma acc routine%> must be applied before use")
20474 : G_("%<#pragma acc routine%> must be applied before"
20475 " definition"));
20476 data->error_seen = true;
20477 return;
20480 /* Set the routine's level of parallelism. */
20481 tree dims = oacc_build_routine_dims (data->clauses);
20482 oacc_replace_fn_attrib (fndecl, dims);
20484 /* Add an "omp declare target" attribute. */
20485 DECL_ATTRIBUTES (fndecl)
20486 = tree_cons (get_identifier ("omp declare target"),
20487 data->clauses, DECL_ATTRIBUTES (fndecl));
20490 /* Remember that we've used this "#pragma acc routine". */
20491 data->fndecl_seen = true;
20494 /* OpenACC 2.0:
20495 # pragma acc update oacc-update-clause[optseq] new-line
20498 #define OACC_UPDATE_CLAUSE_MASK \
20499 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
20501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
20502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20503 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
20504 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20505 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20507 static void
20508 c_parser_oacc_update (c_parser *parser)
20510 location_t loc = c_parser_peek_token (parser)->location;
20512 c_parser_consume_pragma (parser);
20514 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
20515 "#pragma acc update");
20516 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
20518 error_at (loc,
20519 "%<#pragma acc update%> must contain at least one "
20520 "%<device%> or %<host%> or %<self%> clause");
20521 return;
20524 if (parser->error)
20525 return;
20527 tree stmt = make_node (OACC_UPDATE);
20528 TREE_TYPE (stmt) = void_type_node;
20529 OACC_UPDATE_CLAUSES (stmt) = clauses;
20530 SET_EXPR_LOCATION (stmt, loc);
20531 add_stmt (stmt);
20534 /* OpenACC 2.0:
20535 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
20537 LOC is the location of the #pragma token.
20540 #define OACC_WAIT_CLAUSE_MASK \
20541 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
20543 static tree
20544 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
20546 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
20548 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
20549 list = c_parser_oacc_wait_list (parser, loc, list);
20551 strcpy (p_name, " wait");
20552 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
20553 stmt = c_finish_oacc_wait (loc, list, clauses);
20554 add_stmt (stmt);
20556 return stmt;
20559 struct c_omp_loc_tree
20561 location_t loc;
20562 tree var;
20565 /* Check whether the expression used in the allocator clause is declared or
20566 modified between the variable declaration and its allocate directive. */
20567 static tree
20568 c_check_omp_allocate_allocator_r (tree *tp, int *, void *data)
20570 tree var = ((struct c_omp_loc_tree *) data)->var;
20571 location_t loc = ((struct c_omp_loc_tree *) data)->loc;
20572 if (TREE_CODE (*tp) == VAR_DECL && c_check_in_current_scope (*tp))
20574 if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
20575 DECL_SOURCE_LOCATION (*tp)))
20577 error_at (loc, "variable %qD used in the %<allocator%> clause must "
20578 "be declared before %qD", *tp, var);
20579 inform (DECL_SOURCE_LOCATION (*tp), "declared here");
20580 inform (DECL_SOURCE_LOCATION (var),
20581 "to be allocated variable declared here");
20582 return *tp;
20584 else
20586 gcc_assert (cur_stmt_list
20587 && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
20589 tree_stmt_iterator l = tsi_last (cur_stmt_list);
20590 while (!tsi_end_p (l))
20592 if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
20593 DECL_SOURCE_LOCATION (var)))
20594 break;
20595 if (TREE_CODE (*l) == MODIFY_EXPR
20596 && TREE_OPERAND (*l, 0) == *tp)
20598 error_at (loc,
20599 "variable %qD used in the %<allocator%> clause "
20600 "must not be modified between declaration of %qD "
20601 "and its %<allocate%> directive", *tp, var);
20602 inform (EXPR_LOCATION (*l), "modified here");
20603 inform (DECL_SOURCE_LOCATION (var),
20604 "to be allocated variable declared here");
20605 return *tp;
20607 --l;
20611 return NULL_TREE;
20614 /* OpenMP 5.x:
20615 # pragma omp allocate (list) clauses
20617 OpenMP 5.0 clause:
20618 allocator (omp_allocator_handle_t expression)
20620 OpenMP 5.1 additional clause:
20621 align (constant-expression)] */
20623 static void
20624 c_parser_omp_allocate (c_parser *parser)
20626 tree alignment = NULL_TREE;
20627 tree allocator = NULL_TREE;
20628 c_parser_consume_pragma (parser);
20629 location_t loc = c_parser_peek_token (parser)->location;
20630 location_t allocator_loc = UNKNOWN_LOCATION;
20631 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
20634 if (c_parser_next_token_is (parser, CPP_COMMA)
20635 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
20636 c_parser_consume_token (parser);
20637 if (!c_parser_next_token_is (parser, CPP_NAME))
20638 break;
20639 matching_parens parens;
20640 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20641 c_parser_consume_token (parser);
20642 location_t expr_loc = c_parser_peek_token (parser)->location;
20643 if (strcmp ("align", p) != 0 && strcmp ("allocator", p) != 0)
20645 error_at (c_parser_peek_token (parser)->location,
20646 "expected %<allocator%> or %<align%>");
20647 break;
20649 if (!parens.require_open (parser))
20650 break;
20652 c_expr expr = c_parser_expr_no_commas (parser, NULL);
20653 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
20654 expr_loc = c_parser_peek_token (parser)->location;
20655 if (expr.value == error_mark_node)
20657 else if (p[2] == 'i' && alignment)
20659 error_at (expr_loc, "too many %qs clauses", "align");
20660 break;
20662 else if (p[2] == 'i')
20664 alignment = c_fully_fold (expr.value, false, NULL);
20665 if (TREE_CODE (alignment) != INTEGER_CST
20666 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
20667 || tree_int_cst_sgn (alignment) != 1
20668 || !integer_pow2p (alignment))
20670 error_at (expr_loc, "%<align%> clause argument needs to be "
20671 "positive constant power of two integer "
20672 "expression");
20673 alignment = NULL_TREE;
20676 else if (allocator)
20678 error_at (expr_loc, "too many %qs clauses", "allocator");
20679 break;
20681 else
20683 allocator = c_fully_fold (expr.value, false, NULL);
20684 allocator_loc = expr_loc;
20685 tree orig_type
20686 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
20687 orig_type = TYPE_MAIN_VARIANT (orig_type);
20688 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
20689 || TREE_CODE (orig_type) != ENUMERAL_TYPE
20690 || TYPE_NAME (orig_type)
20691 != get_identifier ("omp_allocator_handle_t"))
20693 error_at (expr_loc,
20694 "%<allocator%> clause allocator expression has type "
20695 "%qT rather than %<omp_allocator_handle_t%>",
20696 TREE_TYPE (allocator));
20697 allocator = NULL_TREE;
20700 parens.skip_until_found_close (parser);
20701 } while (true);
20702 c_parser_skip_to_pragma_eol (parser);
20704 c_mark_decl_jump_unsafe_in_current_scope ();
20705 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
20707 tree var = OMP_CLAUSE_DECL (c);
20708 if (TREE_CODE (var) == PARM_DECL)
20710 error_at (OMP_CLAUSE_LOCATION (nl),
20711 "function parameter %qD may not appear as list item in an "
20712 "%<allocate%> directive", var);
20713 continue;
20715 if (!c_check_in_current_scope (var))
20717 error_at (OMP_CLAUSE_LOCATION (nl),
20718 "%<allocate%> directive must be in the same scope as %qD",
20719 var);
20720 inform (DECL_SOURCE_LOCATION (var), "declared here");
20721 continue;
20723 if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var)))
20725 error_at (OMP_CLAUSE_LOCATION (nl),
20726 "%qD already appeared as list item in an "
20727 "%<allocate%> directive", var);
20728 continue;
20730 if (TREE_STATIC (var))
20732 if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION)
20733 error_at (loc, "%<allocator%> clause required for "
20734 "static variable %qD", var);
20735 else if (allocator
20736 && (wi::to_widest (allocator) < 1
20737 || wi::to_widest (allocator) > 8))
20738 /* 8 = largest predefined memory allocator. */
20739 error_at (allocator_loc,
20740 "%<allocator%> clause requires a predefined allocator as "
20741 "%qD is static", var);
20742 else
20743 sorry_at (OMP_CLAUSE_LOCATION (nl),
20744 "%<#pragma omp allocate%> for static variables like "
20745 "%qD not yet supported", var);
20746 continue;
20748 if (allocator)
20750 struct c_omp_loc_tree data
20751 = {EXPR_LOC_OR_LOC (allocator, OMP_CLAUSE_LOCATION (nl)), var};
20752 walk_tree (&allocator, c_check_omp_allocate_allocator_r, &data, NULL);
20754 DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"),
20755 build_tree_list (allocator, alignment),
20756 DECL_ATTRIBUTES (var));
20760 /* OpenMP 2.5:
20761 # pragma omp atomic new-line
20762 expression-stmt
20764 expression-stmt:
20765 x binop= expr | x++ | ++x | x-- | --x
20766 binop:
20767 +, *, -, /, &, ^, |, <<, >>
20769 where x is an lvalue expression with scalar type.
20771 OpenMP 3.1:
20772 # pragma omp atomic new-line
20773 update-stmt
20775 # pragma omp atomic read new-line
20776 read-stmt
20778 # pragma omp atomic write new-line
20779 write-stmt
20781 # pragma omp atomic update new-line
20782 update-stmt
20784 # pragma omp atomic capture new-line
20785 capture-stmt
20787 # pragma omp atomic capture new-line
20788 capture-block
20790 read-stmt:
20791 v = x
20792 write-stmt:
20793 x = expr
20794 update-stmt:
20795 expression-stmt | x = x binop expr
20796 capture-stmt:
20797 v = expression-stmt
20798 capture-block:
20799 { v = x; update-stmt; } | { update-stmt; v = x; }
20801 OpenMP 4.0:
20802 update-stmt:
20803 expression-stmt | x = x binop expr | x = expr binop x
20804 capture-stmt:
20805 v = update-stmt
20806 capture-block:
20807 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
20809 OpenMP 5.1:
20810 # pragma omp atomic compare new-line
20811 conditional-update-atomic
20813 # pragma omp atomic compare capture new-line
20814 conditional-update-capture-atomic
20816 conditional-update-atomic:
20817 cond-expr-stmt | cond-update-stmt
20818 cond-expr-stmt:
20819 x = expr ordop x ? expr : x;
20820 x = x ordop expr ? expr : x;
20821 x = x == e ? d : x;
20822 cond-update-stmt:
20823 if (expr ordop x) { x = expr; }
20824 if (x ordop expr) { x = expr; }
20825 if (x == e) { x = d; }
20826 ordop:
20827 <, >
20828 conditional-update-capture-atomic:
20829 v = cond-expr-stmt
20830 { v = x; cond-expr-stmt }
20831 { cond-expr-stmt v = x; }
20832 { v = x; cond-update-stmt }
20833 { cond-update-stmt v = x; }
20834 if (x == e) { x = d; } else { v = x; }
20835 { r = x == e; if (r) { x = d; } }
20836 { r = x == e; if (r) { x = d; } else { v = x; } }
20838 where x, r and v are lvalue expressions with scalar type,
20839 expr, e and d are expressions with scalar type and e might be
20840 the same as v.
20842 LOC is the location of the #pragma token. */
20844 static void
20845 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
20847 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
20848 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
20849 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
20850 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
20851 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
20852 struct c_expr expr;
20853 location_t eloc;
20854 bool structured_block = false;
20855 bool swapped = false;
20856 bool non_lvalue_p;
20857 tree clauses = NULL_TREE;
20858 bool capture = false;
20859 bool compare = false;
20860 bool weak = false;
20861 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
20862 bool no_semicolon = false;
20863 bool extra_scope = false;
20865 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20867 if (c_parser_next_token_is (parser, CPP_COMMA)
20868 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
20869 c_parser_consume_token (parser);
20871 if (c_parser_next_token_is (parser, CPP_NAME))
20873 const char *p
20874 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20875 location_t cloc = c_parser_peek_token (parser)->location;
20876 enum tree_code new_code = ERROR_MARK;
20877 enum omp_memory_order new_memory_order
20878 = OMP_MEMORY_ORDER_UNSPECIFIED;
20879 bool new_capture = false;
20880 bool new_compare = false;
20881 bool new_weak = false;
20882 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
20884 if (!strcmp (p, "read"))
20885 new_code = OMP_ATOMIC_READ;
20886 else if (!strcmp (p, "write"))
20887 new_code = NOP_EXPR;
20888 else if (!strcmp (p, "update"))
20889 new_code = OMP_ATOMIC;
20890 else if (openacc && !strcmp (p, "capture"))
20891 new_code = OMP_ATOMIC_CAPTURE_NEW;
20892 else if (openacc)
20894 p = NULL;
20895 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
20896 "or %<capture%> clause");
20898 else if (!strcmp (p, "capture"))
20899 new_capture = true;
20900 else if (!strcmp (p, "compare"))
20901 new_compare = true;
20902 else if (!strcmp (p, "weak"))
20903 new_weak = true;
20904 else if (!strcmp (p, "fail"))
20906 matching_parens parens;
20908 c_parser_consume_token (parser);
20909 if (!parens.require_open (parser))
20910 continue;
20912 if (c_parser_next_token_is (parser, CPP_NAME))
20914 const char *q
20915 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20917 if (!strcmp (q, "seq_cst"))
20918 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
20919 else if (!strcmp (q, "acquire"))
20920 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
20921 else if (!strcmp (q, "relaxed"))
20922 new_fail = OMP_MEMORY_ORDER_RELAXED;
20925 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
20927 c_parser_consume_token (parser);
20928 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
20929 error_at (cloc, "too many %qs clauses", "fail");
20930 else
20931 fail = new_fail;
20933 else
20934 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
20935 "or %<relaxed%>");
20936 parens.skip_until_found_close (parser);
20937 continue;
20939 else if (!strcmp (p, "seq_cst"))
20940 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
20941 else if (!strcmp (p, "acq_rel"))
20942 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
20943 else if (!strcmp (p, "release"))
20944 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
20945 else if (!strcmp (p, "acquire"))
20946 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
20947 else if (!strcmp (p, "relaxed"))
20948 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
20949 else if (!strcmp (p, "hint"))
20951 c_parser_consume_token (parser);
20952 clauses = c_parser_omp_clause_hint (parser, clauses);
20953 continue;
20955 else
20957 p = NULL;
20958 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
20959 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
20960 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
20961 "%<relaxed%> or %<hint%> clause");
20963 if (p)
20965 if (new_code != ERROR_MARK)
20967 /* OpenACC permits 'update capture'. */
20968 if (openacc
20969 && code == OMP_ATOMIC
20970 && new_code == OMP_ATOMIC_CAPTURE_NEW)
20971 code = new_code;
20972 else if (code != ERROR_MARK)
20973 error_at (cloc, "too many atomic clauses");
20974 else
20975 code = new_code;
20977 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
20979 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
20980 error_at (cloc, "too many memory order clauses");
20981 else
20982 memory_order = new_memory_order;
20984 else if (new_capture)
20986 if (capture)
20987 error_at (cloc, "too many %qs clauses", "capture");
20988 else
20989 capture = true;
20991 else if (new_compare)
20993 if (compare)
20994 error_at (cloc, "too many %qs clauses", "compare");
20995 else
20996 compare = true;
20998 else if (new_weak)
21000 if (weak)
21001 error_at (cloc, "too many %qs clauses", "weak");
21002 else
21003 weak = true;
21005 c_parser_consume_token (parser);
21006 continue;
21009 break;
21011 c_parser_skip_to_pragma_eol (parser);
21013 if (code == ERROR_MARK)
21014 code = OMP_ATOMIC;
21015 if (capture)
21017 if (code != OMP_ATOMIC)
21018 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
21019 "clauses", "capture");
21020 else
21021 code = OMP_ATOMIC_CAPTURE_NEW;
21023 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
21025 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
21026 "clauses", "compare");
21027 compare = false;
21029 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
21031 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
21032 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
21034 if (weak && !compare)
21036 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
21037 weak = false;
21039 if (openacc)
21040 memory_order = OMP_MEMORY_ORDER_RELAXED;
21041 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
21043 omp_requires_mask
21044 = (enum omp_requires) (omp_requires_mask
21045 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
21046 switch ((enum omp_memory_order)
21047 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
21049 case OMP_MEMORY_ORDER_UNSPECIFIED:
21050 case OMP_MEMORY_ORDER_RELAXED:
21051 memory_order = OMP_MEMORY_ORDER_RELAXED;
21052 break;
21053 case OMP_MEMORY_ORDER_SEQ_CST:
21054 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21055 break;
21056 case OMP_MEMORY_ORDER_ACQUIRE:
21057 if (code == NOP_EXPR) /* atomic write */
21059 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
21060 "%<acquire%> clause implicitly provided by a "
21061 "%<requires%> directive");
21062 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21064 else
21065 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21066 break;
21067 case OMP_MEMORY_ORDER_RELEASE:
21068 if (code == OMP_ATOMIC_READ)
21070 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
21071 "%<release%> clause implicitly provided by a "
21072 "%<requires%> directive");
21073 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21075 else
21076 memory_order = OMP_MEMORY_ORDER_RELEASE;
21077 break;
21078 case OMP_MEMORY_ORDER_ACQ_REL:
21079 switch (code)
21081 case OMP_ATOMIC_READ:
21082 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21083 break;
21084 case NOP_EXPR: /* atomic write */
21085 memory_order = OMP_MEMORY_ORDER_RELEASE;
21086 break;
21087 default:
21088 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
21089 break;
21091 break;
21092 default:
21093 gcc_unreachable ();
21096 else
21097 switch (code)
21099 case OMP_ATOMIC_READ:
21100 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
21102 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
21103 "%<release%> clause");
21104 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21106 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
21107 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21108 break;
21109 case NOP_EXPR: /* atomic write */
21110 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
21112 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
21113 "%<acquire%> clause");
21114 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21116 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
21117 memory_order = OMP_MEMORY_ORDER_RELEASE;
21118 break;
21119 default:
21120 break;
21122 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
21123 memory_order
21124 = (enum omp_memory_order) (memory_order
21125 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
21127 switch (code)
21129 case OMP_ATOMIC_READ:
21130 case NOP_EXPR: /* atomic write */
21131 v = c_parser_cast_expression (parser, NULL).value;
21132 non_lvalue_p = !lvalue_p (v);
21133 v = c_fully_fold (v, false, NULL, true);
21134 if (v == error_mark_node)
21135 goto saw_error;
21136 if (non_lvalue_p)
21137 v = non_lvalue (v);
21138 loc = c_parser_peek_token (parser)->location;
21139 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21140 goto saw_error;
21141 if (code == NOP_EXPR)
21143 lhs = c_parser_expression (parser).value;
21144 lhs = c_fully_fold (lhs, false, NULL);
21145 if (lhs == error_mark_node)
21146 goto saw_error;
21148 else
21150 lhs = c_parser_cast_expression (parser, NULL).value;
21151 non_lvalue_p = !lvalue_p (lhs);
21152 lhs = c_fully_fold (lhs, false, NULL, true);
21153 if (lhs == error_mark_node)
21154 goto saw_error;
21155 if (non_lvalue_p)
21156 lhs = non_lvalue (lhs);
21158 if (code == NOP_EXPR)
21160 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
21161 opcode. */
21162 code = OMP_ATOMIC;
21163 rhs = lhs;
21164 lhs = v;
21165 v = NULL_TREE;
21167 goto done;
21168 case OMP_ATOMIC_CAPTURE_NEW:
21169 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
21171 c_parser_consume_token (parser);
21172 structured_block = true;
21174 else if (compare
21175 && c_parser_next_token_is_keyword (parser, RID_IF))
21176 break;
21177 else
21179 v = c_parser_cast_expression (parser, NULL).value;
21180 non_lvalue_p = !lvalue_p (v);
21181 v = c_fully_fold (v, false, NULL, true);
21182 if (v == error_mark_node)
21183 goto saw_error;
21184 if (non_lvalue_p)
21185 v = non_lvalue (v);
21186 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21187 goto saw_error;
21188 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
21190 eloc = c_parser_peek_token (parser)->location;
21191 error_at (eloc, "expected expression");
21192 goto saw_error;
21195 break;
21196 default:
21197 break;
21200 /* For structured_block case we don't know yet whether
21201 old or new x should be captured. */
21202 restart:
21203 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
21205 c_parser_consume_token (parser);
21207 matching_parens parens;
21208 if (!parens.require_open (parser))
21209 goto saw_error;
21210 eloc = c_parser_peek_token (parser)->location;
21211 c_expr cmp_expr;
21212 if (r)
21214 cmp_expr = c_parser_cast_expression (parser, NULL);
21215 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
21217 else
21218 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
21219 parens.skip_until_found_close (parser);
21220 if (cmp_expr.value == error_mark_node)
21221 goto saw_error;
21222 if (r)
21224 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
21225 goto bad_if;
21226 cmp_expr.value = rhs1;
21227 rhs1 = NULL_TREE;
21228 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
21230 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21232 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
21234 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
21235 "expected %<==%> comparison in %<if%> condition");
21236 goto saw_error;
21238 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
21239 && TREE_CODE (cmp_expr.value) != LT_EXPR)
21241 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
21242 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
21243 "condition");
21244 goto saw_error;
21246 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21247 goto saw_error;
21249 extra_scope = true;
21250 eloc = c_parser_peek_token (parser)->location;
21251 expr = c_parser_cast_expression (parser, NULL);
21252 lhs = expr.value;
21253 expr = default_function_array_conversion (eloc, expr);
21254 unfolded_lhs = expr.value;
21255 lhs = c_fully_fold (lhs, false, NULL, true);
21256 orig_lhs = lhs;
21257 if (lhs == error_mark_node)
21258 goto saw_error;
21259 if (!lvalue_p (unfolded_lhs))
21260 lhs = non_lvalue (lhs);
21261 if (!c_parser_next_token_is (parser, CPP_EQ))
21263 c_parser_error (parser, "expected %<=%>");
21264 goto saw_error;
21266 c_parser_consume_token (parser);
21267 eloc = c_parser_peek_token (parser)->location;
21268 expr = c_parser_expr_no_commas (parser, NULL);
21269 rhs1 = expr.value;
21271 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21272 goto saw_error;
21274 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
21275 goto saw_error;
21277 extra_scope = false;
21278 no_semicolon = true;
21280 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
21282 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21284 opcode = COND_EXPR;
21285 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
21286 false, NULL, true);
21287 rhs1 = c_fully_fold (rhs1, false, NULL, true);
21289 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
21291 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
21292 ? MIN_EXPR : MAX_EXPR);
21293 rhs = c_fully_fold (rhs1, false, NULL, true);
21294 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
21295 false, NULL, true);
21297 else
21298 goto bad_if;
21300 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21301 goto bad_if;
21302 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
21303 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
21305 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
21306 ? MAX_EXPR : MIN_EXPR);
21307 rhs = c_fully_fold (rhs1, false, NULL, true);
21308 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
21309 false, NULL, true);
21311 else
21313 bad_if:
21314 c_parser_error (parser,
21315 "invalid form of %<#pragma omp atomic compare%>");
21316 goto saw_error;
21319 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
21321 if (code != OMP_ATOMIC_CAPTURE_NEW
21322 || (structured_block && r == NULL_TREE)
21323 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
21325 eloc = c_parser_peek_token (parser)->location;
21326 error_at (eloc, "unexpected %<else%>");
21327 goto saw_error;
21330 c_parser_consume_token (parser);
21332 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21333 goto saw_error;
21335 extra_scope = true;
21336 v = c_parser_cast_expression (parser, NULL).value;
21337 non_lvalue_p = !lvalue_p (v);
21338 v = c_fully_fold (v, false, NULL, true);
21339 if (v == error_mark_node)
21340 goto saw_error;
21341 if (non_lvalue_p)
21342 v = non_lvalue (v);
21343 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21344 goto saw_error;
21346 expr = c_parser_expr_no_commas (parser, NULL);
21348 if (!c_tree_equal (expr.value, unfolded_lhs))
21349 goto bad_if;
21351 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21352 goto saw_error;
21354 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
21355 goto saw_error;
21357 extra_scope = false;
21358 code = OMP_ATOMIC_CAPTURE_OLD;
21359 if (r == NULL_TREE)
21360 /* Signal to c_finish_omp_atomic that in
21361 if (x == e) { x = d; } else { v = x; }
21362 case the store to v should be conditional. */
21363 r = void_list_node;
21365 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21367 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
21368 goto saw_error;
21370 else if (code == OMP_ATOMIC_CAPTURE_NEW
21371 && r != NULL_TREE
21372 && v == NULL_TREE)
21373 code = OMP_ATOMIC;
21374 goto stmt_done;
21376 eloc = c_parser_peek_token (parser)->location;
21377 expr = c_parser_cast_expression (parser, NULL);
21378 lhs = expr.value;
21379 expr = default_function_array_conversion (eloc, expr);
21380 unfolded_lhs = expr.value;
21381 lhs = c_fully_fold (lhs, false, NULL, true);
21382 orig_lhs = lhs;
21383 switch (TREE_CODE (lhs))
21385 invalid_compare:
21386 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
21387 /* FALLTHRU */
21388 case ERROR_MARK:
21389 saw_error:
21390 c_parser_skip_to_end_of_block_or_statement (parser);
21391 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21392 c_parser_consume_token (parser);
21393 if (structured_block)
21395 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21396 c_parser_consume_token (parser);
21397 else if (code == OMP_ATOMIC_CAPTURE_NEW)
21399 c_parser_skip_to_end_of_block_or_statement (parser);
21400 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21401 c_parser_consume_token (parser);
21404 return;
21406 case POSTINCREMENT_EXPR:
21407 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21408 code = OMP_ATOMIC_CAPTURE_OLD;
21409 /* FALLTHROUGH */
21410 case PREINCREMENT_EXPR:
21411 lhs = TREE_OPERAND (lhs, 0);
21412 unfolded_lhs = NULL_TREE;
21413 opcode = PLUS_EXPR;
21414 rhs = integer_one_node;
21415 if (compare)
21416 goto invalid_compare;
21417 break;
21419 case POSTDECREMENT_EXPR:
21420 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21421 code = OMP_ATOMIC_CAPTURE_OLD;
21422 /* FALLTHROUGH */
21423 case PREDECREMENT_EXPR:
21424 lhs = TREE_OPERAND (lhs, 0);
21425 unfolded_lhs = NULL_TREE;
21426 opcode = MINUS_EXPR;
21427 rhs = integer_one_node;
21428 if (compare)
21429 goto invalid_compare;
21430 break;
21432 case COMPOUND_EXPR:
21433 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
21434 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
21435 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
21436 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
21437 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
21438 (TREE_OPERAND (lhs, 1), 0), 0))))
21439 /* Undo effects of boolean_increment for post {in,de}crement. */
21440 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
21441 /* FALLTHRU */
21442 case MODIFY_EXPR:
21443 if (TREE_CODE (lhs) == MODIFY_EXPR
21444 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))))
21446 /* Undo effects of boolean_increment. */
21447 if (integer_onep (TREE_OPERAND (lhs, 1)))
21449 /* This is pre or post increment. */
21450 rhs = TREE_OPERAND (lhs, 1);
21451 lhs = TREE_OPERAND (lhs, 0);
21452 unfolded_lhs = NULL_TREE;
21453 opcode = NOP_EXPR;
21454 if (code == OMP_ATOMIC_CAPTURE_NEW
21455 && !structured_block
21456 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
21457 code = OMP_ATOMIC_CAPTURE_OLD;
21458 if (compare)
21459 goto invalid_compare;
21460 break;
21462 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
21463 && TREE_OPERAND (lhs, 0)
21464 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
21466 /* This is pre or post decrement. */
21467 rhs = TREE_OPERAND (lhs, 1);
21468 lhs = TREE_OPERAND (lhs, 0);
21469 unfolded_lhs = NULL_TREE;
21470 opcode = NOP_EXPR;
21471 if (code == OMP_ATOMIC_CAPTURE_NEW
21472 && !structured_block
21473 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
21474 code = OMP_ATOMIC_CAPTURE_OLD;
21475 if (compare)
21476 goto invalid_compare;
21477 break;
21480 /* FALLTHRU */
21481 default:
21482 if (!lvalue_p (unfolded_lhs))
21483 lhs = non_lvalue (lhs);
21484 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
21486 c_parser_error (parser, "expected %<=%>");
21487 goto saw_error;
21489 switch (c_parser_peek_token (parser)->type)
21491 case CPP_MULT_EQ:
21492 opcode = MULT_EXPR;
21493 break;
21494 case CPP_DIV_EQ:
21495 opcode = TRUNC_DIV_EXPR;
21496 break;
21497 case CPP_PLUS_EQ:
21498 opcode = PLUS_EXPR;
21499 break;
21500 case CPP_MINUS_EQ:
21501 opcode = MINUS_EXPR;
21502 break;
21503 case CPP_LSHIFT_EQ:
21504 opcode = LSHIFT_EXPR;
21505 break;
21506 case CPP_RSHIFT_EQ:
21507 opcode = RSHIFT_EXPR;
21508 break;
21509 case CPP_AND_EQ:
21510 opcode = BIT_AND_EXPR;
21511 break;
21512 case CPP_OR_EQ:
21513 opcode = BIT_IOR_EXPR;
21514 break;
21515 case CPP_XOR_EQ:
21516 opcode = BIT_XOR_EXPR;
21517 break;
21518 case CPP_EQ:
21519 c_parser_consume_token (parser);
21520 eloc = c_parser_peek_token (parser)->location;
21521 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
21522 rhs1 = expr.value;
21523 switch (TREE_CODE (rhs1))
21525 case MULT_EXPR:
21526 case TRUNC_DIV_EXPR:
21527 case RDIV_EXPR:
21528 case PLUS_EXPR:
21529 case MINUS_EXPR:
21530 case LSHIFT_EXPR:
21531 case RSHIFT_EXPR:
21532 case BIT_AND_EXPR:
21533 case BIT_IOR_EXPR:
21534 case BIT_XOR_EXPR:
21535 if (compare)
21536 break;
21537 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
21539 opcode = TREE_CODE (rhs1);
21540 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21541 true);
21542 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
21543 true);
21544 goto stmt_done;
21546 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
21548 opcode = TREE_CODE (rhs1);
21549 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
21550 true);
21551 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21552 true);
21553 swapped = !commutative_tree_code (opcode);
21554 goto stmt_done;
21556 break;
21557 case COND_EXPR:
21558 if (!compare)
21559 break;
21560 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
21561 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
21562 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
21563 break;
21564 if (!TREE_OPERAND (rhs1, 1))
21565 break;
21566 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
21567 break;
21568 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
21569 unfolded_lhs))
21571 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
21573 opcode = COND_EXPR;
21574 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21575 0), 1),
21576 false, NULL, true);
21577 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
21578 NULL, true);
21579 goto stmt_done;
21581 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
21582 TREE_OPERAND (rhs1, 1)))
21584 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
21585 ? MIN_EXPR : MAX_EXPR);
21586 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21587 true);
21588 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21589 0), 0),
21590 false, NULL, true);
21591 goto stmt_done;
21594 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
21595 break;
21596 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
21597 unfolded_lhs))
21599 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
21600 TREE_OPERAND (rhs1, 1)))
21602 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
21603 ? MAX_EXPR : MIN_EXPR);
21604 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21605 true);
21606 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21607 0), 1),
21608 false, NULL, true);
21609 goto stmt_done;
21612 break;
21613 case EQ_EXPR:
21614 if (!compare
21615 || code != OMP_ATOMIC_CAPTURE_NEW
21616 || !structured_block
21617 || v
21618 || r)
21619 break;
21620 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
21621 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
21623 r = lhs;
21624 lhs = NULL_TREE;
21625 c_parser_consume_token (parser);
21626 goto restart;
21628 break;
21629 case ERROR_MARK:
21630 goto saw_error;
21631 default:
21632 break;
21634 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
21636 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
21638 code = OMP_ATOMIC_CAPTURE_OLD;
21639 v = lhs;
21640 lhs = NULL_TREE;
21641 expr = default_function_array_read_conversion (eloc, expr);
21642 unfolded_lhs1 = expr.value;
21643 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
21644 rhs1 = NULL_TREE;
21645 c_parser_consume_token (parser);
21646 goto restart;
21648 if (structured_block && !compare)
21650 opcode = NOP_EXPR;
21651 expr = default_function_array_read_conversion (eloc, expr);
21652 rhs = c_fully_fold (expr.value, false, NULL, true);
21653 rhs1 = NULL_TREE;
21654 goto stmt_done;
21657 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
21658 goto saw_error;
21659 default:
21660 c_parser_error (parser,
21661 "invalid operator for %<#pragma omp atomic%>");
21662 goto saw_error;
21665 /* Arrange to pass the location of the assignment operator to
21666 c_finish_omp_atomic. */
21667 loc = c_parser_peek_token (parser)->location;
21668 c_parser_consume_token (parser);
21669 eloc = c_parser_peek_token (parser)->location;
21670 expr = c_parser_expression (parser);
21671 expr = default_function_array_read_conversion (eloc, expr);
21672 rhs = expr.value;
21673 rhs = c_fully_fold (rhs, false, NULL, true);
21674 break;
21676 stmt_done:
21677 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
21679 if (!no_semicolon
21680 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21681 goto saw_error;
21682 no_semicolon = false;
21683 v = c_parser_cast_expression (parser, NULL).value;
21684 non_lvalue_p = !lvalue_p (v);
21685 v = c_fully_fold (v, false, NULL, true);
21686 if (v == error_mark_node)
21687 goto saw_error;
21688 if (non_lvalue_p)
21689 v = non_lvalue (v);
21690 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21691 goto saw_error;
21692 eloc = c_parser_peek_token (parser)->location;
21693 expr = c_parser_cast_expression (parser, NULL);
21694 lhs1 = expr.value;
21695 expr = default_function_array_read_conversion (eloc, expr);
21696 unfolded_lhs1 = expr.value;
21697 lhs1 = c_fully_fold (lhs1, false, NULL, true);
21698 if (lhs1 == error_mark_node)
21699 goto saw_error;
21700 if (!lvalue_p (unfolded_lhs1))
21701 lhs1 = non_lvalue (lhs1);
21703 if (structured_block)
21705 if (!no_semicolon)
21706 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
21707 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
21709 done:
21710 if (weak && opcode != COND_EXPR)
21712 error_at (loc, "%<weak%> clause requires atomic equality comparison");
21713 weak = false;
21715 if (unfolded_lhs && unfolded_lhs1
21716 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
21718 error ("%<#pragma omp atomic capture%> uses two different "
21719 "expressions for memory");
21720 stmt = error_mark_node;
21722 else
21723 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
21724 swapped, memory_order, weak);
21725 if (stmt != error_mark_node)
21726 add_stmt (stmt);
21728 if (!structured_block && !no_semicolon)
21729 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
21733 /* OpenMP 2.5:
21734 # pragma omp barrier new-line
21737 static void
21738 c_parser_omp_barrier (c_parser *parser)
21740 location_t loc = c_parser_peek_token (parser)->location;
21741 c_parser_consume_pragma (parser);
21742 c_parser_skip_to_pragma_eol (parser);
21744 c_finish_omp_barrier (loc);
21747 /* OpenMP 2.5:
21748 # pragma omp critical [(name)] new-line
21749 structured-block
21751 OpenMP 4.5:
21752 # pragma omp critical [(name) [hint(expression)]] new-line
21754 LOC is the location of the #pragma itself. */
21756 #define OMP_CRITICAL_CLAUSE_MASK \
21757 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
21759 static tree
21760 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
21762 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
21764 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21766 c_parser_consume_token (parser);
21767 if (c_parser_next_token_is (parser, CPP_NAME))
21769 name = c_parser_peek_token (parser)->value;
21770 c_parser_consume_token (parser);
21771 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
21773 else
21774 c_parser_error (parser, "expected identifier");
21776 if (c_parser_next_token_is (parser, CPP_COMMA)
21777 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
21778 c_parser_consume_token (parser);
21780 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
21781 "#pragma omp critical");
21782 stmt = c_parser_omp_structured_block (parser, if_p);
21783 return c_finish_omp_critical (loc, stmt, name, clauses);
21786 /* OpenMP 5.0:
21787 # pragma omp depobj ( depobj ) depobj-clause new-line
21789 depobj-clause:
21790 depend (dependence-type : locator)
21791 destroy
21792 update (dependence-type)
21794 OpenMP 5.2 additionally:
21795 destroy ( depobj )
21797 dependence-type:
21800 inout
21801 mutexinout */
21803 static void
21804 c_parser_omp_depobj (c_parser *parser)
21806 location_t loc = c_parser_peek_token (parser)->location;
21807 c_parser_consume_pragma (parser);
21808 matching_parens parens;
21809 if (!parens.require_open (parser))
21811 c_parser_skip_to_pragma_eol (parser);
21812 return;
21815 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
21816 if (depobj != error_mark_node)
21818 if (!lvalue_p (depobj))
21820 error_at (EXPR_LOC_OR_LOC (depobj, loc),
21821 "%<depobj%> expression is not lvalue expression");
21822 depobj = error_mark_node;
21824 else
21826 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
21827 depobj, false);
21828 if (addr == error_mark_node)
21829 depobj = error_mark_node;
21830 else
21831 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
21832 addr, RO_UNARY_STAR);
21836 parens.skip_until_found_close (parser);
21837 tree clause = NULL_TREE;
21838 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
21839 if (c_parser_next_token_is (parser, CPP_COMMA))
21840 c_parser_consume_token (parser);
21841 location_t c_loc = c_parser_peek_token (parser)->location;
21842 if (c_parser_next_token_is (parser, CPP_NAME))
21844 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21846 c_parser_consume_token (parser);
21847 if (!strcmp ("depend", p))
21849 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
21850 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
21851 if (!clause)
21852 clause = error_mark_node;
21854 else if (!strcmp ("destroy", p))
21856 matching_parens c_parens;
21857 kind = OMP_CLAUSE_DEPEND_LAST;
21858 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
21859 && c_parens.require_open (parser))
21861 tree destobj = c_parser_expr_no_commas (parser, NULL).value;
21862 if (!lvalue_p (destobj))
21863 error_at (EXPR_LOC_OR_LOC (destobj, c_loc),
21864 "%<destroy%> expression is not lvalue expression");
21865 else if (depobj != error_mark_node
21866 && !operand_equal_p (destobj, depobj,
21867 OEP_MATCH_SIDE_EFFECTS
21868 | OEP_LEXICOGRAPHIC))
21869 warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), OPT_Wopenmp,
21870 "the %<destroy%> expression %qE should be the same "
21871 "as the %<depobj%> argument %qE", destobj, depobj);
21872 c_parens.skip_until_found_close (parser);
21875 else if (!strcmp ("update", p))
21877 matching_parens c_parens;
21878 if (c_parens.require_open (parser))
21880 location_t c2_loc = c_parser_peek_token (parser)->location;
21881 if (c_parser_next_token_is (parser, CPP_NAME))
21883 const char *p2
21884 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21886 c_parser_consume_token (parser);
21887 if (!strcmp ("in", p2))
21888 kind = OMP_CLAUSE_DEPEND_IN;
21889 else if (!strcmp ("out", p2))
21890 kind = OMP_CLAUSE_DEPEND_OUT;
21891 else if (!strcmp ("inout", p2))
21892 kind = OMP_CLAUSE_DEPEND_INOUT;
21893 else if (!strcmp ("mutexinoutset", p2))
21894 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
21895 else if (!strcmp ("inoutset", p2))
21896 kind = OMP_CLAUSE_DEPEND_INOUTSET;
21898 if (kind == OMP_CLAUSE_DEPEND_INVALID)
21900 clause = error_mark_node;
21901 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
21902 "%<mutexinoutset%> or %<inoutset%>");
21904 c_parens.skip_until_found_close (parser);
21906 else
21907 clause = error_mark_node;
21910 if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
21912 clause = error_mark_node;
21913 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
21915 c_parser_skip_to_pragma_eol (parser);
21917 c_finish_omp_depobj (loc, depobj, kind, clause);
21921 /* OpenMP 2.5:
21922 # pragma omp flush flush-vars[opt] new-line
21924 flush-vars:
21925 ( variable-list )
21927 OpenMP 5.0:
21928 # pragma omp flush memory-order-clause new-line */
21930 static void
21931 c_parser_omp_flush (c_parser *parser)
21933 location_t loc = c_parser_peek_token (parser)->location;
21934 c_parser_consume_pragma (parser);
21935 enum memmodel mo = MEMMODEL_LAST;
21936 if (c_parser_next_token_is (parser, CPP_COMMA)
21937 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
21938 c_parser_consume_token (parser);
21939 if (c_parser_next_token_is (parser, CPP_NAME))
21941 const char *p
21942 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21944 if (!strcmp (p, "seq_cst"))
21945 mo = MEMMODEL_SEQ_CST;
21946 else if (!strcmp (p, "acq_rel"))
21947 mo = MEMMODEL_ACQ_REL;
21948 else if (!strcmp (p, "release"))
21949 mo = MEMMODEL_RELEASE;
21950 else if (!strcmp (p, "acquire"))
21951 mo = MEMMODEL_ACQUIRE;
21952 else
21953 error_at (c_parser_peek_token (parser)->location,
21954 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
21955 "%<acquire%>");
21956 c_parser_consume_token (parser);
21958 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21960 if (mo != MEMMODEL_LAST)
21961 error_at (c_parser_peek_token (parser)->location,
21962 "%<flush%> list specified together with memory order "
21963 "clause");
21964 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
21966 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21967 c_parser_error (parser, "expected %<(%> or end of line");
21968 c_parser_skip_to_pragma_eol (parser);
21970 c_finish_omp_flush (loc, mo);
21973 /* Return true if next tokens contain a standard attribute that contains
21974 omp::directive (DIRECTIVE). */
21976 static bool
21977 c_parser_omp_section_scan (c_parser *parser, const char *directive,
21978 bool tentative)
21980 if (!c_parser_nth_token_starts_std_attributes (parser, 1))
21981 return false;
21982 unsigned int n = 3;
21983 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
21984 return false;
21985 c_token *token = c_parser_peek_nth_token_raw (parser, n);
21986 if (token->type != CPP_CLOSE_SQUARE)
21987 return false;
21988 token = c_parser_peek_nth_token_raw (parser, n + 1);
21989 if (token->type != CPP_CLOSE_SQUARE)
21990 return false;
21991 if (n < 9)
21992 return false;
21993 if (c_parser_peek_nth_token_raw (parser, 3)->type == CPP_NAME
21994 && c_parser_peek_nth_token_raw (parser, 4)->type == CPP_OPEN_PAREN
21995 && c_parser_peek_nth_token_raw (parser, 5)->type == CPP_NAME)
21997 tree first = c_parser_peek_nth_token_raw (parser, 3)->value;
21998 tree second = c_parser_peek_nth_token_raw (parser, 5)->value;
21999 if (strcmp (IDENTIFIER_POINTER (first), "directive")
22000 && strcmp (IDENTIFIER_POINTER (first), "__directive__"))
22001 return false;
22002 if (strcmp (IDENTIFIER_POINTER (second), directive))
22003 return false;
22005 if (tentative)
22006 return true;
22007 location_t first_loc = c_parser_peek_token (parser)->location;
22008 location_t last_loc = c_parser_peek_nth_token_raw (parser, n + 1)->location;
22009 location_t middle_loc = UNKNOWN_LOCATION;
22010 tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
22011 bool seen = false;
22012 int cnt = 0;
22013 for (tree attr = std_attrs; attr; attr = TREE_CHAIN (attr))
22014 if (is_attribute_namespace_p ("omp", attr)
22015 && is_attribute_p ("directive", get_attribute_name (attr)))
22017 for (tree a = TREE_VALUE (attr); a; a = TREE_CHAIN (a))
22019 tree d = TREE_VALUE (a);
22020 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
22021 c_token *first = C_TOKEN_VEC_TOKENS (d)->address ();
22022 cnt++;
22023 if (first->type == CPP_NAME
22024 && strcmp (IDENTIFIER_POINTER (first->value),
22025 directive) == 0)
22027 seen = true;
22028 if (middle_loc == UNKNOWN_LOCATION)
22029 middle_loc = first->location;
22033 if (!seen)
22034 return false;
22035 if (cnt != 1 || TREE_CHAIN (std_attrs))
22037 error_at (make_location (first_loc, last_loc, middle_loc),
22038 "%<[[omp::directive(%s)]]%> must be the only specified "
22039 "attribute on a statement", directive);
22040 return false;
22042 c_parser_handle_statement_omp_attributes (parser, std_attrs, NULL);
22043 return true;
22046 /* Parse an OpenMP structured block sequence. KIND is the corresponding
22047 separating directive. */
22049 static tree
22050 c_parser_omp_structured_block_sequence (c_parser *parser,
22051 enum pragma_kind kind)
22053 tree stmt = push_stmt_list ();
22054 c_parser_statement (parser, NULL);
22057 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
22058 break;
22059 if (c_parser_next_token_is (parser, CPP_EOF))
22060 break;
22062 if (kind != PRAGMA_NONE
22063 && c_parser_peek_token (parser)->pragma_kind == kind)
22064 break;
22066 if (kind != PRAGMA_NONE
22067 && c_parser_omp_section_scan (parser,
22068 kind == PRAGMA_OMP_SCAN
22069 ? "scan" : "section", false))
22070 break;
22072 c_parser_statement (parser, NULL);
22074 while (1);
22075 return pop_stmt_list (stmt);
22078 /* OpenMP 5.0:
22080 scan-loop-body:
22081 { structured-block scan-directive structured-block } */
22083 static void
22084 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
22086 tree substmt;
22087 location_t loc;
22088 tree clauses = NULL_TREE;
22089 bool found_scan = false;
22091 loc = c_parser_peek_token (parser)->location;
22092 if (!open_brace_parsed
22093 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
22095 /* Avoid skipping until the end of the block. */
22096 parser->error = false;
22097 return;
22100 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SCAN)
22101 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
22102 else
22104 warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
22105 "%<#pragma omp scan%> with zero preceding executable "
22106 "statements");
22107 substmt = build_empty_stmt (loc);
22109 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
22110 SET_EXPR_LOCATION (substmt, loc);
22111 add_stmt (substmt);
22113 loc = c_parser_peek_token (parser)->location;
22114 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
22116 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
22117 found_scan = true;
22119 c_parser_consume_pragma (parser);
22121 if (c_parser_next_token_is (parser, CPP_COMMA))
22122 c_parser_consume_token (parser);
22124 if (c_parser_next_token_is (parser, CPP_NAME))
22126 const char *p
22127 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22128 if (strcmp (p, "inclusive") == 0)
22129 clause = OMP_CLAUSE_INCLUSIVE;
22130 else if (strcmp (p, "exclusive") == 0)
22131 clause = OMP_CLAUSE_EXCLUSIVE;
22133 if (clause != OMP_CLAUSE_ERROR)
22135 c_parser_consume_token (parser);
22136 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
22138 else
22139 c_parser_error (parser, "expected %<inclusive%> or "
22140 "%<exclusive%> clause");
22141 c_parser_skip_to_pragma_eol (parser);
22143 else
22144 error ("expected %<#pragma omp scan%>");
22146 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22147 if (!c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
22148 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
22149 else
22151 if (found_scan)
22152 warning_at (loc, OPT_Wopenmp,
22153 "%<#pragma omp scan%> with zero succeeding executable "
22154 "statements");
22155 substmt = build_empty_stmt (loc);
22157 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
22158 SET_EXPR_LOCATION (substmt, loc);
22159 add_stmt (substmt);
22161 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
22162 "expected %<}%>");
22166 /* This function parses a single level of a loop nest, invoking itself
22167 recursively if necessary.
22169 loop-nest :: for (...) loop-body
22170 loop-body :: loop-nest
22171 | { [intervening-code] loop-body [intervening-code] }
22172 | final-loop-body
22173 intervening-code :: structured-block-sequence
22174 final-loop-body :: structured-block
22176 For a collapsed loop nest, only a single OMP_FOR is built, pulling out
22177 all the iterator information from the inner loops into the
22178 parser->omp_for_parse_state structure.
22180 The iterator decl, init, cond, and incr are stored in vectors.
22182 Initialization code for iterator variables is collected into
22183 parser->omp_for_parse_state->pre_body and ends up inserted directly
22184 into the OMP_FOR structure. */
22186 static tree
22187 c_parser_omp_loop_nest (c_parser *parser, bool *if_p)
22189 tree decl, cond, incr, init;
22190 tree body = NULL_TREE;
22191 matching_parens parens;
22192 bool moreloops;
22193 unsigned char save_in_statement;
22194 tree loop_scope;
22195 location_t loc;
22196 struct omp_for_parse_data *omp_for_parse_state
22197 = parser->omp_for_parse_state;
22198 gcc_assert (omp_for_parse_state);
22199 int depth = omp_for_parse_state->depth;
22201 /* We have already matched the FOR token but not consumed it yet. */
22202 loc = c_parser_peek_token (parser)->location;
22203 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
22204 c_parser_consume_token (parser);
22206 /* Forbid break/continue in the loop initializer, condition, and
22207 increment expressions. */
22208 save_in_statement = in_statement;
22209 in_statement = IN_OMP_BLOCK;
22211 /* We are not in intervening code now. */
22212 omp_for_parse_state->in_intervening_code = false;
22214 if (!parens.require_open (parser))
22216 omp_for_parse_state->fail = true;
22217 return NULL_TREE;
22220 /* An implicit scope block surrounds each level of FOR loop, for
22221 declarations of iteration variables at this loop depth. */
22222 loop_scope = c_begin_compound_stmt (true);
22224 /* Parse the initialization declaration or expression. */
22225 if (c_parser_next_tokens_start_declaration (parser))
22227 /* This is a declaration, which must be added to the pre_body code. */
22228 tree this_pre_body = push_stmt_list ();
22229 c_in_omp_for = true;
22230 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
22231 c_in_omp_for = false;
22232 this_pre_body = pop_stmt_list (this_pre_body);
22233 append_to_statement_list_force (this_pre_body,
22234 &(omp_for_parse_state->pre_body));
22235 decl = check_for_loop_decls (omp_for_parse_state->for_loc, flag_isoc99);
22236 if (decl == NULL)
22237 goto error_init;
22238 if (DECL_INITIAL (decl) == error_mark_node)
22239 decl = error_mark_node;
22240 init = decl;
22242 else if (c_parser_next_token_is (parser, CPP_NAME)
22243 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
22245 struct c_expr decl_exp;
22246 struct c_expr init_exp;
22247 location_t init_loc;
22249 decl_exp = c_parser_postfix_expression (parser);
22250 decl = decl_exp.value;
22252 c_parser_require (parser, CPP_EQ, "expected %<=%>");
22254 init_loc = c_parser_peek_token (parser)->location;
22255 init_exp = c_parser_expr_no_commas (parser, NULL);
22256 init_exp = default_function_array_read_conversion (init_loc,
22257 init_exp);
22258 c_in_omp_for = true;
22259 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
22260 NOP_EXPR, init_loc, init_exp.value,
22261 init_exp.original_type);
22262 c_in_omp_for = false;
22263 init = c_process_expr_stmt (init_loc, init);
22265 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
22267 else
22269 error_init:
22270 c_parser_error (parser,
22271 "expected iteration declaration or initialization");
22272 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
22273 "expected %<)%>");
22274 omp_for_parse_state->fail = true;
22275 goto parse_next;
22278 /* Parse the loop condition. */
22279 cond = NULL_TREE;
22280 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
22282 location_t cond_loc = c_parser_peek_token (parser)->location;
22283 c_in_omp_for = true;
22284 struct c_expr cond_expr
22285 = c_parser_binary_expression (parser, NULL, NULL_TREE);
22286 c_in_omp_for = false;
22288 cond = cond_expr.value;
22289 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
22290 switch (cond_expr.original_code)
22292 case GT_EXPR:
22293 case GE_EXPR:
22294 case LT_EXPR:
22295 case LE_EXPR:
22296 break;
22297 case NE_EXPR:
22298 if (omp_for_parse_state->code != OACC_LOOP)
22299 break;
22300 /* FALLTHRU. */
22301 default:
22302 /* Can't be cond = error_mark_node, because we want to preserve
22303 the location until c_finish_omp_for. */
22304 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
22305 break;
22307 protected_set_expr_location (cond, cond_loc);
22309 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
22311 /* Parse the increment expression. */
22312 incr = NULL_TREE;
22313 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
22315 location_t incr_loc = c_parser_peek_token (parser)->location;
22317 incr = c_process_expr_stmt (incr_loc,
22318 c_parser_expression (parser).value);
22320 parens.skip_until_found_close (parser);
22322 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
22323 omp_for_parse_state->fail = true;
22324 else
22326 TREE_VEC_ELT (omp_for_parse_state->declv, depth) = decl;
22327 TREE_VEC_ELT (omp_for_parse_state->initv, depth) = init;
22328 TREE_VEC_ELT (omp_for_parse_state->condv, depth) = cond;
22329 TREE_VEC_ELT (omp_for_parse_state->incrv, depth) = incr;
22332 parse_next:
22333 moreloops = depth < omp_for_parse_state->count - 1;
22334 omp_for_parse_state->want_nested_loop = moreloops;
22335 if (moreloops && c_parser_next_token_is_keyword (parser, RID_FOR))
22337 omp_for_parse_state->depth++;
22338 body = c_parser_omp_loop_nest (parser, if_p);
22339 omp_for_parse_state->depth--;
22341 else if (moreloops && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
22343 /* This is the open brace in the loop-body grammar production. Rather
22344 than trying to special-case braces, just parse it as a compound
22345 statement and handle the nested loop-body case there. Note that
22346 when we see a further open brace inside the compound statement
22347 loop-body, we don't know whether it is the start of intervening
22348 code that is a compound statement, or a level of braces
22349 surrounding a nested loop-body. Use the WANT_NESTED_LOOP state
22350 bit to ensure we have only one nested loop at each level. */
22351 omp_for_parse_state->in_intervening_code = true;
22352 body = c_parser_compound_statement (parser, NULL);
22353 omp_for_parse_state->in_intervening_code = false;
22354 if (omp_for_parse_state->want_nested_loop)
22356 /* We have already parsed the whole loop body and not found a
22357 nested loop. */
22358 error_at (omp_for_parse_state->for_loc,
22359 "not enough nested loops");
22360 omp_for_parse_state->fail = true;
22362 if_p = NULL;
22364 else
22366 /* This is the final-loop-body case in the grammar: we have
22367 something that is not a FOR and not an open brace. */
22368 if (moreloops)
22370 /* If we were expecting a nested loop, give an error and mark
22371 that parsing has failed, and try to recover by parsing the
22372 body as regular code without further collapsing. */
22373 error_at (omp_for_parse_state->for_loc,
22374 "not enough nested loops");
22375 omp_for_parse_state->fail = true;
22377 in_statement = IN_OMP_FOR;
22378 parser->omp_for_parse_state = NULL;
22379 body = push_stmt_list ();
22380 if (omp_for_parse_state->inscan)
22381 c_parser_omp_scan_loop_body (parser, false);
22382 else
22383 add_stmt (c_parser_c99_block_statement (parser, if_p));
22384 body = pop_stmt_list (body);
22385 parser->omp_for_parse_state = omp_for_parse_state;
22387 in_statement = save_in_statement;
22388 omp_for_parse_state->want_nested_loop = false;
22389 omp_for_parse_state->in_intervening_code = true;
22391 /* Pop and return the implicit scope surrounding this level of loop.
22392 If the iteration variable at this depth was bound in the for loop,
22393 pull out and save the binding. Later in c_parser_omp_for_loop,
22394 these bindings will be moved to the scope surrounding the entire
22395 OMP_FOR. That keeps the gimplifier happy later on, and meanwhile
22396 we have already resolved all references to the iteration variable
22397 in its true scope. */
22398 add_stmt (body);
22399 body = c_end_compound_stmt (loc, loop_scope, true);
22400 if (decl && TREE_CODE (body) == BIND_EXPR)
22402 tree t = BIND_EXPR_VARS (body);
22403 tree prev = NULL_TREE, next = NULL_TREE;
22404 while (t)
22406 next = DECL_CHAIN (t);
22407 if (t == decl)
22409 if (prev)
22410 DECL_CHAIN (prev) = next;
22411 else
22413 BIND_EXPR_VARS (body) = next;
22414 BLOCK_VARS (BIND_EXPR_BLOCK (body)) = next;
22416 DECL_CHAIN (t) = omp_for_parse_state->bindings;
22417 omp_for_parse_state->bindings = t;
22418 break;
22420 else
22422 prev = t;
22423 t = next;
22426 if (BIND_EXPR_VARS (body) == NULL_TREE)
22427 body = BIND_EXPR_BODY (body);
22430 return body;
22433 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
22434 The real trick here is to determine the loop control variable early
22435 so that we can push a new decl if necessary to make it private.
22436 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
22437 respectively. */
22439 static tree
22440 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
22441 tree clauses, tree *cclauses, bool *if_p)
22443 tree body, stmt, cl;
22444 tree ret = NULL_TREE;
22445 tree ordered_cl = NULL_TREE;
22446 int i, collapse = 1, ordered = 0, count;
22447 bool tiling = false;
22448 bool inscan = false;
22449 struct omp_for_parse_data data;
22450 struct omp_for_parse_data *save_data = parser->omp_for_parse_state;
22452 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
22453 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
22454 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
22455 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
22457 tiling = true;
22458 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
22460 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
22461 && OMP_CLAUSE_ORDERED_EXPR (cl))
22463 ordered_cl = cl;
22464 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
22466 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
22467 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
22468 && (code == OMP_SIMD || code == OMP_FOR))
22469 inscan = true;
22471 if (ordered && ordered < collapse)
22473 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
22474 "%<ordered%> clause parameter is less than %<collapse%>");
22475 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
22476 = build_int_cst (NULL_TREE, collapse);
22477 ordered = collapse;
22480 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
22481 count = ordered ? ordered : collapse;
22483 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
22485 c_parser_error (parser, "for statement expected");
22486 return NULL;
22489 /* Initialize parse state for recursive descent. */
22490 data.declv = make_tree_vec (count);
22491 data.initv = make_tree_vec (count);
22492 data.condv = make_tree_vec (count);
22493 data.incrv = make_tree_vec (count);
22494 data.pre_body = NULL_TREE;;
22495 data.bindings = NULL_TREE;
22496 data.for_loc = c_parser_peek_token (parser)->location;
22497 data.count = count;
22498 data.depth = 0;
22499 data.want_nested_loop = true;
22500 data.ordered = ordered > 0;
22501 data.in_intervening_code = false;
22502 data.perfect_nesting_fail = false;
22503 data.fail = false;
22504 data.inscan = inscan;
22505 data.saw_intervening_code = false;
22506 data.code = code;
22507 parser->omp_for_parse_state = &data;
22509 body = c_parser_omp_loop_nest (parser, if_p);
22511 /* Add saved bindings for iteration variables that were declared in
22512 the nested for loop to the scope surrounding the entire loop. */
22513 for (tree t = data.bindings; t; )
22515 tree n = TREE_CHAIN (t);
22516 TREE_CHAIN (t) = NULL_TREE;
22517 pushdecl (t);
22518 t = n;
22521 /* Only bother calling c_finish_omp_for if we haven't already generated
22522 an error from the initialization parsing. */
22523 if (!data.fail)
22525 c_in_omp_for = true;
22526 stmt = c_finish_omp_for (loc, code, data.declv, NULL, data.initv,
22527 data.condv, data.incrv,
22528 body, data.pre_body, true);
22529 c_in_omp_for = false;
22531 /* Check for iterators appearing in lb, b or incr expressions. */
22532 if (stmt && !c_omp_check_loop_iv (stmt, data.declv, NULL))
22533 stmt = NULL_TREE;
22535 /* Check for errors involving lb/ub/incr expressions referencing
22536 variables declared in intervening code. */
22537 if (data.saw_intervening_code
22538 && !c_omp_check_loop_binding_exprs (stmt, NULL))
22539 stmt = NULL_TREE;
22541 if (stmt)
22543 add_stmt (stmt);
22545 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
22547 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
22548 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
22549 tree decl = TREE_OPERAND (init, 0);
22550 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
22551 gcc_assert (COMPARISON_CLASS_P (cond));
22552 gcc_assert (TREE_OPERAND (cond, 0) == decl);
22554 tree op0 = TREE_OPERAND (init, 1);
22555 if (!OMP_FOR_NON_RECTANGULAR (stmt)
22556 || TREE_CODE (op0) != TREE_VEC)
22557 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
22558 else
22560 TREE_VEC_ELT (op0, 1)
22561 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
22562 TREE_VEC_ELT (op0, 2)
22563 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
22566 tree op1 = TREE_OPERAND (cond, 1);
22567 if (!OMP_FOR_NON_RECTANGULAR (stmt)
22568 || TREE_CODE (op1) != TREE_VEC)
22569 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
22570 else
22572 TREE_VEC_ELT (op1, 1)
22573 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
22574 TREE_VEC_ELT (op1, 2)
22575 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
22579 if (cclauses != NULL
22580 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
22582 tree *c;
22583 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
22584 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
22585 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
22586 c = &OMP_CLAUSE_CHAIN (*c);
22587 else
22589 for (i = 0; i < count; i++)
22590 if (TREE_VEC_ELT (data.declv, i) == OMP_CLAUSE_DECL (*c))
22591 break;
22592 if (i == count)
22593 c = &OMP_CLAUSE_CHAIN (*c);
22594 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
22596 error_at (loc,
22597 "iteration variable %qD should not be firstprivate",
22598 OMP_CLAUSE_DECL (*c));
22599 *c = OMP_CLAUSE_CHAIN (*c);
22601 else
22603 /* Move lastprivate (decl) clause to
22604 OMP_FOR_CLAUSES. */
22605 tree l = *c;
22606 *c = OMP_CLAUSE_CHAIN (*c);
22607 if (code == OMP_SIMD)
22609 OMP_CLAUSE_CHAIN (l)
22610 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
22611 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
22613 else
22615 OMP_CLAUSE_CHAIN (l) = clauses;
22616 clauses = l;
22621 OMP_FOR_CLAUSES (stmt) = clauses;
22623 ret = stmt;
22626 parser->omp_for_parse_state = save_data;
22627 return ret;
22630 /* Helper function for OpenMP parsing, split clauses and call
22631 finish_omp_clauses on each of the set of clauses afterwards. */
22633 static void
22634 omp_split_clauses (location_t loc, enum tree_code code,
22635 omp_clause_mask mask, tree clauses, tree *cclauses)
22637 int i;
22638 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
22639 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
22640 if (cclauses[i])
22641 cclauses[i] = c_finish_omp_clauses (cclauses[i],
22642 i == C_OMP_CLAUSE_SPLIT_TARGET
22643 ? C_ORT_OMP_TARGET : C_ORT_OMP);
22646 /* OpenMP 5.0:
22647 #pragma omp loop loop-clause[optseq] new-line
22648 for-loop
22650 LOC is the location of the #pragma token.
22653 #define OMP_LOOP_CLAUSE_MASK \
22654 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22655 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22656 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22657 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22658 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
22659 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22661 static tree
22662 c_parser_omp_loop (location_t loc, c_parser *parser,
22663 char *p_name, omp_clause_mask mask, tree *cclauses,
22664 bool *if_p)
22666 tree block, clauses, ret;
22668 strcat (p_name, " loop");
22669 mask |= OMP_LOOP_CLAUSE_MASK;
22671 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22672 if (cclauses)
22674 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
22675 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
22678 block = c_begin_compound_stmt (true);
22679 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
22680 block = c_end_compound_stmt (loc, block, true);
22681 add_stmt (block);
22683 return ret;
22686 /* OpenMP 4.0:
22687 #pragma omp simd simd-clause[optseq] new-line
22688 for-loop
22690 LOC is the location of the #pragma token.
22693 #define OMP_SIMD_CLAUSE_MASK \
22694 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
22695 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
22696 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22697 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
22698 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22699 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
22704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22706 static tree
22707 c_parser_omp_simd (location_t loc, c_parser *parser,
22708 char *p_name, omp_clause_mask mask, tree *cclauses,
22709 bool *if_p)
22711 tree block, clauses, ret;
22713 strcat (p_name, " simd");
22714 mask |= OMP_SIMD_CLAUSE_MASK;
22716 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22717 if (cclauses)
22719 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
22720 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
22723 block = c_begin_compound_stmt (true);
22724 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
22725 block = c_end_compound_stmt (loc, block, true);
22726 add_stmt (block);
22728 return ret;
22731 /* OpenMP 2.5:
22732 #pragma omp for for-clause[optseq] new-line
22733 for-loop
22735 OpenMP 4.0:
22736 #pragma omp for simd for-simd-clause[optseq] new-line
22737 for-loop
22739 LOC is the location of the #pragma token.
22742 #define OMP_FOR_CLAUSE_MASK \
22743 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
22749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
22750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22751 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
22752 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22753 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22755 static tree
22756 c_parser_omp_for (location_t loc, c_parser *parser,
22757 char *p_name, omp_clause_mask mask, tree *cclauses,
22758 bool *if_p)
22760 tree block, clauses, ret;
22762 strcat (p_name, " for");
22763 mask |= OMP_FOR_CLAUSE_MASK;
22764 /* parallel for{, simd} disallows nowait clause, but for
22765 target {teams distribute ,}parallel for{, simd} it should be accepted. */
22766 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
22767 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
22768 /* Composite distribute parallel for{, simd} disallows ordered clause. */
22769 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
22770 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
22772 if (c_parser_next_token_is (parser, CPP_NAME))
22774 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22776 if (strcmp (p, "simd") == 0)
22778 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22779 if (cclauses == NULL)
22780 cclauses = cclauses_buf;
22782 c_parser_consume_token (parser);
22783 if (!flag_openmp) /* flag_openmp_simd */
22784 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22785 if_p);
22786 block = c_begin_compound_stmt (true);
22787 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22788 block = c_end_compound_stmt (loc, block, true);
22789 if (ret == NULL_TREE)
22790 return ret;
22791 ret = make_node (OMP_FOR);
22792 TREE_TYPE (ret) = void_type_node;
22793 OMP_FOR_BODY (ret) = block;
22794 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
22795 SET_EXPR_LOCATION (ret, loc);
22796 add_stmt (ret);
22797 return ret;
22800 if (!flag_openmp) /* flag_openmp_simd */
22802 c_parser_skip_to_pragma_eol (parser, false);
22803 return NULL_TREE;
22806 /* Composite distribute parallel for disallows linear clause. */
22807 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
22808 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
22810 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22811 if (cclauses)
22813 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
22814 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
22817 block = c_begin_compound_stmt (true);
22818 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
22819 block = c_end_compound_stmt (loc, block, true);
22820 add_stmt (block);
22822 return ret;
22825 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
22826 omp_clause_mask, tree *, bool *);
22828 /* OpenMP 2.5:
22829 # pragma omp master new-line
22830 structured-block
22832 LOC is the location of the #pragma token.
22835 static tree
22836 c_parser_omp_master (location_t loc, c_parser *parser,
22837 char *p_name, omp_clause_mask mask, tree *cclauses,
22838 bool *if_p)
22840 tree block, clauses, ret;
22842 strcat (p_name, " master");
22844 if (c_parser_next_token_is (parser, CPP_NAME))
22846 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22848 if (strcmp (p, "taskloop") == 0)
22850 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22851 if (cclauses == NULL)
22852 cclauses = cclauses_buf;
22854 c_parser_consume_token (parser);
22855 if (!flag_openmp) /* flag_openmp_simd */
22856 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22857 if_p);
22858 block = c_begin_compound_stmt (true);
22859 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22860 if_p);
22861 block = c_end_compound_stmt (loc, block, true);
22862 if (ret == NULL_TREE)
22863 return ret;
22864 ret = c_finish_omp_master (loc, block);
22865 OMP_MASTER_COMBINED (ret) = 1;
22866 return ret;
22869 if (!flag_openmp) /* flag_openmp_simd */
22871 c_parser_skip_to_pragma_eol (parser, false);
22872 return NULL_TREE;
22875 if (cclauses)
22877 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
22878 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
22880 else
22881 c_parser_skip_to_pragma_eol (parser);
22883 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
22884 if_p));
22887 /* OpenMP 5.1:
22888 # pragma omp masked masked-clauses new-line
22889 structured-block
22891 LOC is the location of the #pragma token.
22894 #define OMP_MASKED_CLAUSE_MASK \
22895 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
22897 static tree
22898 c_parser_omp_masked (location_t loc, c_parser *parser,
22899 char *p_name, omp_clause_mask mask, tree *cclauses,
22900 bool *if_p)
22902 tree block, clauses, ret;
22904 strcat (p_name, " masked");
22905 mask |= OMP_MASKED_CLAUSE_MASK;
22907 if (c_parser_next_token_is (parser, CPP_NAME))
22909 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22911 if (strcmp (p, "taskloop") == 0)
22913 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22914 if (cclauses == NULL)
22915 cclauses = cclauses_buf;
22917 c_parser_consume_token (parser);
22918 if (!flag_openmp) /* flag_openmp_simd */
22919 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22920 if_p);
22921 block = c_begin_compound_stmt (true);
22922 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22923 if_p);
22924 block = c_end_compound_stmt (loc, block, true);
22925 if (ret == NULL_TREE)
22926 return ret;
22927 ret = c_finish_omp_masked (loc, block,
22928 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
22929 OMP_MASKED_COMBINED (ret) = 1;
22930 return ret;
22933 if (!flag_openmp) /* flag_openmp_simd */
22935 c_parser_skip_to_pragma_eol (parser, false);
22936 return NULL_TREE;
22939 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22940 if (cclauses)
22942 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
22943 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
22946 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
22947 if_p),
22948 clauses);
22951 /* OpenMP 2.5:
22952 # pragma omp ordered new-line
22953 structured-block
22955 OpenMP 4.5:
22956 # pragma omp ordered ordered-clauses new-line
22957 structured-block
22959 # pragma omp ordered depend-clauses new-line
22961 OpenMP 5.2
22962 # pragma omp ordered doacross-clauses new-line */
22964 #define OMP_ORDERED_CLAUSE_MASK \
22965 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
22966 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
22968 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
22969 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
22970 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
22972 static bool
22973 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
22974 bool *if_p)
22976 location_t loc = c_parser_peek_token (parser)->location;
22977 c_parser_consume_pragma (parser);
22979 if (context != pragma_stmt && context != pragma_compound)
22981 c_parser_error (parser, "expected declaration specifiers");
22982 c_parser_skip_to_pragma_eol (parser, false);
22983 return false;
22986 int n = 1;
22987 if (c_parser_next_token_is (parser, CPP_COMMA))
22988 n = 2;
22990 if (c_parser_peek_nth_token (parser, n)->type == CPP_NAME)
22992 const char *p
22993 = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser, n)->value);
22995 if (!strcmp ("depend", p) || !strcmp ("doacross", p))
22997 if (!flag_openmp) /* flag_openmp_simd */
22999 c_parser_skip_to_pragma_eol (parser, false);
23000 return false;
23002 if (context == pragma_stmt)
23004 error_at (loc,
23005 "%<#pragma omp ordered%> with %qs clause may "
23006 "only be used in compound statements", p);
23007 c_parser_skip_to_pragma_eol (parser, false);
23008 return true;
23011 tree clauses
23012 = c_parser_omp_all_clauses (parser,
23013 OMP_ORDERED_DEPEND_CLAUSE_MASK,
23014 "#pragma omp ordered");
23015 c_finish_omp_ordered (loc, clauses, NULL_TREE);
23016 return false;
23020 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
23021 "#pragma omp ordered");
23023 if (!flag_openmp /* flag_openmp_simd */
23024 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
23025 return false;
23027 c_finish_omp_ordered (loc, clauses,
23028 c_parser_omp_structured_block (parser, if_p));
23029 return true;
23032 /* OpenMP 2.5:
23034 section-scope:
23035 { section-sequence }
23037 section-sequence:
23038 section-directive[opt] structured-block
23039 section-sequence section-directive structured-block
23041 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
23043 SECTIONS_LOC is the location of the #pragma omp sections. */
23045 static tree
23046 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
23048 tree stmt, substmt;
23049 bool error_suppress = false;
23050 location_t loc;
23052 loc = c_parser_peek_token (parser)->location;
23053 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23055 /* Avoid skipping until the end of the block. */
23056 parser->error = false;
23057 return NULL_TREE;
23060 stmt = push_stmt_list ();
23062 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION
23063 && !c_parser_omp_section_scan (parser, "section", true))
23065 substmt = c_parser_omp_structured_block_sequence (parser,
23066 PRAGMA_OMP_SECTION);
23067 substmt = build1 (OMP_SECTION, void_type_node, substmt);
23068 SET_EXPR_LOCATION (substmt, loc);
23069 add_stmt (substmt);
23072 while (1)
23074 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
23075 break;
23076 if (c_parser_next_token_is (parser, CPP_EOF))
23077 break;
23079 loc = c_parser_peek_token (parser)->location;
23080 c_parser_omp_section_scan (parser, "section", false);
23081 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
23083 c_parser_consume_pragma (parser);
23084 c_parser_skip_to_pragma_eol (parser);
23085 error_suppress = false;
23087 else if (!error_suppress)
23089 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
23090 error_suppress = true;
23093 substmt = c_parser_omp_structured_block_sequence (parser,
23094 PRAGMA_OMP_SECTION);
23095 substmt = build1 (OMP_SECTION, void_type_node, substmt);
23096 SET_EXPR_LOCATION (substmt, loc);
23097 add_stmt (substmt);
23099 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
23100 "expected %<#pragma omp section%> or %<}%>");
23102 substmt = pop_stmt_list (stmt);
23104 stmt = make_node (OMP_SECTIONS);
23105 SET_EXPR_LOCATION (stmt, sections_loc);
23106 TREE_TYPE (stmt) = void_type_node;
23107 OMP_SECTIONS_BODY (stmt) = substmt;
23109 return add_stmt (stmt);
23112 /* OpenMP 2.5:
23113 # pragma omp sections sections-clause[optseq] newline
23114 sections-scope
23116 LOC is the location of the #pragma token.
23119 #define OMP_SECTIONS_CLAUSE_MASK \
23120 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23121 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23122 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23123 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23124 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23127 static tree
23128 c_parser_omp_sections (location_t loc, c_parser *parser,
23129 char *p_name, omp_clause_mask mask, tree *cclauses)
23131 tree block, clauses, ret;
23133 strcat (p_name, " sections");
23134 mask |= OMP_SECTIONS_CLAUSE_MASK;
23135 if (cclauses)
23136 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
23138 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23139 if (cclauses)
23141 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
23142 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
23145 block = c_begin_compound_stmt (true);
23146 ret = c_parser_omp_sections_scope (loc, parser);
23147 if (ret)
23148 OMP_SECTIONS_CLAUSES (ret) = clauses;
23149 block = c_end_compound_stmt (loc, block, true);
23150 add_stmt (block);
23152 return ret;
23155 /* OpenMP 2.5:
23156 # pragma omp parallel parallel-clause[optseq] new-line
23157 structured-block
23158 # pragma omp parallel for parallel-for-clause[optseq] new-line
23159 structured-block
23160 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
23161 structured-block
23163 OpenMP 4.0:
23164 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
23165 structured-block
23167 LOC is the location of the #pragma token.
23170 #define OMP_PARALLEL_CLAUSE_MASK \
23171 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23172 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23173 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23174 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23175 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
23177 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
23179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23180 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
23182 static tree
23183 c_parser_omp_parallel (location_t loc, c_parser *parser,
23184 char *p_name, omp_clause_mask mask, tree *cclauses,
23185 bool *if_p)
23187 tree stmt, clauses, block;
23189 strcat (p_name, " parallel");
23190 mask |= OMP_PARALLEL_CLAUSE_MASK;
23191 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
23192 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
23193 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
23194 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
23196 if (c_parser_next_token_is_keyword (parser, RID_FOR))
23198 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23199 if (cclauses == NULL)
23200 cclauses = cclauses_buf;
23202 c_parser_consume_token (parser);
23203 if (!flag_openmp) /* flag_openmp_simd */
23204 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
23205 block = c_begin_omp_parallel ();
23206 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
23207 stmt
23208 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23209 block);
23210 if (ret == NULL_TREE)
23211 return ret;
23212 OMP_PARALLEL_COMBINED (stmt) = 1;
23213 return stmt;
23215 /* When combined with distribute, parallel has to be followed by for.
23216 #pragma omp target parallel is allowed though. */
23217 else if (cclauses
23218 && (mask & (OMP_CLAUSE_MASK_1
23219 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
23221 error_at (loc, "expected %<for%> after %qs", p_name);
23222 c_parser_skip_to_pragma_eol (parser);
23223 return NULL_TREE;
23225 else if (c_parser_next_token_is (parser, CPP_NAME))
23227 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23228 if (cclauses == NULL && strcmp (p, "masked") == 0)
23230 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23231 cclauses = cclauses_buf;
23233 c_parser_consume_token (parser);
23234 if (!flag_openmp) /* flag_openmp_simd */
23235 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
23236 if_p);
23237 block = c_begin_omp_parallel ();
23238 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
23239 if_p);
23240 stmt = c_finish_omp_parallel (loc,
23241 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23242 block);
23243 if (ret == NULL)
23244 return ret;
23245 /* masked does have just filter clause, but during gimplification
23246 isn't represented by a gimplification omp context, so for
23247 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
23248 so that
23249 #pragma omp parallel masked
23250 #pragma omp taskloop simd lastprivate (x)
23251 isn't confused with
23252 #pragma omp parallel masked taskloop simd lastprivate (x) */
23253 if (OMP_MASKED_COMBINED (ret))
23254 OMP_PARALLEL_COMBINED (stmt) = 1;
23255 return stmt;
23257 else if (cclauses == NULL && strcmp (p, "master") == 0)
23259 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23260 cclauses = cclauses_buf;
23262 c_parser_consume_token (parser);
23263 if (!flag_openmp) /* flag_openmp_simd */
23264 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
23265 if_p);
23266 block = c_begin_omp_parallel ();
23267 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
23268 if_p);
23269 stmt = c_finish_omp_parallel (loc,
23270 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23271 block);
23272 if (ret == NULL)
23273 return ret;
23274 /* master doesn't have any clauses and during gimplification
23275 isn't represented by a gimplification omp context, so for
23276 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
23277 so that
23278 #pragma omp parallel master
23279 #pragma omp taskloop simd lastprivate (x)
23280 isn't confused with
23281 #pragma omp parallel master taskloop simd lastprivate (x) */
23282 if (OMP_MASTER_COMBINED (ret))
23283 OMP_PARALLEL_COMBINED (stmt) = 1;
23284 return stmt;
23286 else if (strcmp (p, "loop") == 0)
23288 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23289 if (cclauses == NULL)
23290 cclauses = cclauses_buf;
23292 c_parser_consume_token (parser);
23293 if (!flag_openmp) /* flag_openmp_simd */
23294 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23295 if_p);
23296 block = c_begin_omp_parallel ();
23297 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23298 if_p);
23299 stmt
23300 = c_finish_omp_parallel (loc,
23301 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23302 block);
23303 if (ret == NULL_TREE)
23304 return ret;
23305 OMP_PARALLEL_COMBINED (stmt) = 1;
23306 return stmt;
23308 else if (!flag_openmp) /* flag_openmp_simd */
23310 c_parser_skip_to_pragma_eol (parser, false);
23311 return NULL_TREE;
23313 else if (cclauses == NULL && strcmp (p, "sections") == 0)
23315 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23316 cclauses = cclauses_buf;
23318 c_parser_consume_token (parser);
23319 block = c_begin_omp_parallel ();
23320 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
23321 stmt = c_finish_omp_parallel (loc,
23322 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23323 block);
23324 OMP_PARALLEL_COMBINED (stmt) = 1;
23325 return stmt;
23328 else if (!flag_openmp) /* flag_openmp_simd */
23330 c_parser_skip_to_pragma_eol (parser, false);
23331 return NULL_TREE;
23334 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23335 if (cclauses)
23337 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
23338 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
23341 block = c_begin_omp_parallel ();
23342 parser->omp_attrs_forbidden_p = true;
23343 c_parser_statement (parser, if_p);
23344 stmt = c_finish_omp_parallel (loc, clauses, block);
23346 return stmt;
23349 /* OpenMP 2.5:
23350 # pragma omp single single-clause[optseq] new-line
23351 structured-block
23353 LOC is the location of the #pragma.
23356 #define OMP_SINGLE_CLAUSE_MASK \
23357 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23358 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
23360 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23361 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23363 static tree
23364 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
23366 tree stmt = make_node (OMP_SINGLE);
23367 SET_EXPR_LOCATION (stmt, loc);
23368 TREE_TYPE (stmt) = void_type_node;
23370 OMP_SINGLE_CLAUSES (stmt)
23371 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
23372 "#pragma omp single");
23373 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
23375 return add_stmt (stmt);
23378 /* OpenMP 5.1:
23379 # pragma omp scope scope-clause[optseq] new-line
23380 structured-block
23382 LOC is the location of the #pragma.
23385 #define OMP_SCOPE_CLAUSE_MASK \
23386 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23387 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23388 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23389 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23390 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23392 static tree
23393 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
23395 tree stmt = make_node (OMP_SCOPE);
23396 SET_EXPR_LOCATION (stmt, loc);
23397 TREE_TYPE (stmt) = void_type_node;
23399 OMP_SCOPE_CLAUSES (stmt)
23400 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
23401 "#pragma omp scope");
23402 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
23404 return add_stmt (stmt);
23407 /* OpenMP 3.0:
23408 # pragma omp task task-clause[optseq] new-line
23410 LOC is the location of the #pragma.
23413 #define OMP_TASK_CLAUSE_MASK \
23414 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23416 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23417 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23418 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23419 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23423 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23424 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23425 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
23426 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
23427 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
23429 static tree
23430 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
23432 tree clauses, block;
23434 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
23435 "#pragma omp task");
23437 block = c_begin_omp_task ();
23438 parser->omp_attrs_forbidden_p = true;
23439 c_parser_statement (parser, if_p);
23440 return c_finish_omp_task (loc, clauses, block);
23443 /* OpenMP 3.0:
23444 # pragma omp taskwait new-line
23446 OpenMP 5.0:
23447 # pragma omp taskwait taskwait-clause[optseq] new-line
23450 #define OMP_TASKWAIT_CLAUSE_MASK \
23451 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23452 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23454 static void
23455 c_parser_omp_taskwait (c_parser *parser)
23457 location_t loc = c_parser_peek_token (parser)->location;
23458 c_parser_consume_pragma (parser);
23460 tree clauses
23461 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
23462 "#pragma omp taskwait");
23464 if (clauses)
23466 tree stmt = make_node (OMP_TASK);
23467 TREE_TYPE (stmt) = void_node;
23468 OMP_TASK_CLAUSES (stmt) = clauses;
23469 OMP_TASK_BODY (stmt) = NULL_TREE;
23470 SET_EXPR_LOCATION (stmt, loc);
23471 add_stmt (stmt);
23473 else
23474 c_finish_omp_taskwait (loc);
23477 /* OpenMP 3.1:
23478 # pragma omp taskyield new-line
23481 static void
23482 c_parser_omp_taskyield (c_parser *parser)
23484 location_t loc = c_parser_peek_token (parser)->location;
23485 c_parser_consume_pragma (parser);
23486 c_parser_skip_to_pragma_eol (parser);
23488 c_finish_omp_taskyield (loc);
23491 /* OpenMP 4.0:
23492 # pragma omp taskgroup new-line
23494 OpenMP 5.0:
23495 # pragma omp taskgroup taskgroup-clause[optseq] new-line
23498 #define OMP_TASKGROUP_CLAUSE_MASK \
23499 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
23502 static tree
23503 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
23505 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
23506 "#pragma omp taskgroup");
23508 tree body = c_parser_omp_structured_block (parser, if_p);
23509 return c_finish_omp_taskgroup (loc, body, clauses);
23512 /* OpenMP 4.0:
23513 # pragma omp cancel cancel-clause[optseq] new-line
23515 LOC is the location of the #pragma.
23518 #define OMP_CANCEL_CLAUSE_MASK \
23519 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23520 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23521 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23522 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
23523 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
23525 static void
23526 c_parser_omp_cancel (c_parser *parser)
23528 location_t loc = c_parser_peek_token (parser)->location;
23530 c_parser_consume_pragma (parser);
23531 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
23532 "#pragma omp cancel");
23534 c_finish_omp_cancel (loc, clauses);
23537 /* OpenMP 4.0:
23538 # pragma omp cancellation point cancelpt-clause[optseq] new-line
23540 LOC is the location of the #pragma.
23543 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
23544 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
23549 static bool
23550 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
23552 location_t loc = c_parser_peek_token (parser)->location;
23553 tree clauses;
23554 bool point_seen = false;
23556 c_parser_consume_pragma (parser);
23557 if (c_parser_next_token_is (parser, CPP_NAME))
23559 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23560 if (strcmp (p, "point") == 0)
23562 c_parser_consume_token (parser);
23563 point_seen = true;
23566 if (!point_seen)
23568 c_parser_error (parser, "expected %<point%>");
23569 c_parser_skip_to_pragma_eol (parser);
23570 return false;
23573 if (context != pragma_compound)
23575 if (context == pragma_stmt)
23576 error_at (loc,
23577 "%<#pragma %s%> may only be used in compound statements",
23578 "omp cancellation point");
23579 else
23580 c_parser_error (parser, "expected declaration specifiers");
23581 c_parser_skip_to_pragma_eol (parser, false);
23582 return true;
23585 clauses
23586 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
23587 "#pragma omp cancellation point");
23589 c_finish_omp_cancellation_point (loc, clauses);
23590 return true;
23593 /* OpenMP 4.0:
23594 #pragma omp distribute distribute-clause[optseq] new-line
23595 for-loop */
23597 #define OMP_DISTRIBUTE_CLAUSE_MASK \
23598 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23599 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23600 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23601 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
23602 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23603 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23604 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23606 static tree
23607 c_parser_omp_distribute (location_t loc, c_parser *parser,
23608 char *p_name, omp_clause_mask mask, tree *cclauses,
23609 bool *if_p)
23611 tree clauses, block, ret;
23613 strcat (p_name, " distribute");
23614 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
23616 if (c_parser_next_token_is (parser, CPP_NAME))
23618 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23619 bool simd = false;
23620 bool parallel = false;
23622 if (strcmp (p, "simd") == 0)
23623 simd = true;
23624 else
23625 parallel = strcmp (p, "parallel") == 0;
23626 if (parallel || simd)
23628 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23629 if (cclauses == NULL)
23630 cclauses = cclauses_buf;
23631 c_parser_consume_token (parser);
23632 if (!flag_openmp) /* flag_openmp_simd */
23634 if (simd)
23635 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23636 if_p);
23637 else
23638 return c_parser_omp_parallel (loc, parser, p_name, mask,
23639 cclauses, if_p);
23641 block = c_begin_compound_stmt (true);
23642 if (simd)
23643 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23644 if_p);
23645 else
23646 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
23647 if_p);
23648 block = c_end_compound_stmt (loc, block, true);
23649 if (ret == NULL)
23650 return ret;
23651 ret = make_node (OMP_DISTRIBUTE);
23652 TREE_TYPE (ret) = void_type_node;
23653 OMP_FOR_BODY (ret) = block;
23654 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
23655 SET_EXPR_LOCATION (ret, loc);
23656 add_stmt (ret);
23657 return ret;
23660 if (!flag_openmp) /* flag_openmp_simd */
23662 c_parser_skip_to_pragma_eol (parser, false);
23663 return NULL_TREE;
23666 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23667 if (cclauses)
23669 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
23670 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
23673 block = c_begin_compound_stmt (true);
23674 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
23675 if_p);
23676 block = c_end_compound_stmt (loc, block, true);
23677 add_stmt (block);
23679 return ret;
23682 /* OpenMP 4.0:
23683 # pragma omp teams teams-clause[optseq] new-line
23684 structured-block */
23686 #define OMP_TEAMS_CLAUSE_MASK \
23687 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23688 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23689 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23690 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23691 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
23692 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
23693 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23694 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
23696 static tree
23697 c_parser_omp_teams (location_t loc, c_parser *parser,
23698 char *p_name, omp_clause_mask mask, tree *cclauses,
23699 bool *if_p)
23701 tree clauses, block, ret;
23703 strcat (p_name, " teams");
23704 mask |= OMP_TEAMS_CLAUSE_MASK;
23706 if (c_parser_next_token_is (parser, CPP_NAME))
23708 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23709 if (strcmp (p, "distribute") == 0)
23711 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23712 if (cclauses == NULL)
23713 cclauses = cclauses_buf;
23715 c_parser_consume_token (parser);
23716 if (!flag_openmp) /* flag_openmp_simd */
23717 return c_parser_omp_distribute (loc, parser, p_name, mask,
23718 cclauses, if_p);
23719 block = c_begin_omp_parallel ();
23720 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
23721 if_p);
23722 block = c_end_compound_stmt (loc, block, true);
23723 if (ret == NULL)
23724 return ret;
23725 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
23726 ret = make_node (OMP_TEAMS);
23727 TREE_TYPE (ret) = void_type_node;
23728 OMP_TEAMS_CLAUSES (ret) = clauses;
23729 OMP_TEAMS_BODY (ret) = block;
23730 OMP_TEAMS_COMBINED (ret) = 1;
23731 SET_EXPR_LOCATION (ret, loc);
23732 return add_stmt (ret);
23734 else if (strcmp (p, "loop") == 0)
23736 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23737 if (cclauses == NULL)
23738 cclauses = cclauses_buf;
23740 c_parser_consume_token (parser);
23741 if (!flag_openmp) /* flag_openmp_simd */
23742 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23743 if_p);
23744 block = c_begin_omp_parallel ();
23745 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
23746 block = c_end_compound_stmt (loc, block, true);
23747 if (ret == NULL)
23748 return ret;
23749 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
23750 ret = make_node (OMP_TEAMS);
23751 TREE_TYPE (ret) = void_type_node;
23752 OMP_TEAMS_CLAUSES (ret) = clauses;
23753 OMP_TEAMS_BODY (ret) = block;
23754 OMP_TEAMS_COMBINED (ret) = 1;
23755 SET_EXPR_LOCATION (ret, loc);
23756 return add_stmt (ret);
23759 if (!flag_openmp) /* flag_openmp_simd */
23761 c_parser_skip_to_pragma_eol (parser, false);
23762 return NULL_TREE;
23765 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23766 if (cclauses)
23768 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
23769 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
23772 tree stmt = make_node (OMP_TEAMS);
23773 TREE_TYPE (stmt) = void_type_node;
23774 OMP_TEAMS_CLAUSES (stmt) = clauses;
23775 block = c_begin_omp_parallel ();
23776 add_stmt (c_parser_omp_structured_block (parser, if_p));
23777 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
23778 SET_EXPR_LOCATION (stmt, loc);
23780 return add_stmt (stmt);
23783 /* OpenMP 4.0:
23784 # pragma omp target data target-data-clause[optseq] new-line
23785 structured-block */
23787 #define OMP_TARGET_DATA_CLAUSE_MASK \
23788 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23791 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
23792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
23794 static tree
23795 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
23797 if (flag_openmp)
23798 omp_requires_mask
23799 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
23801 tree clauses
23802 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
23803 "#pragma omp target data");
23804 c_omp_adjust_map_clauses (clauses, false);
23805 int map_seen = 0;
23806 for (tree *pc = &clauses; *pc;)
23808 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
23809 switch (OMP_CLAUSE_MAP_KIND (*pc))
23811 case GOMP_MAP_TO:
23812 case GOMP_MAP_ALWAYS_TO:
23813 case GOMP_MAP_PRESENT_TO:
23814 case GOMP_MAP_ALWAYS_PRESENT_TO:
23815 case GOMP_MAP_FROM:
23816 case GOMP_MAP_ALWAYS_FROM:
23817 case GOMP_MAP_PRESENT_FROM:
23818 case GOMP_MAP_ALWAYS_PRESENT_FROM:
23819 case GOMP_MAP_TOFROM:
23820 case GOMP_MAP_ALWAYS_TOFROM:
23821 case GOMP_MAP_PRESENT_TOFROM:
23822 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
23823 case GOMP_MAP_ALLOC:
23824 case GOMP_MAP_PRESENT_ALLOC:
23825 map_seen = 3;
23826 break;
23827 case GOMP_MAP_FIRSTPRIVATE_POINTER:
23828 case GOMP_MAP_ALWAYS_POINTER:
23829 case GOMP_MAP_ATTACH_DETACH:
23830 case GOMP_MAP_ATTACH:
23831 break;
23832 default:
23833 map_seen |= 1;
23834 error_at (OMP_CLAUSE_LOCATION (*pc),
23835 "%<#pragma omp target data%> with map-type other "
23836 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
23837 "on %<map%> clause");
23838 *pc = OMP_CLAUSE_CHAIN (*pc);
23839 continue;
23841 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
23842 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
23843 map_seen = 3;
23844 pc = &OMP_CLAUSE_CHAIN (*pc);
23847 if (map_seen != 3)
23849 if (map_seen == 0)
23850 error_at (loc,
23851 "%<#pragma omp target data%> must contain at least "
23852 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
23853 "clause");
23854 return NULL_TREE;
23857 tree stmt = make_node (OMP_TARGET_DATA);
23858 TREE_TYPE (stmt) = void_type_node;
23859 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
23860 keep_next_level ();
23861 tree block = c_begin_compound_stmt (true);
23862 add_stmt (c_parser_omp_structured_block (parser, if_p));
23863 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
23865 SET_EXPR_LOCATION (stmt, loc);
23866 return add_stmt (stmt);
23869 /* OpenMP 4.0:
23870 # pragma omp target update target-update-clause[optseq] new-line */
23872 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
23873 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
23874 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
23875 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23876 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23877 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23880 static bool
23881 c_parser_omp_target_update (location_t loc, c_parser *parser,
23882 enum pragma_context context)
23884 if (context == pragma_stmt)
23886 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
23887 "omp target update");
23888 c_parser_skip_to_pragma_eol (parser, false);
23889 return true;
23892 tree clauses
23893 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
23894 "#pragma omp target update");
23895 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
23896 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
23898 error_at (loc,
23899 "%<#pragma omp target update%> must contain at least one "
23900 "%<from%> or %<to%> clauses");
23901 return false;
23904 if (flag_openmp)
23905 omp_requires_mask
23906 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
23908 tree stmt = make_node (OMP_TARGET_UPDATE);
23909 TREE_TYPE (stmt) = void_type_node;
23910 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
23911 SET_EXPR_LOCATION (stmt, loc);
23912 add_stmt (stmt);
23913 return false;
23916 /* OpenMP 4.5:
23917 # pragma omp target enter data target-data-clause[optseq] new-line */
23919 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
23920 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23921 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23922 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23923 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23926 static bool
23927 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
23928 enum pragma_context context)
23930 bool data_seen = false;
23931 if (c_parser_next_token_is (parser, CPP_NAME))
23933 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23934 if (strcmp (p, "data") == 0)
23936 c_parser_consume_token (parser);
23937 data_seen = true;
23940 if (!data_seen)
23942 c_parser_error (parser, "expected %<data%>");
23943 c_parser_skip_to_pragma_eol (parser);
23944 return false;
23947 if (context == pragma_stmt)
23949 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
23950 "omp target enter data");
23951 c_parser_skip_to_pragma_eol (parser, false);
23952 return true;
23955 if (flag_openmp)
23956 omp_requires_mask
23957 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
23959 tree clauses
23960 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
23961 "#pragma omp target enter data");
23962 c_omp_adjust_map_clauses (clauses, false);
23963 int map_seen = 0;
23964 for (tree *pc = &clauses; *pc;)
23966 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
23967 switch (OMP_CLAUSE_MAP_KIND (*pc))
23969 case GOMP_MAP_TO:
23970 case GOMP_MAP_ALWAYS_TO:
23971 case GOMP_MAP_PRESENT_TO:
23972 case GOMP_MAP_ALWAYS_PRESENT_TO:
23973 case GOMP_MAP_ALLOC:
23974 case GOMP_MAP_PRESENT_ALLOC:
23975 map_seen = 3;
23976 break;
23977 case GOMP_MAP_TOFROM:
23978 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
23979 map_seen = 3;
23980 break;
23981 case GOMP_MAP_ALWAYS_TOFROM:
23982 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
23983 map_seen = 3;
23984 break;
23985 case GOMP_MAP_PRESENT_TOFROM:
23986 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_TO);
23987 map_seen = 3;
23988 break;
23989 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
23990 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_TO);
23991 map_seen = 3;
23992 break;
23993 case GOMP_MAP_FIRSTPRIVATE_POINTER:
23994 case GOMP_MAP_ALWAYS_POINTER:
23995 case GOMP_MAP_ATTACH_DETACH:
23996 case GOMP_MAP_ATTACH:
23997 break;
23998 default:
23999 map_seen |= 1;
24000 error_at (OMP_CLAUSE_LOCATION (*pc),
24001 "%<#pragma omp target enter data%> with map-type other "
24002 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
24003 *pc = OMP_CLAUSE_CHAIN (*pc);
24004 continue;
24006 pc = &OMP_CLAUSE_CHAIN (*pc);
24009 if (map_seen != 3)
24011 if (map_seen == 0)
24012 error_at (loc,
24013 "%<#pragma omp target enter data%> must contain at least "
24014 "one %<map%> clause");
24015 return true;
24018 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
24019 TREE_TYPE (stmt) = void_type_node;
24020 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
24021 SET_EXPR_LOCATION (stmt, loc);
24022 add_stmt (stmt);
24023 return true;
24026 /* OpenMP 4.5:
24027 # pragma omp target exit data target-data-clause[optseq] new-line */
24029 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
24030 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24031 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24032 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24033 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24034 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24036 static bool
24037 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
24038 enum pragma_context context)
24040 bool data_seen = false;
24041 if (c_parser_next_token_is (parser, CPP_NAME))
24043 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24044 if (strcmp (p, "data") == 0)
24046 c_parser_consume_token (parser);
24047 data_seen = true;
24050 if (!data_seen)
24052 c_parser_error (parser, "expected %<data%>");
24053 c_parser_skip_to_pragma_eol (parser);
24054 return false;
24057 if (context == pragma_stmt)
24059 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
24060 "omp target exit data");
24061 c_parser_skip_to_pragma_eol (parser, false);
24062 return true;
24065 if (flag_openmp)
24066 omp_requires_mask
24067 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24069 tree clauses
24070 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
24071 "#pragma omp target exit data", false);
24072 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP_EXIT_DATA);
24073 c_omp_adjust_map_clauses (clauses, false);
24074 int map_seen = 0;
24075 for (tree *pc = &clauses; *pc;)
24077 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24078 switch (OMP_CLAUSE_MAP_KIND (*pc))
24080 case GOMP_MAP_FROM:
24081 case GOMP_MAP_ALWAYS_FROM:
24082 case GOMP_MAP_PRESENT_FROM:
24083 case GOMP_MAP_ALWAYS_PRESENT_FROM:
24084 case GOMP_MAP_RELEASE:
24085 case GOMP_MAP_DELETE:
24086 map_seen = 3;
24087 break;
24088 case GOMP_MAP_TOFROM:
24089 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
24090 map_seen = 3;
24091 break;
24092 case GOMP_MAP_ALWAYS_TOFROM:
24093 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
24094 map_seen = 3;
24095 break;
24096 case GOMP_MAP_PRESENT_TOFROM:
24097 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_FROM);
24098 map_seen = 3;
24099 break;
24100 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24101 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_FROM);
24102 map_seen = 3;
24103 break;
24104 case GOMP_MAP_FIRSTPRIVATE_POINTER:
24105 case GOMP_MAP_ALWAYS_POINTER:
24106 case GOMP_MAP_ATTACH_DETACH:
24107 case GOMP_MAP_DETACH:
24108 break;
24109 default:
24110 map_seen |= 1;
24111 error_at (OMP_CLAUSE_LOCATION (*pc),
24112 "%<#pragma omp target exit data%> with map-type other "
24113 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
24114 "on %<map%> clause");
24115 *pc = OMP_CLAUSE_CHAIN (*pc);
24116 continue;
24118 pc = &OMP_CLAUSE_CHAIN (*pc);
24121 if (map_seen != 3)
24123 if (map_seen == 0)
24124 error_at (loc,
24125 "%<#pragma omp target exit data%> must contain at least one "
24126 "%<map%> clause");
24127 return true;
24130 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
24131 TREE_TYPE (stmt) = void_type_node;
24132 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
24133 SET_EXPR_LOCATION (stmt, loc);
24134 add_stmt (stmt);
24135 return true;
24138 /* OpenMP 4.0:
24139 # pragma omp target target-clause[optseq] new-line
24140 structured-block */
24142 #define OMP_TARGET_CLAUSE_MASK \
24143 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24144 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24145 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24146 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24147 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
24148 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
24149 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
24150 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
24151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
24152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
24153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
24154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
24155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
24157 static bool
24158 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
24160 location_t loc = c_parser_peek_token (parser)->location;
24161 c_parser_consume_pragma (parser);
24162 tree *pc = NULL, stmt, block;
24164 if (context != pragma_stmt && context != pragma_compound)
24166 c_parser_error (parser, "expected declaration specifiers");
24167 c_parser_skip_to_pragma_eol (parser);
24168 return false;
24171 if (flag_openmp)
24172 omp_requires_mask
24173 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24175 if (c_parser_next_token_is (parser, CPP_NAME))
24177 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24178 enum tree_code ccode = ERROR_MARK;
24180 if (strcmp (p, "teams") == 0)
24181 ccode = OMP_TEAMS;
24182 else if (strcmp (p, "parallel") == 0)
24183 ccode = OMP_PARALLEL;
24184 else if (strcmp (p, "simd") == 0)
24185 ccode = OMP_SIMD;
24186 if (ccode != ERROR_MARK)
24188 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
24189 char p_name[sizeof ("#pragma omp target teams distribute "
24190 "parallel for simd")];
24192 c_parser_consume_token (parser);
24193 strcpy (p_name, "#pragma omp target");
24194 if (!flag_openmp) /* flag_openmp_simd */
24196 tree stmt;
24197 switch (ccode)
24199 case OMP_TEAMS:
24200 stmt = c_parser_omp_teams (loc, parser, p_name,
24201 OMP_TARGET_CLAUSE_MASK,
24202 cclauses, if_p);
24203 break;
24204 case OMP_PARALLEL:
24205 stmt = c_parser_omp_parallel (loc, parser, p_name,
24206 OMP_TARGET_CLAUSE_MASK,
24207 cclauses, if_p);
24208 break;
24209 case OMP_SIMD:
24210 stmt = c_parser_omp_simd (loc, parser, p_name,
24211 OMP_TARGET_CLAUSE_MASK,
24212 cclauses, if_p);
24213 break;
24214 default:
24215 gcc_unreachable ();
24217 return stmt != NULL_TREE;
24219 keep_next_level ();
24220 tree block = c_begin_compound_stmt (true), ret;
24221 switch (ccode)
24223 case OMP_TEAMS:
24224 ret = c_parser_omp_teams (loc, parser, p_name,
24225 OMP_TARGET_CLAUSE_MASK, cclauses,
24226 if_p);
24227 break;
24228 case OMP_PARALLEL:
24229 ret = c_parser_omp_parallel (loc, parser, p_name,
24230 OMP_TARGET_CLAUSE_MASK, cclauses,
24231 if_p);
24232 break;
24233 case OMP_SIMD:
24234 ret = c_parser_omp_simd (loc, parser, p_name,
24235 OMP_TARGET_CLAUSE_MASK, cclauses,
24236 if_p);
24237 break;
24238 default:
24239 gcc_unreachable ();
24241 block = c_end_compound_stmt (loc, block, true);
24242 if (ret == NULL_TREE)
24243 return false;
24244 if (ccode == OMP_TEAMS)
24245 /* For combined target teams, ensure the num_teams and
24246 thread_limit clause expressions are evaluated on the host,
24247 before entering the target construct. */
24248 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
24249 c; c = OMP_CLAUSE_CHAIN (c))
24250 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
24251 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
24252 for (int i = 0;
24253 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
24254 if (OMP_CLAUSE_OPERAND (c, i)
24255 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
24257 tree expr = OMP_CLAUSE_OPERAND (c, i);
24258 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
24259 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
24260 expr, NULL_TREE, NULL_TREE);
24261 add_stmt (expr);
24262 OMP_CLAUSE_OPERAND (c, i) = expr;
24263 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
24264 OMP_CLAUSE_FIRSTPRIVATE);
24265 OMP_CLAUSE_DECL (tc) = tmp;
24266 OMP_CLAUSE_CHAIN (tc)
24267 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
24268 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
24270 tree stmt = make_node (OMP_TARGET);
24271 TREE_TYPE (stmt) = void_type_node;
24272 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
24273 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
24274 OMP_TARGET_BODY (stmt) = block;
24275 OMP_TARGET_COMBINED (stmt) = 1;
24276 SET_EXPR_LOCATION (stmt, loc);
24277 add_stmt (stmt);
24278 pc = &OMP_TARGET_CLAUSES (stmt);
24279 goto check_clauses;
24281 else if (!flag_openmp) /* flag_openmp_simd */
24283 c_parser_skip_to_pragma_eol (parser, false);
24284 return false;
24286 else if (strcmp (p, "data") == 0)
24288 c_parser_consume_token (parser);
24289 c_parser_omp_target_data (loc, parser, if_p);
24290 return true;
24292 else if (strcmp (p, "enter") == 0)
24294 c_parser_consume_token (parser);
24295 return c_parser_omp_target_enter_data (loc, parser, context);
24297 else if (strcmp (p, "exit") == 0)
24299 c_parser_consume_token (parser);
24300 return c_parser_omp_target_exit_data (loc, parser, context);
24302 else if (strcmp (p, "update") == 0)
24304 c_parser_consume_token (parser);
24305 return c_parser_omp_target_update (loc, parser, context);
24308 if (!flag_openmp) /* flag_openmp_simd */
24310 c_parser_skip_to_pragma_eol (parser, false);
24311 return false;
24314 stmt = make_node (OMP_TARGET);
24315 TREE_TYPE (stmt) = void_type_node;
24317 OMP_TARGET_CLAUSES (stmt)
24318 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
24319 "#pragma omp target", false);
24320 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
24321 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
24323 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
24324 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
24325 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
24326 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
24327 OMP_CLAUSE_CHAIN (c) = nc;
24329 OMP_TARGET_CLAUSES (stmt)
24330 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
24331 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
24333 pc = &OMP_TARGET_CLAUSES (stmt);
24334 keep_next_level ();
24335 block = c_begin_compound_stmt (true);
24336 add_stmt (c_parser_omp_structured_block (parser, if_p));
24337 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
24339 SET_EXPR_LOCATION (stmt, loc);
24340 add_stmt (stmt);
24342 check_clauses:
24343 while (*pc)
24345 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24346 switch (OMP_CLAUSE_MAP_KIND (*pc))
24348 case GOMP_MAP_TO:
24349 case GOMP_MAP_ALWAYS_TO:
24350 case GOMP_MAP_PRESENT_TO:
24351 case GOMP_MAP_ALWAYS_PRESENT_TO:
24352 case GOMP_MAP_FROM:
24353 case GOMP_MAP_ALWAYS_FROM:
24354 case GOMP_MAP_PRESENT_FROM:
24355 case GOMP_MAP_ALWAYS_PRESENT_FROM:
24356 case GOMP_MAP_TOFROM:
24357 case GOMP_MAP_ALWAYS_TOFROM:
24358 case GOMP_MAP_PRESENT_TOFROM:
24359 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24360 case GOMP_MAP_ALLOC:
24361 case GOMP_MAP_PRESENT_ALLOC:
24362 case GOMP_MAP_FIRSTPRIVATE_POINTER:
24363 case GOMP_MAP_ALWAYS_POINTER:
24364 case GOMP_MAP_POINTER:
24365 case GOMP_MAP_ATTACH_DETACH:
24366 case GOMP_MAP_ATTACH:
24367 break;
24368 default:
24369 error_at (OMP_CLAUSE_LOCATION (*pc),
24370 "%<#pragma omp target%> with map-type other "
24371 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
24372 "on %<map%> clause");
24373 *pc = OMP_CLAUSE_CHAIN (*pc);
24374 continue;
24376 pc = &OMP_CLAUSE_CHAIN (*pc);
24378 cfun->has_omp_target = true;
24379 return true;
24382 /* OpenMP 4.0:
24383 # pragma omp declare simd declare-simd-clauses[optseq] new-line
24385 OpenMP 5.0:
24386 # pragma omp declare variant (identifier) match(context-selector) new-line
24389 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
24390 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
24391 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
24392 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
24393 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
24394 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
24395 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
24397 static void
24398 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
24400 c_token *token = c_parser_peek_token (parser);
24401 gcc_assert (token->type == CPP_NAME);
24402 tree kind = token->value;
24403 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
24404 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
24406 auto_vec<c_token> clauses;
24407 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
24409 c_token *token = c_parser_peek_token (parser);
24410 if (token->type == CPP_EOF)
24412 c_parser_skip_to_pragma_eol (parser);
24413 return;
24415 clauses.safe_push (*token);
24416 c_parser_consume_token (parser);
24418 clauses.safe_push (*c_parser_peek_token (parser));
24419 c_parser_skip_to_pragma_eol (parser);
24421 while (c_parser_next_token_is (parser, CPP_PRAGMA))
24423 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
24424 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
24425 || c_parser_peek_2nd_token (parser)->value != kind)
24427 error ("%<#pragma omp declare %s%> must be followed by "
24428 "function declaration or definition or another "
24429 "%<#pragma omp declare %s%>",
24430 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
24431 return;
24433 c_parser_consume_pragma (parser);
24434 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
24436 c_token *token = c_parser_peek_token (parser);
24437 if (token->type == CPP_EOF)
24439 c_parser_skip_to_pragma_eol (parser);
24440 return;
24442 clauses.safe_push (*token);
24443 c_parser_consume_token (parser);
24445 clauses.safe_push (*c_parser_peek_token (parser));
24446 c_parser_skip_to_pragma_eol (parser);
24449 /* Make sure nothing tries to read past the end of the tokens. */
24450 c_token eof_token;
24451 memset (&eof_token, 0, sizeof (eof_token));
24452 eof_token.type = CPP_EOF;
24453 clauses.safe_push (eof_token);
24454 clauses.safe_push (eof_token);
24456 switch (context)
24458 case pragma_external:
24459 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24460 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
24462 int ext = disable_extension_diagnostics ();
24464 c_parser_consume_token (parser);
24465 while (c_parser_next_token_is (parser, CPP_KEYWORD)
24466 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
24467 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
24468 NULL, &clauses);
24469 restore_extension_diagnostics (ext);
24471 else
24472 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
24473 NULL, &clauses);
24474 break;
24475 case pragma_struct:
24476 case pragma_param:
24477 case pragma_stmt:
24478 error ("%<#pragma omp declare %s%> must be followed by "
24479 "function declaration or definition",
24480 IDENTIFIER_POINTER (kind));
24481 break;
24482 case pragma_compound:
24483 bool have_std_attrs;
24484 tree std_attrs;
24485 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
24486 if (have_std_attrs)
24487 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
24488 else
24489 std_attrs = NULL_TREE;
24490 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24491 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
24493 int ext = disable_extension_diagnostics ();
24495 c_parser_consume_token (parser);
24496 while (c_parser_next_token_is (parser, CPP_KEYWORD)
24497 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
24498 if (c_parser_next_tokens_start_declaration (parser)
24499 || c_parser_nth_token_starts_std_attributes (parser, 1))
24501 c_parser_declaration_or_fndef (parser, true, true, true, true,
24502 true, NULL, &clauses,
24503 have_std_attrs, std_attrs);
24504 restore_extension_diagnostics (ext);
24505 break;
24507 restore_extension_diagnostics (ext);
24509 else if (c_parser_next_tokens_start_declaration (parser))
24511 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
24512 NULL, &clauses, have_std_attrs,
24513 std_attrs);
24514 break;
24516 error ("%<#pragma omp declare %s%> must be followed by "
24517 "function declaration or definition",
24518 IDENTIFIER_POINTER (kind));
24519 break;
24520 default:
24521 gcc_unreachable ();
24525 /* OpenMP 5.0:
24527 trait-selector:
24528 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
24530 trait-score:
24531 score(score-expression)
24533 Note that this function returns a list of trait selectors for the
24534 trait-selector-set SET. */
24536 static tree
24537 c_parser_omp_context_selector (c_parser *parser, enum omp_tss_code set,
24538 tree parms)
24540 tree ret = NULL_TREE;
24543 tree selector;
24544 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24545 || c_parser_next_token_is (parser, CPP_NAME))
24546 selector = c_parser_peek_token (parser)->value;
24547 else
24549 c_parser_error (parser, "expected trait selector name");
24550 return error_mark_node;
24552 enum omp_ts_code sel
24553 = omp_lookup_ts_code (set, IDENTIFIER_POINTER (selector));
24555 if (sel == OMP_TRAIT_INVALID)
24557 /* Per the spec, "Implementations can ignore specified selectors
24558 that are not those described in this section"; however, we
24559 must record such selectors because they cause match failures. */
24560 warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
24561 "unknown selector %qs for context selector set %qs",
24562 IDENTIFIER_POINTER (selector), omp_tss_map[set]);
24563 c_parser_consume_token (parser);
24564 ret = make_trait_selector (sel, NULL_TREE, NULL_TREE, ret);
24565 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
24566 c_parser_balanced_token_sequence (parser);
24567 if (c_parser_next_token_is (parser, CPP_COMMA))
24569 c_parser_consume_token (parser);
24570 continue;
24572 else
24573 break;
24576 c_parser_consume_token (parser);
24578 tree properties = NULL_TREE;
24579 tree scoreval = NULL_TREE;
24580 enum omp_tp_type property_kind = omp_ts_map[sel].tp_type;
24581 bool allow_score = omp_ts_map[sel].allow_score;
24582 tree t;
24584 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
24586 if (property_kind == OMP_TRAIT_PROPERTY_NONE)
24588 error_at (c_parser_peek_token (parser)->location,
24589 "selector %qs does not accept any properties",
24590 IDENTIFIER_POINTER (selector));
24591 return error_mark_node;
24594 matching_parens parens;
24595 parens.require_open (parser);
24597 c_token *token = c_parser_peek_token (parser);
24598 if (c_parser_next_token_is (parser, CPP_NAME)
24599 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
24600 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
24602 c_parser_consume_token (parser);
24604 matching_parens parens2;
24605 parens2.require_open (parser);
24606 tree score = c_parser_expr_no_commas (parser, NULL).value;
24607 parens2.skip_until_found_close (parser);
24608 c_parser_require (parser, CPP_COLON, "expected %<:%>");
24609 if (!allow_score)
24610 error_at (token->location,
24611 "%<score%> cannot be specified in traits "
24612 "in the %qs trait-selector-set",
24613 omp_tss_map[set]);
24614 else if (score != error_mark_node)
24616 mark_exp_read (score);
24617 score = c_fully_fold (score, false, NULL);
24618 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
24619 || TREE_CODE (score) != INTEGER_CST)
24620 error_at (token->location, "%<score%> argument must "
24621 "be constant integer expression");
24622 else if (tree_int_cst_sgn (score) < 0)
24623 error_at (token->location, "%<score%> argument must "
24624 "be non-negative");
24625 else
24626 scoreval = score;
24628 token = c_parser_peek_token (parser);
24631 switch (property_kind)
24633 case OMP_TRAIT_PROPERTY_ID:
24634 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24635 || c_parser_next_token_is (parser, CPP_NAME))
24637 tree prop = c_parser_peek_token (parser)->value;
24638 c_parser_consume_token (parser);
24639 properties = make_trait_property (prop, NULL_TREE,
24640 properties);
24642 else
24644 c_parser_error (parser, "expected identifier");
24645 return error_mark_node;
24647 break;
24648 case OMP_TRAIT_PROPERTY_NAME_LIST:
24651 tree prop = OMP_TP_NAMELIST_NODE;
24652 tree value = NULL_TREE;
24653 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24654 || c_parser_next_token_is (parser, CPP_NAME))
24656 value = c_parser_peek_token (parser)->value;
24657 c_parser_consume_token (parser);
24659 else if (c_parser_next_token_is (parser, CPP_STRING))
24660 value = c_parser_string_literal (parser, false,
24661 false).value;
24662 else
24664 c_parser_error (parser, "expected identifier or "
24665 "string literal");
24666 return error_mark_node;
24669 properties = make_trait_property (prop, value, properties);
24671 if (c_parser_next_token_is (parser, CPP_COMMA))
24672 c_parser_consume_token (parser);
24673 else
24674 break;
24676 while (1);
24677 break;
24678 case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR:
24679 case OMP_TRAIT_PROPERTY_BOOL_EXPR:
24680 t = c_parser_expr_no_commas (parser, NULL).value;
24681 if (t != error_mark_node)
24683 mark_exp_read (t);
24684 t = c_fully_fold (t, false, NULL);
24685 /* FIXME: this is bogus, both device_num and
24686 condition selectors allow arbitrary expressions. */
24687 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
24688 || !tree_fits_shwi_p (t))
24689 error_at (token->location, "property must be "
24690 "constant integer expression");
24691 else
24692 properties = make_trait_property (NULL_TREE, t,
24693 properties);
24695 else
24696 return error_mark_node;
24697 break;
24698 case OMP_TRAIT_PROPERTY_CLAUSE_LIST:
24699 if (sel == OMP_TRAIT_CONSTRUCT_SIMD)
24701 if (parms == NULL_TREE)
24703 error_at (token->location, "properties for %<simd%> "
24704 "selector may not be specified in "
24705 "%<metadirective%>");
24706 return error_mark_node;
24708 tree c;
24709 c = c_parser_omp_all_clauses (parser,
24710 OMP_DECLARE_SIMD_CLAUSE_MASK,
24711 "simd", true, 2);
24712 c = c_omp_declare_simd_clauses_to_numbers (parms
24713 == error_mark_node
24714 ? NULL_TREE : parms,
24716 properties = c;
24718 else if (sel == OMP_TRAIT_IMPLEMENTATION_REQUIRES)
24720 /* FIXME: The "requires" selector was added in OpenMP 5.1.
24721 Currently only the now-deprecated syntax
24722 from OpenMP 5.0 is supported. */
24723 sorry_at (token->location,
24724 "%<requires%> selector is not supported yet");
24725 return error_mark_node;
24727 else
24728 gcc_unreachable ();
24729 break;
24730 default:
24731 gcc_unreachable ();
24734 parens.skip_until_found_close (parser);
24735 properties = nreverse (properties);
24737 else if (property_kind != OMP_TRAIT_PROPERTY_NONE
24738 && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST
24739 && property_kind != OMP_TRAIT_PROPERTY_EXTENSION)
24741 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
24742 return error_mark_node;
24745 ret = make_trait_selector (sel, scoreval, properties, ret);
24747 if (c_parser_next_token_is (parser, CPP_COMMA))
24748 c_parser_consume_token (parser);
24749 else
24750 break;
24752 while (1);
24754 return nreverse (ret);
24757 /* OpenMP 5.0:
24759 trait-set-selector[,trait-set-selector[,...]]
24761 trait-set-selector:
24762 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
24764 trait-set-selector-name:
24765 constructor
24766 device
24767 implementation
24768 user */
24770 static tree
24771 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
24773 tree ret = NULL_TREE;
24776 const char *setp = "";
24777 if (c_parser_next_token_is (parser, CPP_NAME))
24778 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24779 enum omp_tss_code set = omp_lookup_tss_code (setp);
24781 if (set == OMP_TRAIT_SET_INVALID)
24783 c_parser_error (parser, "expected context selector set name");
24784 return error_mark_node;
24787 c_parser_consume_token (parser);
24789 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
24790 return error_mark_node;
24792 matching_braces braces;
24793 if (!braces.require_open (parser))
24794 return error_mark_node;
24796 tree selectors = c_parser_omp_context_selector (parser, set, parms);
24797 if (selectors == error_mark_node)
24798 ret = error_mark_node;
24799 else if (ret != error_mark_node)
24800 ret = make_trait_set_selector (set, selectors, ret);
24802 braces.skip_until_found_close (parser);
24804 if (c_parser_next_token_is (parser, CPP_COMMA))
24805 c_parser_consume_token (parser);
24806 else
24807 break;
24809 while (1);
24811 if (ret == error_mark_node)
24812 return ret;
24813 return nreverse (ret);
24816 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
24817 that into "omp declare variant base" attribute. */
24819 static void
24820 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
24822 matching_parens parens;
24823 if (!parens.require_open (parser))
24825 fail:
24826 c_parser_skip_to_pragma_eol (parser, false);
24827 return;
24830 if (c_parser_next_token_is_not (parser, CPP_NAME)
24831 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
24833 c_parser_error (parser, "expected identifier");
24834 goto fail;
24837 c_token *token = c_parser_peek_token (parser);
24838 tree variant = lookup_name (token->value);
24840 if (variant == NULL_TREE)
24842 undeclared_variable (token->location, token->value);
24843 variant = error_mark_node;
24846 c_parser_consume_token (parser);
24848 parens.require_close (parser);
24850 if (c_parser_next_token_is (parser, CPP_COMMA)
24851 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
24852 c_parser_consume_token (parser);
24854 const char *clause = "";
24855 location_t match_loc = c_parser_peek_token (parser)->location;
24856 if (c_parser_next_token_is (parser, CPP_NAME))
24857 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24858 if (strcmp (clause, "match"))
24860 c_parser_error (parser, "expected %<match%>");
24861 goto fail;
24864 c_parser_consume_token (parser);
24866 if (!parens.require_open (parser))
24867 goto fail;
24869 if (parms == NULL_TREE)
24870 parms = error_mark_node;
24872 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
24873 if (ctx == error_mark_node)
24874 goto fail;
24875 ctx = omp_check_context_selector (match_loc, ctx);
24876 if (ctx != error_mark_node && variant != error_mark_node)
24878 if (TREE_CODE (variant) != FUNCTION_DECL)
24880 error_at (token->location, "variant %qD is not a function", variant);
24881 variant = error_mark_node;
24883 else if (!omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
24884 OMP_TRAIT_CONSTRUCT_SIMD)
24885 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
24887 error_at (token->location, "variant %qD and base %qD have "
24888 "incompatible types", variant, fndecl);
24889 variant = error_mark_node;
24891 else if (fndecl_built_in_p (variant)
24892 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
24893 "__builtin_", strlen ("__builtin_")) == 0
24894 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
24895 "__sync_", strlen ("__sync_")) == 0
24896 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
24897 "__atomic_", strlen ("__atomic_")) == 0))
24899 error_at (token->location, "variant %qD is a built-in", variant);
24900 variant = error_mark_node;
24902 if (variant != error_mark_node)
24904 C_DECL_USED (variant) = 1;
24905 tree construct
24906 = omp_get_context_selector_list (ctx, OMP_TRAIT_SET_CONSTRUCT);
24907 omp_mark_declare_variant (match_loc, variant, construct);
24908 if (omp_context_selector_matches (ctx))
24910 tree attr
24911 = tree_cons (get_identifier ("omp declare variant base"),
24912 build_tree_list (variant, ctx),
24913 DECL_ATTRIBUTES (fndecl));
24914 DECL_ATTRIBUTES (fndecl) = attr;
24919 parens.require_close (parser);
24920 c_parser_skip_to_pragma_eol (parser);
24923 /* Finalize #pragma omp declare simd or #pragma omp declare variant
24924 clauses after FNDECL has been parsed, and put that into "omp declare simd"
24925 or "omp declare variant base" attribute. */
24927 static void
24928 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
24929 vec<c_token> *pclauses)
24931 vec<c_token> &clauses = *pclauses;
24933 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
24934 indicates error has been reported and CPP_PRAGMA that
24935 c_finish_omp_declare_simd has already processed the tokens. */
24936 if (clauses.exists () && clauses[0].type == CPP_EOF)
24937 return;
24938 const char *kind = "simd";
24939 if (clauses.exists ()
24940 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
24941 kind = IDENTIFIER_POINTER (clauses[0].value);
24942 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
24943 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
24945 error ("%<#pragma omp declare %s%> not immediately followed by "
24946 "a function declaration or definition", kind);
24947 clauses[0].type = CPP_EOF;
24948 return;
24950 if (clauses.exists () && clauses[0].type != CPP_NAME)
24952 error_at (DECL_SOURCE_LOCATION (fndecl),
24953 "%<#pragma omp declare %s%> not immediately followed by "
24954 "a single function declaration or definition", kind);
24955 clauses[0].type = CPP_EOF;
24956 return;
24959 if (parms == NULL_TREE)
24960 parms = DECL_ARGUMENTS (fndecl);
24962 unsigned int tokens_avail = parser->tokens_avail;
24963 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
24965 parser->tokens = clauses.address ();
24966 parser->tokens_avail = clauses.length ();
24968 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
24969 while (parser->tokens_avail > 3)
24971 c_token *token = c_parser_peek_token (parser);
24972 gcc_assert (token->type == CPP_NAME);
24973 kind = IDENTIFIER_POINTER (token->value);
24974 c_parser_consume_token (parser);
24975 parser->in_pragma = true;
24977 if (strcmp (kind, "simd") == 0)
24979 tree c;
24980 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
24981 "#pragma omp declare simd");
24982 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
24983 if (c != NULL_TREE)
24984 c = tree_cons (NULL_TREE, c, NULL_TREE);
24985 c = build_tree_list (get_identifier ("omp declare simd"), c);
24986 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
24987 DECL_ATTRIBUTES (fndecl) = c;
24989 else
24991 gcc_assert (strcmp (kind, "variant") == 0);
24992 c_finish_omp_declare_variant (parser, fndecl, parms);
24996 parser->tokens = &parser->tokens_buf[0];
24997 parser->tokens_avail = tokens_avail;
24998 if (clauses.exists ())
24999 clauses[0].type = CPP_PRAGMA;
25002 /* D should be C_TOKEN_VEC from omp::decl attribute. If it contains
25003 a threadprivate, groupprivate, allocate or declare target directive,
25004 return true and parse it for DECL. */
25006 bool
25007 c_maybe_parse_omp_decl (tree decl, tree d)
25009 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
25010 vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
25011 c_token *first = toks->address ();
25012 c_token *last = first + toks->length ();
25013 const char *directive[3] = {};
25014 for (int j = 0; j < 3; j++)
25016 tree id = NULL_TREE;
25017 if (first + j == last)
25018 break;
25019 if (first[j].type == CPP_NAME)
25020 id = first[j].value;
25021 else if (first[j].type == CPP_KEYWORD)
25022 id = ridpointers[(int) first[j].keyword];
25023 else
25024 break;
25025 directive[j] = IDENTIFIER_POINTER (id);
25027 const c_omp_directive *dir = NULL;
25028 if (directive[0])
25029 dir = c_omp_categorize_directive (directive[0], directive[1],
25030 directive[2]);
25031 if (dir == NULL)
25033 error_at (first->location,
25034 "unknown OpenMP directive name in "
25035 "%qs attribute argument", "omp::decl");
25036 return false;
25038 if (dir->id != PRAGMA_OMP_THREADPRIVATE
25039 /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
25040 && dir->id != PRAGMA_OMP_ALLOCATE
25041 && (dir->id != PRAGMA_OMP_DECLARE
25042 || strcmp (directive[1], "target") != 0))
25043 return false;
25045 if (!flag_openmp && !dir->simd)
25046 return true;
25048 c_parser *parser = the_parser;
25049 unsigned int tokens_avail = parser->tokens_avail;
25050 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
25051 toks = NULL;
25052 vec_safe_reserve (toks, last - first + 2, true);
25053 c_token tok = {};
25054 tok.type = CPP_PRAGMA;
25055 tok.keyword = RID_MAX;
25056 tok.pragma_kind = pragma_kind (dir->id);
25057 tok.location = first->location;
25058 toks->quick_push (tok);
25059 while (++first < last)
25060 toks->quick_push (*first);
25061 tok = {};
25062 tok.type = CPP_PRAGMA_EOL;
25063 tok.keyword = RID_MAX;
25064 tok.location = last[-1].location;
25065 toks->quick_push (tok);
25066 tok = {};
25067 tok.type = CPP_EOF;
25068 tok.keyword = RID_MAX;
25069 tok.location = last[-1].location;
25070 tok.flags = tokens_avail;
25071 toks->quick_push (tok);
25072 parser->in_omp_decl_attribute = decl;
25073 parser->tokens = toks->address ();
25074 parser->tokens_avail = toks->length ();
25075 parser->in_omp_attribute_pragma = toks;
25076 c_parser_pragma (parser, pragma_external, NULL);
25077 parser->in_omp_decl_attribute = NULL_TREE;
25078 return true;
25081 /* OpenMP 4.0:
25082 # pragma omp declare target new-line
25083 declarations and definitions
25084 # pragma omp end declare target new-line
25086 OpenMP 4.5:
25087 # pragma omp declare target ( extended-list ) new-line
25089 # pragma omp declare target declare-target-clauses[seq] new-line */
25091 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
25092 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
25093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
25094 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
25095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25098 static void
25099 c_parser_omp_declare_target (c_parser *parser)
25101 tree clauses = NULL_TREE;
25102 int device_type = 0;
25103 bool indirect = false;
25104 bool only_device_type_or_indirect = true;
25105 if (c_parser_next_token_is (parser, CPP_NAME)
25106 || (c_parser_next_token_is (parser, CPP_COMMA)
25107 && c_parser_peek_2nd_token (parser)->type == CPP_NAME))
25108 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
25109 "#pragma omp declare target");
25110 else if (parser->in_omp_decl_attribute
25111 || c_parser_next_token_is (parser, CPP_OPEN_PAREN))
25113 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
25114 clauses);
25115 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
25116 c_parser_skip_to_pragma_eol (parser);
25118 else
25120 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25121 c_parser_skip_to_pragma_eol (parser);
25122 c_omp_declare_target_attr attr = { attr_syntax, -1, 0 };
25123 vec_safe_push (current_omp_declare_target_attribute, attr);
25124 return;
25126 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25128 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
25129 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
25130 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25131 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
25133 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25135 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE
25136 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25137 continue;
25138 tree t = OMP_CLAUSE_DECL (c), id;
25139 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
25140 tree at2 = lookup_attribute ("omp declare target link",
25141 DECL_ATTRIBUTES (t));
25142 only_device_type_or_indirect = false;
25143 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
25145 id = get_identifier ("omp declare target link");
25146 std::swap (at1, at2);
25148 else
25149 id = get_identifier ("omp declare target");
25150 if (at2)
25152 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
25153 error_at (OMP_CLAUSE_LOCATION (c),
25154 "%qD specified both in declare target %<link%> and %qs"
25155 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
25156 else
25157 error_at (OMP_CLAUSE_LOCATION (c),
25158 "%qD specified both in declare target %<link%> and "
25159 "%<to%> or %<enter%> clauses", t);
25160 continue;
25162 if (!at1)
25164 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25165 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
25166 continue;
25168 symtab_node *node = symtab_node::get (t);
25169 if (node != NULL)
25171 node->offloadable = 1;
25172 if (ENABLE_OFFLOADING)
25174 g->have_offload = true;
25175 if (is_a <varpool_node *> (node))
25176 vec_safe_push (offload_vars, t);
25180 if (TREE_CODE (t) != FUNCTION_DECL)
25181 continue;
25182 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
25184 tree at3 = lookup_attribute ("omp declare target host",
25185 DECL_ATTRIBUTES (t));
25186 if (at3 == NULL_TREE)
25188 id = get_identifier ("omp declare target host");
25189 DECL_ATTRIBUTES (t)
25190 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25193 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
25195 tree at3 = lookup_attribute ("omp declare target nohost",
25196 DECL_ATTRIBUTES (t));
25197 if (at3 == NULL_TREE)
25199 id = get_identifier ("omp declare target nohost");
25200 DECL_ATTRIBUTES (t)
25201 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25204 if (indirect)
25206 tree at4 = lookup_attribute ("omp declare target indirect",
25207 DECL_ATTRIBUTES (t));
25208 if (at4 == NULL_TREE)
25210 id = get_identifier ("omp declare target indirect");
25211 DECL_ATTRIBUTES (t)
25212 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25216 if ((device_type || indirect) && only_device_type_or_indirect)
25217 error_at (OMP_CLAUSE_LOCATION (clauses),
25218 "directive with only %<device_type%> or %<indirect%> clauses");
25219 if (indirect && device_type && device_type != OMP_CLAUSE_DEVICE_TYPE_ANY)
25220 error_at (OMP_CLAUSE_LOCATION (clauses),
25221 "%<device_type%> clause must specify 'any' when used with "
25222 "an %<indirect%> clause");
25225 /* OpenMP 5.1
25226 #pragma omp begin assumes clauses[optseq] new-line
25228 #pragma omp begin declare target clauses[optseq] new-line */
25230 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
25231 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25232 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25234 static void
25235 c_parser_omp_begin (c_parser *parser)
25237 const char *p = "";
25238 c_parser_consume_pragma (parser);
25239 if (c_parser_next_token_is (parser, CPP_NAME))
25240 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25241 if (strcmp (p, "declare") == 0)
25243 c_parser_consume_token (parser);
25244 p = "";
25245 if (c_parser_next_token_is (parser, CPP_NAME))
25246 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25247 if (strcmp (p, "target") == 0)
25249 c_parser_consume_token (parser);
25250 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25251 tree clauses
25252 = c_parser_omp_all_clauses (parser,
25253 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
25254 "#pragma omp begin declare target");
25255 int device_type = 0;
25256 int indirect = 0;
25257 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25259 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
25260 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
25261 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25262 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
25264 c_omp_declare_target_attr attr = { attr_syntax, device_type,
25265 indirect };
25266 vec_safe_push (current_omp_declare_target_attribute, attr);
25268 else
25270 c_parser_error (parser, "expected %<target%>");
25271 c_parser_skip_to_pragma_eol (parser);
25274 else if (strcmp (p, "assumes") == 0)
25276 c_parser_consume_token (parser);
25277 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25278 c_parser_omp_assumption_clauses (parser, false);
25279 struct c_omp_begin_assumes_data a = { attr_syntax };
25280 vec_safe_push (current_omp_begin_assumes, a);
25282 else
25284 c_parser_error (parser, "expected %<declare target%> or %<assumes%>");
25285 c_parser_skip_to_pragma_eol (parser);
25289 /* OpenMP 4.0
25290 #pragma omp end declare target
25292 OpenMP 5.1
25293 #pragma omp end assumes */
25295 static void
25296 c_parser_omp_end (c_parser *parser)
25298 location_t loc = c_parser_peek_token (parser)->location;
25299 const char *p = "";
25300 c_parser_consume_pragma (parser);
25301 if (c_parser_next_token_is (parser, CPP_NAME))
25302 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25303 if (strcmp (p, "declare") == 0)
25305 c_parser_consume_token (parser);
25306 if (c_parser_next_token_is (parser, CPP_NAME)
25307 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
25308 "target") == 0)
25309 c_parser_consume_token (parser);
25310 else
25312 c_parser_error (parser, "expected %<target%>");
25313 c_parser_skip_to_pragma_eol (parser);
25314 return;
25316 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25317 c_parser_skip_to_pragma_eol (parser);
25318 if (!vec_safe_length (current_omp_declare_target_attribute))
25319 error_at (loc, "%<#pragma omp end declare target%> without "
25320 "corresponding %<#pragma omp declare target%> or "
25321 "%<#pragma omp begin declare target%>");
25322 else
25324 c_omp_declare_target_attr
25325 a = current_omp_declare_target_attribute->pop ();
25326 if (a.attr_syntax != attr_syntax)
25328 if (a.attr_syntax)
25329 error_at (loc,
25330 "%qs in attribute syntax terminated "
25331 "with %qs in pragma syntax",
25332 a.device_type >= 0 ? "begin declare target"
25333 : "declare target",
25334 "end declare target");
25335 else
25336 error_at (loc,
25337 "%qs in pragma syntax terminated "
25338 "with %qs in attribute syntax",
25339 a.device_type >= 0 ? "begin declare target"
25340 : "declare target",
25341 "end declare target");
25345 else if (strcmp (p, "assumes") == 0)
25347 c_parser_consume_token (parser);
25348 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25349 c_parser_skip_to_pragma_eol (parser);
25350 if (!vec_safe_length (current_omp_begin_assumes))
25351 error_at (loc, "%qs without corresponding %qs",
25352 "#pragma omp end assumes", "#pragma omp begin assumes");
25353 else
25355 c_omp_begin_assumes_data
25356 a = current_omp_begin_assumes->pop ();
25357 if (a.attr_syntax != attr_syntax)
25359 if (a.attr_syntax)
25360 error_at (loc,
25361 "%qs in attribute syntax terminated "
25362 "with %qs in pragma syntax",
25363 "begin assumes", "end assumes");
25364 else
25365 error_at (loc,
25366 "%qs in pragma syntax terminated "
25367 "with %qs in attribute syntax",
25368 "begin assumes", "end assumes");
25372 else
25374 c_parser_error (parser, "expected %<declare%> or %<assumes%>");
25375 c_parser_skip_to_pragma_eol (parser);
25379 /* OpenMP 4.0
25380 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25381 initializer-clause[opt] new-line
25383 initializer-clause:
25384 initializer (omp_priv = initializer)
25385 initializer (function-name (argument-list)) */
25387 static void
25388 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
25390 unsigned int tokens_avail = 0, i;
25391 c_token *saved_tokens = NULL;
25392 vec<tree> types = vNULL;
25393 vec<c_token> clauses = vNULL;
25394 enum tree_code reduc_code = ERROR_MARK;
25395 tree reduc_id = NULL_TREE;
25396 tree type;
25397 location_t rloc = c_parser_peek_token (parser)->location;
25399 if (context == pragma_struct || context == pragma_param)
25401 error ("%<#pragma omp declare reduction%> not at file or block scope");
25402 goto fail;
25405 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
25406 goto fail;
25408 switch (c_parser_peek_token (parser)->type)
25410 case CPP_PLUS:
25411 reduc_code = PLUS_EXPR;
25412 break;
25413 case CPP_MULT:
25414 reduc_code = MULT_EXPR;
25415 break;
25416 case CPP_MINUS:
25417 reduc_code = MINUS_EXPR;
25418 break;
25419 case CPP_AND:
25420 reduc_code = BIT_AND_EXPR;
25421 break;
25422 case CPP_XOR:
25423 reduc_code = BIT_XOR_EXPR;
25424 break;
25425 case CPP_OR:
25426 reduc_code = BIT_IOR_EXPR;
25427 break;
25428 case CPP_AND_AND:
25429 reduc_code = TRUTH_ANDIF_EXPR;
25430 break;
25431 case CPP_OR_OR:
25432 reduc_code = TRUTH_ORIF_EXPR;
25433 break;
25434 case CPP_NAME:
25435 const char *p;
25436 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25437 if (strcmp (p, "min") == 0)
25439 reduc_code = MIN_EXPR;
25440 break;
25442 if (strcmp (p, "max") == 0)
25444 reduc_code = MAX_EXPR;
25445 break;
25447 reduc_id = c_parser_peek_token (parser)->value;
25448 break;
25449 default:
25450 c_parser_error (parser,
25451 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
25452 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
25453 goto fail;
25456 tree orig_reduc_id, reduc_decl;
25457 orig_reduc_id = reduc_id;
25458 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
25459 reduc_decl = c_omp_reduction_decl (reduc_id);
25460 c_parser_consume_token (parser);
25462 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
25463 goto fail;
25465 while (true)
25467 location_t loc = c_parser_peek_token (parser)->location;
25468 struct c_type_name *ctype = c_parser_type_name (parser);
25469 if (ctype != NULL)
25471 type = groktypename (ctype, NULL, NULL);
25472 if (type == error_mark_node)
25474 else if ((INTEGRAL_TYPE_P (type)
25475 || SCALAR_FLOAT_TYPE_P (type)
25476 || TREE_CODE (type) == COMPLEX_TYPE)
25477 && orig_reduc_id == NULL_TREE)
25478 error_at (loc, "predeclared arithmetic type in "
25479 "%<#pragma omp declare reduction%>");
25480 else if (TREE_CODE (type) == FUNCTION_TYPE
25481 || TREE_CODE (type) == ARRAY_TYPE)
25482 error_at (loc, "function or array type in "
25483 "%<#pragma omp declare reduction%>");
25484 else if (TYPE_ATOMIC (type))
25485 error_at (loc, "%<_Atomic%> qualified type in "
25486 "%<#pragma omp declare reduction%>");
25487 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
25488 error_at (loc, "const, volatile or restrict qualified type in "
25489 "%<#pragma omp declare reduction%>");
25490 else
25492 tree t;
25493 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
25494 if (comptypes (TREE_PURPOSE (t), type))
25496 error_at (loc, "redeclaration of %qs "
25497 "%<#pragma omp declare reduction%> for "
25498 "type %qT",
25499 IDENTIFIER_POINTER (reduc_id)
25500 + sizeof ("omp declare reduction ") - 1,
25501 type);
25502 location_t ploc
25503 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
25504 0));
25505 error_at (ploc, "previous %<#pragma omp declare "
25506 "reduction%>");
25507 break;
25509 if (t == NULL_TREE)
25510 types.safe_push (type);
25512 if (c_parser_next_token_is (parser, CPP_COMMA))
25513 c_parser_consume_token (parser);
25514 else
25515 break;
25517 else
25518 break;
25521 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
25522 || types.is_empty ())
25524 fail:
25525 clauses.release ();
25526 types.release ();
25527 while (true)
25529 c_token *token = c_parser_peek_token (parser);
25530 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
25531 break;
25532 c_parser_consume_token (parser);
25534 c_parser_skip_to_pragma_eol (parser);
25535 return;
25538 if (types.length () > 1)
25540 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
25542 c_token *token = c_parser_peek_token (parser);
25543 if (token->type == CPP_EOF)
25544 goto fail;
25545 clauses.safe_push (*token);
25546 c_parser_consume_token (parser);
25548 clauses.safe_push (*c_parser_peek_token (parser));
25549 c_parser_skip_to_pragma_eol (parser);
25551 /* Make sure nothing tries to read past the end of the tokens. */
25552 c_token eof_token;
25553 memset (&eof_token, 0, sizeof (eof_token));
25554 eof_token.type = CPP_EOF;
25555 clauses.safe_push (eof_token);
25556 clauses.safe_push (eof_token);
25559 int errs = errorcount;
25560 FOR_EACH_VEC_ELT (types, i, type)
25562 saved_tokens = parser->tokens;
25563 tokens_avail = parser->tokens_avail;
25564 if (!clauses.is_empty ())
25566 parser->tokens = clauses.address ();
25567 parser->tokens_avail = clauses.length ();
25568 parser->in_pragma = true;
25571 bool nested = current_function_decl != NULL_TREE;
25572 if (nested)
25573 c_push_function_context ();
25574 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
25575 reduc_id, default_function_type);
25576 current_function_decl = fndecl;
25577 allocate_struct_function (fndecl, true);
25578 push_scope ();
25579 tree stmt = push_stmt_list ();
25580 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
25581 warn about these. */
25582 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
25583 get_identifier ("omp_out"), type);
25584 DECL_ARTIFICIAL (omp_out) = 1;
25585 DECL_CONTEXT (omp_out) = fndecl;
25586 pushdecl (omp_out);
25587 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
25588 get_identifier ("omp_in"), type);
25589 DECL_ARTIFICIAL (omp_in) = 1;
25590 DECL_CONTEXT (omp_in) = fndecl;
25591 pushdecl (omp_in);
25592 struct c_expr combiner = c_parser_expression (parser);
25593 struct c_expr initializer;
25594 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
25595 bool bad = false;
25596 initializer.set_error ();
25597 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
25598 bad = true;
25599 else if (c_parser_next_token_is (parser, CPP_COMMA)
25600 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
25601 c_parser_consume_token (parser);
25602 if (!bad
25603 && (c_parser_next_token_is (parser, CPP_NAME)
25604 && strcmp (IDENTIFIER_POINTER
25605 (c_parser_peek_token (parser)->value),
25606 "initializer") == 0))
25608 c_parser_consume_token (parser);
25609 pop_scope ();
25610 push_scope ();
25611 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
25612 get_identifier ("omp_priv"), type);
25613 DECL_ARTIFICIAL (omp_priv) = 1;
25614 DECL_INITIAL (omp_priv) = error_mark_node;
25615 DECL_CONTEXT (omp_priv) = fndecl;
25616 pushdecl (omp_priv);
25617 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
25618 get_identifier ("omp_orig"), type);
25619 DECL_ARTIFICIAL (omp_orig) = 1;
25620 DECL_CONTEXT (omp_orig) = fndecl;
25621 pushdecl (omp_orig);
25622 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
25623 bad = true;
25624 else if (!c_parser_next_token_is (parser, CPP_NAME))
25626 c_parser_error (parser, "expected %<omp_priv%> or "
25627 "function-name");
25628 bad = true;
25630 else if (strcmp (IDENTIFIER_POINTER
25631 (c_parser_peek_token (parser)->value),
25632 "omp_priv") != 0)
25634 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
25635 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
25637 c_parser_error (parser, "expected function-name %<(%>");
25638 bad = true;
25640 else
25641 initializer = c_parser_postfix_expression (parser);
25642 if (initializer.value
25643 && TREE_CODE (initializer.value) == CALL_EXPR)
25645 int j;
25646 tree c = initializer.value;
25647 for (j = 0; j < call_expr_nargs (c); j++)
25649 tree a = CALL_EXPR_ARG (c, j);
25650 STRIP_NOPS (a);
25651 if (TREE_CODE (a) == ADDR_EXPR
25652 && TREE_OPERAND (a, 0) == omp_priv)
25653 break;
25655 if (j == call_expr_nargs (c))
25656 error ("one of the initializer call arguments should be "
25657 "%<&omp_priv%>");
25660 else
25662 c_parser_consume_token (parser);
25663 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
25664 bad = true;
25665 else
25667 tree st = push_stmt_list ();
25668 location_t loc = c_parser_peek_token (parser)->location;
25669 rich_location richloc (line_table, loc);
25670 start_init (omp_priv, NULL_TREE, false, false, &richloc);
25671 struct c_expr init = c_parser_initializer (parser, omp_priv);
25672 finish_init ();
25673 finish_decl (omp_priv, loc, init.value,
25674 init.original_type, NULL_TREE);
25675 pop_stmt_list (st);
25678 if (!bad
25679 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
25680 bad = true;
25683 if (!bad)
25685 c_parser_skip_to_pragma_eol (parser);
25687 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
25688 DECL_INITIAL (reduc_decl));
25689 DECL_INITIAL (reduc_decl) = t;
25690 DECL_SOURCE_LOCATION (omp_out) = rloc;
25691 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
25692 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
25693 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
25694 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
25695 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
25696 if (omp_priv)
25698 DECL_SOURCE_LOCATION (omp_priv) = rloc;
25699 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
25700 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
25701 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
25702 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
25703 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
25704 walk_tree (&DECL_INITIAL (omp_priv),
25705 c_check_omp_declare_reduction_r,
25706 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
25710 pop_stmt_list (stmt);
25711 pop_scope ();
25712 if (cfun->language != NULL)
25714 ggc_free (cfun->language);
25715 cfun->language = NULL;
25717 set_cfun (NULL);
25718 current_function_decl = NULL_TREE;
25719 if (nested)
25720 c_pop_function_context ();
25722 if (!clauses.is_empty ())
25724 parser->tokens = saved_tokens;
25725 parser->tokens_avail = tokens_avail;
25727 if (bad)
25728 goto fail;
25729 if (errs != errorcount)
25730 break;
25733 clauses.release ();
25734 types.release ();
25738 /* OpenMP 4.0
25739 #pragma omp declare simd declare-simd-clauses[optseq] new-line
25740 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25741 initializer-clause[opt] new-line
25742 #pragma omp declare target new-line
25744 OpenMP 5.0
25745 #pragma omp declare variant (identifier) match (context-selector) */
25747 static bool
25748 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
25750 c_parser_consume_pragma (parser);
25751 if (c_parser_next_token_is (parser, CPP_NAME))
25753 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25754 if (strcmp (p, "simd") == 0)
25756 /* c_parser_consume_token (parser); done in
25757 c_parser_omp_declare_simd. */
25758 c_parser_omp_declare_simd (parser, context);
25759 return true;
25761 if (strcmp (p, "reduction") == 0)
25763 c_parser_consume_token (parser);
25764 c_parser_omp_declare_reduction (parser, context);
25765 return false;
25767 if (!flag_openmp) /* flag_openmp_simd */
25769 c_parser_skip_to_pragma_eol (parser, false);
25770 return false;
25772 if (strcmp (p, "target") == 0)
25774 c_parser_consume_token (parser);
25775 c_parser_omp_declare_target (parser);
25776 return false;
25778 if (strcmp (p, "variant") == 0)
25780 /* c_parser_consume_token (parser); done in
25781 c_parser_omp_declare_simd. */
25782 c_parser_omp_declare_simd (parser, context);
25783 return true;
25787 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
25788 "%<target%> or %<variant%>");
25789 c_parser_skip_to_pragma_eol (parser);
25790 return false;
25793 /* OpenMP 5.0
25794 #pragma omp requires clauses[optseq] new-line */
25796 static void
25797 c_parser_omp_requires (c_parser *parser)
25799 enum omp_requires new_req = (enum omp_requires) 0;
25801 c_parser_consume_pragma (parser);
25803 location_t loc = c_parser_peek_token (parser)->location;
25804 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
25806 if (c_parser_next_token_is (parser, CPP_COMMA)
25807 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
25808 c_parser_consume_token (parser);
25810 if (c_parser_next_token_is (parser, CPP_NAME))
25812 const char *p
25813 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25814 location_t cloc = c_parser_peek_token (parser)->location;
25815 enum omp_requires this_req = (enum omp_requires) 0;
25817 if (!strcmp (p, "unified_address"))
25818 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
25819 else if (!strcmp (p, "unified_shared_memory"))
25820 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
25821 else if (!strcmp (p, "dynamic_allocators"))
25822 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
25823 else if (!strcmp (p, "reverse_offload"))
25824 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
25825 else if (!strcmp (p, "atomic_default_mem_order"))
25827 c_parser_consume_token (parser);
25829 matching_parens parens;
25830 if (parens.require_open (parser))
25832 if (c_parser_next_token_is (parser, CPP_NAME))
25834 tree v = c_parser_peek_token (parser)->value;
25835 p = IDENTIFIER_POINTER (v);
25837 if (!strcmp (p, "seq_cst"))
25838 this_req
25839 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
25840 else if (!strcmp (p, "relaxed"))
25841 this_req
25842 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
25843 else if (!strcmp (p, "release"))
25844 this_req
25845 = (enum omp_requires) OMP_MEMORY_ORDER_RELEASE;
25846 else if (!strcmp (p, "acq_rel"))
25847 this_req
25848 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
25849 else if (!strcmp (p, "acquire"))
25850 this_req
25851 = (enum omp_requires) OMP_MEMORY_ORDER_ACQUIRE;
25853 if (this_req == 0)
25855 error_at (c_parser_peek_token (parser)->location,
25856 "expected %<acq_rel%>, %<acquire%>, "
25857 "%<relaxed%>, %<release%> or %<seq_cst%>");
25858 switch (c_parser_peek_token (parser)->type)
25860 case CPP_EOF:
25861 case CPP_PRAGMA_EOL:
25862 case CPP_CLOSE_PAREN:
25863 break;
25864 default:
25865 if (c_parser_peek_2nd_token (parser)->type
25866 == CPP_CLOSE_PAREN)
25867 c_parser_consume_token (parser);
25868 break;
25871 else
25872 c_parser_consume_token (parser);
25874 parens.skip_until_found_close (parser);
25875 if (this_req == 0)
25877 c_parser_skip_to_pragma_eol (parser, false);
25878 return;
25881 p = NULL;
25883 else
25885 error_at (cloc, "expected %<unified_address%>, "
25886 "%<unified_shared_memory%>, "
25887 "%<dynamic_allocators%>, "
25888 "%<reverse_offload%> "
25889 "or %<atomic_default_mem_order%> clause");
25890 c_parser_skip_to_pragma_eol (parser, false);
25891 return;
25893 if (p)
25894 c_parser_consume_token (parser);
25895 if (this_req)
25897 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
25899 if ((this_req & new_req) != 0)
25900 error_at (cloc, "too many %qs clauses", p);
25901 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
25902 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
25903 error_at (cloc, "%qs clause used lexically after first "
25904 "target construct or offloading API", p);
25906 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
25908 error_at (cloc, "too many %qs clauses",
25909 "atomic_default_mem_order");
25910 this_req = (enum omp_requires) 0;
25912 else if ((omp_requires_mask
25913 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
25915 error_at (cloc, "more than one %<atomic_default_mem_order%>"
25916 " clause in a single compilation unit");
25917 this_req
25918 = (enum omp_requires)
25919 (omp_requires_mask
25920 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
25922 else if ((omp_requires_mask
25923 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
25924 error_at (cloc, "%<atomic_default_mem_order%> clause used "
25925 "lexically after first %<atomic%> construct "
25926 "without memory order clause");
25927 new_req = (enum omp_requires) (new_req | this_req);
25928 omp_requires_mask
25929 = (enum omp_requires) (omp_requires_mask | this_req);
25930 continue;
25933 break;
25935 c_parser_skip_to_pragma_eol (parser);
25937 if (new_req == 0)
25938 error_at (loc, "%<pragma omp requires%> requires at least one clause");
25941 /* Helper function for c_parser_omp_taskloop.
25942 Disallow zero sized or potentially zero sized task reductions. */
25944 static tree
25945 c_finish_taskloop_clauses (tree clauses)
25947 tree *pc = &clauses;
25948 for (tree c = clauses; c; c = *pc)
25950 bool remove = false;
25951 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
25953 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
25954 if (integer_zerop (TYPE_SIZE_UNIT (type)))
25956 error_at (OMP_CLAUSE_LOCATION (c),
25957 "zero sized type %qT in %<reduction%> clause", type);
25958 remove = true;
25960 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
25962 error_at (OMP_CLAUSE_LOCATION (c),
25963 "variable sized type %qT in %<reduction%> clause",
25964 type);
25965 remove = true;
25968 if (remove)
25969 *pc = OMP_CLAUSE_CHAIN (c);
25970 else
25971 pc = &OMP_CLAUSE_CHAIN (c);
25973 return clauses;
25976 /* OpenMP 4.5:
25977 #pragma omp taskloop taskloop-clause[optseq] new-line
25978 for-loop
25980 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
25981 for-loop */
25983 #define OMP_TASKLOOP_CLAUSE_MASK \
25984 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
25985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
25986 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
25987 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
25988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
25989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
25990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
25991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
25992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
25993 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
25994 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
25995 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
25996 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
25997 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
25998 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
25999 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
26000 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
26002 static tree
26003 c_parser_omp_taskloop (location_t loc, c_parser *parser,
26004 char *p_name, omp_clause_mask mask, tree *cclauses,
26005 bool *if_p)
26007 tree clauses, block, ret;
26009 strcat (p_name, " taskloop");
26010 mask |= OMP_TASKLOOP_CLAUSE_MASK;
26011 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
26012 clause. */
26013 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
26014 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
26016 if (c_parser_next_token_is (parser, CPP_NAME))
26018 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26020 if (strcmp (p, "simd") == 0)
26022 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
26023 if (cclauses == NULL)
26024 cclauses = cclauses_buf;
26025 c_parser_consume_token (parser);
26026 if (!flag_openmp) /* flag_openmp_simd */
26027 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
26028 if_p);
26029 block = c_begin_compound_stmt (true);
26030 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
26031 block = c_end_compound_stmt (loc, block, true);
26032 if (ret == NULL)
26033 return ret;
26034 ret = make_node (OMP_TASKLOOP);
26035 TREE_TYPE (ret) = void_type_node;
26036 OMP_FOR_BODY (ret) = block;
26037 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
26038 OMP_FOR_CLAUSES (ret)
26039 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
26040 SET_EXPR_LOCATION (ret, loc);
26041 add_stmt (ret);
26042 return ret;
26045 if (!flag_openmp) /* flag_openmp_simd */
26047 c_parser_skip_to_pragma_eol (parser, false);
26048 return NULL_TREE;
26051 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
26052 if (cclauses)
26054 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
26055 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
26058 clauses = c_finish_taskloop_clauses (clauses);
26059 block = c_begin_compound_stmt (true);
26060 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
26061 block = c_end_compound_stmt (loc, block, true);
26062 add_stmt (block);
26064 return ret;
26067 /* OpenMP 5.1
26068 #pragma omp nothing new-line */
26070 static void
26071 c_parser_omp_nothing (c_parser *parser)
26073 c_parser_consume_pragma (parser);
26074 c_parser_skip_to_pragma_eol (parser);
26077 /* OpenMP 5.1
26078 #pragma omp error clauses[optseq] new-line */
26080 static bool
26081 c_parser_omp_error (c_parser *parser, enum pragma_context context)
26083 int at_compilation = -1;
26084 int severity_fatal = -1;
26085 tree message = NULL_TREE;
26086 bool bad = false;
26087 location_t loc = c_parser_peek_token (parser)->location;
26089 c_parser_consume_pragma (parser);
26091 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
26093 if (c_parser_next_token_is (parser, CPP_COMMA)
26094 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
26095 c_parser_consume_token (parser);
26097 if (!c_parser_next_token_is (parser, CPP_NAME))
26098 break;
26100 const char *p
26101 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26102 location_t cloc = c_parser_peek_token (parser)->location;
26103 static const char *args[] = {
26104 "execution", "compilation", "warning", "fatal"
26106 int *v = NULL;
26107 int idx = 0, n = -1;
26108 tree m = NULL_TREE;
26110 if (!strcmp (p, "at"))
26111 v = &at_compilation;
26112 else if (!strcmp (p, "severity"))
26114 v = &severity_fatal;
26115 idx += 2;
26117 else if (strcmp (p, "message"))
26119 error_at (cloc,
26120 "expected %<at%>, %<severity%> or %<message%> clause");
26121 c_parser_skip_to_pragma_eol (parser, false);
26122 return false;
26125 c_parser_consume_token (parser);
26127 matching_parens parens;
26128 if (parens.require_open (parser))
26130 if (v == NULL)
26132 location_t expr_loc = c_parser_peek_token (parser)->location;
26133 c_expr expr = c_parser_expr_no_commas (parser, NULL);
26134 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
26135 m = convert (const_string_type_node, expr.value);
26136 m = c_fully_fold (m, false, NULL);
26138 else
26140 if (c_parser_next_token_is (parser, CPP_NAME))
26142 tree val = c_parser_peek_token (parser)->value;
26143 const char *q = IDENTIFIER_POINTER (val);
26145 if (!strcmp (q, args[idx]))
26146 n = 0;
26147 else if (!strcmp (q, args[idx + 1]))
26148 n = 1;
26150 if (n == -1)
26152 error_at (c_parser_peek_token (parser)->location,
26153 "expected %qs or %qs", args[idx], args[idx + 1]);
26154 bad = true;
26155 switch (c_parser_peek_token (parser)->type)
26157 case CPP_EOF:
26158 case CPP_PRAGMA_EOL:
26159 case CPP_CLOSE_PAREN:
26160 break;
26161 default:
26162 if (c_parser_peek_2nd_token (parser)->type
26163 == CPP_CLOSE_PAREN)
26164 c_parser_consume_token (parser);
26165 break;
26168 else
26169 c_parser_consume_token (parser);
26172 parens.skip_until_found_close (parser);
26174 if (v == NULL)
26176 if (message)
26178 error_at (cloc, "too many %qs clauses", p);
26179 bad = true;
26181 else
26182 message = m;
26184 else if (n != -1)
26186 if (*v != -1)
26188 error_at (cloc, "too many %qs clauses", p);
26189 bad = true;
26191 else
26192 *v = n;
26195 else
26196 bad = true;
26198 c_parser_skip_to_pragma_eol (parser);
26199 if (bad)
26200 return true;
26202 if (at_compilation == -1)
26203 at_compilation = 1;
26204 if (severity_fatal == -1)
26205 severity_fatal = 1;
26206 if (!at_compilation)
26208 if (context != pragma_compound)
26210 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
26211 "may only be used in compound statements");
26212 return true;
26214 tree fndecl
26215 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
26216 : BUILT_IN_GOMP_WARNING);
26217 if (!message)
26218 message = build_zero_cst (const_string_type_node);
26219 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
26220 build_all_ones_cst (size_type_node));
26221 add_stmt (stmt);
26222 return true;
26224 const char *msg = NULL;
26225 if (message)
26227 msg = c_getstr (message);
26228 if (msg == NULL)
26229 msg = _("<message unknown at compile time>");
26231 if (msg)
26232 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
26233 "%<pragma omp error%> encountered: %s", msg);
26234 else
26235 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
26236 "%<pragma omp error%> encountered");
26237 return false;
26240 /* Assumption clauses:
26241 OpenMP 5.1
26242 absent (directive-name-list)
26243 contains (directive-name-list)
26244 holds (expression)
26245 no_openmp
26246 no_openmp_routines
26247 no_parallelism */
26249 static void
26250 c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
26252 bool no_openmp = false;
26253 bool no_openmp_routines = false;
26254 bool no_parallelism = false;
26255 bitmap_head absent_head, contains_head;
26257 bitmap_obstack_initialize (NULL);
26258 bitmap_initialize (&absent_head, &bitmap_default_obstack);
26259 bitmap_initialize (&contains_head, &bitmap_default_obstack);
26261 if (c_parser_next_token_is (parser, CPP_PRAGMA_EOL))
26262 error_at (c_parser_peek_token (parser)->location,
26263 "expected at least one assumption clause");
26265 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
26267 if (c_parser_next_token_is (parser, CPP_COMMA)
26268 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
26269 c_parser_consume_token (parser);
26271 if (!c_parser_next_token_is (parser, CPP_NAME))
26272 break;
26274 const char *p
26275 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26276 location_t cloc = c_parser_peek_token (parser)->location;
26278 if (!strcmp (p, "no_openmp"))
26280 c_parser_consume_token (parser);
26281 if (no_openmp)
26282 error_at (cloc, "too many %qs clauses", "no_openmp");
26283 no_openmp = true;
26285 else if (!strcmp (p, "no_openmp_routines"))
26287 c_parser_consume_token (parser);
26288 if (no_openmp_routines)
26289 error_at (cloc, "too many %qs clauses", "no_openmp_routines");
26290 no_openmp_routines = true;
26292 else if (!strcmp (p, "no_parallelism"))
26294 c_parser_consume_token (parser);
26295 if (no_parallelism)
26296 error_at (cloc, "too many %qs clauses", "no_parallelism");
26297 no_parallelism = true;
26299 else if (!strcmp (p, "holds"))
26301 c_parser_consume_token (parser);
26302 matching_parens parens;
26303 if (parens.require_open (parser))
26305 location_t eloc = c_parser_peek_token (parser)->location;
26306 c_expr expr = c_parser_expr_no_commas (parser, NULL);
26307 tree t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
26308 t = c_objc_common_truthvalue_conversion (eloc, t);
26309 t = c_fully_fold (t, false, NULL);
26310 if (is_assume && t != error_mark_node)
26312 tree fn = build_call_expr_internal_loc (eloc, IFN_ASSUME,
26313 void_type_node, 1,
26315 add_stmt (fn);
26317 parens.skip_until_found_close (parser);
26320 else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
26322 c_parser_consume_token (parser);
26323 matching_parens parens;
26324 if (parens.require_open (parser))
26328 const char *directive[3] = {};
26329 int i;
26330 location_t dloc = c_parser_peek_token (parser)->location;
26331 for (i = 0; i < 3; i++)
26333 tree id;
26334 if (c_parser_peek_nth_token (parser, i + 1)->type
26335 == CPP_NAME)
26336 id = c_parser_peek_nth_token (parser, i + 1)->value;
26337 else if (c_parser_peek_nth_token (parser, i + 1)->keyword
26338 != RID_MAX)
26340 enum rid rid
26341 = c_parser_peek_nth_token (parser, i + 1)->keyword;
26342 id = ridpointers[rid];
26344 else
26345 break;
26346 directive[i] = IDENTIFIER_POINTER (id);
26348 if (i == 0)
26349 error_at (dloc, "expected directive name");
26350 else
26352 const struct c_omp_directive *dir
26353 = c_omp_categorize_directive (directive[0],
26354 directive[1],
26355 directive[2]);
26356 if (dir == NULL
26357 || dir->kind == C_OMP_DIR_DECLARATIVE
26358 || dir->kind == C_OMP_DIR_INFORMATIONAL
26359 || dir->id == PRAGMA_OMP_END
26360 || (!dir->second && directive[1])
26361 || (!dir->third && directive[2]))
26362 error_at (dloc, "unknown OpenMP directive name in "
26363 "%qs clause argument", p);
26364 else
26366 int id = dir - c_omp_directives;
26367 if (bitmap_bit_p (p[0] == 'a' ? &contains_head
26368 : &absent_head, id))
26369 error_at (dloc, "%<%s%s%s%s%s%> directive "
26370 "mentioned in both %<absent%> and "
26371 "%<contains%> clauses",
26372 directive[0],
26373 directive[1] ? " " : "",
26374 directive[1] ? directive[1] : "",
26375 directive[2] ? " " : "",
26376 directive[2] ? directive[2] : "");
26377 else if (!bitmap_set_bit (p[0] == 'a'
26378 ? &absent_head
26379 : &contains_head, id))
26380 error_at (dloc, "%<%s%s%s%s%s%> directive "
26381 "mentioned multiple times in %qs "
26382 "clauses",
26383 directive[0],
26384 directive[1] ? " " : "",
26385 directive[1] ? directive[1] : "",
26386 directive[2] ? " " : "",
26387 directive[2] ? directive[2] : "", p);
26389 for (; i; --i)
26390 c_parser_consume_token (parser);
26392 if (c_parser_next_token_is (parser, CPP_COMMA))
26393 c_parser_consume_token (parser);
26394 else
26395 break;
26397 while (1);
26398 parens.skip_until_found_close (parser);
26401 else if (startswith (p, "ext_"))
26403 warning_at (cloc, OPT_Wopenmp, "unknown assumption clause %qs", p);
26404 c_parser_consume_token (parser);
26405 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
26407 matching_parens parens;
26408 parens.consume_open (parser);
26409 c_parser_balanced_token_sequence (parser);
26410 parens.require_close (parser);
26413 else
26415 c_parser_consume_token (parser);
26416 error_at (cloc, "expected assumption clause");
26417 break;
26420 c_parser_skip_to_pragma_eol (parser);
26423 /* OpenMP 5.1
26424 #pragma omp assume clauses[optseq] new-line */
26426 static void
26427 c_parser_omp_assume (c_parser *parser, bool *if_p)
26429 c_parser_omp_assumption_clauses (parser, true);
26430 add_stmt (c_parser_omp_structured_block (parser, if_p));
26433 /* OpenMP 5.1
26434 #pragma omp assumes clauses[optseq] new-line */
26436 static void
26437 c_parser_omp_assumes (c_parser *parser)
26439 c_parser_consume_pragma (parser);
26440 c_parser_omp_assumption_clauses (parser, false);
26443 /* Main entry point to parsing most OpenMP pragmas. */
26445 static void
26446 c_parser_omp_construct (c_parser *parser, bool *if_p)
26448 enum pragma_kind p_kind;
26449 location_t loc;
26450 tree stmt;
26451 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
26452 omp_clause_mask mask (0);
26454 loc = c_parser_peek_token (parser)->location;
26455 p_kind = c_parser_peek_token (parser)->pragma_kind;
26456 c_parser_consume_pragma (parser);
26458 switch (p_kind)
26460 case PRAGMA_OACC_ATOMIC:
26461 c_parser_omp_atomic (loc, parser, true);
26462 return;
26463 case PRAGMA_OACC_CACHE:
26464 strcpy (p_name, "#pragma acc");
26465 stmt = c_parser_oacc_cache (loc, parser);
26466 break;
26467 case PRAGMA_OACC_DATA:
26468 stmt = c_parser_oacc_data (loc, parser, if_p);
26469 break;
26470 case PRAGMA_OACC_HOST_DATA:
26471 stmt = c_parser_oacc_host_data (loc, parser, if_p);
26472 break;
26473 case PRAGMA_OACC_KERNELS:
26474 case PRAGMA_OACC_PARALLEL:
26475 case PRAGMA_OACC_SERIAL:
26476 strcpy (p_name, "#pragma acc");
26477 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
26478 break;
26479 case PRAGMA_OACC_LOOP:
26480 strcpy (p_name, "#pragma acc");
26481 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
26482 break;
26483 case PRAGMA_OACC_WAIT:
26484 strcpy (p_name, "#pragma wait");
26485 stmt = c_parser_oacc_wait (loc, parser, p_name);
26486 break;
26487 case PRAGMA_OMP_ATOMIC:
26488 c_parser_omp_atomic (loc, parser, false);
26489 return;
26490 case PRAGMA_OMP_CRITICAL:
26491 stmt = c_parser_omp_critical (loc, parser, if_p);
26492 break;
26493 case PRAGMA_OMP_DISTRIBUTE:
26494 strcpy (p_name, "#pragma omp");
26495 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
26496 break;
26497 case PRAGMA_OMP_FOR:
26498 strcpy (p_name, "#pragma omp");
26499 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
26500 break;
26501 case PRAGMA_OMP_LOOP:
26502 strcpy (p_name, "#pragma omp");
26503 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
26504 break;
26505 case PRAGMA_OMP_MASKED:
26506 strcpy (p_name, "#pragma omp");
26507 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
26508 break;
26509 case PRAGMA_OMP_MASTER:
26510 strcpy (p_name, "#pragma omp");
26511 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
26512 break;
26513 case PRAGMA_OMP_PARALLEL:
26514 strcpy (p_name, "#pragma omp");
26515 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
26516 break;
26517 case PRAGMA_OMP_SCOPE:
26518 stmt = c_parser_omp_scope (loc, parser, if_p);
26519 break;
26520 case PRAGMA_OMP_SECTIONS:
26521 strcpy (p_name, "#pragma omp");
26522 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
26523 break;
26524 case PRAGMA_OMP_SIMD:
26525 strcpy (p_name, "#pragma omp");
26526 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
26527 break;
26528 case PRAGMA_OMP_SINGLE:
26529 stmt = c_parser_omp_single (loc, parser, if_p);
26530 break;
26531 case PRAGMA_OMP_TASK:
26532 stmt = c_parser_omp_task (loc, parser, if_p);
26533 break;
26534 case PRAGMA_OMP_TASKGROUP:
26535 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
26536 break;
26537 case PRAGMA_OMP_TASKLOOP:
26538 strcpy (p_name, "#pragma omp");
26539 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
26540 break;
26541 case PRAGMA_OMP_TEAMS:
26542 strcpy (p_name, "#pragma omp");
26543 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
26544 break;
26545 case PRAGMA_OMP_ASSUME:
26546 c_parser_omp_assume (parser, if_p);
26547 return;
26548 default:
26549 gcc_unreachable ();
26552 if (stmt && stmt != error_mark_node)
26553 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
26557 /* OpenMP 2.5:
26558 # pragma omp threadprivate (variable-list) */
26560 static void
26561 c_parser_omp_threadprivate (c_parser *parser)
26563 tree vars, t;
26564 location_t loc;
26566 c_parser_consume_pragma (parser);
26567 loc = c_parser_peek_token (parser)->location;
26568 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
26570 /* Mark every variable in VARS to be assigned thread local storage. */
26571 for (t = vars; t; t = TREE_CHAIN (t))
26573 tree v = TREE_PURPOSE (t);
26575 /* FIXME diagnostics: Ideally we should keep individual
26576 locations for all the variables in the var list to make the
26577 following errors more precise. Perhaps
26578 c_parser_omp_var_list_parens() should construct a list of
26579 locations to go along with the var list. */
26581 /* If V had already been marked threadprivate, it doesn't matter
26582 whether it had been used prior to this point. */
26583 if (!VAR_P (v))
26584 error_at (loc, "%qD is not a variable", v);
26585 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
26586 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
26587 else if (! is_global_var (v))
26588 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
26589 else if (TREE_TYPE (v) == error_mark_node)
26591 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
26592 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
26593 else
26595 if (! DECL_THREAD_LOCAL_P (v))
26597 set_decl_tls_model (v, decl_default_tls_model (v));
26598 /* If rtl has been already set for this var, call
26599 make_decl_rtl once again, so that encode_section_info
26600 has a chance to look at the new decl flags. */
26601 if (DECL_RTL_SET_P (v))
26602 make_decl_rtl (v);
26604 C_DECL_THREADPRIVATE_P (v) = 1;
26608 c_parser_skip_to_pragma_eol (parser);
26611 /* Parse a transaction attribute (GCC Extension).
26613 transaction-attribute:
26614 gnu-attributes
26615 attribute-specifier
26618 static tree
26619 c_parser_transaction_attributes (c_parser *parser)
26621 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
26622 return c_parser_gnu_attributes (parser);
26624 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
26625 return NULL_TREE;
26626 return c_parser_std_attribute_specifier (parser, true);
26629 /* Parse a __transaction_atomic or __transaction_relaxed statement
26630 (GCC Extension).
26632 transaction-statement:
26633 __transaction_atomic transaction-attribute[opt] compound-statement
26634 __transaction_relaxed compound-statement
26636 Note that the only valid attribute is: "outer".
26639 static tree
26640 c_parser_transaction (c_parser *parser, enum rid keyword)
26642 unsigned int old_in = parser->in_transaction;
26643 unsigned int this_in = 1, new_in;
26644 location_t loc = c_parser_peek_token (parser)->location;
26645 tree stmt, attrs;
26647 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
26648 || keyword == RID_TRANSACTION_RELAXED)
26649 && c_parser_next_token_is_keyword (parser, keyword));
26650 c_parser_consume_token (parser);
26652 if (keyword == RID_TRANSACTION_RELAXED)
26653 this_in |= TM_STMT_ATTR_RELAXED;
26654 else
26656 attrs = c_parser_transaction_attributes (parser);
26657 if (attrs)
26658 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
26661 /* Keep track if we're in the lexical scope of an outer transaction. */
26662 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
26664 parser->in_transaction = new_in;
26665 stmt = c_parser_compound_statement (parser);
26666 parser->in_transaction = old_in;
26668 if (flag_tm)
26669 stmt = c_finish_transaction (loc, stmt, this_in);
26670 else
26671 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
26672 "%<__transaction_atomic%> without transactional memory support enabled"
26673 : "%<__transaction_relaxed %> "
26674 "without transactional memory support enabled"));
26676 return stmt;
26679 /* Parse a __transaction_atomic or __transaction_relaxed expression
26680 (GCC Extension).
26682 transaction-expression:
26683 __transaction_atomic ( expression )
26684 __transaction_relaxed ( expression )
26687 static struct c_expr
26688 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
26690 struct c_expr ret;
26691 unsigned int old_in = parser->in_transaction;
26692 unsigned int this_in = 1;
26693 location_t loc = c_parser_peek_token (parser)->location;
26694 tree attrs;
26696 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
26697 || keyword == RID_TRANSACTION_RELAXED)
26698 && c_parser_next_token_is_keyword (parser, keyword));
26699 c_parser_consume_token (parser);
26701 if (keyword == RID_TRANSACTION_RELAXED)
26702 this_in |= TM_STMT_ATTR_RELAXED;
26703 else
26705 attrs = c_parser_transaction_attributes (parser);
26706 if (attrs)
26707 this_in |= parse_tm_stmt_attr (attrs, 0);
26710 parser->in_transaction = this_in;
26711 matching_parens parens;
26712 if (parens.require_open (parser))
26714 tree expr = c_parser_expression (parser).value;
26715 ret.original_type = TREE_TYPE (expr);
26716 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
26717 if (this_in & TM_STMT_ATTR_RELAXED)
26718 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
26719 SET_EXPR_LOCATION (ret.value, loc);
26720 ret.original_code = TRANSACTION_EXPR;
26721 ret.m_decimal = 0;
26722 if (!parens.require_close (parser))
26724 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
26725 goto error;
26728 else
26730 error:
26731 ret.set_error ();
26732 ret.original_code = ERROR_MARK;
26733 ret.original_type = NULL;
26735 parser->in_transaction = old_in;
26737 if (!flag_tm)
26738 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
26739 "%<__transaction_atomic%> without transactional memory support enabled"
26740 : "%<__transaction_relaxed %> "
26741 "without transactional memory support enabled"));
26743 set_c_expr_source_range (&ret, loc, loc);
26745 return ret;
26748 /* Parse a __transaction_cancel statement (GCC Extension).
26750 transaction-cancel-statement:
26751 __transaction_cancel transaction-attribute[opt] ;
26753 Note that the only valid attribute is "outer".
26756 static tree
26757 c_parser_transaction_cancel (c_parser *parser)
26759 location_t loc = c_parser_peek_token (parser)->location;
26760 tree attrs;
26761 bool is_outer = false;
26763 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
26764 c_parser_consume_token (parser);
26766 attrs = c_parser_transaction_attributes (parser);
26767 if (attrs)
26768 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
26770 if (!flag_tm)
26772 error_at (loc, "%<__transaction_cancel%> without "
26773 "transactional memory support enabled");
26774 goto ret_error;
26776 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
26778 error_at (loc, "%<__transaction_cancel%> within a "
26779 "%<__transaction_relaxed%>");
26780 goto ret_error;
26782 else if (is_outer)
26784 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
26785 && !is_tm_may_cancel_outer (current_function_decl))
26787 error_at (loc, "outer %<__transaction_cancel%> not "
26788 "within outer %<__transaction_atomic%> or "
26789 "a %<transaction_may_cancel_outer%> function");
26790 goto ret_error;
26793 else if (parser->in_transaction == 0)
26795 error_at (loc, "%<__transaction_cancel%> not within "
26796 "%<__transaction_atomic%>");
26797 goto ret_error;
26800 return add_stmt (build_tm_abort_call (loc, is_outer));
26802 ret_error:
26803 return build1 (NOP_EXPR, void_type_node, error_mark_node);
26806 /* Parse a single source file. */
26808 void
26809 c_parse_file (void)
26811 /* Use local storage to begin. If the first token is a pragma, parse it.
26812 If it is #pragma GCC pch_preprocess, then this will load a PCH file
26813 which will cause garbage collection. */
26814 c_parser tparser;
26816 memset (&tparser, 0, sizeof tparser);
26817 tparser.translate_strings_p = true;
26818 tparser.tokens = &tparser.tokens_buf[0];
26819 the_parser = &tparser;
26821 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
26822 c_parser_pragma_pch_preprocess (&tparser);
26823 else
26824 c_common_no_more_pch ();
26826 the_parser = ggc_alloc<c_parser> ();
26827 *the_parser = tparser;
26828 if (tparser.tokens == &tparser.tokens_buf[0])
26829 the_parser->tokens = &the_parser->tokens_buf[0];
26831 /* Initialize EH, if we've been told to do so. */
26832 if (flag_exceptions)
26833 using_eh_for_cleanups ();
26835 c_parser_translation_unit (the_parser);
26836 the_parser = NULL;
26839 void
26840 c_init_preprocess (void)
26842 /* Create a parser for use by pragma_lex during preprocessing. */
26843 the_parser = ggc_alloc<c_parser> ();
26844 memset (the_parser, 0, sizeof (c_parser));
26845 the_parser->tokens = &the_parser->tokens_buf[0];
26848 /* Parse the body of a function declaration marked with "__RTL".
26850 The RTL parser works on the level of characters read from a
26851 FILE *, whereas c_parser works at the level of tokens.
26852 Square this circle by consuming all of the tokens up to and
26853 including the closing brace, recording the start/end of the RTL
26854 fragment, and reopening the file and re-reading the relevant
26855 lines within the RTL parser.
26857 This requires the opening and closing braces of the C function
26858 to be on separate lines from the RTL they wrap.
26860 Take ownership of START_WITH_PASS, if non-NULL. */
26862 location_t
26863 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
26865 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
26867 free (start_with_pass);
26868 return c_parser_peek_token (parser)->location;
26871 location_t start_loc = c_parser_peek_token (parser)->location;
26873 /* Consume all tokens, up to the closing brace, handling
26874 matching pairs of braces in the rtl dump. */
26875 int num_open_braces = 1;
26876 while (1)
26878 switch (c_parser_peek_token (parser)->type)
26880 case CPP_OPEN_BRACE:
26881 num_open_braces++;
26882 break;
26883 case CPP_CLOSE_BRACE:
26884 if (--num_open_braces == 0)
26885 goto found_closing_brace;
26886 break;
26887 case CPP_EOF:
26888 error_at (start_loc, "no closing brace");
26889 free (start_with_pass);
26890 return c_parser_peek_token (parser)->location;
26891 default:
26892 break;
26894 c_parser_consume_token (parser);
26897 found_closing_brace:
26898 /* At the closing brace; record its location. */
26899 location_t end_loc = c_parser_peek_token (parser)->location;
26901 /* Consume the closing brace. */
26902 c_parser_consume_token (parser);
26904 /* Invoke the RTL parser. */
26905 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
26907 free (start_with_pass);
26908 return end_loc;
26911 /* Run the backend on the cfun created above, transferring ownership of
26912 START_WITH_PASS. */
26913 run_rtl_passes (start_with_pass);
26914 return end_loc;
26917 #include "gt-c-c-parser.h"