Skip various cmp-mem-const tests on lp64 hppa*-*-*
[official-gcc.git] / gcc / c / c-parser.cc
blobc31349dae2ff708580f42995fe7a13638bbc441d
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,
5709 bool loose_scope_p = false)
5711 c_token *token = c_parser_peek_token (parser);
5712 tree ns, name, attribute;
5714 /* Parse the attribute-token. */
5715 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5717 c_parser_error (parser, "expected identifier");
5718 return error_mark_node;
5720 name = canonicalize_attr_name (token->value);
5721 c_parser_consume_token (parser);
5722 if (c_parser_next_token_is (parser, CPP_SCOPE)
5723 || (loose_scope_p
5724 && c_parser_next_token_is (parser, CPP_COLON)
5725 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5727 ns = name;
5728 if (c_parser_next_token_is (parser, CPP_COLON))
5729 c_parser_consume_token (parser);
5730 c_parser_consume_token (parser);
5731 token = c_parser_peek_token (parser);
5732 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5734 c_parser_error (parser, "expected identifier");
5735 return error_mark_node;
5737 name = canonicalize_attr_name (token->value);
5738 c_parser_consume_token (parser);
5740 else
5741 ns = NULL_TREE;
5742 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
5744 /* Parse the arguments, if any. */
5745 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
5746 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5748 if ((flag_openmp || flag_openmp_simd)
5749 && ns
5750 && is_attribute_p ("omp", ns)
5751 && (is_attribute_p ("directive", name)
5752 || is_attribute_p ("sequence", name)
5753 || is_attribute_p ("decl", name)))
5755 error ("%<omp::%E%> attribute requires argument", name);
5756 return error_mark_node;
5758 goto out;
5761 location_t open_loc = c_parser_peek_token (parser)->location;
5762 matching_parens parens;
5763 parens.consume_open (parser);
5764 if ((as && as->max_length == 0)
5765 /* Special-case the transactional-memory attribute "outer",
5766 which is specially handled but not registered as an
5767 attribute, to avoid allowing arbitrary balanced token
5768 sequences as arguments. */
5769 || is_attribute_p ("outer", name))
5771 error_at (open_loc, "%qE attribute does not take any arguments", name);
5772 parens.skip_until_found_close (parser);
5773 return error_mark_node;
5775 /* If this is a fake attribute created to handle -Wno-attributes,
5776 we must skip parsing the arguments. */
5777 if (as && !attribute_ignored_p (as))
5779 bool takes_identifier
5780 = (ns != NULL_TREE
5781 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5782 && attribute_takes_identifier_p (name));
5783 bool require_string
5784 = (ns == NULL_TREE
5785 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
5786 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
5787 bool assume_attr
5788 = (ns != NULL_TREE
5789 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5790 && strcmp (IDENTIFIER_POINTER (name), "assume") == 0);
5791 TREE_VALUE (attribute)
5792 = c_parser_attribute_arguments (parser, takes_identifier,
5793 require_string, assume_attr, false);
5795 else
5797 if ((flag_openmp || flag_openmp_simd)
5798 && ns
5799 && is_attribute_p ("omp", ns))
5801 if (is_attribute_p ("directive", name))
5803 c_parser_omp_directive_args (parser, attribute, false);
5804 parens.skip_until_found_close (parser);
5805 return attribute;
5807 else if (is_attribute_p ("decl", name))
5809 TREE_VALUE (TREE_PURPOSE (attribute))
5810 = get_identifier ("directive");
5811 c_parser_omp_directive_args (parser, attribute, true);
5812 parens.skip_until_found_close (parser);
5813 return attribute;
5815 else if (is_attribute_p ("sequence", name))
5817 TREE_VALUE (TREE_PURPOSE (attribute))
5818 = get_identifier ("directive");
5819 c_parser_omp_sequence_args (parser, attribute);
5820 parens.skip_until_found_close (parser);
5821 TREE_VALUE (attribute) = nreverse (TREE_VALUE (attribute));
5822 return attribute;
5825 c_parser_balanced_token_sequence (parser);
5827 parens.require_close (parser);
5829 out:
5830 if (ns == NULL_TREE && !for_tm && !as)
5832 /* An attribute with standard syntax and no namespace specified
5833 is a constraint violation if it is not one of the known
5834 standard attributes. Diagnose it here with a pedwarn and
5835 then discard it to prevent a duplicate warning later. */
5836 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
5837 name);
5838 return error_mark_node;
5840 return attribute;
5843 static tree
5844 c_parser_std_attribute_list (c_parser *parser, bool for_tm,
5845 bool loose_scope_p = false)
5847 tree attributes = NULL_TREE;
5848 while (true)
5850 c_token *token = c_parser_peek_token (parser);
5851 if (token->type == CPP_CLOSE_SQUARE)
5852 break;
5853 if (token->type == CPP_COMMA)
5855 c_parser_consume_token (parser);
5856 continue;
5858 tree attribute = c_parser_std_attribute (parser, for_tm, loose_scope_p);
5859 if (attribute != error_mark_node)
5861 TREE_CHAIN (attribute) = attributes;
5862 attributes = attribute;
5864 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5865 break;
5867 return attributes;
5870 static tree
5871 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
5873 location_t loc = c_parser_peek_token (parser)->location;
5874 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5875 return NULL_TREE;
5876 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5878 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5879 return NULL_TREE;
5881 tree attributes;
5882 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5884 auto ext = disable_extension_diagnostics ();
5885 c_parser_consume_token (parser);
5886 attributes = c_parser_std_attribute_list (parser, for_tm, true);
5887 restore_extension_diagnostics (ext);
5889 else
5891 if (!for_tm)
5892 pedwarn_c11 (loc, OPT_Wpedantic,
5893 "ISO C does not support %<[[]]%> attributes before C23");
5894 attributes = c_parser_std_attribute_list (parser, for_tm);
5896 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5897 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5898 return nreverse (attributes);
5901 /* Look past an optional balanced token sequence of raw look-ahead
5902 tokens starting with the *Nth token. *N is updated to point to the
5903 following token. Return true if such a sequence was found, false
5904 if the tokens parsed were not balanced. */
5906 static bool
5907 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5909 while (true)
5911 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5912 switch (token->type)
5914 case CPP_OPEN_BRACE:
5916 ++*n;
5917 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5919 token = c_parser_peek_nth_token_raw (parser, *n);
5920 if (token->type == CPP_CLOSE_BRACE)
5921 ++*n;
5922 else
5923 return false;
5925 else
5926 return false;
5927 break;
5930 case CPP_OPEN_PAREN:
5932 ++*n;
5933 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5935 token = c_parser_peek_nth_token_raw (parser, *n);
5936 if (token->type == CPP_CLOSE_PAREN)
5937 ++*n;
5938 else
5939 return false;
5941 else
5942 return false;
5943 break;
5946 case CPP_OPEN_SQUARE:
5948 ++*n;
5949 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5951 token = c_parser_peek_nth_token_raw (parser, *n);
5952 if (token->type == CPP_CLOSE_SQUARE)
5953 ++*n;
5954 else
5955 return false;
5957 else
5958 return false;
5959 break;
5962 case CPP_CLOSE_BRACE:
5963 case CPP_CLOSE_PAREN:
5964 case CPP_CLOSE_SQUARE:
5965 case CPP_EOF:
5966 return true;
5968 default:
5969 ++*n;
5970 break;
5975 /* Return whether standard attributes start with the Nth token. */
5977 static bool
5978 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5980 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5981 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5982 return false;
5983 /* In C, '[[' must start attributes. In Objective-C, we need to
5984 check whether '[[' is matched by ']]'. */
5985 if (!c_dialect_objc ())
5986 return true;
5987 n += 2;
5988 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5989 return false;
5990 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5991 if (token->type != CPP_CLOSE_SQUARE)
5992 return false;
5993 token = c_parser_peek_nth_token_raw (parser, n + 1);
5994 return token->type == CPP_CLOSE_SQUARE;
5997 static tree
5998 c_parser_std_attribute_specifier_sequence (c_parser *parser)
6000 tree attributes = NULL_TREE;
6003 tree attrs = c_parser_std_attribute_specifier (parser, false);
6004 attributes = chainon (attributes, attrs);
6006 while (c_parser_nth_token_starts_std_attributes (parser, 1));
6007 return attributes;
6010 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
6011 says whether alignment specifiers are OK (only in cases that might
6012 be the type name of a compound literal).
6014 type-name:
6015 specifier-qualifier-list abstract-declarator[opt]
6018 struct c_type_name *
6019 c_parser_type_name (c_parser *parser, bool alignas_ok)
6021 struct c_declspecs *specs = build_null_declspecs ();
6022 struct c_declarator *declarator;
6023 struct c_type_name *ret;
6024 bool dummy = false;
6025 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
6026 false, true, cla_prefer_type);
6027 if (!specs->declspecs_seen_p)
6029 c_parser_error (parser, "expected specifier-qualifier-list");
6030 return NULL;
6032 if (specs->type != error_mark_node)
6034 pending_xref_error ();
6035 finish_declspecs (specs);
6037 declarator = c_parser_declarator (parser,
6038 specs->typespec_kind != ctsk_none,
6039 C_DTR_ABSTRACT, &dummy);
6040 if (declarator == NULL)
6041 return NULL;
6042 ret = XOBNEW (&parser_obstack, struct c_type_name);
6043 ret->specs = specs;
6044 ret->declarator = declarator;
6045 return ret;
6048 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
6050 initializer:
6051 assignment-expression
6052 { initializer-list }
6053 { initializer-list , }
6055 initializer-list:
6056 designation[opt] initializer
6057 initializer-list , designation[opt] initializer
6059 designation:
6060 designator-list =
6062 designator-list:
6063 designator
6064 designator-list designator
6066 designator:
6067 array-designator
6068 . identifier
6070 array-designator:
6071 [ constant-expression ]
6073 GNU extensions:
6075 initializer:
6078 designation:
6079 array-designator
6080 identifier :
6082 array-designator:
6083 [ constant-expression ... constant-expression ]
6085 Any expression without commas is accepted in the syntax for the
6086 constant-expressions, with non-constant expressions rejected later.
6088 DECL is the declaration we're parsing this initializer for.
6090 This function is only used for top-level initializers; for nested
6091 ones, see c_parser_initval. */
6093 static struct c_expr
6094 c_parser_initializer (c_parser *parser, tree decl)
6096 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6097 return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
6098 else
6100 struct c_expr ret;
6101 location_t loc = c_parser_peek_token (parser)->location;
6102 ret = c_parser_expr_no_commas (parser, NULL);
6103 if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
6105 error_at (loc,
6106 "variable-sized object may not be initialized except "
6107 "with an empty initializer");
6108 ret.set_error ();
6110 /* This is handled mostly by gimplify.cc, but we have to deal with
6111 not warning about int x = x; as it is a GCC extension to turn off
6112 this warning but only if warn_init_self is zero. */
6113 if (VAR_P (decl)
6114 && !DECL_EXTERNAL (decl)
6115 && !TREE_STATIC (decl)
6116 && ret.value == decl
6117 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl), OPT_Winit_self))
6118 suppress_warning (decl, OPT_Winit_self);
6119 if (TREE_CODE (ret.value) != STRING_CST
6120 && (TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR
6121 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6122 (ret.value))))
6123 ret = convert_lvalue_to_rvalue (loc, ret, true, true, true);
6124 return ret;
6128 /* The location of the last comma within the current initializer list,
6129 or UNKNOWN_LOCATION if not within one. */
6131 location_t last_init_list_comma;
6133 /* Parse a braced initializer list. TYPE is the type specified for a
6134 compound literal, and NULL_TREE for other initializers and for
6135 nested braced lists. NESTED_P is true for nested braced lists,
6136 false for the list of a compound literal or the list that is the
6137 top-level initializer in a declaration. DECL is the declaration for
6138 the top-level initializer for a declaration, otherwise NULL_TREE. */
6140 static struct c_expr
6141 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
6142 struct obstack *outer_obstack, tree decl)
6144 struct c_expr ret;
6145 struct obstack braced_init_obstack;
6146 location_t brace_loc = c_parser_peek_token (parser)->location;
6147 gcc_obstack_init (&braced_init_obstack);
6148 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
6149 bool save_c_omp_array_section_p = c_omp_array_section_p;
6150 c_omp_array_section_p = false;
6151 matching_braces braces;
6152 braces.consume_open (parser);
6153 if (nested_p)
6155 finish_implicit_inits (brace_loc, outer_obstack);
6156 push_init_level (brace_loc, 0, &braced_init_obstack);
6158 else
6159 really_start_incremental_init (type);
6160 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6162 pedwarn_c11 (brace_loc, OPT_Wpedantic,
6163 "ISO C forbids empty initializer braces before C23");
6165 else
6167 if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
6168 error_at (brace_loc,
6169 "variable-sized object may not be initialized except "
6170 "with an empty initializer");
6171 /* Parse a non-empty initializer list, possibly with a trailing
6172 comma. */
6173 while (true)
6175 c_parser_initelt (parser, &braced_init_obstack);
6176 if (parser->error)
6177 break;
6178 if (c_parser_next_token_is (parser, CPP_COMMA))
6180 last_init_list_comma = c_parser_peek_token (parser)->location;
6181 c_parser_consume_token (parser);
6183 else
6184 break;
6185 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6186 break;
6189 c_omp_array_section_p = save_c_omp_array_section_p;
6190 c_token *next_tok = c_parser_peek_token (parser);
6191 if (next_tok->type != CPP_CLOSE_BRACE)
6193 ret.set_error ();
6194 ret.original_code = ERROR_MARK;
6195 ret.original_type = NULL;
6196 braces.skip_until_found_close (parser);
6197 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
6198 obstack_free (&braced_init_obstack, NULL);
6199 return ret;
6201 location_t close_loc = next_tok->location;
6202 c_parser_consume_token (parser);
6203 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
6204 obstack_free (&braced_init_obstack, NULL);
6205 set_c_expr_source_range (&ret, brace_loc, close_loc);
6206 return ret;
6209 /* Parse a nested initializer, including designators. */
6211 static void
6212 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
6214 /* Parse any designator or designator list. A single array
6215 designator may have the subsequent "=" omitted in GNU C, but a
6216 longer list or a structure member designator may not. */
6217 if (c_parser_next_token_is (parser, CPP_NAME)
6218 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
6220 /* Old-style structure member designator. */
6221 set_init_label (c_parser_peek_token (parser)->location,
6222 c_parser_peek_token (parser)->value,
6223 c_parser_peek_token (parser)->location,
6224 braced_init_obstack);
6225 /* Use the colon as the error location. */
6226 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
6227 "obsolete use of designated initializer with %<:%>");
6228 c_parser_consume_token (parser);
6229 c_parser_consume_token (parser);
6231 else
6233 /* des_seen is 0 if there have been no designators, 1 if there
6234 has been a single array designator and 2 otherwise. */
6235 int des_seen = 0;
6236 /* Location of a designator. */
6237 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6238 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
6239 || c_parser_next_token_is (parser, CPP_DOT))
6241 int des_prev = des_seen;
6242 if (!des_seen)
6243 des_loc = c_parser_peek_token (parser)->location;
6244 if (des_seen < 2)
6245 des_seen++;
6246 if (c_parser_next_token_is (parser, CPP_DOT))
6248 des_seen = 2;
6249 c_parser_consume_token (parser);
6250 if (c_parser_next_token_is (parser, CPP_NAME))
6252 set_init_label (des_loc, c_parser_peek_token (parser)->value,
6253 c_parser_peek_token (parser)->location,
6254 braced_init_obstack);
6255 c_parser_consume_token (parser);
6257 else
6259 struct c_expr init;
6260 init.set_error ();
6261 init.original_code = ERROR_MARK;
6262 init.original_type = NULL;
6263 c_parser_error (parser, "expected identifier");
6264 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
6265 process_init_element (input_location, init, false,
6266 braced_init_obstack);
6267 return;
6270 else
6272 struct c_expr first_expr;
6273 tree first, second;
6274 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6275 location_t array_index_loc = UNKNOWN_LOCATION;
6276 /* ??? Following the old parser, [ objc-receiver
6277 objc-message-args ] is accepted as an initializer,
6278 being distinguished from a designator by what follows
6279 the first assignment expression inside the square
6280 brackets, but after a first array designator a
6281 subsequent square bracket is for Objective-C taken to
6282 start an expression, using the obsolete form of
6283 designated initializer without '=', rather than
6284 possibly being a second level of designation: in LALR
6285 terms, the '[' is shifted rather than reducing
6286 designator to designator-list. */
6287 if (des_prev == 1 && c_dialect_objc ())
6289 des_seen = des_prev;
6290 break;
6292 if (des_prev == 0 && c_dialect_objc ())
6294 /* This might be an array designator or an
6295 Objective-C message expression. If the former,
6296 continue parsing here; if the latter, parse the
6297 remainder of the initializer given the starting
6298 primary-expression. ??? It might make sense to
6299 distinguish when des_prev == 1 as well; see
6300 previous comment. */
6301 tree rec, args;
6302 struct c_expr mexpr;
6303 c_parser_consume_token (parser);
6304 if (c_parser_peek_token (parser)->type == CPP_NAME
6305 && ((c_parser_peek_token (parser)->id_kind
6306 == C_ID_TYPENAME)
6307 || (c_parser_peek_token (parser)->id_kind
6308 == C_ID_CLASSNAME)))
6310 /* Type name receiver. */
6311 tree id = c_parser_peek_token (parser)->value;
6312 c_parser_consume_token (parser);
6313 rec = objc_get_class_reference (id);
6314 goto parse_message_args;
6316 array_index_loc = c_parser_peek_token (parser)->location;
6317 first_expr = c_parser_expr_no_commas (parser, NULL);
6318 mark_exp_read (first_expr.value);
6319 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
6320 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
6321 goto array_desig_after_first;
6322 first = first_expr.value;
6323 /* Expression receiver. So far only one part
6324 without commas has been parsed; there might be
6325 more of the expression. */
6326 rec = first;
6327 while (c_parser_next_token_is (parser, CPP_COMMA))
6329 struct c_expr next;
6330 location_t comma_loc, exp_loc;
6331 comma_loc = c_parser_peek_token (parser)->location;
6332 c_parser_consume_token (parser);
6333 exp_loc = c_parser_peek_token (parser)->location;
6334 next = c_parser_expr_no_commas (parser, NULL);
6335 next = convert_lvalue_to_rvalue (exp_loc, next,
6336 true, true);
6337 rec = build_compound_expr (comma_loc, rec, next.value);
6339 parse_message_args:
6340 /* Now parse the objc-message-args. */
6341 args = c_parser_objc_message_args (parser);
6342 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6343 "expected %<]%>");
6344 mexpr.value
6345 = objc_build_message_expr (rec, args);
6346 mexpr.original_code = ERROR_MARK;
6347 mexpr.original_type = NULL;
6348 mexpr.m_decimal = 0;
6349 /* Now parse and process the remainder of the
6350 initializer, starting with this message
6351 expression as a primary-expression. */
6352 c_parser_initval (parser, &mexpr, braced_init_obstack);
6353 return;
6355 c_parser_consume_token (parser);
6356 array_index_loc = c_parser_peek_token (parser)->location;
6357 first_expr = c_parser_expr_no_commas (parser, NULL);
6358 mark_exp_read (first_expr.value);
6359 array_desig_after_first:
6360 first_expr = convert_lvalue_to_rvalue (array_index_loc,
6361 first_expr,
6362 true, true);
6363 first = first_expr.value;
6364 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
6366 ellipsis_loc = c_parser_peek_token (parser)->location;
6367 c_parser_consume_token (parser);
6368 second = convert_lvalue_to_rvalue (ellipsis_loc,
6369 (c_parser_expr_no_commas
6370 (parser, NULL)),
6371 true, true).value;
6372 mark_exp_read (second);
6374 else
6375 second = NULL_TREE;
6376 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
6378 c_parser_consume_token (parser);
6379 set_init_index (array_index_loc, first, second,
6380 braced_init_obstack);
6381 if (second)
6382 pedwarn (ellipsis_loc, OPT_Wpedantic,
6383 "ISO C forbids specifying range of elements to initialize");
6385 else
6386 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6387 "expected %<]%>");
6390 if (des_seen >= 1)
6392 if (c_parser_next_token_is (parser, CPP_EQ))
6394 pedwarn_c90 (des_loc, OPT_Wpedantic,
6395 "ISO C90 forbids specifying subobject "
6396 "to initialize");
6397 c_parser_consume_token (parser);
6399 else
6401 if (des_seen == 1)
6402 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
6403 "obsolete use of designated initializer without %<=%>");
6404 else
6406 struct c_expr init;
6407 init.set_error ();
6408 init.original_code = ERROR_MARK;
6409 init.original_type = NULL;
6410 c_parser_error (parser, "expected %<=%>");
6411 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
6412 process_init_element (input_location, init, false,
6413 braced_init_obstack);
6414 return;
6419 c_parser_initval (parser, NULL, braced_init_obstack);
6422 /* Parse a nested initializer; as c_parser_initializer but parses
6423 initializers within braced lists, after any designators have been
6424 applied. If AFTER is not NULL then it is an Objective-C message
6425 expression which is the primary-expression starting the
6426 initializer. */
6428 static void
6429 c_parser_initval (c_parser *parser, struct c_expr *after,
6430 struct obstack * braced_init_obstack)
6432 struct c_expr init;
6433 gcc_assert (!after || c_dialect_objc ());
6434 location_t loc = c_parser_peek_token (parser)->location;
6436 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
6437 init = c_parser_braced_init (parser, NULL_TREE, true,
6438 braced_init_obstack, NULL_TREE);
6439 else
6441 init = c_parser_expr_no_commas (parser, after);
6442 if (init.value != NULL_TREE
6443 && TREE_CODE (init.value) != STRING_CST
6444 && (TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR
6445 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6446 (init.value))))
6447 init = convert_lvalue_to_rvalue (loc, init, true, true, true);
6449 process_init_element (loc, init, false, braced_init_obstack);
6452 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6453 C99 6.8.2, C11 6.8.2, C23 6.8.2).
6455 compound-statement:
6456 { block-item-list[opt] }
6457 { label-declarations block-item-list }
6459 block-item-list:
6460 block-item
6461 block-item-list block-item
6463 block-item:
6464 label
6465 nested-declaration
6466 statement
6468 nested-declaration:
6469 declaration
6471 GNU extensions:
6473 compound-statement:
6474 { label-declarations block-item-list }
6476 nested-declaration:
6477 __extension__ nested-declaration
6478 nested-function-definition
6480 label-declarations:
6481 label-declaration
6482 label-declarations label-declaration
6484 label-declaration:
6485 __label__ identifier-list ;
6487 Allowing the mixing of declarations and code is new in C99. The
6488 GNU syntax also permits (not shown above) labels at the end of
6489 compound statements, which yield an error. We don't allow labels
6490 on declarations; this might seem like a natural extension, but
6491 there would be a conflict between gnu-attributes on the label and
6492 prefix gnu-attributes on the declaration. ??? The syntax follows the
6493 old parser in requiring something after label declarations.
6494 Although they are erroneous if the labels declared aren't defined,
6495 is it useful for the syntax to be this way?
6497 OpenACC:
6499 block-item:
6500 openacc-directive
6502 openacc-directive:
6503 update-directive
6505 OpenMP:
6507 block-item:
6508 openmp-directive
6510 openmp-directive:
6511 barrier-directive
6512 flush-directive
6513 taskwait-directive
6514 taskyield-directive
6515 cancel-directive
6516 cancellation-point-directive */
6518 static tree
6519 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
6521 tree stmt;
6522 location_t brace_loc;
6523 brace_loc = c_parser_peek_token (parser)->location;
6524 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
6526 /* Ensure a scope is entered and left anyway to avoid confusion
6527 if we have just prepared to enter a function body. */
6528 stmt = c_begin_compound_stmt (true);
6529 c_end_compound_stmt (brace_loc, stmt, true);
6530 return error_mark_node;
6532 stmt = c_begin_compound_stmt (true);
6533 location_t end_loc = c_parser_compound_statement_nostart (parser);
6534 if (endlocp)
6535 *endlocp = end_loc;
6537 return c_end_compound_stmt (brace_loc, stmt, true);
6540 /* Diagnose errors related to imperfectly nested loops in an OMP
6541 loop construct. This function is called when such code is seen.
6542 Only issue one such diagnostic no matter how much invalid
6543 intervening code there is in the loop.
6544 FIXME: maybe the location associated with the diagnostic should
6545 be the current parser token instead of the location of the outer loop
6546 nest. */
6548 static void
6549 check_omp_intervening_code (c_parser *parser)
6551 struct omp_for_parse_data *omp_for_parse_state = parser->omp_for_parse_state;
6552 gcc_assert (omp_for_parse_state);
6554 if (!omp_for_parse_state->in_intervening_code)
6555 return;
6556 omp_for_parse_state->saw_intervening_code = true;
6558 /* Only diagnose errors related to perfect nesting once. */
6559 if (!omp_for_parse_state->perfect_nesting_fail)
6562 /* OpenACC does not (yet) permit intervening code, in
6563 addition to situations forbidden by the OpenMP spec. */
6564 if (omp_for_parse_state->code == OACC_LOOP)
6566 error_at (omp_for_parse_state->for_loc,
6567 "inner loops must be perfectly nested in "
6568 "%<#pragma acc loop%>");
6569 omp_for_parse_state->perfect_nesting_fail = true;
6571 else if (omp_for_parse_state->ordered)
6573 error_at (omp_for_parse_state->for_loc,
6574 "inner loops must be perfectly nested with "
6575 "%<ordered%> clause");
6576 omp_for_parse_state->perfect_nesting_fail = true;
6578 else if (omp_for_parse_state->inscan)
6580 error_at (omp_for_parse_state->for_loc,
6581 "inner loops must be perfectly nested with "
6582 "%<reduction%> %<inscan%> clause");
6583 omp_for_parse_state->perfect_nesting_fail = true;
6585 /* TODO: Also reject loops with TILE directive. */
6586 if (omp_for_parse_state->perfect_nesting_fail)
6587 omp_for_parse_state->fail = true;
6591 /* Helper function for below: wrap an OMP_STRUCTURED_BLOCK around SL
6592 and add the statement to the current list. If SL is an empty statement
6593 list, do nothing. */
6594 static void
6595 add_structured_block_stmt (tree sl)
6597 if (TREE_CODE (sl) != STATEMENT_LIST
6598 || !tsi_end_p (tsi_start (sl)))
6599 add_stmt (build1 (OMP_STRUCTURED_BLOCK, void_type_node, sl));
6602 struct c_omp_attribute_data
6604 vec<c_token, va_gc> *tokens;
6605 const c_omp_directive *dir;
6606 c_omp_directive_kind kind;
6609 /* Handle omp::directive and omp::sequence attributes in ATTRS
6610 (if any) at the start of a statement or in attribute-declaration. */
6612 static bool
6613 c_parser_handle_statement_omp_attributes (c_parser *parser, tree &attrs,
6614 bool *have_std_attrs)
6616 if (!flag_openmp && !flag_openmp_simd)
6617 return false;
6619 auto_vec<c_omp_attribute_data, 16> vd;
6620 int cnt = 0;
6621 int tokens = 0;
6622 bool bad = false;
6623 for (tree *pa = &attrs; *pa; )
6624 if (is_attribute_namespace_p ("omp", *pa)
6625 && is_attribute_p ("directive", get_attribute_name (*pa)))
6627 cnt++;
6628 for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
6630 tree d = TREE_VALUE (a);
6631 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
6632 vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
6633 c_token *first = toks->address ();
6634 c_token *last = first + toks->length ();
6635 if (parser->omp_attrs_forbidden_p)
6637 error_at (first->location,
6638 "mixing OpenMP directives with attribute and pragma "
6639 "syntax on the same statement");
6640 parser->omp_attrs_forbidden_p = false;
6641 bad = true;
6643 else if (TREE_PUBLIC (d))
6645 error_at (first->location,
6646 "OpenMP %<omp::decl%> attribute on a statement");
6647 bad = true;
6649 const char *directive[3] = {};
6650 for (int i = 0; i < 3; i++)
6652 tree id = NULL_TREE;
6653 if (first + i == last)
6654 break;
6655 if (first[i].type == CPP_NAME)
6656 id = first[i].value;
6657 else if (first[i].type == CPP_KEYWORD)
6658 id = ridpointers[(int) first[i].keyword];
6659 else
6660 break;
6661 directive[i] = IDENTIFIER_POINTER (id);
6663 const c_omp_directive *dir = NULL;
6664 if (directive[0])
6665 dir = c_omp_categorize_directive (directive[0], directive[1],
6666 directive[2]);
6667 if (dir == NULL)
6669 error_at (first->location,
6670 "unknown OpenMP directive name in %qs attribute "
6671 "argument",
6672 TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
6673 continue;
6675 c_omp_directive_kind kind = dir->kind;
6676 if (dir->id == PRAGMA_OMP_ORDERED)
6678 /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
6679 depend/doacross clause. */
6680 if (directive[1]
6681 && (strcmp (directive[1], "depend") == 0
6682 || strcmp (directive[1], "doacross") == 0))
6683 kind = C_OMP_DIR_STANDALONE;
6684 else if (first + 2 < last
6685 && first[1].type == CPP_COMMA
6686 && first[2].type == CPP_NAME
6687 && (strcmp (IDENTIFIER_POINTER (first[2].value),
6688 "depend") == 0
6689 || strcmp (IDENTIFIER_POINTER (first[2].value),
6690 "doacross") == 0))
6691 kind = C_OMP_DIR_STANDALONE;
6693 else if (dir->id == PRAGMA_OMP_ERROR)
6695 /* error with at(execution) clause is C_OMP_DIR_STANDALONE. */
6696 int paren_depth = 0;
6697 for (int i = 1; first + i < last; i++)
6698 if (first[i].type == CPP_OPEN_PAREN)
6699 paren_depth++;
6700 else if (first[i].type == CPP_CLOSE_PAREN)
6701 paren_depth--;
6702 else if (paren_depth == 0
6703 && first + i + 2 < last
6704 && first[i].type == CPP_NAME
6705 && first[i + 1].type == CPP_OPEN_PAREN
6706 && first[i + 2].type == CPP_NAME
6707 && !strcmp (IDENTIFIER_POINTER (first[i].value),
6708 "at")
6709 && !strcmp (IDENTIFIER_POINTER (first[i
6710 + 2].value),
6711 "execution"))
6713 kind = C_OMP_DIR_STANDALONE;
6714 break;
6717 c_omp_attribute_data v = { toks, dir, kind };
6718 vd.safe_push (v);
6719 if (flag_openmp || dir->simd)
6720 tokens += (last - first) + 1;
6722 c_omp_attribute_data v = {};
6723 vd.safe_push (v);
6724 *pa = TREE_CHAIN (*pa);
6726 else
6727 pa = &TREE_CHAIN (*pa);
6729 if (bad)
6731 fail:
6732 if (have_std_attrs && attrs == NULL)
6733 *have_std_attrs = false;
6734 return false;
6737 unsigned int i;
6738 c_omp_attribute_data *v;
6739 c_omp_attribute_data *construct_seen = nullptr;
6740 c_omp_attribute_data *standalone_seen = nullptr;
6741 c_omp_attribute_data *prev_standalone_seen = nullptr;
6742 FOR_EACH_VEC_ELT (vd, i, v)
6743 if (v->tokens)
6745 if (v->kind == C_OMP_DIR_CONSTRUCT && !construct_seen)
6746 construct_seen = v;
6747 else if (v->kind == C_OMP_DIR_STANDALONE && !standalone_seen)
6748 standalone_seen = v;
6750 else
6752 if (standalone_seen && !prev_standalone_seen)
6754 prev_standalone_seen = standalone_seen;
6755 standalone_seen = nullptr;
6759 if (cnt > 1 && construct_seen)
6761 error_at ((*construct_seen->tokens)[0].location,
6762 "OpenMP construct among %<omp::directive%> attributes"
6763 " requires all %<omp::directive%> attributes on the"
6764 " same statement to be in the same %<omp::sequence%>");
6765 goto fail;
6767 if (cnt > 1 && standalone_seen && prev_standalone_seen)
6769 error_at ((*standalone_seen->tokens)[0].location,
6770 "multiple OpenMP standalone directives among"
6771 " %<omp::directive%> attributes must be all within the"
6772 " same %<omp::sequence%>");
6773 goto fail;
6776 if (prev_standalone_seen)
6777 standalone_seen = prev_standalone_seen;
6778 if (standalone_seen
6779 && !c_parser_next_token_is (parser, CPP_SEMICOLON))
6781 error_at (standalone_seen->tokens->address ()->location,
6782 "standalone OpenMP directives in %<omp::directive%> attribute"
6783 " can only appear on an empty statement");
6784 goto fail;
6786 if (cnt && c_parser_next_token_is (parser, CPP_PRAGMA))
6788 c_token *token = c_parser_peek_token (parser);
6789 enum pragma_kind kind = token->pragma_kind;
6790 if (kind >= PRAGMA_OMP__START_ && kind <= PRAGMA_OMP__LAST_)
6792 error_at (token->location,
6793 "mixing OpenMP directives with attribute and pragma "
6794 "syntax on the same statement");
6795 goto fail;
6799 if (!tokens)
6800 return false;
6802 unsigned int tokens_avail = parser->tokens_avail;
6803 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
6805 tokens++;
6806 vec<c_token, va_gc> *toks = NULL;
6807 vec_safe_reserve (toks, tokens, true);
6808 FOR_EACH_VEC_ELT (vd, i, v)
6810 if (!v->tokens)
6811 continue;
6812 if (!flag_openmp && !v->dir->simd)
6813 continue;
6814 c_token *first = v->tokens->address ();
6815 c_token *last = first + v->tokens->length ();
6816 c_token tok = {};
6817 tok.type = CPP_PRAGMA;
6818 tok.keyword = RID_MAX;
6819 tok.pragma_kind = pragma_kind (v->dir->id);
6820 tok.location = first->location;
6821 toks->quick_push (tok);
6822 while (++first < last)
6823 toks->quick_push (*first);
6824 tok = {};
6825 tok.type = CPP_PRAGMA_EOL;
6826 tok.keyword = RID_MAX;
6827 tok.location = last[-1].location;
6828 toks->quick_push (tok);
6831 c_token tok = {};
6832 tok.type = CPP_EOF;
6833 tok.keyword = RID_MAX;
6834 tok.location = toks->last ().location;
6835 tok.flags = tokens_avail;
6836 toks->quick_push (tok);
6838 parser->tokens = toks->address ();
6839 parser->tokens_avail = tokens;
6840 parser->in_omp_attribute_pragma = toks;
6841 return true;
6844 /* Handle omp::directive and omp::sequence attributes in ATTRS
6845 (if any) at the start or after declaration-id of a declaration. */
6847 static void
6848 c_parser_handle_directive_omp_attributes (tree &attrs,
6849 vec<c_token> *&pragma_clauses,
6850 vec<c_token> *attr_clauses)
6852 if (!flag_openmp && !flag_openmp_simd)
6853 return;
6855 for (tree *pa = &attrs; *pa; )
6856 if (is_attribute_namespace_p ("omp", *pa)
6857 && is_attribute_p ("directive", get_attribute_name (*pa)))
6859 int cnt = 0;
6860 for (tree *pa2 = &TREE_VALUE (*pa); *pa2; )
6862 tree a = *pa2;
6863 tree d = TREE_VALUE (a);
6864 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
6865 vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
6866 c_token *first = toks->address ();
6867 c_token *last = first + toks->length ();
6868 const char *directive[3] = {};
6869 for (int i = 0; i < 3; i++)
6871 tree id = NULL_TREE;
6872 if (first + i == last)
6873 break;
6874 if (first[i].type == CPP_NAME)
6875 id = first[i].value;
6876 else if (first[i].type == CPP_KEYWORD)
6877 id = ridpointers[(int) first[i].keyword];
6878 else
6879 break;
6880 directive[i] = IDENTIFIER_POINTER (id);
6882 const c_omp_directive *dir = NULL;
6883 if (directive[0])
6884 dir = c_omp_categorize_directive (directive[0], directive[1],
6885 directive[2]);
6886 if (dir == NULL)
6888 error_at (first->location,
6889 "unknown OpenMP directive name in "
6890 "%qs attribute argument",
6891 TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
6892 *pa2 = TREE_CHAIN (a);
6894 else if (dir->id == PRAGMA_OMP_DECLARE
6895 && (strcmp (directive[1], "simd") == 0
6896 || strcmp (directive[1], "variant") == 0))
6898 if (pragma_clauses)
6900 error_at (first->location,
6901 "mixing OpenMP directives with attribute and "
6902 "pragma syntax on the same declaration");
6903 for (pa = &attrs; *pa; )
6904 if (is_attribute_namespace_p ("omp", *pa)
6905 && is_attribute_p ("directive",
6906 get_attribute_name (*pa)))
6907 *pa = TREE_CHAIN (*pa);
6908 else
6909 pa = &TREE_CHAIN (*pa);
6910 return;
6912 ++cnt;
6913 attr_clauses->reserve (attr_clauses->length ()
6914 + toks->length () + 2);
6915 for (++first; first < last; ++first)
6916 attr_clauses->quick_push (*first);
6917 c_token tok = {};
6918 tok.type = CPP_PRAGMA_EOL;
6919 tok.keyword = RID_MAX;
6920 tok.location = last[-1].location;
6921 attr_clauses->quick_push (tok);
6922 *pa2 = TREE_CHAIN (a);
6924 else
6925 pa2 = &TREE_CHAIN (a);
6927 if (cnt && TREE_VALUE (*pa) == NULL_TREE)
6928 *pa = TREE_CHAIN (*pa);
6929 else
6930 pa = &TREE_CHAIN (*pa);
6932 else
6933 pa = &TREE_CHAIN (*pa);
6934 if (attr_clauses->length ())
6936 c_token tok = {};
6937 tok.type = CPP_EOF;
6938 tok.keyword = RID_MAX;
6939 tok.location = attr_clauses->last ().location;
6940 attr_clauses->quick_push (tok);
6941 attr_clauses->quick_push (tok);
6942 pragma_clauses = attr_clauses;
6946 /* Parse a compound statement except for the opening brace. This is
6947 used for parsing both compound statements and statement expressions
6948 (which follow different paths to handling the opening). */
6950 static location_t
6951 c_parser_compound_statement_nostart (c_parser *parser)
6953 bool last_stmt = false;
6954 bool last_label = false;
6955 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
6956 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6957 struct omp_for_parse_data *omp_for_parse_state
6958 = parser->omp_for_parse_state;
6959 bool in_omp_loop_block
6960 = omp_for_parse_state ? omp_for_parse_state->want_nested_loop : false;
6961 tree sl = NULL_TREE;
6963 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6965 location_t endloc = c_parser_peek_token (parser)->location;
6966 add_debug_begin_stmt (endloc);
6967 c_parser_consume_token (parser);
6968 return endloc;
6971 /* If we're parsing a {} sequence in an OMP_FOR body, start a
6972 statement list for intervening code. */
6973 if (in_omp_loop_block)
6974 sl = push_stmt_list ();
6976 mark_valid_location_for_stdc_pragma (true);
6977 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
6979 /* Read zero or more forward-declarations for labels that nested
6980 functions can jump to. */
6981 mark_valid_location_for_stdc_pragma (false);
6982 if (in_omp_loop_block)
6983 check_omp_intervening_code (parser);
6984 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
6986 label_loc = c_parser_peek_token (parser)->location;
6987 c_parser_consume_token (parser);
6988 /* Any identifiers, including those declared as type names,
6989 are OK here. */
6990 while (true)
6992 tree label;
6993 if (c_parser_next_token_is_not (parser, CPP_NAME))
6995 c_parser_error (parser, "expected identifier");
6996 break;
6998 label
6999 = declare_label (c_parser_peek_token (parser)->value);
7000 C_DECLARED_LABEL_FLAG (label) = 1;
7001 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
7002 c_parser_consume_token (parser);
7003 if (c_parser_next_token_is (parser, CPP_COMMA))
7004 c_parser_consume_token (parser);
7005 else
7006 break;
7008 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7010 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
7012 /* We must now have at least one statement, label or declaration. */
7013 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
7015 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7016 c_parser_error (parser, "expected declaration or statement");
7017 location_t endloc = c_parser_peek_token (parser)->location;
7018 c_parser_consume_token (parser);
7019 return endloc;
7021 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
7023 location_t loc = c_parser_peek_token (parser)->location;
7024 loc = expansion_point_location_if_in_system_header (loc);
7026 bool want_nested_loop = (omp_for_parse_state
7027 ? omp_for_parse_state->want_nested_loop
7028 : false);
7030 /* First take care of special cases for OpenMP "canonical loop
7031 nest form", that do not allow standard attributes, labels, or
7032 __extension__ before the nested statement. */
7033 if (in_omp_loop_block && !last_label)
7035 if (want_nested_loop
7036 && c_parser_next_token_is_keyword (parser, RID_FOR))
7038 /* Found the next nested loop. If there were intervening
7039 code statements collected before now, wrap them in an
7040 OMP_STRUCTURED_BLOCK node, and start a new structured
7041 block to hold statements that may come after the FOR. */
7042 gcc_assert (sl);
7043 add_structured_block_stmt (pop_stmt_list (sl));
7044 omp_for_parse_state->depth++;
7045 add_stmt (c_parser_omp_loop_nest (parser, NULL));
7046 omp_for_parse_state->depth--;
7047 sl = push_stmt_list ();
7048 parser->error = false;
7049 continue;
7051 else if (want_nested_loop
7052 && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7054 /* If this nested compound statement contains the nested loop,
7055 we need to separate the other statements in the current
7056 statement into separate blocks of intervening code. If
7057 there's no nested loop, it's all part of the same
7058 chunk of intervening code. */
7059 tree pre_sl = pop_stmt_list (sl);
7060 tree nested_sl = push_stmt_list ();
7061 mark_valid_location_for_stdc_pragma (false);
7062 c_parser_statement_after_labels (parser, NULL);
7063 nested_sl = pop_stmt_list (nested_sl);
7064 if (omp_for_parse_state->want_nested_loop)
7066 /* This block didn't contain a loop-nest, so it's
7067 all part of the same chunk of intervening code. */
7068 check_omp_intervening_code (parser);
7069 sl = push_stmt_list ();
7070 add_stmt (pre_sl);
7071 add_stmt (nested_sl);
7073 else
7075 /* It contains the nested loop. */
7076 add_structured_block_stmt (pre_sl);
7077 add_stmt (nested_sl);
7078 sl = push_stmt_list ();
7080 parser->error = false;
7081 continue;
7083 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7085 /* Prior to implementing the OpenMP 5.1 syntax for canonical
7086 loop form, GCC used to accept an empty statements that
7087 would now be flagged as intervening code. Continue to
7088 do that, as an extension. */
7089 /* FIXME: Maybe issue a warning or something here? */
7090 c_parser_consume_token (parser);
7091 continue;
7095 /* Standard attributes may start a label, statement or declaration. */
7096 bool have_std_attrs
7097 = c_parser_nth_token_starts_std_attributes (parser, 1);
7098 tree std_attrs = NULL_TREE;
7099 if (have_std_attrs)
7100 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7101 if (c_parser_next_token_is_keyword (parser, RID_CASE)
7102 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
7103 || (c_parser_next_token_is (parser, CPP_NAME)
7104 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
7106 if (c_parser_next_token_is_keyword (parser, RID_CASE))
7107 label_loc = c_parser_peek_2nd_token (parser)->location;
7108 else
7109 label_loc = c_parser_peek_token (parser)->location;
7110 last_label = true;
7111 last_stmt = false;
7112 mark_valid_location_for_stdc_pragma (false);
7113 if (in_omp_loop_block)
7114 check_omp_intervening_code (parser);
7115 c_parser_label (parser, std_attrs);
7117 else if (c_parser_next_tokens_start_declaration (parser)
7118 || (have_std_attrs
7119 && !c_parser_handle_statement_omp_attributes
7120 (parser, std_attrs, &have_std_attrs)
7121 && c_parser_next_token_is (parser, CPP_SEMICOLON)
7122 && (have_std_attrs = true)))
7124 if (last_label)
7125 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
7126 "a label can only be part of a statement and "
7127 "a declaration is not a statement");
7128 /* It's unlikely we'll see a nested loop in a declaration in
7129 intervening code in an OMP loop, but disallow it anyway. */
7130 if (in_omp_loop_block)
7132 check_omp_intervening_code (parser);
7133 omp_for_parse_state->want_nested_loop = false;
7135 mark_valid_location_for_stdc_pragma (false);
7136 bool fallthru_attr_p = false;
7137 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
7138 true, true, true, NULL,
7139 NULL, have_std_attrs, std_attrs,
7140 NULL, &fallthru_attr_p);
7142 if (in_omp_loop_block)
7143 omp_for_parse_state->want_nested_loop = want_nested_loop;
7144 if (last_stmt && !fallthru_attr_p)
7145 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
7146 "ISO C90 forbids mixed declarations and code");
7147 last_stmt = fallthru_attr_p;
7148 last_label = false;
7150 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
7152 /* __extension__ can start a declaration, but is also an
7153 unary operator that can start an expression. Consume all
7154 but the last of a possible series of __extension__ to
7155 determine which. If standard attributes have already
7156 been seen, it must start a statement, not a declaration,
7157 but standard attributes starting a declaration may appear
7158 after __extension__. */
7159 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
7160 && (c_parser_peek_2nd_token (parser)->keyword
7161 == RID_EXTENSION))
7162 c_parser_consume_token (parser);
7163 if (!have_std_attrs
7164 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
7165 || c_parser_nth_token_starts_std_attributes (parser, 2)))
7167 int ext;
7168 ext = disable_extension_diagnostics ();
7169 c_parser_consume_token (parser);
7170 last_label = false;
7171 /* It's unlikely we'll see a nested loop in a declaration in
7172 intervening code in an OMP loop, but disallow it anyway. */
7173 if (in_omp_loop_block)
7175 check_omp_intervening_code (parser);
7176 omp_for_parse_state->want_nested_loop = false;
7178 mark_valid_location_for_stdc_pragma (false);
7179 c_parser_declaration_or_fndef (parser, true, true, true, true,
7180 true);
7181 if (in_omp_loop_block)
7182 omp_for_parse_state->want_nested_loop = want_nested_loop;
7183 /* Following the old parser, __extension__ does not
7184 disable this diagnostic. */
7185 restore_extension_diagnostics (ext);
7186 if (last_stmt)
7187 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
7188 "ISO C90 forbids mixed declarations and code");
7189 last_stmt = false;
7191 else
7192 goto statement;
7194 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
7196 if (have_std_attrs && !parser->in_omp_attribute_pragma)
7197 c_parser_error (parser, "expected declaration or statement");
7198 else if (std_attrs)
7199 c_warn_unused_attributes (std_attrs);
7200 /* External pragmas, and some omp pragmas, are not associated
7201 with regular c code, and so are not to be considered statements
7202 syntactically. This ensures that the user doesn't put them
7203 places that would turn into syntax errors if the directive
7204 were ignored. */
7205 if (omp_for_parse_state)
7206 omp_for_parse_state->want_nested_loop = false;
7207 if (c_parser_pragma (parser,
7208 last_label ? pragma_stmt : pragma_compound,
7209 NULL))
7211 last_label = false;
7212 last_stmt = true;
7213 if (omp_for_parse_state)
7214 check_omp_intervening_code (parser);
7216 if (omp_for_parse_state)
7217 omp_for_parse_state->want_nested_loop = want_nested_loop;
7219 else if (c_parser_next_token_is (parser, CPP_EOF))
7221 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7222 c_parser_error (parser, "expected declaration or statement");
7223 return c_parser_peek_token (parser)->location;
7225 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
7227 if (parser->in_if_block)
7229 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7230 error_at (loc, "expected %<}%> before %<else%>");
7231 return c_parser_peek_token (parser)->location;
7233 else
7235 error_at (loc, "%<else%> without a previous %<if%>");
7236 c_parser_consume_token (parser);
7237 continue;
7240 else
7242 statement:
7243 c_warn_unused_attributes (std_attrs);
7244 last_label = false;
7245 last_stmt = true;
7246 mark_valid_location_for_stdc_pragma (false);
7247 if (!omp_for_parse_state)
7248 c_parser_statement_after_labels (parser, NULL);
7249 else
7251 /* In canonical loop nest form, nested loops can only appear
7252 directly, or in a directly nested compound statement. We
7253 already took care of those cases above, so now we have
7254 something else. This statement and everything inside
7255 it must be intervening code. */
7256 omp_for_parse_state->want_nested_loop = false;
7257 check_omp_intervening_code (parser);
7258 c_parser_statement_after_labels (parser, NULL);
7259 omp_for_parse_state->want_nested_loop = want_nested_loop;
7263 parser->error = false;
7265 if (last_label)
7266 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
7267 location_t endloc = c_parser_peek_token (parser)->location;
7268 c_parser_consume_token (parser);
7270 /* Restore the value we started with. */
7271 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7273 /* Package leftover intervening code, or the whole contents of the
7274 compound statement if we were looking for a nested loop in an OMP_FOR
7275 construct and didn't find one. */
7276 if (sl)
7278 sl = pop_stmt_list (sl);
7279 if (omp_for_parse_state->want_nested_loop)
7280 add_stmt (sl);
7281 else
7282 add_structured_block_stmt (sl);
7284 return endloc;
7287 /* Parse all consecutive labels, possibly preceded by standard
7288 attributes. In this context, a statement is required, not a
7289 declaration, so attributes must be followed by a statement that is
7290 not just a semicolon. */
7292 static void
7293 c_parser_all_labels (c_parser *parser)
7295 bool have_std_attrs;
7296 tree std_attrs = NULL;
7297 if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1)))
7298 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7299 while (c_parser_next_token_is_keyword (parser, RID_CASE)
7300 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
7301 || (c_parser_next_token_is (parser, CPP_NAME)
7302 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
7304 c_parser_label (parser, std_attrs);
7305 std_attrs = NULL;
7306 if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser,
7307 1)))
7308 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7310 if (std_attrs
7311 && (!c_parser_handle_statement_omp_attributes (parser, std_attrs, &have_std_attrs)
7312 || std_attrs))
7314 if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
7315 c_parser_error (parser, "expected statement");
7316 c_warn_unused_attributes (std_attrs);
7318 else if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
7319 c_parser_error (parser, "expected statement");
7322 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
7324 label:
7325 identifier : gnu-attributes[opt]
7326 case constant-expression :
7327 default :
7329 GNU extensions:
7331 label:
7332 case constant-expression ... constant-expression :
7334 The use of gnu-attributes on labels is a GNU extension. The syntax in
7335 GNU C accepts any expressions without commas, non-constant
7336 expressions being rejected later. Any standard
7337 attribute-specifier-sequence before the first label has been parsed
7338 in the caller, to distinguish statements from declarations. Any
7339 attribute-specifier-sequence after the label is parsed in this
7340 function. */
7341 static void
7342 c_parser_label (c_parser *parser, tree std_attrs)
7344 location_t loc1 = c_parser_peek_token (parser)->location;
7345 tree label = NULL_TREE;
7347 /* Remember whether this case or a user-defined label is allowed to fall
7348 through to. */
7349 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
7351 if (c_parser_next_token_is_keyword (parser, RID_CASE))
7353 tree exp1, exp2;
7354 c_parser_consume_token (parser);
7355 exp1 = convert_lvalue_to_rvalue (loc1,
7356 c_parser_expr_no_commas (parser, NULL),
7357 true, true).value;
7358 if (c_parser_next_token_is (parser, CPP_COLON))
7360 c_parser_consume_token (parser);
7361 label = do_case (loc1, exp1, NULL_TREE, std_attrs);
7363 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
7365 c_parser_consume_token (parser);
7366 exp2 = convert_lvalue_to_rvalue (loc1,
7367 c_parser_expr_no_commas (parser,
7368 NULL),
7369 true, true).value;
7370 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7371 label = do_case (loc1, exp1, exp2, std_attrs);
7373 else
7374 c_parser_error (parser, "expected %<:%> or %<...%>");
7376 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
7378 c_parser_consume_token (parser);
7379 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7380 label = do_case (loc1, NULL_TREE, NULL_TREE, std_attrs);
7382 else
7384 tree name = c_parser_peek_token (parser)->value;
7385 tree tlab;
7386 tree attrs;
7387 location_t loc2 = c_parser_peek_token (parser)->location;
7388 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
7389 c_parser_consume_token (parser);
7390 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
7391 c_parser_consume_token (parser);
7392 attrs = c_parser_gnu_attributes (parser);
7393 tlab = define_label (loc2, name);
7394 if (tlab)
7396 decl_attributes (&tlab, attrs, 0);
7397 decl_attributes (&tlab, std_attrs, 0);
7398 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
7400 if (attrs
7401 && c_parser_next_tokens_start_declaration (parser))
7402 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
7403 " label and declaration appertains to the label");
7405 if (label)
7407 if (TREE_CODE (label) == LABEL_EXPR)
7408 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
7409 else
7410 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
7414 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
7416 statement:
7417 labeled-statement
7418 attribute-specifier-sequence[opt] compound-statement
7419 expression-statement
7420 attribute-specifier-sequence[opt] selection-statement
7421 attribute-specifier-sequence[opt] iteration-statement
7422 attribute-specifier-sequence[opt] jump-statement
7424 labeled-statement:
7425 attribute-specifier-sequence[opt] label statement
7427 expression-statement:
7428 expression[opt] ;
7429 attribute-specifier-sequence expression ;
7431 selection-statement:
7432 if-statement
7433 switch-statement
7435 iteration-statement:
7436 while-statement
7437 do-statement
7438 for-statement
7440 jump-statement:
7441 goto identifier ;
7442 continue ;
7443 break ;
7444 return expression[opt] ;
7446 GNU extensions:
7448 statement:
7449 attribute-specifier-sequence[opt] asm-statement
7451 jump-statement:
7452 goto * expression ;
7454 expression-statement:
7455 gnu-attributes ;
7457 Objective-C:
7459 statement:
7460 attribute-specifier-sequence[opt] objc-throw-statement
7461 attribute-specifier-sequence[opt] objc-try-catch-statement
7462 attribute-specifier-sequence[opt] objc-synchronized-statement
7464 objc-throw-statement:
7465 @throw expression ;
7466 @throw ;
7468 OpenACC:
7470 statement:
7471 attribute-specifier-sequence[opt] openacc-construct
7473 openacc-construct:
7474 parallel-construct
7475 kernels-construct
7476 data-construct
7477 loop-construct
7479 parallel-construct:
7480 parallel-directive structured-block
7482 kernels-construct:
7483 kernels-directive structured-block
7485 data-construct:
7486 data-directive structured-block
7488 loop-construct:
7489 loop-directive structured-block
7491 OpenMP:
7493 statement:
7494 attribute-specifier-sequence[opt] openmp-construct
7496 openmp-construct:
7497 parallel-construct
7498 for-construct
7499 simd-construct
7500 for-simd-construct
7501 sections-construct
7502 single-construct
7503 parallel-for-construct
7504 parallel-for-simd-construct
7505 parallel-sections-construct
7506 master-construct
7507 critical-construct
7508 atomic-construct
7509 ordered-construct
7511 parallel-construct:
7512 parallel-directive structured-block
7514 for-construct:
7515 for-directive iteration-statement
7517 simd-construct:
7518 simd-directive iteration-statements
7520 for-simd-construct:
7521 for-simd-directive iteration-statements
7523 sections-construct:
7524 sections-directive section-scope
7526 single-construct:
7527 single-directive structured-block
7529 parallel-for-construct:
7530 parallel-for-directive iteration-statement
7532 parallel-for-simd-construct:
7533 parallel-for-simd-directive iteration-statement
7535 parallel-sections-construct:
7536 parallel-sections-directive section-scope
7538 master-construct:
7539 master-directive structured-block
7541 critical-construct:
7542 critical-directive structured-block
7544 atomic-construct:
7545 atomic-directive expression-statement
7547 ordered-construct:
7548 ordered-directive structured-block
7550 Transactional Memory:
7552 statement:
7553 attribute-specifier-sequence[opt] transaction-statement
7554 attribute-specifier-sequence[opt] transaction-cancel-statement
7556 IF_P is used to track whether there's a (possibly labeled) if statement
7557 which is not enclosed in braces and has an else clause. This is used to
7558 implement -Wparentheses. */
7560 static void
7561 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
7563 c_parser_all_labels (parser);
7564 if (loc_after_labels)
7565 *loc_after_labels = c_parser_peek_token (parser)->location;
7566 parser->omp_attrs_forbidden_p = false;
7567 c_parser_statement_after_labels (parser, if_p, NULL);
7570 /* Parse a statement, other than a labeled statement. CHAIN is a vector
7571 of if-else-if conditions. All labels and standard attributes have
7572 been parsed in the caller.
7574 IF_P is used to track whether there's a (possibly labeled) if statement
7575 which is not enclosed in braces and has an else clause. This is used to
7576 implement -Wparentheses. */
7578 static void
7579 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
7580 vec<tree> *chain)
7582 location_t loc = c_parser_peek_token (parser)->location;
7583 tree stmt = NULL_TREE;
7584 bool in_if_block = parser->in_if_block;
7585 parser->in_if_block = false;
7586 if (if_p != NULL)
7587 *if_p = false;
7589 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
7590 add_debug_begin_stmt (loc);
7592 restart:
7593 switch (c_parser_peek_token (parser)->type)
7595 case CPP_OPEN_BRACE:
7596 add_stmt (c_parser_compound_statement (parser));
7597 break;
7598 case CPP_KEYWORD:
7599 switch (c_parser_peek_token (parser)->keyword)
7601 case RID_IF:
7602 c_parser_if_statement (parser, if_p, chain);
7603 break;
7604 case RID_SWITCH:
7605 c_parser_switch_statement (parser, if_p);
7606 break;
7607 case RID_WHILE:
7608 c_parser_while_statement (parser, false, 0, false, if_p);
7609 break;
7610 case RID_DO:
7611 c_parser_do_statement (parser, false, 0, false);
7612 break;
7613 case RID_FOR:
7614 c_parser_for_statement (parser, false, 0, false, if_p);
7615 break;
7616 case RID_GOTO:
7617 c_parser_consume_token (parser);
7618 if (c_parser_next_token_is (parser, CPP_NAME))
7620 stmt = c_finish_goto_label (loc,
7621 c_parser_peek_token (parser)->value);
7622 c_parser_consume_token (parser);
7624 else if (c_parser_next_token_is (parser, CPP_MULT))
7626 struct c_expr val;
7628 c_parser_consume_token (parser);
7629 val = c_parser_expression (parser);
7630 val = convert_lvalue_to_rvalue (loc, val, false, true);
7631 stmt = c_finish_goto_ptr (loc, val);
7633 else
7634 c_parser_error (parser, "expected identifier or %<*%>");
7635 goto expect_semicolon;
7636 case RID_CONTINUE:
7637 c_parser_consume_token (parser);
7638 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
7639 goto expect_semicolon;
7640 case RID_BREAK:
7641 c_parser_consume_token (parser);
7642 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
7643 goto expect_semicolon;
7644 case RID_RETURN:
7645 c_parser_consume_token (parser);
7646 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7648 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
7649 c_parser_consume_token (parser);
7651 else
7653 location_t xloc = c_parser_peek_token (parser)->location;
7654 struct c_expr expr = c_parser_expression_conv (parser);
7655 mark_exp_read (expr.value);
7656 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
7657 expr.value, expr.original_type);
7658 goto expect_semicolon;
7660 break;
7661 case RID_ASM:
7662 stmt = c_parser_asm_statement (parser);
7663 break;
7664 case RID_TRANSACTION_ATOMIC:
7665 case RID_TRANSACTION_RELAXED:
7666 stmt = c_parser_transaction (parser,
7667 c_parser_peek_token (parser)->keyword);
7668 break;
7669 case RID_TRANSACTION_CANCEL:
7670 stmt = c_parser_transaction_cancel (parser);
7671 goto expect_semicolon;
7672 case RID_AT_THROW:
7673 gcc_assert (c_dialect_objc ());
7674 c_parser_consume_token (parser);
7675 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7677 stmt = objc_build_throw_stmt (loc, NULL_TREE);
7678 c_parser_consume_token (parser);
7680 else
7682 struct c_expr expr = c_parser_expression (parser);
7683 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
7684 expr.value = c_fully_fold (expr.value, false, NULL);
7685 stmt = objc_build_throw_stmt (loc, expr.value);
7686 goto expect_semicolon;
7688 break;
7689 case RID_AT_TRY:
7690 gcc_assert (c_dialect_objc ());
7691 c_parser_objc_try_catch_finally_statement (parser);
7692 break;
7693 case RID_AT_SYNCHRONIZED:
7694 gcc_assert (c_dialect_objc ());
7695 c_parser_objc_synchronized_statement (parser);
7696 break;
7697 case RID_ATTRIBUTE:
7699 /* Allow '__attribute__((fallthrough));' or
7700 '__attribute__((assume(cond)));'. */
7701 tree attrs = c_parser_gnu_attributes (parser);
7702 bool has_assume = lookup_attribute ("assume", attrs);
7703 if (has_assume)
7705 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7706 attrs = handle_assume_attribute (loc, attrs, true);
7707 else
7709 warning_at (loc, OPT_Wattributes,
7710 "%<assume%> attribute not followed by %<;%>");
7711 has_assume = false;
7714 if (attribute_fallthrough_p (attrs))
7716 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7718 tree fn = build_call_expr_internal_loc (loc,
7719 IFN_FALLTHROUGH,
7720 void_type_node, 0);
7721 add_stmt (fn);
7722 /* Eat the ';'. */
7723 c_parser_consume_token (parser);
7725 else
7726 warning_at (loc, OPT_Wattributes,
7727 "%<fallthrough%> attribute not followed "
7728 "by %<;%>");
7730 else if (has_assume)
7731 /* Eat the ';'. */
7732 c_parser_consume_token (parser);
7733 else if (attrs != NULL_TREE)
7734 warning_at (loc, OPT_Wattributes,
7735 "only attribute %<fallthrough%> or %<assume%> can "
7736 "be applied to a null statement");
7737 break;
7739 default:
7740 goto expr_stmt;
7742 break;
7743 case CPP_SEMICOLON:
7744 c_parser_consume_token (parser);
7745 break;
7746 case CPP_CLOSE_PAREN:
7747 case CPP_CLOSE_SQUARE:
7748 /* Avoid infinite loop in error recovery:
7749 c_parser_skip_until_found stops at a closing nesting
7750 delimiter without consuming it, but here we need to consume
7751 it to proceed further. */
7752 c_parser_error (parser, "expected statement");
7753 c_parser_consume_token (parser);
7754 break;
7755 case CPP_PRAGMA:
7756 if (!c_parser_pragma (parser, pragma_stmt, if_p))
7757 goto restart;
7758 break;
7759 default:
7760 expr_stmt:
7761 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
7762 expect_semicolon:
7763 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7764 break;
7766 /* Two cases cannot and do not have line numbers associated: If stmt
7767 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
7768 cannot hold line numbers. But that's OK because the statement
7769 will either be changed to a MODIFY_EXPR during gimplification of
7770 the statement expr, or discarded. If stmt was compound, but
7771 without new variables, we will have skipped the creation of a
7772 BIND and will have a bare STATEMENT_LIST. But that's OK because
7773 (recursively) all of the component statements should already have
7774 line numbers assigned. ??? Can we discard no-op statements
7775 earlier? */
7776 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
7777 protected_set_expr_location (stmt, loc);
7779 parser->in_if_block = in_if_block;
7782 /* Parse the condition from an if, do, while or for statements. */
7784 static tree
7785 c_parser_condition (c_parser *parser)
7787 location_t loc = c_parser_peek_token (parser)->location;
7788 tree cond;
7789 cond = c_parser_expression_conv (parser).value;
7790 cond = c_objc_common_truthvalue_conversion (loc, cond);
7791 cond = c_fully_fold (cond, false, NULL);
7792 if (warn_sequence_point)
7793 verify_sequence_points (cond);
7794 return cond;
7797 /* Parse a parenthesized condition from an if, do or while statement.
7799 condition:
7800 ( expression )
7802 static tree
7803 c_parser_paren_condition (c_parser *parser)
7805 tree cond;
7806 matching_parens parens;
7807 if (!parens.require_open (parser))
7808 return error_mark_node;
7809 cond = c_parser_condition (parser);
7810 parens.skip_until_found_close (parser);
7811 return cond;
7814 /* Parse a statement which is a block in C99.
7816 IF_P is used to track whether there's a (possibly labeled) if statement
7817 which is not enclosed in braces and has an else clause. This is used to
7818 implement -Wparentheses. */
7820 static tree
7821 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
7822 location_t *loc_after_labels)
7824 tree block = c_begin_compound_stmt (flag_isoc99);
7825 location_t loc = c_parser_peek_token (parser)->location;
7826 c_parser_statement (parser, if_p, loc_after_labels);
7827 return c_end_compound_stmt (loc, block, flag_isoc99);
7830 /* Parse the body of an if statement. This is just parsing a
7831 statement but (a) it is a block in C99, (b) we track whether the
7832 body is an if statement for the sake of -Wparentheses warnings, (c)
7833 we handle an empty body specially for the sake of -Wempty-body
7834 warnings, and (d) we call parser_compound_statement directly
7835 because c_parser_statement_after_labels resets
7836 parser->in_if_block.
7838 IF_P is used to track whether there's a (possibly labeled) if statement
7839 which is not enclosed in braces and has an else clause. This is used to
7840 implement -Wparentheses. */
7842 static tree
7843 c_parser_if_body (c_parser *parser, bool *if_p,
7844 const token_indent_info &if_tinfo)
7846 tree block = c_begin_compound_stmt (flag_isoc99);
7847 location_t body_loc = c_parser_peek_token (parser)->location;
7848 location_t body_loc_after_labels = UNKNOWN_LOCATION;
7849 token_indent_info body_tinfo
7850 = get_token_indent_info (c_parser_peek_token (parser));
7852 c_parser_all_labels (parser);
7853 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7855 location_t loc = c_parser_peek_token (parser)->location;
7856 add_stmt (build_empty_stmt (loc));
7857 c_parser_consume_token (parser);
7858 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
7859 warning_at (loc, OPT_Wempty_body,
7860 "suggest braces around empty body in an %<if%> statement");
7862 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7863 add_stmt (c_parser_compound_statement (parser));
7864 else
7866 body_loc_after_labels = c_parser_peek_token (parser)->location;
7867 c_parser_statement_after_labels (parser, if_p);
7870 token_indent_info next_tinfo
7871 = get_token_indent_info (c_parser_peek_token (parser));
7872 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
7873 if (body_loc_after_labels != UNKNOWN_LOCATION
7874 && next_tinfo.type != CPP_SEMICOLON)
7875 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
7876 if_tinfo.location, RID_IF);
7878 return c_end_compound_stmt (body_loc, block, flag_isoc99);
7881 /* Parse the else body of an if statement. This is just parsing a
7882 statement but (a) it is a block in C99, (b) we handle an empty body
7883 specially for the sake of -Wempty-body warnings. CHAIN is a vector
7884 of if-else-if conditions. */
7886 static tree
7887 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
7888 vec<tree> *chain)
7890 location_t body_loc = c_parser_peek_token (parser)->location;
7891 tree block = c_begin_compound_stmt (flag_isoc99);
7892 token_indent_info body_tinfo
7893 = get_token_indent_info (c_parser_peek_token (parser));
7894 location_t body_loc_after_labels = UNKNOWN_LOCATION;
7896 c_parser_all_labels (parser);
7897 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7899 location_t loc = c_parser_peek_token (parser)->location;
7900 warning_at (loc,
7901 OPT_Wempty_body,
7902 "suggest braces around empty body in an %<else%> statement");
7903 add_stmt (build_empty_stmt (loc));
7904 c_parser_consume_token (parser);
7906 else
7908 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7909 body_loc_after_labels = c_parser_peek_token (parser)->location;
7910 c_parser_statement_after_labels (parser, NULL, chain);
7913 token_indent_info next_tinfo
7914 = get_token_indent_info (c_parser_peek_token (parser));
7915 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
7916 if (body_loc_after_labels != UNKNOWN_LOCATION
7917 && next_tinfo.type != CPP_SEMICOLON)
7918 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
7919 else_tinfo.location, RID_ELSE);
7921 return c_end_compound_stmt (body_loc, block, flag_isoc99);
7924 /* We might need to reclassify any previously-lexed identifier, e.g.
7925 when we've left a for loop with an if-statement without else in the
7926 body - we might have used a wrong scope for the token. See PR67784. */
7928 static void
7929 c_parser_maybe_reclassify_token (c_parser *parser)
7931 if (c_parser_next_token_is (parser, CPP_NAME))
7933 c_token *token = c_parser_peek_token (parser);
7935 if (token->id_kind != C_ID_CLASSNAME)
7937 tree decl = lookup_name (token->value);
7939 token->id_kind = C_ID_ID;
7940 if (decl)
7942 if (TREE_CODE (decl) == TYPE_DECL)
7943 token->id_kind = C_ID_TYPENAME;
7945 else if (c_dialect_objc ())
7947 tree objc_interface_decl = objc_is_class_name (token->value);
7948 /* Objective-C class names are in the same namespace as
7949 variables and typedefs, and hence are shadowed by local
7950 declarations. */
7951 if (objc_interface_decl)
7953 token->value = objc_interface_decl;
7954 token->id_kind = C_ID_CLASSNAME;
7961 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
7963 if-statement:
7964 if ( expression ) statement
7965 if ( expression ) statement else statement
7967 CHAIN is a vector of if-else-if conditions.
7968 IF_P is used to track whether there's a (possibly labeled) if statement
7969 which is not enclosed in braces and has an else clause. This is used to
7970 implement -Wparentheses. */
7972 static void
7973 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
7975 tree block;
7976 location_t loc;
7977 tree cond;
7978 bool nested_if = false;
7979 tree first_body, second_body;
7980 bool in_if_block;
7982 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
7983 token_indent_info if_tinfo
7984 = get_token_indent_info (c_parser_peek_token (parser));
7985 c_parser_consume_token (parser);
7986 block = c_begin_compound_stmt (flag_isoc99);
7987 loc = c_parser_peek_token (parser)->location;
7988 cond = c_parser_paren_condition (parser);
7989 in_if_block = parser->in_if_block;
7990 parser->in_if_block = true;
7991 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
7992 parser->in_if_block = in_if_block;
7994 if (warn_duplicated_cond)
7995 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
7997 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
7999 token_indent_info else_tinfo
8000 = get_token_indent_info (c_parser_peek_token (parser));
8001 c_parser_consume_token (parser);
8002 if (warn_duplicated_cond)
8004 if (c_parser_next_token_is_keyword (parser, RID_IF)
8005 && chain == NULL)
8007 /* We've got "if (COND) else if (COND2)". Start the
8008 condition chain and add COND as the first element. */
8009 chain = new vec<tree> ();
8010 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
8011 chain->safe_push (cond);
8013 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
8014 /* This is if-else without subsequent if. Zap the condition
8015 chain; we would have already warned at this point. */
8016 vec_free (chain);
8018 second_body = c_parser_else_body (parser, else_tinfo, chain);
8019 /* Set IF_P to true to indicate that this if statement has an
8020 else clause. This may trigger the Wparentheses warning
8021 below when we get back up to the parent if statement. */
8022 if (if_p != NULL)
8023 *if_p = true;
8025 else
8027 second_body = NULL_TREE;
8029 /* Diagnose an ambiguous else if if-then-else is nested inside
8030 if-then. */
8031 if (nested_if)
8032 warning_at (loc, OPT_Wdangling_else,
8033 "suggest explicit braces to avoid ambiguous %<else%>");
8035 if (warn_duplicated_cond)
8036 /* This if statement does not have an else clause. We don't
8037 need the condition chain anymore. */
8038 vec_free (chain);
8040 c_finish_if_stmt (loc, cond, first_body, second_body);
8041 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8043 c_parser_maybe_reclassify_token (parser);
8046 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8048 switch-statement:
8049 switch (expression) statement
8052 static void
8053 c_parser_switch_statement (c_parser *parser, bool *if_p)
8055 struct c_expr ce;
8056 tree block, expr, body;
8057 unsigned char save_in_statement;
8058 location_t switch_loc = c_parser_peek_token (parser)->location;
8059 location_t switch_cond_loc;
8060 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
8061 c_parser_consume_token (parser);
8062 block = c_begin_compound_stmt (flag_isoc99);
8063 bool explicit_cast_p = false;
8064 matching_parens parens;
8065 if (parens.require_open (parser))
8067 switch_cond_loc = c_parser_peek_token (parser)->location;
8068 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8069 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8070 explicit_cast_p = true;
8071 ce = c_parser_expression (parser);
8072 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
8073 expr = ce.value;
8074 /* ??? expr has no valid location? */
8075 parens.skip_until_found_close (parser);
8077 else
8079 switch_cond_loc = UNKNOWN_LOCATION;
8080 expr = error_mark_node;
8081 ce.original_type = error_mark_node;
8083 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
8084 save_in_statement = in_statement;
8085 in_statement |= IN_SWITCH_STMT;
8086 location_t loc_after_labels;
8087 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
8088 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8089 location_t next_loc = c_parser_peek_token (parser)->location;
8090 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
8091 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
8092 RID_SWITCH);
8093 c_finish_switch (body, ce.original_type);
8094 in_statement = save_in_statement;
8095 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
8096 c_parser_maybe_reclassify_token (parser);
8099 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8101 while-statement:
8102 while (expression) statement
8104 IF_P is used to track whether there's a (possibly labeled) if statement
8105 which is not enclosed in braces and has an else clause. This is used to
8106 implement -Wparentheses. */
8108 static void
8109 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8110 bool novector, bool *if_p)
8112 tree block, cond, body;
8113 unsigned char save_in_statement;
8114 location_t loc;
8115 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
8116 token_indent_info while_tinfo
8117 = get_token_indent_info (c_parser_peek_token (parser));
8119 if (parser->omp_for_parse_state)
8121 error_at (c_parser_peek_token (parser)->location,
8122 "loop not permitted in intervening code in OpenMP loop body");
8123 parser->omp_for_parse_state->fail = true;
8126 c_parser_consume_token (parser);
8127 block = c_begin_compound_stmt (flag_isoc99);
8128 loc = c_parser_peek_token (parser)->location;
8129 cond = c_parser_paren_condition (parser);
8130 if (ivdep && cond != error_mark_node)
8131 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8132 build_int_cst (integer_type_node,
8133 annot_expr_ivdep_kind),
8134 integer_zero_node);
8135 if (unroll && cond != error_mark_node)
8136 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8137 build_int_cst (integer_type_node,
8138 annot_expr_unroll_kind),
8139 build_int_cst (integer_type_node, unroll));
8140 if (novector && cond != error_mark_node)
8141 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8142 build_int_cst (integer_type_node,
8143 annot_expr_no_vector_kind),
8144 integer_zero_node);
8145 save_in_statement = in_statement;
8146 in_statement = IN_ITERATION_STMT;
8148 token_indent_info body_tinfo
8149 = get_token_indent_info (c_parser_peek_token (parser));
8151 location_t loc_after_labels;
8152 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
8153 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8154 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
8155 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8156 c_parser_maybe_reclassify_token (parser);
8158 token_indent_info next_tinfo
8159 = get_token_indent_info (c_parser_peek_token (parser));
8160 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
8162 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
8163 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
8164 while_tinfo.location, RID_WHILE);
8166 in_statement = save_in_statement;
8169 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8171 do-statement:
8172 do statement while ( expression ) ;
8175 static void
8176 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8177 bool novector)
8179 tree block, cond, body;
8180 unsigned char save_in_statement;
8181 location_t loc;
8182 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
8184 if (parser->omp_for_parse_state)
8186 error_at (c_parser_peek_token (parser)->location,
8187 "loop not permitted in intervening code in OpenMP loop body");
8188 parser->omp_for_parse_state->fail = true;
8191 c_parser_consume_token (parser);
8192 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8193 warning_at (c_parser_peek_token (parser)->location,
8194 OPT_Wempty_body,
8195 "suggest braces around empty body in %<do%> statement");
8196 block = c_begin_compound_stmt (flag_isoc99);
8197 loc = c_parser_peek_token (parser)->location;
8198 save_in_statement = in_statement;
8199 in_statement = IN_ITERATION_STMT;
8200 body = c_parser_c99_block_statement (parser, NULL);
8201 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
8202 in_statement = save_in_statement;
8203 cond = c_parser_paren_condition (parser);
8204 if (ivdep && cond != error_mark_node)
8205 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8206 build_int_cst (integer_type_node,
8207 annot_expr_ivdep_kind),
8208 integer_zero_node);
8209 if (unroll && cond != error_mark_node)
8210 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8211 build_int_cst (integer_type_node,
8212 annot_expr_unroll_kind),
8213 build_int_cst (integer_type_node, unroll));
8214 if (novector && cond != error_mark_node)
8215 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8216 build_int_cst (integer_type_node,
8217 annot_expr_no_vector_kind),
8218 integer_zero_node);
8219 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
8220 c_parser_skip_to_end_of_block_or_statement (parser);
8222 add_stmt (build_stmt (loc, DO_STMT, cond, body));
8223 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8226 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8228 for-statement:
8229 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
8230 for ( nested-declaration expression[opt] ; expression[opt] ) statement
8232 The form with a declaration is new in C99.
8234 ??? In accordance with the old parser, the declaration may be a
8235 nested function, which is then rejected in check_for_loop_decls,
8236 but does it make any sense for this to be included in the grammar?
8237 Note in particular that the nested function does not include a
8238 trailing ';', whereas the "declaration" production includes one.
8239 Also, can we reject bad declarations earlier and cheaper than
8240 check_for_loop_decls?
8242 In Objective-C, there are two additional variants:
8244 foreach-statement:
8245 for ( expression in expresssion ) statement
8246 for ( declaration in expression ) statement
8248 This is inconsistent with C, because the second variant is allowed
8249 even if c99 is not enabled.
8251 The rest of the comment documents these Objective-C foreach-statement.
8253 Here is the canonical example of the first variant:
8254 for (object in array) { do something with object }
8255 we call the first expression ("object") the "object_expression" and
8256 the second expression ("array") the "collection_expression".
8257 object_expression must be an lvalue of type "id" (a generic Objective-C
8258 object) because the loop works by assigning to object_expression the
8259 various objects from the collection_expression. collection_expression
8260 must evaluate to something of type "id" which responds to the method
8261 countByEnumeratingWithState:objects:count:.
8263 The canonical example of the second variant is:
8264 for (id object in array) { do something with object }
8265 which is completely equivalent to
8267 id object;
8268 for (object in array) { do something with object }
8270 Note that initizializing 'object' in some way (eg, "for ((object =
8271 xxx) in array) { do something with object }") is possibly
8272 technically valid, but completely pointless as 'object' will be
8273 assigned to something else as soon as the loop starts. We should
8274 most likely reject it (TODO).
8276 The beginning of the Objective-C foreach-statement looks exactly
8277 like the beginning of the for-statement, and we can tell it is a
8278 foreach-statement only because the initial declaration or
8279 expression is terminated by 'in' instead of ';'.
8281 IF_P is used to track whether there's a (possibly labeled) if statement
8282 which is not enclosed in braces and has an else clause. This is used to
8283 implement -Wparentheses. */
8285 static void
8286 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8287 bool novector, bool *if_p)
8289 tree block, cond, incr, body;
8290 unsigned char save_in_statement;
8291 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
8292 /* The following are only used when parsing an ObjC foreach statement. */
8293 tree object_expression;
8294 /* Silence the bogus uninitialized warning. */
8295 tree collection_expression = NULL;
8296 location_t loc = c_parser_peek_token (parser)->location;
8297 location_t for_loc = loc;
8298 bool is_foreach_statement = false;
8299 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
8300 token_indent_info for_tinfo
8301 = get_token_indent_info (c_parser_peek_token (parser));
8303 if (parser->omp_for_parse_state)
8305 error_at (for_loc,
8306 "loop not permitted in intervening code in OpenMP loop body");
8307 parser->omp_for_parse_state->fail = true;
8310 c_parser_consume_token (parser);
8311 /* Open a compound statement in Objective-C as well, just in case this is
8312 as foreach expression. */
8313 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
8314 cond = error_mark_node;
8315 incr = error_mark_node;
8316 matching_parens parens;
8317 if (parens.require_open (parser))
8319 /* Parse the initialization declaration or expression. */
8320 object_expression = error_mark_node;
8321 parser->objc_could_be_foreach_context = c_dialect_objc ();
8322 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8324 parser->objc_could_be_foreach_context = false;
8325 c_parser_consume_token (parser);
8326 c_finish_expr_stmt (loc, NULL_TREE);
8328 else if (c_parser_next_tokens_start_declaration (parser)
8329 || c_parser_nth_token_starts_std_attributes (parser, 1))
8331 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
8332 &object_expression);
8333 parser->objc_could_be_foreach_context = false;
8335 if (c_parser_next_token_is_keyword (parser, RID_IN))
8337 c_parser_consume_token (parser);
8338 is_foreach_statement = true;
8339 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
8340 c_parser_error (parser, "multiple iterating variables in "
8341 "fast enumeration");
8343 else
8344 check_for_loop_decls (for_loc, flag_isoc99);
8346 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
8348 /* __extension__ can start a declaration, but is also an
8349 unary operator that can start an expression. Consume all
8350 but the last of a possible series of __extension__ to
8351 determine which. */
8352 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
8353 && (c_parser_peek_2nd_token (parser)->keyword
8354 == RID_EXTENSION))
8355 c_parser_consume_token (parser);
8356 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
8357 || c_parser_nth_token_starts_std_attributes (parser, 2))
8359 int ext;
8360 ext = disable_extension_diagnostics ();
8361 c_parser_consume_token (parser);
8362 c_parser_declaration_or_fndef (parser, true, true, true, true,
8363 true, &object_expression);
8364 parser->objc_could_be_foreach_context = false;
8366 restore_extension_diagnostics (ext);
8367 if (c_parser_next_token_is_keyword (parser, RID_IN))
8369 c_parser_consume_token (parser);
8370 is_foreach_statement = true;
8371 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
8372 c_parser_error (parser, "multiple iterating variables in "
8373 "fast enumeration");
8375 else
8376 check_for_loop_decls (for_loc, flag_isoc99);
8378 else
8379 goto init_expr;
8381 else
8383 init_expr:
8385 struct c_expr ce;
8386 tree init_expression;
8387 ce = c_parser_expression (parser);
8388 init_expression = ce.value;
8389 parser->objc_could_be_foreach_context = false;
8390 if (c_parser_next_token_is_keyword (parser, RID_IN))
8392 c_parser_consume_token (parser);
8393 is_foreach_statement = true;
8394 if (! lvalue_p (init_expression))
8395 c_parser_error (parser, "invalid iterating variable in "
8396 "fast enumeration");
8397 object_expression
8398 = c_fully_fold (init_expression, false, NULL);
8400 else
8402 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
8403 init_expression = ce.value;
8404 c_finish_expr_stmt (loc, init_expression);
8405 c_parser_skip_until_found (parser, CPP_SEMICOLON,
8406 "expected %<;%>");
8410 /* Parse the loop condition. In the case of a foreach
8411 statement, there is no loop condition. */
8412 gcc_assert (!parser->objc_could_be_foreach_context);
8413 if (!is_foreach_statement)
8415 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8417 if (ivdep)
8419 c_parser_error (parser, "missing loop condition in loop "
8420 "with %<GCC ivdep%> pragma");
8421 cond = error_mark_node;
8423 else if (unroll)
8425 c_parser_error (parser, "missing loop condition in loop "
8426 "with %<GCC unroll%> pragma");
8427 cond = error_mark_node;
8429 else
8431 c_parser_consume_token (parser);
8432 cond = NULL_TREE;
8435 else
8437 cond = c_parser_condition (parser);
8438 c_parser_skip_until_found (parser, CPP_SEMICOLON,
8439 "expected %<;%>");
8441 if (ivdep && cond != error_mark_node)
8442 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8443 build_int_cst (integer_type_node,
8444 annot_expr_ivdep_kind),
8445 integer_zero_node);
8446 if (unroll && cond != error_mark_node)
8447 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8448 build_int_cst (integer_type_node,
8449 annot_expr_unroll_kind),
8450 build_int_cst (integer_type_node, unroll));
8451 if (novector && cond && cond != error_mark_node)
8452 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8453 build_int_cst (integer_type_node,
8454 annot_expr_no_vector_kind),
8455 integer_zero_node);
8457 /* Parse the increment expression (the third expression in a
8458 for-statement). In the case of a foreach-statement, this is
8459 the expression that follows the 'in'. */
8460 loc = c_parser_peek_token (parser)->location;
8461 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8463 if (is_foreach_statement)
8465 c_parser_error (parser,
8466 "missing collection in fast enumeration");
8467 collection_expression = error_mark_node;
8469 else
8470 incr = c_process_expr_stmt (loc, NULL_TREE);
8472 else
8474 if (is_foreach_statement)
8475 collection_expression
8476 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
8477 else
8479 struct c_expr ce = c_parser_expression (parser);
8480 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
8481 incr = c_process_expr_stmt (loc, ce.value);
8484 parens.skip_until_found_close (parser);
8486 save_in_statement = in_statement;
8487 if (is_foreach_statement)
8489 in_statement = IN_OBJC_FOREACH;
8490 save_objc_foreach_break_label = objc_foreach_break_label;
8491 save_objc_foreach_continue_label = objc_foreach_continue_label;
8492 objc_foreach_break_label = create_artificial_label (loc);
8493 objc_foreach_continue_label = create_artificial_label (loc);
8495 else
8496 in_statement = IN_ITERATION_STMT;
8498 token_indent_info body_tinfo
8499 = get_token_indent_info (c_parser_peek_token (parser));
8501 location_t loc_after_labels;
8502 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
8503 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8505 if (is_foreach_statement)
8506 objc_finish_foreach_loop (for_loc, object_expression,
8507 collection_expression, body,
8508 objc_foreach_break_label,
8509 objc_foreach_continue_label);
8510 else
8511 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
8512 body, NULL_TREE));
8513 add_stmt (c_end_compound_stmt (for_loc, block,
8514 flag_isoc99 || c_dialect_objc ()));
8515 c_parser_maybe_reclassify_token (parser);
8517 token_indent_info next_tinfo
8518 = get_token_indent_info (c_parser_peek_token (parser));
8519 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
8521 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
8522 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
8523 for_tinfo.location, RID_FOR);
8525 in_statement = save_in_statement;
8526 if (is_foreach_statement)
8528 objc_foreach_break_label = save_objc_foreach_break_label;
8529 objc_foreach_continue_label = save_objc_foreach_continue_label;
8533 /* Parse an asm statement, a GNU extension. This is a full-blown asm
8534 statement with inputs, outputs, clobbers, and volatile, inline, and goto
8535 tags allowed.
8537 asm-qualifier:
8538 volatile
8539 inline
8540 goto
8542 asm-qualifier-list:
8543 asm-qualifier-list asm-qualifier
8544 asm-qualifier
8546 asm-statement:
8547 asm asm-qualifier-list[opt] ( asm-argument ) ;
8549 asm-argument:
8550 asm-string-literal
8551 asm-string-literal : asm-operands[opt]
8552 asm-string-literal : asm-operands[opt] : asm-operands[opt]
8553 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
8554 : asm-clobbers[opt]
8555 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
8556 : asm-goto-operands
8558 The form with asm-goto-operands is valid if and only if the
8559 asm-qualifier-list contains goto, and is the only allowed form in that case.
8560 Duplicate asm-qualifiers are not allowed.
8562 The :: token is considered equivalent to two consecutive : tokens. */
8564 static tree
8565 c_parser_asm_statement (c_parser *parser)
8567 tree str, outputs, inputs, clobbers, labels, ret;
8568 bool simple;
8569 location_t asm_loc = c_parser_peek_token (parser)->location;
8570 int section, nsections;
8572 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
8573 c_parser_consume_token (parser);
8575 /* Handle the asm-qualifier-list. */
8576 location_t volatile_loc = UNKNOWN_LOCATION;
8577 location_t inline_loc = UNKNOWN_LOCATION;
8578 location_t goto_loc = UNKNOWN_LOCATION;
8579 for (;;)
8581 c_token *token = c_parser_peek_token (parser);
8582 location_t loc = token->location;
8583 switch (token->keyword)
8585 case RID_VOLATILE:
8586 if (volatile_loc)
8588 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8589 inform (volatile_loc, "first seen here");
8591 else
8592 volatile_loc = loc;
8593 c_parser_consume_token (parser);
8594 continue;
8596 case RID_INLINE:
8597 if (inline_loc)
8599 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8600 inform (inline_loc, "first seen here");
8602 else
8603 inline_loc = loc;
8604 c_parser_consume_token (parser);
8605 continue;
8607 case RID_GOTO:
8608 if (goto_loc)
8610 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8611 inform (goto_loc, "first seen here");
8613 else
8614 goto_loc = loc;
8615 c_parser_consume_token (parser);
8616 continue;
8618 case RID_CONST:
8619 case RID_RESTRICT:
8620 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
8621 c_parser_consume_token (parser);
8622 continue;
8624 default:
8625 break;
8627 break;
8630 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
8631 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
8632 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
8634 ret = NULL;
8636 matching_parens parens;
8637 if (!parens.require_open (parser))
8638 goto error;
8640 str = c_parser_asm_string_literal (parser);
8641 if (str == NULL_TREE)
8642 goto error_close_paren;
8644 simple = true;
8645 outputs = NULL_TREE;
8646 inputs = NULL_TREE;
8647 clobbers = NULL_TREE;
8648 labels = NULL_TREE;
8650 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
8651 goto done_asm;
8653 /* Parse each colon-delimited section of operands. */
8654 nsections = 3 + is_goto;
8655 for (section = 0; section < nsections; ++section)
8657 if (c_parser_next_token_is (parser, CPP_SCOPE))
8659 ++section;
8660 if (section == nsections)
8662 c_parser_error (parser, "expected %<)%>");
8663 goto error_close_paren;
8665 c_parser_consume_token (parser);
8667 else if (!c_parser_require (parser, CPP_COLON,
8668 is_goto
8669 ? G_("expected %<:%>")
8670 : G_("expected %<:%> or %<)%>"),
8671 UNKNOWN_LOCATION, is_goto))
8672 goto error_close_paren;
8674 /* Once past any colon, we're no longer a simple asm. */
8675 simple = false;
8677 if ((!c_parser_next_token_is (parser, CPP_COLON)
8678 && !c_parser_next_token_is (parser, CPP_SCOPE)
8679 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8680 || section == 3)
8681 switch (section)
8683 case 0:
8684 outputs = c_parser_asm_operands (parser);
8685 break;
8686 case 1:
8687 inputs = c_parser_asm_operands (parser);
8688 break;
8689 case 2:
8690 clobbers = c_parser_asm_clobbers (parser);
8691 break;
8692 case 3:
8693 labels = c_parser_asm_goto_operands (parser);
8694 break;
8695 default:
8696 gcc_unreachable ();
8699 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
8700 goto done_asm;
8703 done_asm:
8704 if (!parens.require_close (parser))
8706 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8707 goto error;
8710 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
8711 c_parser_skip_to_end_of_block_or_statement (parser);
8713 ret = build_asm_stmt (is_volatile,
8714 build_asm_expr (asm_loc, str, outputs, inputs,
8715 clobbers, labels, simple, is_inline));
8717 error:
8718 return ret;
8720 error_close_paren:
8721 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8722 goto error;
8725 /* Parse asm operands, a GNU extension.
8727 asm-operands:
8728 asm-operand
8729 asm-operands , asm-operand
8731 asm-operand:
8732 asm-string-literal ( expression )
8733 [ identifier ] asm-string-literal ( expression )
8736 static tree
8737 c_parser_asm_operands (c_parser *parser)
8739 tree list = NULL_TREE;
8740 while (true)
8742 tree name, str;
8743 struct c_expr expr;
8744 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
8746 c_parser_consume_token (parser);
8747 if (c_parser_next_token_is (parser, CPP_NAME))
8749 tree id = c_parser_peek_token (parser)->value;
8750 c_parser_consume_token (parser);
8751 name = build_string (IDENTIFIER_LENGTH (id),
8752 IDENTIFIER_POINTER (id));
8754 else
8756 c_parser_error (parser, "expected identifier");
8757 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
8758 return NULL_TREE;
8760 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
8761 "expected %<]%>");
8763 else
8764 name = NULL_TREE;
8765 str = c_parser_asm_string_literal (parser);
8766 if (str == NULL_TREE)
8767 return NULL_TREE;
8768 matching_parens parens;
8769 if (!parens.require_open (parser))
8770 return NULL_TREE;
8771 expr = c_parser_expression (parser);
8772 mark_exp_read (expr.value);
8773 if (!parens.require_close (parser))
8775 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8776 return NULL_TREE;
8778 list = chainon (list, build_tree_list (build_tree_list (name, str),
8779 expr.value));
8780 if (c_parser_next_token_is (parser, CPP_COMMA))
8781 c_parser_consume_token (parser);
8782 else
8783 break;
8785 return list;
8788 /* Parse asm clobbers, a GNU extension.
8790 asm-clobbers:
8791 asm-string-literal
8792 asm-clobbers , asm-string-literal
8795 static tree
8796 c_parser_asm_clobbers (c_parser *parser)
8798 tree list = NULL_TREE;
8799 while (true)
8801 tree str = c_parser_asm_string_literal (parser);
8802 if (str)
8803 list = tree_cons (NULL_TREE, str, list);
8804 else
8805 return NULL_TREE;
8806 if (c_parser_next_token_is (parser, CPP_COMMA))
8807 c_parser_consume_token (parser);
8808 else
8809 break;
8811 return list;
8814 /* Parse asm goto labels, a GNU extension.
8816 asm-goto-operands:
8817 identifier
8818 asm-goto-operands , identifier
8821 static tree
8822 c_parser_asm_goto_operands (c_parser *parser)
8824 tree list = NULL_TREE;
8825 while (true)
8827 tree name, label;
8829 if (c_parser_next_token_is (parser, CPP_NAME))
8831 c_token *tok = c_parser_peek_token (parser);
8832 name = tok->value;
8833 label = lookup_label_for_goto (tok->location, name);
8834 c_parser_consume_token (parser);
8835 TREE_USED (label) = 1;
8837 else
8839 c_parser_error (parser, "expected identifier");
8840 return NULL_TREE;
8843 name = build_string (IDENTIFIER_LENGTH (name),
8844 IDENTIFIER_POINTER (name));
8845 list = tree_cons (name, label, list);
8846 if (c_parser_next_token_is (parser, CPP_COMMA))
8847 c_parser_consume_token (parser);
8848 else
8849 return nreverse (list);
8853 /* Parse a possibly concatenated sequence of string literals.
8854 TRANSLATE says whether to translate them to the execution character
8855 set; WIDE_OK says whether any kind of prefixed string literal is
8856 permitted in this context. This code is based on that in
8857 lex_string. */
8859 struct c_expr
8860 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
8862 struct c_expr ret;
8863 size_t count;
8864 struct obstack str_ob;
8865 struct obstack loc_ob;
8866 cpp_string str, istr, *strs;
8867 c_token *tok;
8868 location_t loc, last_tok_loc;
8869 enum cpp_ttype type;
8870 tree value, string_tree;
8872 tok = c_parser_peek_token (parser);
8873 loc = tok->location;
8874 last_tok_loc = linemap_resolve_location (line_table, loc,
8875 LRK_MACRO_DEFINITION_LOCATION,
8876 NULL);
8877 type = tok->type;
8878 switch (type)
8880 case CPP_STRING:
8881 case CPP_WSTRING:
8882 case CPP_STRING16:
8883 case CPP_STRING32:
8884 case CPP_UTF8STRING:
8885 string_tree = tok->value;
8886 break;
8888 default:
8889 c_parser_error (parser, "expected string literal");
8890 ret.set_error ();
8891 ret.value = NULL_TREE;
8892 ret.original_code = ERROR_MARK;
8893 ret.original_type = NULL_TREE;
8894 return ret;
8897 /* Try to avoid the overhead of creating and destroying an obstack
8898 for the common case of just one string. */
8899 switch (c_parser_peek_2nd_token (parser)->type)
8901 default:
8902 c_parser_consume_token (parser);
8903 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
8904 str.len = TREE_STRING_LENGTH (string_tree);
8905 count = 1;
8906 strs = &str;
8907 break;
8909 case CPP_STRING:
8910 case CPP_WSTRING:
8911 case CPP_STRING16:
8912 case CPP_STRING32:
8913 case CPP_UTF8STRING:
8914 gcc_obstack_init (&str_ob);
8915 gcc_obstack_init (&loc_ob);
8916 count = 0;
8919 c_parser_consume_token (parser);
8920 count++;
8921 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
8922 str.len = TREE_STRING_LENGTH (string_tree);
8923 if (type != tok->type)
8925 if (type == CPP_STRING)
8926 type = tok->type;
8927 else if (tok->type != CPP_STRING)
8928 error ("unsupported non-standard concatenation "
8929 "of string literals");
8931 obstack_grow (&str_ob, &str, sizeof (cpp_string));
8932 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
8933 tok = c_parser_peek_token (parser);
8934 string_tree = tok->value;
8935 last_tok_loc
8936 = linemap_resolve_location (line_table, tok->location,
8937 LRK_MACRO_DEFINITION_LOCATION, NULL);
8939 while (tok->type == CPP_STRING
8940 || tok->type == CPP_WSTRING
8941 || tok->type == CPP_STRING16
8942 || tok->type == CPP_STRING32
8943 || tok->type == CPP_UTF8STRING);
8944 strs = (cpp_string *) obstack_finish (&str_ob);
8947 if (count > 1 && !in_system_header_at (input_location))
8948 warning (OPT_Wtraditional,
8949 "traditional C rejects string constant concatenation");
8951 if ((type == CPP_STRING || wide_ok)
8952 && ((translate
8953 ? cpp_interpret_string : cpp_interpret_string_notranslate)
8954 (parse_in, strs, count, &istr, type)))
8956 value = build_string (istr.len, (const char *) istr.text);
8957 free (CONST_CAST (unsigned char *, istr.text));
8958 if (count > 1)
8960 location_t *locs = (location_t *) obstack_finish (&loc_ob);
8961 gcc_assert (g_string_concat_db);
8962 g_string_concat_db->record_string_concatenation (count, locs);
8965 else
8967 if (type != CPP_STRING && !wide_ok)
8969 error_at (loc, "a wide string is invalid in this context");
8970 type = CPP_STRING;
8972 /* Callers cannot generally handle error_mark_node in this
8973 context, so return the empty string instead. An error has
8974 been issued, either above or from cpp_interpret_string. */
8975 switch (type)
8977 default:
8978 case CPP_STRING:
8979 case CPP_UTF8STRING:
8980 if (type == CPP_UTF8STRING && flag_char8_t)
8982 value = build_string (TYPE_PRECISION (char8_type_node)
8983 / TYPE_PRECISION (char_type_node),
8984 ""); /* char8_t is 8 bits */
8986 else
8987 value = build_string (1, "");
8988 break;
8989 case CPP_STRING16:
8990 value = build_string (TYPE_PRECISION (char16_type_node)
8991 / TYPE_PRECISION (char_type_node),
8992 "\0"); /* char16_t is 16 bits */
8993 break;
8994 case CPP_STRING32:
8995 value = build_string (TYPE_PRECISION (char32_type_node)
8996 / TYPE_PRECISION (char_type_node),
8997 "\0\0\0"); /* char32_t is 32 bits */
8998 break;
8999 case CPP_WSTRING:
9000 value = build_string (TYPE_PRECISION (wchar_type_node)
9001 / TYPE_PRECISION (char_type_node),
9002 "\0\0\0"); /* widest supported wchar_t
9003 is 32 bits */
9004 break;
9008 switch (type)
9010 default:
9011 case CPP_STRING:
9012 TREE_TYPE (value) = char_array_type_node;
9013 break;
9014 case CPP_UTF8STRING:
9015 if (flag_char8_t)
9016 TREE_TYPE (value) = char8_array_type_node;
9017 else
9018 TREE_TYPE (value) = char_array_type_node;
9019 break;
9020 case CPP_STRING16:
9021 TREE_TYPE (value) = char16_array_type_node;
9022 break;
9023 case CPP_STRING32:
9024 TREE_TYPE (value) = char32_array_type_node;
9025 break;
9026 case CPP_WSTRING:
9027 TREE_TYPE (value) = wchar_array_type_node;
9029 value = fix_string_type (value);
9031 if (count > 1)
9033 obstack_free (&str_ob, 0);
9034 obstack_free (&loc_ob, 0);
9037 ret.value = value;
9038 ret.original_code = STRING_CST;
9039 ret.original_type = NULL_TREE;
9040 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
9041 ret.m_decimal = 0;
9042 parser->seen_string_literal = true;
9043 return ret;
9046 /* Parse an expression other than a compound expression; that is, an
9047 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
9048 AFTER is not NULL then it is an Objective-C message expression which
9049 is the primary-expression starting the expression as an initializer.
9051 assignment-expression:
9052 conditional-expression
9053 unary-expression assignment-operator assignment-expression
9055 assignment-operator: one of
9056 = *= /= %= += -= <<= >>= &= ^= |=
9058 In GNU C we accept any conditional expression on the LHS and
9059 diagnose the invalid lvalue rather than producing a syntax
9060 error. */
9062 static struct c_expr
9063 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
9064 tree omp_atomic_lhs)
9066 struct c_expr lhs, rhs, ret;
9067 enum tree_code code;
9068 location_t op_location, exp_location;
9069 bool save_in_omp_for = c_in_omp_for;
9070 c_in_omp_for = false;
9071 gcc_assert (!after || c_dialect_objc ());
9072 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
9073 op_location = c_parser_peek_token (parser)->location;
9074 switch (c_parser_peek_token (parser)->type)
9076 case CPP_EQ:
9077 code = NOP_EXPR;
9078 break;
9079 case CPP_MULT_EQ:
9080 code = MULT_EXPR;
9081 break;
9082 case CPP_DIV_EQ:
9083 code = TRUNC_DIV_EXPR;
9084 break;
9085 case CPP_MOD_EQ:
9086 code = TRUNC_MOD_EXPR;
9087 break;
9088 case CPP_PLUS_EQ:
9089 code = PLUS_EXPR;
9090 break;
9091 case CPP_MINUS_EQ:
9092 code = MINUS_EXPR;
9093 break;
9094 case CPP_LSHIFT_EQ:
9095 code = LSHIFT_EXPR;
9096 break;
9097 case CPP_RSHIFT_EQ:
9098 code = RSHIFT_EXPR;
9099 break;
9100 case CPP_AND_EQ:
9101 code = BIT_AND_EXPR;
9102 break;
9103 case CPP_XOR_EQ:
9104 code = BIT_XOR_EXPR;
9105 break;
9106 case CPP_OR_EQ:
9107 code = BIT_IOR_EXPR;
9108 break;
9109 default:
9110 c_in_omp_for = save_in_omp_for;
9111 return lhs;
9113 c_parser_consume_token (parser);
9114 exp_location = c_parser_peek_token (parser)->location;
9115 rhs = c_parser_expr_no_commas (parser, NULL);
9116 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
9118 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
9119 code, exp_location, rhs.value,
9120 rhs.original_type);
9121 ret.m_decimal = 0;
9122 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
9123 if (code == NOP_EXPR)
9124 ret.original_code = MODIFY_EXPR;
9125 else
9127 suppress_warning (ret.value, OPT_Wparentheses);
9128 ret.original_code = ERROR_MARK;
9130 ret.original_type = NULL;
9131 c_in_omp_for = save_in_omp_for;
9132 return ret;
9135 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
9136 AFTER is not NULL then it is an Objective-C message expression which is
9137 the primary-expression starting the expression as an initializer.
9139 conditional-expression:
9140 logical-OR-expression
9141 logical-OR-expression ? expression : conditional-expression
9143 GNU extensions:
9145 conditional-expression:
9146 logical-OR-expression ? : conditional-expression
9149 static struct c_expr
9150 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
9151 tree omp_atomic_lhs)
9153 struct c_expr cond, exp1, exp2, ret;
9154 location_t start, cond_loc, colon_loc;
9155 bool save_c_omp_array_section_p = c_omp_array_section_p;
9157 gcc_assert (!after || c_dialect_objc ());
9159 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
9161 if (c_parser_next_token_is_not (parser, CPP_QUERY))
9162 return cond;
9163 c_omp_array_section_p = false;
9164 if (cond.value != error_mark_node)
9165 start = cond.get_start ();
9166 else
9167 start = UNKNOWN_LOCATION;
9168 cond_loc = c_parser_peek_token (parser)->location;
9169 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
9170 c_parser_consume_token (parser);
9171 if (c_parser_next_token_is (parser, CPP_COLON))
9173 tree eptype = NULL_TREE;
9175 location_t middle_loc = c_parser_peek_token (parser)->location;
9176 pedwarn (middle_loc, OPT_Wpedantic,
9177 "ISO C forbids omitting the middle term of a %<?:%> expression");
9178 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
9180 eptype = TREE_TYPE (cond.value);
9181 cond.value = TREE_OPERAND (cond.value, 0);
9183 tree e = cond.value;
9184 while (TREE_CODE (e) == COMPOUND_EXPR)
9185 e = TREE_OPERAND (e, 1);
9186 warn_for_omitted_condop (middle_loc, e);
9187 /* Make sure first operand is calculated only once. */
9188 exp1.value = save_expr (default_conversion (cond.value));
9189 if (eptype)
9190 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
9191 exp1.original_type = NULL;
9192 exp1.src_range = cond.src_range;
9193 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
9194 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
9196 else
9198 cond.value
9199 = c_objc_common_truthvalue_conversion
9200 (cond_loc, default_conversion (cond.value));
9201 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
9202 exp1 = c_parser_expression_conv (parser);
9203 mark_exp_read (exp1.value);
9204 c_inhibit_evaluation_warnings +=
9205 ((cond.value == truthvalue_true_node)
9206 - (cond.value == truthvalue_false_node));
9209 colon_loc = c_parser_peek_token (parser)->location;
9210 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
9212 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
9213 ret.set_error ();
9214 ret.original_code = ERROR_MARK;
9215 ret.original_type = NULL;
9216 c_omp_array_section_p = save_c_omp_array_section_p;
9217 return ret;
9220 location_t exp2_loc = c_parser_peek_token (parser)->location;
9221 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
9222 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
9224 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
9225 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
9226 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
9227 if (UNLIKELY (omp_atomic_lhs != NULL)
9228 && (TREE_CODE (cond.value) == GT_EXPR
9229 || TREE_CODE (cond.value) == LT_EXPR
9230 || TREE_CODE (cond.value) == EQ_EXPR)
9231 && c_tree_equal (exp2.value, omp_atomic_lhs)
9232 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
9233 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
9234 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
9235 cond.value, exp1.value, exp2.value);
9236 else
9237 ret.value
9238 = build_conditional_expr (colon_loc, cond.value,
9239 cond.original_code == C_MAYBE_CONST_EXPR,
9240 exp1.value, exp1.original_type, loc1,
9241 exp2.value, exp2.original_type, loc2);
9242 ret.original_code = ERROR_MARK;
9243 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
9244 ret.original_type = NULL;
9245 else
9247 tree t1, t2;
9249 /* If both sides are enum type, the default conversion will have
9250 made the type of the result be an integer type. We want to
9251 remember the enum types we started with. */
9252 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
9253 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
9254 ret.original_type = ((t1 != error_mark_node
9255 && t2 != error_mark_node
9256 && (TYPE_MAIN_VARIANT (t1)
9257 == TYPE_MAIN_VARIANT (t2)))
9258 ? t1
9259 : NULL);
9261 set_c_expr_source_range (&ret, start, exp2.get_finish ());
9262 ret.m_decimal = 0;
9263 c_omp_array_section_p = save_c_omp_array_section_p;
9264 return ret;
9267 /* Parse a binary expression; that is, a logical-OR-expression (C90
9268 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
9269 NULL then it is an Objective-C message expression which is the
9270 primary-expression starting the expression as an initializer.
9272 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
9273 when it should be the unfolded lhs. In a valid OpenMP source,
9274 one of the operands of the toplevel binary expression must be equal
9275 to it. In that case, just return a build2 created binary operation
9276 rather than result of parser_build_binary_op.
9278 multiplicative-expression:
9279 cast-expression
9280 multiplicative-expression * cast-expression
9281 multiplicative-expression / cast-expression
9282 multiplicative-expression % cast-expression
9284 additive-expression:
9285 multiplicative-expression
9286 additive-expression + multiplicative-expression
9287 additive-expression - multiplicative-expression
9289 shift-expression:
9290 additive-expression
9291 shift-expression << additive-expression
9292 shift-expression >> additive-expression
9294 relational-expression:
9295 shift-expression
9296 relational-expression < shift-expression
9297 relational-expression > shift-expression
9298 relational-expression <= shift-expression
9299 relational-expression >= shift-expression
9301 equality-expression:
9302 relational-expression
9303 equality-expression == relational-expression
9304 equality-expression != relational-expression
9306 AND-expression:
9307 equality-expression
9308 AND-expression & equality-expression
9310 exclusive-OR-expression:
9311 AND-expression
9312 exclusive-OR-expression ^ AND-expression
9314 inclusive-OR-expression:
9315 exclusive-OR-expression
9316 inclusive-OR-expression | exclusive-OR-expression
9318 logical-AND-expression:
9319 inclusive-OR-expression
9320 logical-AND-expression && inclusive-OR-expression
9322 logical-OR-expression:
9323 logical-AND-expression
9324 logical-OR-expression || logical-AND-expression
9327 static struct c_expr
9328 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
9329 tree omp_atomic_lhs)
9331 /* A binary expression is parsed using operator-precedence parsing,
9332 with the operands being cast expressions. All the binary
9333 operators are left-associative. Thus a binary expression is of
9334 form:
9336 E0 op1 E1 op2 E2 ...
9338 which we represent on a stack. On the stack, the precedence
9339 levels are strictly increasing. When a new operator is
9340 encountered of higher precedence than that at the top of the
9341 stack, it is pushed; its LHS is the top expression, and its RHS
9342 is everything parsed until it is popped. When a new operator is
9343 encountered with precedence less than or equal to that at the top
9344 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
9345 by the result of the operation until the operator at the top of
9346 the stack has lower precedence than the new operator or there is
9347 only one element on the stack; then the top expression is the LHS
9348 of the new operator. In the case of logical AND and OR
9349 expressions, we also need to adjust c_inhibit_evaluation_warnings
9350 as appropriate when the operators are pushed and popped. */
9352 struct {
9353 /* The expression at this stack level. */
9354 struct c_expr expr;
9355 /* The precedence of the operator on its left, PREC_NONE at the
9356 bottom of the stack. */
9357 enum c_parser_prec prec;
9358 /* The operation on its left. */
9359 enum tree_code op;
9360 /* The source location of this operation. */
9361 location_t loc;
9362 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
9363 tree sizeof_arg;
9364 } stack[NUM_PRECS];
9365 int sp;
9366 /* Location of the binary operator. */
9367 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
9368 #define POP \
9369 do { \
9370 switch (stack[sp].op) \
9372 case TRUTH_ANDIF_EXPR: \
9373 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9374 == truthvalue_false_node); \
9375 break; \
9376 case TRUTH_ORIF_EXPR: \
9377 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9378 == truthvalue_true_node); \
9379 break; \
9380 case TRUNC_DIV_EXPR: \
9381 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
9382 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
9383 && (stack[sp].expr.original_code == SIZEOF_EXPR \
9384 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
9386 tree type0 = stack[sp - 1].sizeof_arg; \
9387 tree type1 = stack[sp].sizeof_arg; \
9388 tree first_arg = type0; \
9389 if (!TYPE_P (type0)) \
9390 type0 = TREE_TYPE (type0); \
9391 if (!TYPE_P (type1)) \
9392 type1 = TREE_TYPE (type1); \
9393 if (POINTER_TYPE_P (type0) \
9394 && comptypes (TREE_TYPE (type0), type1) \
9395 && !(TREE_CODE (first_arg) == PARM_DECL \
9396 && C_ARRAY_PARAMETER (first_arg) \
9397 && warn_sizeof_array_argument)) \
9399 auto_diagnostic_group d; \
9400 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
9401 "division %<sizeof (%T) / sizeof (%T)%> " \
9402 "does not compute the number of array " \
9403 "elements", \
9404 type0, type1)) \
9405 if (DECL_P (first_arg)) \
9406 inform (DECL_SOURCE_LOCATION (first_arg), \
9407 "first %<sizeof%> operand was declared here"); \
9409 else if (TREE_CODE (type0) == ARRAY_TYPE \
9410 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
9411 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
9412 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
9413 stack[sp].sizeof_arg, type1); \
9415 break; \
9416 default: \
9417 break; \
9419 stack[sp - 1].expr \
9420 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
9421 stack[sp - 1].expr, true, true); \
9422 stack[sp].expr \
9423 = convert_lvalue_to_rvalue (stack[sp].loc, \
9424 stack[sp].expr, true, true); \
9425 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
9426 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
9427 && ((1 << stack[sp].prec) \
9428 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
9429 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
9430 | (1 << PREC_ADD) | (1 << PREC_MULT) \
9431 | (1 << PREC_EQ)))) \
9432 || ((c_parser_next_token_is (parser, CPP_QUERY) \
9433 || (omp_atomic_lhs == void_list_node \
9434 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
9435 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
9436 && stack[sp].op != TRUNC_MOD_EXPR \
9437 && stack[sp].op != GE_EXPR \
9438 && stack[sp].op != LE_EXPR \
9439 && stack[sp].op != NE_EXPR \
9440 && stack[0].expr.value != error_mark_node \
9441 && stack[1].expr.value != error_mark_node \
9442 && (omp_atomic_lhs == void_list_node \
9443 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
9444 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
9445 || (stack[sp].op == EQ_EXPR \
9446 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
9448 tree t = make_node (stack[1].op); \
9449 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
9450 TREE_OPERAND (t, 0) = stack[0].expr.value; \
9451 TREE_OPERAND (t, 1) = stack[1].expr.value; \
9452 stack[0].expr.value = t; \
9453 stack[0].expr.m_decimal = 0; \
9455 else \
9456 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
9457 stack[sp].op, \
9458 stack[sp - 1].expr, \
9459 stack[sp].expr); \
9460 sp--; \
9461 } while (0)
9462 gcc_assert (!after || c_dialect_objc ());
9463 stack[0].loc = c_parser_peek_token (parser)->location;
9464 stack[0].expr = c_parser_cast_expression (parser, after);
9465 stack[0].prec = PREC_NONE;
9466 stack[0].sizeof_arg = c_last_sizeof_arg;
9467 sp = 0;
9468 while (true)
9470 enum c_parser_prec oprec;
9471 enum tree_code ocode;
9472 source_range src_range;
9473 if (parser->error)
9474 goto out;
9475 switch (c_parser_peek_token (parser)->type)
9477 case CPP_MULT:
9478 oprec = PREC_MULT;
9479 ocode = MULT_EXPR;
9480 break;
9481 case CPP_DIV:
9482 oprec = PREC_MULT;
9483 ocode = TRUNC_DIV_EXPR;
9484 break;
9485 case CPP_MOD:
9486 oprec = PREC_MULT;
9487 ocode = TRUNC_MOD_EXPR;
9488 break;
9489 case CPP_PLUS:
9490 oprec = PREC_ADD;
9491 ocode = PLUS_EXPR;
9492 break;
9493 case CPP_MINUS:
9494 oprec = PREC_ADD;
9495 ocode = MINUS_EXPR;
9496 break;
9497 case CPP_LSHIFT:
9498 oprec = PREC_SHIFT;
9499 ocode = LSHIFT_EXPR;
9500 break;
9501 case CPP_RSHIFT:
9502 oprec = PREC_SHIFT;
9503 ocode = RSHIFT_EXPR;
9504 break;
9505 case CPP_LESS:
9506 oprec = PREC_REL;
9507 ocode = LT_EXPR;
9508 break;
9509 case CPP_GREATER:
9510 oprec = PREC_REL;
9511 ocode = GT_EXPR;
9512 break;
9513 case CPP_LESS_EQ:
9514 oprec = PREC_REL;
9515 ocode = LE_EXPR;
9516 break;
9517 case CPP_GREATER_EQ:
9518 oprec = PREC_REL;
9519 ocode = GE_EXPR;
9520 break;
9521 case CPP_EQ_EQ:
9522 oprec = PREC_EQ;
9523 ocode = EQ_EXPR;
9524 break;
9525 case CPP_NOT_EQ:
9526 oprec = PREC_EQ;
9527 ocode = NE_EXPR;
9528 break;
9529 case CPP_AND:
9530 oprec = PREC_BITAND;
9531 ocode = BIT_AND_EXPR;
9532 break;
9533 case CPP_XOR:
9534 oprec = PREC_BITXOR;
9535 ocode = BIT_XOR_EXPR;
9536 break;
9537 case CPP_OR:
9538 oprec = PREC_BITOR;
9539 ocode = BIT_IOR_EXPR;
9540 break;
9541 case CPP_AND_AND:
9542 oprec = PREC_LOGAND;
9543 ocode = TRUTH_ANDIF_EXPR;
9544 break;
9545 case CPP_OR_OR:
9546 oprec = PREC_LOGOR;
9547 ocode = TRUTH_ORIF_EXPR;
9548 break;
9549 default:
9550 /* Not a binary operator, so end of the binary
9551 expression. */
9552 goto out;
9554 binary_loc = c_parser_peek_token (parser)->location;
9555 while (oprec <= stack[sp].prec)
9556 POP;
9557 c_parser_consume_token (parser);
9558 switch (ocode)
9560 case TRUTH_ANDIF_EXPR:
9561 src_range = stack[sp].expr.src_range;
9562 stack[sp].expr
9563 = convert_lvalue_to_rvalue (stack[sp].loc,
9564 stack[sp].expr, true, true);
9565 stack[sp].expr.value = c_objc_common_truthvalue_conversion
9566 (stack[sp].loc, default_conversion (stack[sp].expr.value));
9567 c_inhibit_evaluation_warnings += (stack[sp].expr.value
9568 == truthvalue_false_node);
9569 set_c_expr_source_range (&stack[sp].expr, src_range);
9570 break;
9571 case TRUTH_ORIF_EXPR:
9572 src_range = stack[sp].expr.src_range;
9573 stack[sp].expr
9574 = convert_lvalue_to_rvalue (stack[sp].loc,
9575 stack[sp].expr, true, true);
9576 stack[sp].expr.value = c_objc_common_truthvalue_conversion
9577 (stack[sp].loc, default_conversion (stack[sp].expr.value));
9578 c_inhibit_evaluation_warnings += (stack[sp].expr.value
9579 == truthvalue_true_node);
9580 set_c_expr_source_range (&stack[sp].expr, src_range);
9581 break;
9582 default:
9583 break;
9585 sp++;
9586 stack[sp].loc = binary_loc;
9587 stack[sp].expr = c_parser_cast_expression (parser, NULL);
9588 stack[sp].prec = oprec;
9589 stack[sp].op = ocode;
9590 stack[sp].sizeof_arg = c_last_sizeof_arg;
9592 out:
9593 while (sp > 0)
9594 POP;
9595 return stack[0].expr;
9596 #undef POP
9599 /* Parse any storage class specifiers after an open parenthesis in a
9600 context where a compound literal is permitted. */
9602 static struct c_declspecs *
9603 c_parser_compound_literal_scspecs (c_parser *parser)
9605 bool seen_scspec = false;
9606 struct c_declspecs *specs = build_null_declspecs ();
9607 while (c_parser_next_token_is (parser, CPP_KEYWORD))
9609 switch (c_parser_peek_token (parser)->keyword)
9611 case RID_CONSTEXPR:
9612 case RID_REGISTER:
9613 case RID_STATIC:
9614 case RID_THREAD:
9615 seen_scspec = true;
9616 declspecs_add_scspec (c_parser_peek_token (parser)->location,
9617 specs, c_parser_peek_token (parser)->value);
9618 c_parser_consume_token (parser);
9619 break;
9620 default:
9621 goto out;
9624 out:
9625 return seen_scspec ? specs : NULL;
9628 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
9629 is not NULL then it is an Objective-C message expression which is the
9630 primary-expression starting the expression as an initializer.
9632 cast-expression:
9633 unary-expression
9634 ( type-name ) unary-expression
9637 static struct c_expr
9638 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
9640 location_t cast_loc = c_parser_peek_token (parser)->location;
9641 gcc_assert (!after || c_dialect_objc ());
9642 if (after)
9643 return c_parser_postfix_expression_after_primary (parser,
9644 cast_loc, *after);
9645 /* If the expression begins with a parenthesized type name, it may
9646 be either a cast or a compound literal; we need to see whether
9647 the next character is '{' to tell the difference. If not, it is
9648 an unary expression. Full detection of unknown typenames here
9649 would require a 3-token lookahead. */
9650 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9651 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9653 struct c_declspecs *scspecs;
9654 struct c_type_name *type_name;
9655 struct c_expr ret;
9656 struct c_expr expr;
9657 matching_parens parens;
9658 parens.consume_open (parser);
9659 scspecs = c_parser_compound_literal_scspecs (parser);
9660 type_name = c_parser_type_name (parser, true);
9661 parens.skip_until_found_close (parser);
9662 if (type_name == NULL)
9664 ret.set_error ();
9665 ret.original_code = ERROR_MARK;
9666 ret.original_type = NULL;
9667 return ret;
9670 /* Save casted types in the function's used types hash table. */
9671 used_types_insert (type_name->specs->type);
9673 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9674 return c_parser_postfix_expression_after_paren_type (parser, scspecs,
9675 type_name,
9676 cast_loc);
9677 if (scspecs)
9678 error_at (cast_loc, "storage class specifier in cast");
9679 if (type_name->specs->alignas_p)
9680 error_at (type_name->specs->locations[cdw_alignas],
9681 "alignment specified for type name in cast");
9683 location_t expr_loc = c_parser_peek_token (parser)->location;
9684 expr = c_parser_cast_expression (parser, NULL);
9685 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
9687 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
9688 if (ret.value && expr.value)
9689 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
9690 ret.original_code = ERROR_MARK;
9691 ret.original_type = NULL;
9692 ret.m_decimal = 0;
9693 return ret;
9695 else
9696 return c_parser_unary_expression (parser);
9699 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
9701 unary-expression:
9702 postfix-expression
9703 ++ unary-expression
9704 -- unary-expression
9705 unary-operator cast-expression
9706 sizeof unary-expression
9707 sizeof ( type-name )
9709 unary-operator: one of
9710 & * + - ~ !
9712 GNU extensions:
9714 unary-expression:
9715 __alignof__ unary-expression
9716 __alignof__ ( type-name )
9717 && identifier
9719 (C11 permits _Alignof with type names only.)
9721 unary-operator: one of
9722 __extension__ __real__ __imag__
9724 Transactional Memory:
9726 unary-expression:
9727 transaction-expression
9729 In addition, the GNU syntax treats ++ and -- as unary operators, so
9730 they may be applied to cast expressions with errors for non-lvalues
9731 given later. */
9733 static struct c_expr
9734 c_parser_unary_expression (c_parser *parser)
9736 int ext;
9737 struct c_expr ret, op;
9738 location_t op_loc = c_parser_peek_token (parser)->location;
9739 location_t exp_loc;
9740 location_t finish;
9741 ret.original_code = ERROR_MARK;
9742 ret.original_type = NULL;
9743 switch (c_parser_peek_token (parser)->type)
9745 case CPP_PLUS_PLUS:
9746 c_parser_consume_token (parser);
9747 exp_loc = c_parser_peek_token (parser)->location;
9748 op = c_parser_cast_expression (parser, NULL);
9750 op = default_function_array_read_conversion (exp_loc, op);
9751 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
9752 case CPP_MINUS_MINUS:
9753 c_parser_consume_token (parser);
9754 exp_loc = c_parser_peek_token (parser)->location;
9755 op = c_parser_cast_expression (parser, NULL);
9757 op = default_function_array_read_conversion (exp_loc, op);
9758 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
9759 case CPP_AND:
9760 c_parser_consume_token (parser);
9761 op = c_parser_cast_expression (parser, NULL);
9762 mark_exp_read (op.value);
9763 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
9764 case CPP_MULT:
9766 c_parser_consume_token (parser);
9767 exp_loc = c_parser_peek_token (parser)->location;
9768 op = c_parser_cast_expression (parser, NULL);
9769 finish = op.get_finish ();
9770 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9771 location_t combined_loc = make_location (op_loc, op_loc, finish);
9772 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
9773 ret.src_range.m_start = op_loc;
9774 ret.src_range.m_finish = finish;
9775 ret.m_decimal = 0;
9776 return ret;
9778 case CPP_PLUS:
9779 if (!c_dialect_objc () && !in_system_header_at (input_location))
9780 warning_at (op_loc,
9781 OPT_Wtraditional,
9782 "traditional C rejects the unary plus operator");
9783 c_parser_consume_token (parser);
9784 exp_loc = c_parser_peek_token (parser)->location;
9785 op = c_parser_cast_expression (parser, NULL);
9786 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9787 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
9788 case CPP_MINUS:
9789 c_parser_consume_token (parser);
9790 exp_loc = c_parser_peek_token (parser)->location;
9791 op = c_parser_cast_expression (parser, NULL);
9792 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9793 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
9794 case CPP_COMPL:
9795 c_parser_consume_token (parser);
9796 exp_loc = c_parser_peek_token (parser)->location;
9797 op = c_parser_cast_expression (parser, NULL);
9798 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9799 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
9800 case CPP_NOT:
9801 c_parser_consume_token (parser);
9802 exp_loc = c_parser_peek_token (parser)->location;
9803 op = c_parser_cast_expression (parser, NULL);
9804 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9805 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
9806 case CPP_AND_AND:
9807 /* Refer to the address of a label as a pointer. */
9808 c_parser_consume_token (parser);
9809 if (c_parser_next_token_is (parser, CPP_NAME))
9811 ret.value = finish_label_address_expr
9812 (c_parser_peek_token (parser)->value, op_loc);
9813 set_c_expr_source_range (&ret, op_loc,
9814 c_parser_peek_token (parser)->get_finish ());
9815 c_parser_consume_token (parser);
9817 else
9819 c_parser_error (parser, "expected identifier");
9820 ret.set_error ();
9822 return ret;
9823 case CPP_KEYWORD:
9824 switch (c_parser_peek_token (parser)->keyword)
9826 case RID_SIZEOF:
9827 return c_parser_sizeof_expression (parser);
9828 case RID_ALIGNOF:
9829 return c_parser_alignof_expression (parser);
9830 case RID_BUILTIN_HAS_ATTRIBUTE:
9831 return c_parser_has_attribute_expression (parser);
9832 case RID_EXTENSION:
9833 c_parser_consume_token (parser);
9834 ext = disable_extension_diagnostics ();
9835 ret = c_parser_cast_expression (parser, NULL);
9836 restore_extension_diagnostics (ext);
9837 return ret;
9838 case RID_REALPART:
9839 c_parser_consume_token (parser);
9840 exp_loc = c_parser_peek_token (parser)->location;
9841 op = c_parser_cast_expression (parser, NULL);
9842 op = default_function_array_conversion (exp_loc, op);
9843 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
9844 case RID_IMAGPART:
9845 c_parser_consume_token (parser);
9846 exp_loc = c_parser_peek_token (parser)->location;
9847 op = c_parser_cast_expression (parser, NULL);
9848 op = default_function_array_conversion (exp_loc, op);
9849 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
9850 case RID_TRANSACTION_ATOMIC:
9851 case RID_TRANSACTION_RELAXED:
9852 return c_parser_transaction_expression (parser,
9853 c_parser_peek_token (parser)->keyword);
9854 default:
9855 return c_parser_postfix_expression (parser);
9857 default:
9858 return c_parser_postfix_expression (parser);
9862 /* Parse a sizeof expression. */
9864 static struct c_expr
9865 c_parser_sizeof_expression (c_parser *parser)
9867 struct c_expr expr;
9868 struct c_expr result;
9869 location_t expr_loc;
9870 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
9872 location_t start;
9873 location_t finish = UNKNOWN_LOCATION;
9875 start = c_parser_peek_token (parser)->location;
9877 c_parser_consume_token (parser);
9878 c_inhibit_evaluation_warnings++;
9879 in_sizeof++;
9880 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9881 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9883 /* Either sizeof ( type-name ) or sizeof unary-expression
9884 starting with a compound literal. */
9885 struct c_declspecs *scspecs;
9886 struct c_type_name *type_name;
9887 matching_parens parens;
9888 parens.consume_open (parser);
9889 expr_loc = c_parser_peek_token (parser)->location;
9890 scspecs = c_parser_compound_literal_scspecs (parser);
9891 type_name = c_parser_type_name (parser, true);
9892 parens.skip_until_found_close (parser);
9893 finish = parser->tokens_buf[0].location;
9894 if (type_name == NULL)
9896 struct c_expr ret;
9897 c_inhibit_evaluation_warnings--;
9898 in_sizeof--;
9899 ret.set_error ();
9900 ret.original_code = ERROR_MARK;
9901 ret.original_type = NULL;
9902 return ret;
9904 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9906 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
9907 type_name,
9908 expr_loc);
9909 finish = expr.get_finish ();
9910 goto sizeof_expr;
9912 /* sizeof ( type-name ). */
9913 if (scspecs)
9914 error_at (expr_loc, "storage class specifier in %<sizeof%>");
9915 if (type_name->specs->alignas_p)
9916 error_at (type_name->specs->locations[cdw_alignas],
9917 "alignment specified for type name in %<sizeof%>");
9918 c_inhibit_evaluation_warnings--;
9919 in_sizeof--;
9920 result = c_expr_sizeof_type (expr_loc, type_name);
9922 else
9924 expr_loc = c_parser_peek_token (parser)->location;
9925 expr = c_parser_unary_expression (parser);
9926 finish = expr.get_finish ();
9927 sizeof_expr:
9928 c_inhibit_evaluation_warnings--;
9929 in_sizeof--;
9930 mark_exp_read (expr.value);
9931 if (TREE_CODE (expr.value) == COMPONENT_REF
9932 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
9933 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
9934 result = c_expr_sizeof_expr (expr_loc, expr);
9936 if (finish == UNKNOWN_LOCATION)
9937 finish = start;
9938 set_c_expr_source_range (&result, start, finish);
9939 return result;
9942 /* Parse an alignof expression. */
9944 static struct c_expr
9945 c_parser_alignof_expression (c_parser *parser)
9947 struct c_expr expr;
9948 location_t start_loc = c_parser_peek_token (parser)->location;
9949 location_t end_loc;
9950 tree alignof_spelling = c_parser_peek_token (parser)->value;
9951 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
9952 bool is_c11_alignof = (strcmp (IDENTIFIER_POINTER (alignof_spelling),
9953 "_Alignof") == 0
9954 || strcmp (IDENTIFIER_POINTER (alignof_spelling),
9955 "alignof") == 0);
9956 /* A diagnostic is not required for the use of this identifier in
9957 the implementation namespace; only diagnose it for the C11 or C23
9958 spelling because of existing code using the other spellings. */
9959 if (is_c11_alignof)
9961 if (flag_isoc99)
9962 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
9963 alignof_spelling);
9964 else
9965 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
9966 alignof_spelling);
9968 c_parser_consume_token (parser);
9969 c_inhibit_evaluation_warnings++;
9970 in_alignof++;
9971 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9972 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9974 /* Either __alignof__ ( type-name ) or __alignof__
9975 unary-expression starting with a compound literal. */
9976 location_t loc;
9977 struct c_declspecs *scspecs;
9978 struct c_type_name *type_name;
9979 struct c_expr ret;
9980 matching_parens parens;
9981 parens.consume_open (parser);
9982 loc = c_parser_peek_token (parser)->location;
9983 scspecs = c_parser_compound_literal_scspecs (parser);
9984 type_name = c_parser_type_name (parser, true);
9985 end_loc = c_parser_peek_token (parser)->location;
9986 parens.skip_until_found_close (parser);
9987 if (type_name == NULL)
9989 struct c_expr ret;
9990 c_inhibit_evaluation_warnings--;
9991 in_alignof--;
9992 ret.set_error ();
9993 ret.original_code = ERROR_MARK;
9994 ret.original_type = NULL;
9995 return ret;
9997 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9999 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
10000 type_name,
10001 loc);
10002 goto alignof_expr;
10004 /* alignof ( type-name ). */
10005 if (scspecs)
10006 error_at (loc, "storage class specifier in %qE", alignof_spelling);
10007 if (type_name->specs->alignas_p)
10008 error_at (type_name->specs->locations[cdw_alignas],
10009 "alignment specified for type name in %qE",
10010 alignof_spelling);
10011 c_inhibit_evaluation_warnings--;
10012 in_alignof--;
10013 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
10014 NULL, NULL),
10015 false, is_c11_alignof, 1);
10016 ret.original_code = ERROR_MARK;
10017 ret.original_type = NULL;
10018 set_c_expr_source_range (&ret, start_loc, end_loc);
10019 ret.m_decimal = 0;
10020 return ret;
10022 else
10024 struct c_expr ret;
10025 expr = c_parser_unary_expression (parser);
10026 end_loc = expr.src_range.m_finish;
10027 alignof_expr:
10028 mark_exp_read (expr.value);
10029 c_inhibit_evaluation_warnings--;
10030 in_alignof--;
10031 if (is_c11_alignof)
10032 pedwarn (start_loc,
10033 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
10034 alignof_spelling);
10035 ret.value = c_alignof_expr (start_loc, expr.value);
10036 ret.original_code = ERROR_MARK;
10037 ret.original_type = NULL;
10038 set_c_expr_source_range (&ret, start_loc, end_loc);
10039 ret.m_decimal = 0;
10040 return ret;
10044 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
10045 expression. */
10047 static struct c_expr
10048 c_parser_has_attribute_expression (c_parser *parser)
10050 gcc_assert (c_parser_next_token_is_keyword (parser,
10051 RID_BUILTIN_HAS_ATTRIBUTE));
10052 location_t start = c_parser_peek_token (parser)->location;
10053 c_parser_consume_token (parser);
10055 c_inhibit_evaluation_warnings++;
10057 matching_parens parens;
10058 if (!parens.require_open (parser))
10060 c_inhibit_evaluation_warnings--;
10061 in_typeof--;
10063 struct c_expr result;
10064 result.set_error ();
10065 result.original_code = ERROR_MARK;
10066 result.original_type = NULL;
10067 return result;
10070 /* Treat the type argument the same way as in typeof for the purposes
10071 of warnings. FIXME: Generalize this so the warning refers to
10072 __builtin_has_attribute rather than typeof. */
10073 in_typeof++;
10075 /* The first operand: one of DECL, EXPR, or TYPE. */
10076 tree oper = NULL_TREE;
10077 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
10079 struct c_type_name *tname = c_parser_type_name (parser);
10080 in_typeof--;
10081 if (tname)
10083 oper = groktypename (tname, NULL, NULL);
10084 pop_maybe_used (c_type_variably_modified_p (oper));
10087 else
10089 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
10090 c_inhibit_evaluation_warnings--;
10091 in_typeof--;
10092 if (cexpr.value != error_mark_node)
10094 mark_exp_read (cexpr.value);
10095 oper = cexpr.value;
10096 tree etype = TREE_TYPE (oper);
10097 bool was_vm = c_type_variably_modified_p (etype);
10098 /* This is returned with the type so that when the type is
10099 evaluated, this can be evaluated. */
10100 if (was_vm)
10101 oper = c_fully_fold (oper, false, NULL);
10102 pop_maybe_used (was_vm);
10106 struct c_expr result;
10107 result.original_code = ERROR_MARK;
10108 result.original_type = NULL;
10110 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10112 /* Consume the closing parenthesis if that's the next token
10113 in the likely case the built-in was invoked with fewer
10114 than two arguments. */
10115 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10116 c_parser_consume_token (parser);
10117 c_inhibit_evaluation_warnings--;
10118 result.set_error ();
10119 return result;
10122 bool save_translate_strings_p = parser->translate_strings_p;
10124 location_t atloc = c_parser_peek_token (parser)->location;
10125 /* Parse a single attribute. Require no leading comma and do not
10126 allow empty attributes. */
10127 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
10129 parser->translate_strings_p = save_translate_strings_p;
10131 location_t finish = c_parser_peek_token (parser)->location;
10132 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10133 c_parser_consume_token (parser);
10134 else
10136 c_parser_error (parser, "expected identifier");
10137 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10139 result.set_error ();
10140 return result;
10143 if (!attr)
10145 error_at (atloc, "expected identifier");
10146 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10147 "expected %<)%>");
10148 result.set_error ();
10149 return result;
10152 result.original_code = INTEGER_CST;
10153 result.original_type = boolean_type_node;
10155 if (has_attribute (atloc, oper, attr, default_conversion))
10156 result.value = boolean_true_node;
10157 else
10158 result.value = boolean_false_node;
10160 set_c_expr_source_range (&result, start, finish);
10161 result.m_decimal = 0;
10162 return result;
10165 /* Helper function to read arguments of builtins which are interfaces
10166 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
10167 others. The name of the builtin is passed using BNAME parameter.
10168 Function returns true if there were no errors while parsing and
10169 stores the arguments in CEXPR_LIST. If it returns true,
10170 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
10171 parenthesis. */
10172 static bool
10173 c_parser_get_builtin_args (c_parser *parser, const char *bname,
10174 vec<c_expr_t, va_gc> **ret_cexpr_list,
10175 bool choose_expr_p,
10176 location_t *out_close_paren_loc)
10178 location_t loc = c_parser_peek_token (parser)->location;
10179 vec<c_expr_t, va_gc> *cexpr_list;
10180 c_expr_t expr;
10181 bool saved_force_folding_builtin_constant_p;
10183 *ret_cexpr_list = NULL;
10184 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
10186 error_at (loc, "cannot take address of %qs", bname);
10187 return false;
10190 c_parser_consume_token (parser);
10192 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10194 *out_close_paren_loc = c_parser_peek_token (parser)->location;
10195 c_parser_consume_token (parser);
10196 return true;
10199 saved_force_folding_builtin_constant_p
10200 = force_folding_builtin_constant_p;
10201 force_folding_builtin_constant_p |= choose_expr_p;
10202 expr = c_parser_expr_no_commas (parser, NULL);
10203 force_folding_builtin_constant_p
10204 = saved_force_folding_builtin_constant_p;
10205 vec_alloc (cexpr_list, 1);
10206 vec_safe_push (cexpr_list, expr);
10207 while (c_parser_next_token_is (parser, CPP_COMMA))
10209 c_parser_consume_token (parser);
10210 expr = c_parser_expr_no_commas (parser, NULL);
10211 vec_safe_push (cexpr_list, expr);
10214 *out_close_paren_loc = c_parser_peek_token (parser)->location;
10215 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
10216 return false;
10218 *ret_cexpr_list = cexpr_list;
10219 return true;
10222 /* This represents a single generic-association. */
10224 struct c_generic_association
10226 /* The location of the starting token of the type. */
10227 location_t type_location;
10228 /* The association's type, or NULL_TREE for 'default'. */
10229 tree type;
10230 /* The association's expression. */
10231 struct c_expr expression;
10234 /* Parse a generic-selection. (C11 6.5.1.1).
10236 generic-selection:
10237 _Generic ( assignment-expression , generic-assoc-list )
10239 generic-assoc-list:
10240 generic-association
10241 generic-assoc-list , generic-association
10243 generic-association:
10244 type-name : assignment-expression
10245 default : assignment-expression
10248 static struct c_expr
10249 c_parser_generic_selection (c_parser *parser)
10251 struct c_expr selector, error_expr;
10252 tree selector_type;
10253 struct c_generic_association matched_assoc;
10254 int match_found = -1;
10255 location_t generic_loc, selector_loc;
10257 error_expr.original_code = ERROR_MARK;
10258 error_expr.original_type = NULL;
10259 error_expr.set_error ();
10260 matched_assoc.type_location = UNKNOWN_LOCATION;
10261 matched_assoc.type = NULL_TREE;
10262 matched_assoc.expression = error_expr;
10264 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
10265 generic_loc = c_parser_peek_token (parser)->location;
10266 c_parser_consume_token (parser);
10267 if (flag_isoc99)
10268 pedwarn_c99 (generic_loc, OPT_Wpedantic,
10269 "ISO C99 does not support %<_Generic%>");
10270 else
10271 pedwarn_c99 (generic_loc, OPT_Wpedantic,
10272 "ISO C90 does not support %<_Generic%>");
10274 matching_parens parens;
10275 if (!parens.require_open (parser))
10276 return error_expr;
10278 c_inhibit_evaluation_warnings++;
10279 selector_loc = c_parser_peek_token (parser)->location;
10280 selector = c_parser_expr_no_commas (parser, NULL);
10281 selector = default_function_array_conversion (selector_loc, selector);
10282 c_inhibit_evaluation_warnings--;
10284 if (selector.value == error_mark_node)
10286 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10287 return selector;
10289 mark_exp_read (selector.value);
10290 selector_type = TREE_TYPE (selector.value);
10291 /* In ISO C terms, rvalues (including the controlling expression of
10292 _Generic) do not have qualified types. */
10293 if (TREE_CODE (selector_type) != ARRAY_TYPE)
10294 selector_type = TYPE_MAIN_VARIANT (selector_type);
10295 /* In ISO C terms, _Noreturn is not part of the type of expressions
10296 such as &abort, but in GCC it is represented internally as a type
10297 qualifier. */
10298 if (FUNCTION_POINTER_TYPE_P (selector_type)
10299 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
10300 selector_type
10301 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
10303 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10305 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10306 return error_expr;
10309 auto_vec<c_generic_association> associations;
10310 while (1)
10312 struct c_generic_association assoc, *iter;
10313 unsigned int ix;
10314 c_token *token = c_parser_peek_token (parser);
10316 assoc.type_location = token->location;
10317 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
10319 c_parser_consume_token (parser);
10320 assoc.type = NULL_TREE;
10322 else
10324 struct c_type_name *type_name;
10326 type_name = c_parser_type_name (parser);
10327 if (type_name == NULL)
10329 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10330 return error_expr;
10332 assoc.type = groktypename (type_name, NULL, NULL);
10333 if (assoc.type == error_mark_node)
10335 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10336 return error_expr;
10339 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
10340 error_at (assoc.type_location,
10341 "%<_Generic%> association has function type");
10342 else if (!COMPLETE_TYPE_P (assoc.type))
10343 error_at (assoc.type_location,
10344 "%<_Generic%> association has incomplete type");
10346 if (c_type_variably_modified_p (assoc.type))
10347 error_at (assoc.type_location,
10348 "%<_Generic%> association has "
10349 "variable length type");
10352 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
10354 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10355 return error_expr;
10358 bool match = assoc.type == NULL_TREE
10359 || comptypes (assoc.type, selector_type);
10361 if (!match)
10362 c_inhibit_evaluation_warnings++;
10364 assoc.expression = c_parser_expr_no_commas (parser, NULL);
10366 if (!match)
10367 c_inhibit_evaluation_warnings--;
10369 if (assoc.expression.value == error_mark_node)
10371 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10372 return error_expr;
10375 for (ix = 0; associations.iterate (ix, &iter); ++ix)
10377 if (assoc.type == NULL_TREE)
10379 if (iter->type == NULL_TREE)
10381 error_at (assoc.type_location,
10382 "duplicate %<default%> case in %<_Generic%>");
10383 inform (iter->type_location, "original %<default%> is here");
10386 else if (iter->type != NULL_TREE)
10388 if (comptypes (assoc.type, iter->type))
10390 error_at (assoc.type_location,
10391 "%<_Generic%> specifies two compatible types");
10392 inform (iter->type_location, "compatible type is here");
10397 if (assoc.type == NULL_TREE)
10399 if (match_found < 0)
10401 matched_assoc = assoc;
10402 match_found = associations.length ();
10405 else if (match)
10407 if (match_found < 0 || matched_assoc.type == NULL_TREE)
10409 matched_assoc = assoc;
10410 match_found = associations.length ();
10412 else
10414 error_at (assoc.type_location,
10415 "%<_Generic%> selector matches multiple associations");
10416 inform (matched_assoc.type_location,
10417 "other match is here");
10421 associations.safe_push (assoc);
10423 if (c_parser_peek_token (parser)->type != CPP_COMMA)
10424 break;
10425 c_parser_consume_token (parser);
10428 unsigned int ix;
10429 struct c_generic_association *iter;
10430 FOR_EACH_VEC_ELT (associations, ix, iter)
10431 if (ix != (unsigned) match_found)
10432 mark_exp_read (iter->expression.value);
10434 if (!parens.require_close (parser))
10436 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10437 return error_expr;
10440 if (match_found < 0)
10442 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
10443 "compatible with any association",
10444 selector_type);
10445 return error_expr;
10448 return matched_assoc.expression;
10451 /* Check the validity of a function pointer argument *EXPR (argument
10452 position POS) to __builtin_tgmath. Return the number of function
10453 arguments if possibly valid; return 0 having reported an error if
10454 not valid. */
10456 static unsigned int
10457 check_tgmath_function (c_expr *expr, unsigned int pos)
10459 tree type = TREE_TYPE (expr->value);
10460 if (!FUNCTION_POINTER_TYPE_P (type))
10462 error_at (expr->get_location (),
10463 "argument %u of %<__builtin_tgmath%> is not a function pointer",
10464 pos);
10465 return 0;
10467 type = TREE_TYPE (type);
10468 if (!prototype_p (type))
10470 error_at (expr->get_location (),
10471 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
10472 return 0;
10474 if (stdarg_p (type))
10476 error_at (expr->get_location (),
10477 "argument %u of %<__builtin_tgmath%> has variable arguments",
10478 pos);
10479 return 0;
10481 unsigned int nargs = 0;
10482 function_args_iterator iter;
10483 tree t;
10484 FOREACH_FUNCTION_ARGS (type, t, iter)
10486 if (t == void_type_node)
10487 break;
10488 nargs++;
10490 if (nargs == 0)
10492 error_at (expr->get_location (),
10493 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
10494 return 0;
10496 return nargs;
10499 /* Ways in which a parameter or return value of a type-generic macro
10500 may vary between the different functions the macro may call. */
10501 enum tgmath_parm_kind
10503 tgmath_fixed, tgmath_real, tgmath_complex
10506 /* Helper function for c_parser_postfix_expression. Parse predefined
10507 identifiers. */
10509 static struct c_expr
10510 c_parser_predefined_identifier (c_parser *parser)
10512 location_t loc = c_parser_peek_token (parser)->location;
10513 switch (c_parser_peek_token (parser)->keyword)
10515 case RID_FUNCTION_NAME:
10516 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
10517 "identifier", "__FUNCTION__");
10518 break;
10519 case RID_PRETTY_FUNCTION_NAME:
10520 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
10521 "identifier", "__PRETTY_FUNCTION__");
10522 break;
10523 case RID_C99_FUNCTION_NAME:
10524 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
10525 "%<__func__%> predefined identifier");
10526 break;
10527 default:
10528 gcc_unreachable ();
10531 struct c_expr expr;
10532 expr.original_code = ERROR_MARK;
10533 expr.original_type = NULL;
10534 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
10535 c_parser_peek_token (parser)->value);
10536 set_c_expr_source_range (&expr, loc, loc);
10537 expr.m_decimal = 0;
10538 c_parser_consume_token (parser);
10539 return expr;
10542 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
10543 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
10544 call c_parser_postfix_expression_after_paren_type on encountering them.
10546 postfix-expression:
10547 primary-expression
10548 postfix-expression [ expression ]
10549 postfix-expression ( argument-expression-list[opt] )
10550 postfix-expression . identifier
10551 postfix-expression -> identifier
10552 postfix-expression ++
10553 postfix-expression --
10554 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
10555 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
10557 argument-expression-list:
10558 argument-expression
10559 argument-expression-list , argument-expression
10561 primary-expression:
10562 identifier
10563 constant
10564 string-literal
10565 ( expression )
10566 generic-selection
10568 GNU extensions:
10570 primary-expression:
10571 __func__
10572 (treated as a keyword in GNU C)
10573 __FUNCTION__
10574 __PRETTY_FUNCTION__
10575 ( compound-statement )
10576 __builtin_va_arg ( assignment-expression , type-name )
10577 __builtin_offsetof ( type-name , offsetof-member-designator )
10578 __builtin_choose_expr ( assignment-expression ,
10579 assignment-expression ,
10580 assignment-expression )
10581 __builtin_types_compatible_p ( type-name , type-name )
10582 __builtin_tgmath ( expr-list )
10583 __builtin_complex ( assignment-expression , assignment-expression )
10584 __builtin_shuffle ( assignment-expression , assignment-expression )
10585 __builtin_shuffle ( assignment-expression ,
10586 assignment-expression ,
10587 assignment-expression, )
10588 __builtin_convertvector ( assignment-expression , type-name )
10589 __builtin_assoc_barrier ( assignment-expression )
10591 offsetof-member-designator:
10592 identifier
10593 offsetof-member-designator . identifier
10594 offsetof-member-designator [ expression ]
10596 Objective-C:
10598 primary-expression:
10599 [ objc-receiver objc-message-args ]
10600 @selector ( objc-selector-arg )
10601 @protocol ( identifier )
10602 @encode ( type-name )
10603 objc-string-literal
10604 Classname . identifier
10607 static struct c_expr
10608 c_parser_postfix_expression (c_parser *parser)
10610 struct c_expr expr, e1;
10611 struct c_type_name *t1, *t2;
10612 location_t loc = c_parser_peek_token (parser)->location;
10613 source_range tok_range = c_parser_peek_token (parser)->get_range ();
10614 expr.original_code = ERROR_MARK;
10615 expr.original_type = NULL;
10616 expr.m_decimal = 0;
10617 switch (c_parser_peek_token (parser)->type)
10619 case CPP_NUMBER:
10620 expr.value = c_parser_peek_token (parser)->value;
10621 set_c_expr_source_range (&expr, tok_range);
10622 loc = c_parser_peek_token (parser)->location;
10623 expr.m_decimal = c_parser_peek_token (parser)->flags & DECIMAL_INT;
10624 c_parser_consume_token (parser);
10625 if (TREE_CODE (expr.value) == FIXED_CST
10626 && !targetm.fixed_point_supported_p ())
10628 error_at (loc, "fixed-point types not supported for this target");
10629 expr.set_error ();
10631 break;
10632 case CPP_CHAR:
10633 case CPP_CHAR16:
10634 case CPP_CHAR32:
10635 case CPP_UTF8CHAR:
10636 case CPP_WCHAR:
10637 expr.value = c_parser_peek_token (parser)->value;
10638 /* For the purpose of warning when a pointer is compared with
10639 a zero character constant. */
10640 expr.original_type = char_type_node;
10641 set_c_expr_source_range (&expr, tok_range);
10642 c_parser_consume_token (parser);
10643 break;
10644 case CPP_STRING:
10645 case CPP_STRING16:
10646 case CPP_STRING32:
10647 case CPP_WSTRING:
10648 case CPP_UTF8STRING:
10649 expr = c_parser_string_literal (parser, parser->translate_strings_p,
10650 true);
10651 break;
10652 case CPP_OBJC_STRING:
10653 gcc_assert (c_dialect_objc ());
10654 expr.value
10655 = objc_build_string_object (c_parser_peek_token (parser)->value);
10656 set_c_expr_source_range (&expr, tok_range);
10657 c_parser_consume_token (parser);
10658 break;
10659 case CPP_NAME:
10660 switch (c_parser_peek_token (parser)->id_kind)
10662 case C_ID_ID:
10664 tree id = c_parser_peek_token (parser)->value;
10665 c_parser_consume_token (parser);
10666 expr.value = build_external_ref (loc, id,
10667 (c_parser_peek_token (parser)->type
10668 == CPP_OPEN_PAREN),
10669 &expr.original_type);
10670 set_c_expr_source_range (&expr, tok_range);
10671 break;
10673 case C_ID_CLASSNAME:
10675 /* Here we parse the Objective-C 2.0 Class.name dot
10676 syntax. */
10677 tree class_name = c_parser_peek_token (parser)->value;
10678 tree component;
10679 c_parser_consume_token (parser);
10680 gcc_assert (c_dialect_objc ());
10681 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
10683 expr.set_error ();
10684 break;
10686 if (c_parser_next_token_is_not (parser, CPP_NAME))
10688 c_parser_error (parser, "expected identifier");
10689 expr.set_error ();
10690 break;
10692 c_token *component_tok = c_parser_peek_token (parser);
10693 component = component_tok->value;
10694 location_t end_loc = component_tok->get_finish ();
10695 c_parser_consume_token (parser);
10696 expr.value = objc_build_class_component_ref (class_name,
10697 component);
10698 set_c_expr_source_range (&expr, loc, end_loc);
10699 break;
10701 default:
10702 c_parser_error (parser, "expected expression");
10703 expr.set_error ();
10704 break;
10706 break;
10707 case CPP_OPEN_PAREN:
10708 /* A parenthesized expression, statement expression or compound
10709 literal. */
10710 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
10712 /* A statement expression. */
10713 tree stmt;
10714 location_t brace_loc;
10715 bool save_c_omp_array_section_p = c_omp_array_section_p;
10716 c_parser_consume_token (parser);
10717 brace_loc = c_parser_peek_token (parser)->location;
10718 c_parser_consume_token (parser);
10719 /* If we've not yet started the current function's statement list,
10720 or we're in the parameter scope of an old-style function
10721 declaration, statement expressions are not allowed. */
10722 if (!building_stmt_list_p () || old_style_parameter_scope ())
10724 error_at (loc, "braced-group within expression allowed "
10725 "only inside a function");
10726 parser->error = true;
10727 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
10728 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10729 expr.set_error ();
10730 break;
10732 c_omp_array_section_p = false;
10733 stmt = c_begin_stmt_expr ();
10734 c_parser_compound_statement_nostart (parser);
10735 location_t close_loc = c_parser_peek_token (parser)->location;
10736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10737 "expected %<)%>");
10738 pedwarn (loc, OPT_Wpedantic,
10739 "ISO C forbids braced-groups within expressions");
10740 expr.value = c_finish_stmt_expr (brace_loc, stmt);
10741 set_c_expr_source_range (&expr, loc, close_loc);
10742 mark_exp_read (expr.value);
10743 c_omp_array_section_p = save_c_omp_array_section_p;
10745 else
10747 /* A parenthesized expression. */
10748 location_t loc_open_paren = c_parser_peek_token (parser)->location;
10749 c_parser_consume_token (parser);
10750 expr = c_parser_expression (parser);
10751 if (TREE_CODE (expr.value) == MODIFY_EXPR)
10752 suppress_warning (expr.value, OPT_Wparentheses);
10753 if (expr.original_code != C_MAYBE_CONST_EXPR
10754 && expr.original_code != SIZEOF_EXPR)
10755 expr.original_code = ERROR_MARK;
10756 /* Remember that we saw ( ) around the sizeof. */
10757 if (expr.original_code == SIZEOF_EXPR)
10758 expr.original_code = PAREN_SIZEOF_EXPR;
10759 /* Don't change EXPR.ORIGINAL_TYPE. */
10760 location_t loc_close_paren = c_parser_peek_token (parser)->location;
10761 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
10762 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10763 "expected %<)%>", loc_open_paren);
10765 break;
10766 case CPP_KEYWORD:
10767 switch (c_parser_peek_token (parser)->keyword)
10769 case RID_FUNCTION_NAME:
10770 case RID_PRETTY_FUNCTION_NAME:
10771 case RID_C99_FUNCTION_NAME:
10772 expr = c_parser_predefined_identifier (parser);
10773 break;
10774 case RID_VA_ARG:
10776 location_t start_loc = loc;
10777 c_parser_consume_token (parser);
10778 matching_parens parens;
10779 if (!parens.require_open (parser))
10781 expr.set_error ();
10782 break;
10784 e1 = c_parser_expr_no_commas (parser, NULL);
10785 mark_exp_read (e1.value);
10786 e1.value = c_fully_fold (e1.value, false, NULL);
10787 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10789 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10790 expr.set_error ();
10791 break;
10793 loc = c_parser_peek_token (parser)->location;
10794 t1 = c_parser_type_name (parser);
10795 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10796 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10797 "expected %<)%>");
10798 if (t1 == NULL)
10800 expr.set_error ();
10802 else
10804 tree type_expr = NULL_TREE;
10805 expr.value = c_build_va_arg (start_loc, e1.value, loc,
10806 groktypename (t1, &type_expr, NULL));
10807 if (type_expr)
10809 expr.value = build2 (C_MAYBE_CONST_EXPR,
10810 TREE_TYPE (expr.value), type_expr,
10811 expr.value);
10812 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
10814 set_c_expr_source_range (&expr, start_loc, end_loc);
10817 break;
10818 case RID_OFFSETOF:
10820 c_parser_consume_token (parser);
10821 matching_parens parens;
10822 if (!parens.require_open (parser))
10824 expr.set_error ();
10825 break;
10827 t1 = c_parser_type_name (parser);
10828 if (t1 == NULL)
10829 parser->error = true;
10830 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10831 gcc_assert (parser->error);
10832 if (parser->error)
10834 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10835 expr.set_error ();
10836 break;
10838 tree type = groktypename (t1, NULL, NULL);
10839 tree offsetof_ref;
10840 if (type == error_mark_node)
10841 offsetof_ref = error_mark_node;
10842 else
10844 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
10845 SET_EXPR_LOCATION (offsetof_ref, loc);
10847 /* Parse the second argument to __builtin_offsetof. We
10848 must have one identifier, and beyond that we want to
10849 accept sub structure and sub array references. */
10850 if (c_parser_next_token_is (parser, CPP_NAME))
10852 c_token *comp_tok = c_parser_peek_token (parser);
10853 offsetof_ref
10854 = build_component_ref (loc, offsetof_ref, comp_tok->value,
10855 comp_tok->location, UNKNOWN_LOCATION);
10856 c_parser_consume_token (parser);
10857 while (c_parser_next_token_is (parser, CPP_DOT)
10858 || c_parser_next_token_is (parser,
10859 CPP_OPEN_SQUARE)
10860 || c_parser_next_token_is (parser,
10861 CPP_DEREF))
10863 if (c_parser_next_token_is (parser, CPP_DEREF))
10865 loc = c_parser_peek_token (parser)->location;
10866 offsetof_ref = build_array_ref (loc,
10867 offsetof_ref,
10868 integer_zero_node);
10869 goto do_dot;
10871 else if (c_parser_next_token_is (parser, CPP_DOT))
10873 do_dot:
10874 c_parser_consume_token (parser);
10875 if (c_parser_next_token_is_not (parser,
10876 CPP_NAME))
10878 c_parser_error (parser, "expected identifier");
10879 break;
10881 c_token *comp_tok = c_parser_peek_token (parser);
10882 offsetof_ref
10883 = build_component_ref (loc, offsetof_ref,
10884 comp_tok->value,
10885 comp_tok->location,
10886 UNKNOWN_LOCATION);
10887 c_parser_consume_token (parser);
10889 else
10891 struct c_expr ce;
10892 tree idx;
10893 loc = c_parser_peek_token (parser)->location;
10894 c_parser_consume_token (parser);
10895 ce = c_parser_expression (parser);
10896 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
10897 idx = ce.value;
10898 idx = c_fully_fold (idx, false, NULL);
10899 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10900 "expected %<]%>");
10901 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
10905 else
10906 c_parser_error (parser, "expected identifier");
10907 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10908 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10909 "expected %<)%>");
10910 expr.value = fold_offsetof (offsetof_ref);
10911 set_c_expr_source_range (&expr, loc, end_loc);
10913 break;
10914 case RID_CHOOSE_EXPR:
10916 vec<c_expr_t, va_gc> *cexpr_list;
10917 c_expr_t *e1_p, *e2_p, *e3_p;
10918 tree c;
10919 location_t close_paren_loc;
10921 c_parser_consume_token (parser);
10922 if (!c_parser_get_builtin_args (parser,
10923 "__builtin_choose_expr",
10924 &cexpr_list, true,
10925 &close_paren_loc))
10927 expr.set_error ();
10928 break;
10931 if (vec_safe_length (cexpr_list) != 3)
10933 error_at (loc, "wrong number of arguments to "
10934 "%<__builtin_choose_expr%>");
10935 expr.set_error ();
10936 break;
10939 e1_p = &(*cexpr_list)[0];
10940 e2_p = &(*cexpr_list)[1];
10941 e3_p = &(*cexpr_list)[2];
10943 c = e1_p->value;
10944 mark_exp_read (e2_p->value);
10945 mark_exp_read (e3_p->value);
10946 if (TREE_CODE (c) != INTEGER_CST
10947 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
10948 error_at (loc,
10949 "first argument to %<__builtin_choose_expr%> not"
10950 " a constant");
10951 constant_expression_warning (c);
10952 expr = integer_zerop (c) ? *e3_p : *e2_p;
10953 set_c_expr_source_range (&expr, loc, close_paren_loc);
10954 break;
10956 case RID_TYPES_COMPATIBLE_P:
10958 c_parser_consume_token (parser);
10959 matching_parens parens;
10960 if (!parens.require_open (parser))
10962 expr.set_error ();
10963 break;
10965 t1 = c_parser_type_name (parser);
10966 if (t1 == NULL)
10968 expr.set_error ();
10969 break;
10971 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10973 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10974 expr.set_error ();
10975 break;
10977 t2 = c_parser_type_name (parser);
10978 if (t2 == NULL)
10980 expr.set_error ();
10981 break;
10983 location_t close_paren_loc = c_parser_peek_token (parser)->location;
10984 parens.skip_until_found_close (parser);
10985 tree e1, e2;
10986 e1 = groktypename (t1, NULL, NULL);
10987 e2 = groktypename (t2, NULL, NULL);
10988 if (e1 == error_mark_node || e2 == error_mark_node)
10990 expr.set_error ();
10991 break;
10994 e1 = TYPE_MAIN_VARIANT (e1);
10995 e2 = TYPE_MAIN_VARIANT (e2);
10997 expr.value
10998 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
10999 set_c_expr_source_range (&expr, loc, close_paren_loc);
11001 break;
11002 case RID_BUILTIN_TGMATH:
11004 vec<c_expr_t, va_gc> *cexpr_list;
11005 location_t close_paren_loc;
11007 c_parser_consume_token (parser);
11008 if (!c_parser_get_builtin_args (parser,
11009 "__builtin_tgmath",
11010 &cexpr_list, false,
11011 &close_paren_loc))
11013 expr.set_error ();
11014 break;
11017 if (vec_safe_length (cexpr_list) < 3)
11019 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11020 expr.set_error ();
11021 break;
11024 unsigned int i;
11025 c_expr_t *p;
11026 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
11027 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11028 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
11029 if (nargs == 0)
11031 expr.set_error ();
11032 break;
11034 if (vec_safe_length (cexpr_list) < nargs)
11036 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11037 expr.set_error ();
11038 break;
11040 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
11041 if (num_functions < 2)
11043 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11044 expr.set_error ();
11045 break;
11048 /* The first NUM_FUNCTIONS expressions are the function
11049 pointers. The remaining NARGS expressions are the
11050 arguments that are to be passed to one of those
11051 functions, chosen following <tgmath.h> rules. */
11052 for (unsigned int j = 1; j < num_functions; j++)
11054 unsigned int this_nargs
11055 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
11056 if (this_nargs == 0)
11058 expr.set_error ();
11059 goto out;
11061 if (this_nargs != nargs)
11063 error_at ((*cexpr_list)[j].get_location (),
11064 "argument %u of %<__builtin_tgmath%> has "
11065 "wrong number of arguments", j + 1);
11066 expr.set_error ();
11067 goto out;
11071 /* The functions all have the same number of arguments.
11072 Determine whether arguments and return types vary in
11073 ways permitted for <tgmath.h> functions. */
11074 /* The first entry in each of these vectors is for the
11075 return type, subsequent entries for parameter
11076 types. */
11077 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
11078 auto_vec<tree> parm_first (nargs + 1);
11079 auto_vec<bool> parm_complex (nargs + 1);
11080 auto_vec<bool> parm_varies (nargs + 1);
11081 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
11082 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
11083 parm_first.quick_push (first_ret);
11084 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
11085 parm_varies.quick_push (false);
11086 function_args_iterator iter;
11087 tree t;
11088 unsigned int argpos;
11089 FOREACH_FUNCTION_ARGS (first_type, t, iter)
11091 if (t == void_type_node)
11092 break;
11093 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
11094 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
11095 parm_varies.quick_push (false);
11097 for (unsigned int j = 1; j < num_functions; j++)
11099 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11100 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
11101 if (ret != parm_first[0])
11103 parm_varies[0] = true;
11104 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
11105 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
11107 error_at ((*cexpr_list)[0].get_location (),
11108 "invalid type-generic return type for "
11109 "argument %u of %<__builtin_tgmath%>",
11111 expr.set_error ();
11112 goto out;
11114 if (!SCALAR_FLOAT_TYPE_P (ret)
11115 && !COMPLEX_FLOAT_TYPE_P (ret))
11117 error_at ((*cexpr_list)[j].get_location (),
11118 "invalid type-generic return type for "
11119 "argument %u of %<__builtin_tgmath%>",
11120 j + 1);
11121 expr.set_error ();
11122 goto out;
11125 if (TREE_CODE (ret) == COMPLEX_TYPE)
11126 parm_complex[0] = true;
11127 argpos = 1;
11128 FOREACH_FUNCTION_ARGS (type, t, iter)
11130 if (t == void_type_node)
11131 break;
11132 t = TYPE_MAIN_VARIANT (t);
11133 if (t != parm_first[argpos])
11135 parm_varies[argpos] = true;
11136 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
11137 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
11139 error_at ((*cexpr_list)[0].get_location (),
11140 "invalid type-generic type for "
11141 "argument %u of argument %u of "
11142 "%<__builtin_tgmath%>", argpos, 1);
11143 expr.set_error ();
11144 goto out;
11146 if (!SCALAR_FLOAT_TYPE_P (t)
11147 && !COMPLEX_FLOAT_TYPE_P (t))
11149 error_at ((*cexpr_list)[j].get_location (),
11150 "invalid type-generic type for "
11151 "argument %u of argument %u of "
11152 "%<__builtin_tgmath%>", argpos, j + 1);
11153 expr.set_error ();
11154 goto out;
11157 if (TREE_CODE (t) == COMPLEX_TYPE)
11158 parm_complex[argpos] = true;
11159 argpos++;
11162 enum tgmath_parm_kind max_variation = tgmath_fixed;
11163 for (unsigned int j = 0; j <= nargs; j++)
11165 enum tgmath_parm_kind this_kind;
11166 if (parm_varies[j])
11168 if (parm_complex[j])
11169 max_variation = this_kind = tgmath_complex;
11170 else
11172 this_kind = tgmath_real;
11173 if (max_variation != tgmath_complex)
11174 max_variation = tgmath_real;
11177 else
11178 this_kind = tgmath_fixed;
11179 parm_kind.quick_push (this_kind);
11181 if (max_variation == tgmath_fixed)
11183 error_at (loc, "function arguments of %<__builtin_tgmath%> "
11184 "all have the same type");
11185 expr.set_error ();
11186 break;
11189 /* Identify a parameter (not the return type) that varies,
11190 including with complex types if any variation includes
11191 complex types; there must be at least one such
11192 parameter. */
11193 unsigned int tgarg = 0;
11194 for (unsigned int j = 1; j <= nargs; j++)
11195 if (parm_kind[j] == max_variation)
11197 tgarg = j;
11198 break;
11200 if (tgarg == 0)
11202 error_at (loc, "function arguments of %<__builtin_tgmath%> "
11203 "lack type-generic parameter");
11204 expr.set_error ();
11205 break;
11208 /* Determine the type of the relevant parameter for each
11209 function. */
11210 auto_vec<tree> tg_type (num_functions);
11211 for (unsigned int j = 0; j < num_functions; j++)
11213 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11214 argpos = 1;
11215 FOREACH_FUNCTION_ARGS (type, t, iter)
11217 if (argpos == tgarg)
11219 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
11220 break;
11222 argpos++;
11226 /* Verify that the corresponding types are different for
11227 all the listed functions. Also determine whether all
11228 the types are complex, whether all the types are
11229 standard or binary, and whether all the types are
11230 decimal. */
11231 bool all_complex = true;
11232 bool all_binary = true;
11233 bool all_decimal = true;
11234 hash_set<tree> tg_types;
11235 FOR_EACH_VEC_ELT (tg_type, i, t)
11237 if (TREE_CODE (t) == COMPLEX_TYPE)
11238 all_decimal = false;
11239 else
11241 all_complex = false;
11242 if (DECIMAL_FLOAT_TYPE_P (t))
11243 all_binary = false;
11244 else
11245 all_decimal = false;
11247 if (tg_types.add (t))
11249 error_at ((*cexpr_list)[i].get_location (),
11250 "duplicate type-generic parameter type for "
11251 "function argument %u of %<__builtin_tgmath%>",
11252 i + 1);
11253 expr.set_error ();
11254 goto out;
11258 /* Verify that other parameters and the return type whose
11259 types vary have their types varying in the correct
11260 way. */
11261 for (unsigned int j = 0; j < num_functions; j++)
11263 tree exp_type = tg_type[j];
11264 tree exp_real_type = exp_type;
11265 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
11266 exp_real_type = TREE_TYPE (exp_type);
11267 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11268 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
11269 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
11270 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
11272 error_at ((*cexpr_list)[j].get_location (),
11273 "bad return type for function argument %u "
11274 "of %<__builtin_tgmath%>", j + 1);
11275 expr.set_error ();
11276 goto out;
11278 argpos = 1;
11279 FOREACH_FUNCTION_ARGS (type, t, iter)
11281 if (t == void_type_node)
11282 break;
11283 t = TYPE_MAIN_VARIANT (t);
11284 if ((parm_kind[argpos] == tgmath_complex
11285 && t != exp_type)
11286 || (parm_kind[argpos] == tgmath_real
11287 && t != exp_real_type))
11289 error_at ((*cexpr_list)[j].get_location (),
11290 "bad type for argument %u of "
11291 "function argument %u of "
11292 "%<__builtin_tgmath%>", argpos, j + 1);
11293 expr.set_error ();
11294 goto out;
11296 argpos++;
11300 /* The functions listed are a valid set of functions for a
11301 <tgmath.h> macro to select between. Identify the
11302 matching function, if any. First, the argument types
11303 must be combined following <tgmath.h> rules. Integer
11304 types are treated as _Decimal64 if any type-generic
11305 argument is decimal, or if the only alternatives for
11306 type-generic arguments are of decimal types, and are
11307 otherwise treated as _Float32x (or _Complex _Float32x
11308 for complex integer types) if any type-generic argument
11309 has _FloatNx type, otherwise as double (or _Complex
11310 double for complex integer types). After that
11311 adjustment, types are combined following the usual
11312 arithmetic conversions. If the function only accepts
11313 complex arguments, a complex type is produced. */
11314 bool arg_complex = all_complex;
11315 bool arg_binary = all_binary;
11316 bool arg_int_decimal = all_decimal;
11317 bool arg_int_floatnx = false;
11318 for (unsigned int j = 1; j <= nargs; j++)
11320 if (parm_kind[j] == tgmath_fixed)
11321 continue;
11322 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
11323 tree type = TREE_TYPE (ce->value);
11324 if (!INTEGRAL_TYPE_P (type)
11325 && !SCALAR_FLOAT_TYPE_P (type)
11326 && TREE_CODE (type) != COMPLEX_TYPE)
11328 error_at (ce->get_location (),
11329 "invalid type of argument %u of type-generic "
11330 "function", j);
11331 expr.set_error ();
11332 goto out;
11334 if (DECIMAL_FLOAT_TYPE_P (type))
11336 arg_int_decimal = true;
11337 if (all_complex)
11339 error_at (ce->get_location (),
11340 "decimal floating-point argument %u to "
11341 "complex-only type-generic function", j);
11342 expr.set_error ();
11343 goto out;
11345 else if (all_binary)
11347 error_at (ce->get_location (),
11348 "decimal floating-point argument %u to "
11349 "binary-only type-generic function", j);
11350 expr.set_error ();
11351 goto out;
11353 else if (arg_complex)
11355 error_at (ce->get_location (),
11356 "both complex and decimal floating-point "
11357 "arguments to type-generic function");
11358 expr.set_error ();
11359 goto out;
11361 else if (arg_binary)
11363 error_at (ce->get_location (),
11364 "both binary and decimal floating-point "
11365 "arguments to type-generic function");
11366 expr.set_error ();
11367 goto out;
11370 else if (TREE_CODE (type) == COMPLEX_TYPE)
11372 arg_complex = true;
11373 if (COMPLEX_FLOAT_TYPE_P (type))
11374 arg_binary = true;
11375 if (all_decimal)
11377 error_at (ce->get_location (),
11378 "complex argument %u to "
11379 "decimal-only type-generic function", j);
11380 expr.set_error ();
11381 goto out;
11383 else if (arg_int_decimal)
11385 error_at (ce->get_location (),
11386 "both complex and decimal floating-point "
11387 "arguments to type-generic function");
11388 expr.set_error ();
11389 goto out;
11392 else if (SCALAR_FLOAT_TYPE_P (type))
11394 arg_binary = true;
11395 if (all_decimal)
11397 error_at (ce->get_location (),
11398 "binary argument %u to "
11399 "decimal-only type-generic function", j);
11400 expr.set_error ();
11401 goto out;
11403 else if (arg_int_decimal)
11405 error_at (ce->get_location (),
11406 "both binary and decimal floating-point "
11407 "arguments to type-generic function");
11408 expr.set_error ();
11409 goto out;
11412 tree rtype = TYPE_MAIN_VARIANT (type);
11413 if (TREE_CODE (rtype) == COMPLEX_TYPE)
11414 rtype = TREE_TYPE (rtype);
11415 if (SCALAR_FLOAT_TYPE_P (rtype))
11416 for (unsigned int j = 0; j < NUM_FLOATNX_TYPES; j++)
11417 if (rtype == FLOATNX_TYPE_NODE (j))
11419 arg_int_floatnx = true;
11420 break;
11423 tree arg_real = NULL_TREE;
11424 for (unsigned int j = 1; j <= nargs; j++)
11426 if (parm_kind[j] == tgmath_fixed)
11427 continue;
11428 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
11429 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
11430 if (TREE_CODE (type) == COMPLEX_TYPE)
11431 type = TREE_TYPE (type);
11432 if (INTEGRAL_TYPE_P (type))
11433 type = (arg_int_decimal
11434 ? dfloat64_type_node
11435 : arg_int_floatnx
11436 ? float32x_type_node
11437 : double_type_node);
11438 if (arg_real == NULL_TREE)
11439 arg_real = type;
11440 else
11441 arg_real = common_type (arg_real, type);
11442 if (arg_real == error_mark_node)
11444 expr.set_error ();
11445 goto out;
11448 tree arg_type = (arg_complex
11449 ? build_complex_type (arg_real)
11450 : arg_real);
11452 /* Look for a function to call with type-generic parameter
11453 type ARG_TYPE. */
11454 c_expr_t *fn = NULL;
11455 for (unsigned int j = 0; j < num_functions; j++)
11457 if (tg_type[j] == arg_type)
11459 fn = &(*cexpr_list)[j];
11460 break;
11463 if (fn == NULL
11464 && parm_kind[0] == tgmath_fixed
11465 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
11467 /* Presume this is a macro that rounds its result to a
11468 narrower type, and look for the first function with
11469 at least the range and precision of the argument
11470 type. */
11471 for (unsigned int j = 0; j < num_functions; j++)
11473 if (arg_complex
11474 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
11475 continue;
11476 tree real_tg_type = (arg_complex
11477 ? TREE_TYPE (tg_type[j])
11478 : tg_type[j]);
11479 if (DECIMAL_FLOAT_TYPE_P (arg_real)
11480 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
11481 continue;
11482 scalar_float_mode arg_mode
11483 = SCALAR_FLOAT_TYPE_MODE (arg_real);
11484 scalar_float_mode tg_mode
11485 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
11486 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
11487 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
11488 if (arg_fmt->b == tg_fmt->b
11489 && arg_fmt->p <= tg_fmt->p
11490 && arg_fmt->emax <= tg_fmt->emax
11491 && (arg_fmt->emin - arg_fmt->p
11492 >= tg_fmt->emin - tg_fmt->p))
11494 fn = &(*cexpr_list)[j];
11495 break;
11499 if (fn == NULL)
11501 error_at (loc, "no matching function for type-generic call");
11502 expr.set_error ();
11503 break;
11506 /* Construct a call to FN. */
11507 vec<tree, va_gc> *args;
11508 vec_alloc (args, nargs);
11509 vec<tree, va_gc> *origtypes;
11510 vec_alloc (origtypes, nargs);
11511 auto_vec<location_t> arg_loc (nargs);
11512 for (unsigned int j = 0; j < nargs; j++)
11514 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
11515 args->quick_push (ce->value);
11516 arg_loc.quick_push (ce->get_location ());
11517 origtypes->quick_push (ce->original_type);
11519 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
11520 args, origtypes);
11521 set_c_expr_source_range (&expr, loc, close_paren_loc);
11522 break;
11524 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
11526 vec<c_expr_t, va_gc> *cexpr_list;
11527 c_expr_t *e2_p;
11528 tree chain_value;
11529 location_t close_paren_loc;
11531 c_parser_consume_token (parser);
11532 if (!c_parser_get_builtin_args (parser,
11533 "__builtin_call_with_static_chain",
11534 &cexpr_list, false,
11535 &close_paren_loc))
11537 expr.set_error ();
11538 break;
11540 if (vec_safe_length (cexpr_list) != 2)
11542 error_at (loc, "wrong number of arguments to "
11543 "%<__builtin_call_with_static_chain%>");
11544 expr.set_error ();
11545 break;
11548 expr = (*cexpr_list)[0];
11549 e2_p = &(*cexpr_list)[1];
11550 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
11551 chain_value = e2_p->value;
11552 mark_exp_read (chain_value);
11554 if (TREE_CODE (expr.value) != CALL_EXPR)
11555 error_at (loc, "first argument to "
11556 "%<__builtin_call_with_static_chain%> "
11557 "must be a call expression");
11558 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
11559 error_at (loc, "second argument to "
11560 "%<__builtin_call_with_static_chain%> "
11561 "must be a pointer type");
11562 else
11563 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
11564 set_c_expr_source_range (&expr, loc, close_paren_loc);
11565 break;
11567 case RID_BUILTIN_COMPLEX:
11569 vec<c_expr_t, va_gc> *cexpr_list;
11570 c_expr_t *e1_p, *e2_p;
11571 location_t close_paren_loc;
11573 c_parser_consume_token (parser);
11574 if (!c_parser_get_builtin_args (parser,
11575 "__builtin_complex",
11576 &cexpr_list, false,
11577 &close_paren_loc))
11579 expr.set_error ();
11580 break;
11583 if (vec_safe_length (cexpr_list) != 2)
11585 error_at (loc, "wrong number of arguments to "
11586 "%<__builtin_complex%>");
11587 expr.set_error ();
11588 break;
11591 e1_p = &(*cexpr_list)[0];
11592 e2_p = &(*cexpr_list)[1];
11594 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
11595 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
11596 e1_p->value = convert (TREE_TYPE (e1_p->value),
11597 TREE_OPERAND (e1_p->value, 0));
11598 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
11599 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
11600 e2_p->value = convert (TREE_TYPE (e2_p->value),
11601 TREE_OPERAND (e2_p->value, 0));
11602 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
11603 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
11604 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
11605 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
11607 error_at (loc, "%<__builtin_complex%> operand "
11608 "not of real binary floating-point type");
11609 expr.set_error ();
11610 break;
11612 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
11613 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
11615 error_at (loc,
11616 "%<__builtin_complex%> operands of different types");
11617 expr.set_error ();
11618 break;
11620 pedwarn_c90 (loc, OPT_Wpedantic,
11621 "ISO C90 does not support complex types");
11622 expr.value = build2_loc (loc, COMPLEX_EXPR,
11623 build_complex_type
11624 (TYPE_MAIN_VARIANT
11625 (TREE_TYPE (e1_p->value))),
11626 e1_p->value, e2_p->value);
11627 set_c_expr_source_range (&expr, loc, close_paren_loc);
11628 break;
11630 case RID_BUILTIN_SHUFFLE:
11632 vec<c_expr_t, va_gc> *cexpr_list;
11633 unsigned int i;
11634 c_expr_t *p;
11635 location_t close_paren_loc;
11637 c_parser_consume_token (parser);
11638 if (!c_parser_get_builtin_args (parser,
11639 "__builtin_shuffle",
11640 &cexpr_list, false,
11641 &close_paren_loc))
11643 expr.set_error ();
11644 break;
11647 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
11648 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11650 if (vec_safe_length (cexpr_list) == 2)
11651 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
11652 NULL_TREE,
11653 (*cexpr_list)[1].value);
11655 else if (vec_safe_length (cexpr_list) == 3)
11656 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
11657 (*cexpr_list)[1].value,
11658 (*cexpr_list)[2].value);
11659 else
11661 error_at (loc, "wrong number of arguments to "
11662 "%<__builtin_shuffle%>");
11663 expr.set_error ();
11665 set_c_expr_source_range (&expr, loc, close_paren_loc);
11666 break;
11668 case RID_BUILTIN_SHUFFLEVECTOR:
11670 vec<c_expr_t, va_gc> *cexpr_list;
11671 unsigned int i;
11672 c_expr_t *p;
11673 location_t close_paren_loc;
11675 c_parser_consume_token (parser);
11676 if (!c_parser_get_builtin_args (parser,
11677 "__builtin_shufflevector",
11678 &cexpr_list, false,
11679 &close_paren_loc))
11681 expr.set_error ();
11682 break;
11685 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
11686 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11688 if (vec_safe_length (cexpr_list) < 3)
11690 error_at (loc, "wrong number of arguments to "
11691 "%<__builtin_shuffle%>");
11692 expr.set_error ();
11694 else
11696 auto_vec<tree, 16> mask;
11697 for (i = 2; i < cexpr_list->length (); ++i)
11698 mask.safe_push ((*cexpr_list)[i].value);
11699 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
11700 (*cexpr_list)[1].value,
11701 mask);
11703 set_c_expr_source_range (&expr, loc, close_paren_loc);
11704 break;
11706 case RID_BUILTIN_CONVERTVECTOR:
11708 location_t start_loc = loc;
11709 c_parser_consume_token (parser);
11710 matching_parens parens;
11711 if (!parens.require_open (parser))
11713 expr.set_error ();
11714 break;
11716 e1 = c_parser_expr_no_commas (parser, NULL);
11717 mark_exp_read (e1.value);
11718 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
11720 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
11721 expr.set_error ();
11722 break;
11724 loc = c_parser_peek_token (parser)->location;
11725 t1 = c_parser_type_name (parser);
11726 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
11727 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11728 "expected %<)%>");
11729 if (t1 == NULL)
11730 expr.set_error ();
11731 else
11733 tree type_expr = NULL_TREE;
11734 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
11735 groktypename (t1, &type_expr,
11736 NULL));
11737 set_c_expr_source_range (&expr, start_loc, end_loc);
11740 break;
11741 case RID_BUILTIN_ASSOC_BARRIER:
11743 location_t start_loc = loc;
11744 c_parser_consume_token (parser);
11745 matching_parens parens;
11746 if (!parens.require_open (parser))
11748 expr.set_error ();
11749 break;
11751 e1 = c_parser_expr_no_commas (parser, NULL);
11752 mark_exp_read (e1.value);
11753 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
11754 parens.skip_until_found_close (parser);
11755 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
11756 set_c_expr_source_range (&expr, start_loc, end_loc);
11758 break;
11759 case RID_BUILTIN_STDC:
11761 vec<c_expr_t, va_gc> *cexpr_list;
11762 c_expr_t *arg_p;
11763 location_t close_paren_loc;
11764 enum c_builtin_stdc {
11765 C_BUILTIN_STDC_BIT_CEIL,
11766 C_BUILTIN_STDC_BIT_FLOOR,
11767 C_BUILTIN_STDC_BIT_WIDTH,
11768 C_BUILTIN_STDC_COUNT_ONES,
11769 C_BUILTIN_STDC_COUNT_ZEROS,
11770 C_BUILTIN_STDC_FIRST_LEADING_ONE,
11771 C_BUILTIN_STDC_FIRST_LEADING_ZERO,
11772 C_BUILTIN_STDC_FIRST_TRAILING_ONE,
11773 C_BUILTIN_STDC_FIRST_TRAILING_ZERO,
11774 C_BUILTIN_STDC_HAS_SINGLE_BIT,
11775 C_BUILTIN_STDC_LEADING_ONES,
11776 C_BUILTIN_STDC_LEADING_ZEROS,
11777 C_BUILTIN_STDC_TRAILING_ONES,
11778 C_BUILTIN_STDC_TRAILING_ZEROS,
11779 C_BUILTIN_STDC_MAX
11780 } stdc_rid = C_BUILTIN_STDC_MAX;
11781 const char *name
11782 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
11783 switch (name[sizeof ("__builtin_stdc_") - 1])
11785 case 'b':
11786 switch (name[sizeof ("__builtin_stdc_bit_") - 1])
11788 case 'c':
11789 stdc_rid = C_BUILTIN_STDC_BIT_CEIL;
11790 break;
11791 case 'f':
11792 stdc_rid = C_BUILTIN_STDC_BIT_FLOOR;
11793 break;
11794 default:
11795 stdc_rid = C_BUILTIN_STDC_BIT_WIDTH;
11796 break;
11798 break;
11799 case 'c':
11800 if (name[sizeof ("__builtin_stdc_count_") - 1] == 'o')
11801 stdc_rid = C_BUILTIN_STDC_COUNT_ONES;
11802 else
11803 stdc_rid = C_BUILTIN_STDC_COUNT_ZEROS;
11804 break;
11805 case 'f':
11806 switch (name[sizeof ("__builtin_stdc_first_trailing_") - 1])
11808 case 'n':
11809 stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ONE;
11810 break;
11811 case 'e':
11812 stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ZERO;
11813 break;
11814 case 'o':
11815 stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ONE;
11816 break;
11817 default:
11818 stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ZERO;
11819 break;
11821 break;
11822 case 'h':
11823 stdc_rid = C_BUILTIN_STDC_HAS_SINGLE_BIT;
11824 break;
11825 case 'l':
11826 if (name[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
11827 stdc_rid = C_BUILTIN_STDC_LEADING_ONES;
11828 else
11829 stdc_rid = C_BUILTIN_STDC_LEADING_ZEROS;
11830 break;
11831 case 't':
11832 if (name[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
11833 stdc_rid = C_BUILTIN_STDC_TRAILING_ONES;
11834 else
11835 stdc_rid = C_BUILTIN_STDC_TRAILING_ZEROS;
11836 break;
11838 gcc_checking_assert (stdc_rid != C_BUILTIN_STDC_MAX);
11840 c_parser_consume_token (parser);
11841 if (!c_parser_get_builtin_args (parser, name,
11842 &cexpr_list, false,
11843 &close_paren_loc))
11845 expr.set_error ();
11846 break;
11849 if (vec_safe_length (cexpr_list) != 1)
11851 error_at (loc, "wrong number of arguments to %qs", name);
11852 expr.set_error ();
11853 break;
11856 arg_p = &(*cexpr_list)[0];
11857 *arg_p = convert_lvalue_to_rvalue (loc, *arg_p, true, true);
11858 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p->value)))
11860 error_at (loc, "%qs operand not an integral type", name);
11861 expr.set_error ();
11862 break;
11864 tree arg = arg_p->value;
11865 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
11866 /* Expand:
11867 __builtin_stdc_leading_zeros (arg) as
11868 (unsigned int) __builtin_clzg (arg, prec)
11869 __builtin_stdc_leading_ones (arg) as
11870 (unsigned int) __builtin_clzg ((type) ~arg, prec)
11871 __builtin_stdc_trailing_zeros (arg) as
11872 (unsigned int) __builtin_ctzg (arg, prec)
11873 __builtin_stdc_trailing_ones (arg) as
11874 (unsigned int) __builtin_ctzg ((type) ~arg, prec)
11875 __builtin_stdc_first_leading_zero (arg) as
11876 __builtin_clzg ((type) ~arg, -1) + 1U
11877 __builtin_stdc_first_leading_one (arg) as
11878 __builtin_clzg (arg, -1) + 1U
11879 __builtin_stdc_first_trailing_zero (arg) as
11880 __builtin_ctzg ((type) ~arg, -1) + 1U
11881 __builtin_stdc_first_trailing_one (arg) as
11882 __builtin_ctzg (arg, -1) + 1U
11883 __builtin_stdc_count_zeros (arg) as
11884 (unsigned int) __builtin_popcountg ((type) ~arg)
11885 __builtin_stdc_count_ones (arg) as
11886 (unsigned int) __builtin_popcountg (arg)
11887 __builtin_stdc_has_single_bit (arg) as
11888 (_Bool) (__builtin_popcountg (arg) == 1)
11889 __builtin_stdc_bit_width (arg) as
11890 (unsigned int) (prec - __builtin_clzg (arg, prec))
11891 __builtin_stdc_bit_floor (arg) as
11892 arg == 0 ? (type) 0
11893 : (type) 1 << (prec - 1 - __builtin_clzg (arg))
11894 __builtin_stdc_bit_ceil (arg) as
11895 arg <= 1 ? (type) 1
11896 : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
11897 without evaluating arg multiple times, type being
11898 __typeof (arg) and prec __builtin_popcountg ((type) ~0)). */
11899 int prec = TYPE_PRECISION (type);
11900 tree barg1 = arg;
11901 switch (stdc_rid)
11903 case C_BUILTIN_STDC_BIT_CEIL:
11904 arg = save_expr (arg);
11905 barg1 = build2_loc (loc, PLUS_EXPR, type, arg,
11906 build_int_cst (type, -1));
11907 break;
11908 case C_BUILTIN_STDC_BIT_FLOOR:
11909 barg1 = arg = save_expr (arg);
11910 break;
11911 case C_BUILTIN_STDC_COUNT_ZEROS:
11912 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
11913 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
11914 case C_BUILTIN_STDC_LEADING_ONES:
11915 case C_BUILTIN_STDC_TRAILING_ONES:
11916 barg1 = build1_loc (loc, BIT_NOT_EXPR, type, arg);
11917 break;
11918 default:
11919 break;
11921 tree barg2 = NULL_TREE;
11922 switch (stdc_rid)
11924 case C_BUILTIN_STDC_BIT_WIDTH:
11925 case C_BUILTIN_STDC_LEADING_ONES:
11926 case C_BUILTIN_STDC_LEADING_ZEROS:
11927 case C_BUILTIN_STDC_TRAILING_ONES:
11928 case C_BUILTIN_STDC_TRAILING_ZEROS:
11929 barg2 = build_int_cst (integer_type_node, prec);
11930 break;
11931 case C_BUILTIN_STDC_FIRST_LEADING_ONE:
11932 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
11933 case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
11934 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
11935 barg2 = integer_minus_one_node;
11936 break;
11937 default:
11938 break;
11940 tree fndecl = NULL_TREE;
11941 switch (stdc_rid)
11943 case C_BUILTIN_STDC_BIT_CEIL:
11944 case C_BUILTIN_STDC_BIT_FLOOR:
11945 case C_BUILTIN_STDC_BIT_WIDTH:
11946 case C_BUILTIN_STDC_FIRST_LEADING_ONE:
11947 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
11948 case C_BUILTIN_STDC_LEADING_ONES:
11949 case C_BUILTIN_STDC_LEADING_ZEROS:
11950 fndecl = builtin_decl_explicit (BUILT_IN_CLZG);
11951 break;
11952 case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
11953 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
11954 case C_BUILTIN_STDC_TRAILING_ONES:
11955 case C_BUILTIN_STDC_TRAILING_ZEROS:
11956 fndecl = builtin_decl_explicit (BUILT_IN_CTZG);
11957 break;
11958 case C_BUILTIN_STDC_COUNT_ONES:
11959 case C_BUILTIN_STDC_COUNT_ZEROS:
11960 case C_BUILTIN_STDC_HAS_SINGLE_BIT:
11961 fndecl = builtin_decl_explicit (BUILT_IN_POPCOUNTG);
11962 break;
11963 default:
11964 gcc_unreachable ();
11966 /* Construct a call to __builtin_{clz,ctz,popcount}g. */
11967 int nargs = barg2 != NULL_TREE ? 2 : 1;
11968 vec<tree, va_gc> *args;
11969 vec_alloc (args, nargs);
11970 vec<tree, va_gc> *origtypes;
11971 vec_alloc (origtypes, nargs);
11972 auto_vec<location_t> arg_loc (nargs);
11973 args->quick_push (barg1);
11974 arg_loc.quick_push (arg_p->get_location ());
11975 origtypes->quick_push (arg_p->original_type);
11976 if (nargs == 2)
11978 args->quick_push (barg2);
11979 arg_loc.quick_push (loc);
11980 origtypes->quick_push (integer_type_node);
11982 expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
11983 args, origtypes);
11984 set_c_expr_source_range (&expr, loc, close_paren_loc);
11985 if (expr.value == error_mark_node)
11986 break;
11987 switch (stdc_rid)
11989 case C_BUILTIN_STDC_BIT_CEIL:
11990 case C_BUILTIN_STDC_BIT_FLOOR:
11991 --prec;
11992 /* FALLTHRU */
11993 case C_BUILTIN_STDC_BIT_WIDTH:
11994 expr.value = build2_loc (loc, MINUS_EXPR, integer_type_node,
11995 build_int_cst (integer_type_node,
11996 prec), expr.value);
11997 break;
11998 case C_BUILTIN_STDC_FIRST_LEADING_ONE:
11999 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
12000 case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
12001 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
12002 expr.value = build2_loc (loc, PLUS_EXPR, integer_type_node,
12003 expr.value, integer_one_node);
12004 break;
12005 case C_BUILTIN_STDC_HAS_SINGLE_BIT:
12006 expr.value = build2_loc (loc, EQ_EXPR, boolean_type_node,
12007 expr.value, integer_one_node);
12008 break;
12009 default:
12010 break;
12013 if (stdc_rid != C_BUILTIN_STDC_BIT_CEIL
12014 && stdc_rid != C_BUILTIN_STDC_BIT_FLOOR)
12016 if (stdc_rid != C_BUILTIN_STDC_HAS_SINGLE_BIT)
12017 expr.value = fold_convert_loc (loc, unsigned_type_node,
12018 expr.value);
12019 break;
12021 /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
12022 or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
12023 warnings. The LSHIFT_EXPR is in dead code in that case. */
12024 if (integer_zerop (arg)
12025 || (stdc_rid == C_BUILTIN_STDC_BIT_CEIL && integer_onep (arg)))
12026 expr.value = build_int_cst (type, 0);
12027 else
12028 expr.value
12029 = build2_loc (loc, LSHIFT_EXPR, type,
12030 build_int_cst (type,
12031 (stdc_rid
12032 == C_BUILTIN_STDC_BIT_CEIL
12033 ? 2 : 1)), expr.value);
12034 if (stdc_rid == C_BUILTIN_STDC_BIT_CEIL)
12035 expr.value = build3_loc (loc, COND_EXPR, type,
12036 build2_loc (loc, LE_EXPR,
12037 boolean_type_node, arg,
12038 build_int_cst (type, 1)),
12039 build_int_cst (type, 1),
12040 expr.value);
12041 else
12042 expr.value = build3_loc (loc, COND_EXPR, type,
12043 build2_loc (loc, EQ_EXPR,
12044 boolean_type_node, arg,
12045 build_int_cst (type, 0)),
12046 build_int_cst (type, 0),
12047 expr.value);
12048 break;
12050 case RID_AT_SELECTOR:
12052 gcc_assert (c_dialect_objc ());
12053 c_parser_consume_token (parser);
12054 matching_parens parens;
12055 if (!parens.require_open (parser))
12057 expr.set_error ();
12058 break;
12060 tree sel = c_parser_objc_selector_arg (parser);
12061 location_t close_loc = c_parser_peek_token (parser)->location;
12062 parens.skip_until_found_close (parser);
12063 expr.value = objc_build_selector_expr (loc, sel);
12064 set_c_expr_source_range (&expr, loc, close_loc);
12066 break;
12067 case RID_AT_PROTOCOL:
12069 gcc_assert (c_dialect_objc ());
12070 c_parser_consume_token (parser);
12071 matching_parens parens;
12072 if (!parens.require_open (parser))
12074 expr.set_error ();
12075 break;
12077 if (c_parser_next_token_is_not (parser, CPP_NAME))
12079 c_parser_error (parser, "expected identifier");
12080 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
12081 expr.set_error ();
12082 break;
12084 tree id = c_parser_peek_token (parser)->value;
12085 c_parser_consume_token (parser);
12086 location_t close_loc = c_parser_peek_token (parser)->location;
12087 parens.skip_until_found_close (parser);
12088 expr.value = objc_build_protocol_expr (id);
12089 set_c_expr_source_range (&expr, loc, close_loc);
12091 break;
12092 case RID_AT_ENCODE:
12094 /* Extension to support C-structures in the archiver. */
12095 gcc_assert (c_dialect_objc ());
12096 c_parser_consume_token (parser);
12097 matching_parens parens;
12098 if (!parens.require_open (parser))
12100 expr.set_error ();
12101 break;
12103 t1 = c_parser_type_name (parser);
12104 if (t1 == NULL)
12106 expr.set_error ();
12107 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
12108 break;
12110 location_t close_loc = c_parser_peek_token (parser)->location;
12111 parens.skip_until_found_close (parser);
12112 tree type = groktypename (t1, NULL, NULL);
12113 expr.value = objc_build_encode_expr (type);
12114 set_c_expr_source_range (&expr, loc, close_loc);
12116 break;
12117 case RID_GENERIC:
12118 expr = c_parser_generic_selection (parser);
12119 break;
12120 case RID_OMP_ALL_MEMORY:
12121 gcc_assert (flag_openmp);
12122 c_parser_consume_token (parser);
12123 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
12124 "%<depend%> clause");
12125 expr.set_error ();
12126 break;
12127 /* C23 'nullptr' literal. */
12128 case RID_NULLPTR:
12129 c_parser_consume_token (parser);
12130 expr.value = nullptr_node;
12131 set_c_expr_source_range (&expr, tok_range);
12132 pedwarn_c11 (loc, OPT_Wpedantic,
12133 "ISO C does not support %qs before C23", "nullptr");
12134 break;
12135 case RID_TRUE:
12136 c_parser_consume_token (parser);
12137 expr.value = boolean_true_node;
12138 set_c_expr_source_range (&expr, tok_range);
12139 break;
12140 case RID_FALSE:
12141 c_parser_consume_token (parser);
12142 expr.value = boolean_false_node;
12143 set_c_expr_source_range (&expr, tok_range);
12144 break;
12145 default:
12146 c_parser_error (parser, "expected expression");
12147 expr.set_error ();
12148 break;
12150 break;
12151 case CPP_OPEN_SQUARE:
12152 if (c_dialect_objc ())
12154 tree receiver, args;
12155 c_parser_consume_token (parser);
12156 receiver = c_parser_objc_receiver (parser);
12157 args = c_parser_objc_message_args (parser);
12158 location_t close_loc = c_parser_peek_token (parser)->location;
12159 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
12160 "expected %<]%>");
12161 expr.value = objc_build_message_expr (receiver, args);
12162 set_c_expr_source_range (&expr, loc, close_loc);
12163 break;
12165 /* Else fall through to report error. */
12166 /* FALLTHRU */
12167 default:
12168 c_parser_error (parser, "expected expression");
12169 expr.set_error ();
12170 break;
12172 out:
12173 return c_parser_postfix_expression_after_primary
12174 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
12177 /* Parse a postfix expression after a parenthesized type name: the
12178 brace-enclosed initializer of a compound literal, possibly followed
12179 by some postfix operators. This is separate because it is not
12180 possible to tell until after the type name whether a cast
12181 expression has a cast or a compound literal, or whether the operand
12182 of sizeof is a parenthesized type name or starts with a compound
12183 literal. TYPE_LOC is the location where TYPE_NAME starts--the
12184 location of the first token after the parentheses around the type
12185 name. */
12187 static struct c_expr
12188 c_parser_postfix_expression_after_paren_type (c_parser *parser,
12189 struct c_declspecs *scspecs,
12190 struct c_type_name *type_name,
12191 location_t type_loc)
12193 tree type;
12194 struct c_expr init;
12195 bool non_const;
12196 struct c_expr expr;
12197 location_t start_loc;
12198 tree type_expr = NULL_TREE;
12199 bool type_expr_const = true;
12200 bool constexpr_p = scspecs ? scspecs->constexpr_p : false;
12201 unsigned int underspec_state = 0;
12202 check_compound_literal_type (type_loc, type_name);
12203 rich_location richloc (line_table, type_loc);
12204 start_loc = c_parser_peek_token (parser)->location;
12205 if (constexpr_p)
12207 underspec_state = start_underspecified_init (start_loc, NULL_TREE);
12208 /* A constexpr compound literal is subject to the constraints on
12209 underspecified declarations, which may not declare tags or
12210 members or structures or unions; it is undefined behavior to
12211 declare the members of an enumeration. Where the structure,
12212 union or enumeration type is declared within the compound
12213 literal initializer, this is diagnosed elsewhere as a result
12214 of the above call to start_underspecified_init. Diagnose
12215 here the case of declaring such a type in the type specifiers
12216 of the compound literal. */
12217 switch (type_name->specs->typespec_kind)
12219 case ctsk_tagfirstref:
12220 case ctsk_tagfirstref_attrs:
12221 error_at (type_loc, "%qT declared in %<constexpr%> compound literal",
12222 type_name->specs->type);
12223 break;
12225 case ctsk_tagdef:
12226 error_at (type_loc, "%qT defined in %<constexpr%> compound literal",
12227 type_name->specs->type);
12228 break;
12230 default:
12231 break;
12234 start_init (NULL_TREE, NULL,
12235 (global_bindings_p ()
12236 || (scspecs && scspecs->storage_class == csc_static)
12237 || constexpr_p), constexpr_p, &richloc);
12238 type = groktypename (type_name, &type_expr, &type_expr_const);
12239 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
12241 error_at (type_loc, "compound literal has variable size");
12242 type = error_mark_node;
12244 else if (TREE_CODE (type) == FUNCTION_TYPE)
12246 error_at (type_loc, "compound literal has function type");
12247 type = error_mark_node;
12249 if (constexpr_p && type != error_mark_node)
12251 tree type_no_array = strip_array_types (type);
12252 /* The type of a constexpr object must not be variably modified
12253 (which applies to all compound literals), volatile, atomic or
12254 restrict qualified or have a member with such a qualifier.
12255 const qualification is implicitly added. */
12256 if (TYPE_QUALS (type_no_array)
12257 & (TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC))
12258 error_at (type_loc, "invalid qualifiers for %<constexpr%> object");
12259 else if (RECORD_OR_UNION_TYPE_P (type_no_array)
12260 && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array))
12261 error_at (type_loc, "invalid qualifiers for field of "
12262 "%<constexpr%> object");
12263 type = c_build_qualified_type (type,
12264 (TYPE_QUALS (type_no_array)
12265 | TYPE_QUAL_CONST));
12267 init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
12268 if (constexpr_p)
12269 finish_underspecified_init (NULL_TREE, underspec_state);
12270 finish_init ();
12271 maybe_warn_string_init (type_loc, type, init);
12273 if (type != error_mark_node
12274 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
12275 && current_function_decl)
12277 error ("compound literal qualified by address-space qualifier");
12278 type = error_mark_node;
12281 if (!pedwarn_c90 (start_loc, OPT_Wpedantic,
12282 "ISO C90 forbids compound literals") && scspecs)
12283 pedwarn_c11 (start_loc, OPT_Wpedantic,
12284 "ISO C forbids storage class specifiers in compound literals "
12285 "before C23");
12286 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
12287 ? CONSTRUCTOR_NON_CONST (init.value)
12288 : init.original_code == C_MAYBE_CONST_EXPR);
12289 non_const |= !type_expr_const;
12290 unsigned int alignas_align = 0;
12291 if (type != error_mark_node
12292 && type_name->specs->align_log != -1)
12294 alignas_align = 1U << type_name->specs->align_log;
12295 if (alignas_align < min_align_of_type (type))
12297 error_at (type_name->specs->locations[cdw_alignas],
12298 "%<_Alignas%> specifiers cannot reduce "
12299 "alignment of compound literal");
12300 alignas_align = 0;
12303 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
12304 alignas_align, scspecs);
12305 set_c_expr_source_range (&expr, init.src_range);
12306 expr.m_decimal = 0;
12307 expr.original_code = ERROR_MARK;
12308 expr.original_type = NULL;
12309 if (type != error_mark_node
12310 && expr.value != error_mark_node
12311 && type_expr)
12313 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
12315 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
12316 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
12318 else
12320 gcc_assert (!non_const);
12321 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
12322 type_expr, expr.value);
12325 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
12328 /* Callback function for sizeof_pointer_memaccess_warning to compare
12329 types. */
12331 static bool
12332 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
12334 return comptypes (type1, type2) == 1;
12337 /* Warn for patterns where abs-like function appears to be used incorrectly,
12338 gracefully ignore any non-abs-like function. The warning location should
12339 be LOC. FNDECL is the declaration of called function, it must be a
12340 BUILT_IN_NORMAL function. ARG is the first and only argument of the
12341 call. */
12343 static void
12344 warn_for_abs (location_t loc, tree fndecl, tree arg)
12346 /* Avoid warning in unreachable subexpressions. */
12347 if (c_inhibit_evaluation_warnings)
12348 return;
12350 tree atype = TREE_TYPE (arg);
12352 /* Casts from pointers (and thus arrays and fndecls) will generate
12353 -Wint-conversion warnings. Most other wrong types hopefully lead to type
12354 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
12355 types and possibly other exotic types. */
12356 if (!INTEGRAL_TYPE_P (atype)
12357 && !SCALAR_FLOAT_TYPE_P (atype)
12358 && TREE_CODE (atype) != COMPLEX_TYPE)
12359 return;
12361 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
12363 switch (fcode)
12365 case BUILT_IN_ABS:
12366 case BUILT_IN_LABS:
12367 case BUILT_IN_LLABS:
12368 case BUILT_IN_IMAXABS:
12369 if (!INTEGRAL_TYPE_P (atype))
12371 if (SCALAR_FLOAT_TYPE_P (atype))
12372 warning_at (loc, OPT_Wabsolute_value,
12373 "using integer absolute value function %qD when "
12374 "argument is of floating-point type %qT",
12375 fndecl, atype);
12376 else if (TREE_CODE (atype) == COMPLEX_TYPE)
12377 warning_at (loc, OPT_Wabsolute_value,
12378 "using integer absolute value function %qD when "
12379 "argument is of complex type %qT", fndecl, atype);
12380 else
12381 gcc_unreachable ();
12382 return;
12384 if (TYPE_UNSIGNED (atype))
12385 warning_at (loc, OPT_Wabsolute_value,
12386 "taking the absolute value of unsigned type %qT "
12387 "has no effect", atype);
12388 break;
12390 CASE_FLT_FN (BUILT_IN_FABS):
12391 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
12392 if (!SCALAR_FLOAT_TYPE_P (atype)
12393 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
12395 if (INTEGRAL_TYPE_P (atype))
12396 warning_at (loc, OPT_Wabsolute_value,
12397 "using floating-point absolute value function %qD "
12398 "when argument is of integer type %qT", fndecl, atype);
12399 else if (DECIMAL_FLOAT_TYPE_P (atype))
12400 warning_at (loc, OPT_Wabsolute_value,
12401 "using floating-point absolute value function %qD "
12402 "when argument is of decimal floating-point type %qT",
12403 fndecl, atype);
12404 else if (TREE_CODE (atype) == COMPLEX_TYPE)
12405 warning_at (loc, OPT_Wabsolute_value,
12406 "using floating-point absolute value function %qD when "
12407 "argument is of complex type %qT", fndecl, atype);
12408 else
12409 gcc_unreachable ();
12410 return;
12412 break;
12414 CASE_FLT_FN (BUILT_IN_CABS):
12415 if (TREE_CODE (atype) != COMPLEX_TYPE)
12417 if (INTEGRAL_TYPE_P (atype))
12418 warning_at (loc, OPT_Wabsolute_value,
12419 "using complex absolute value function %qD when "
12420 "argument is of integer type %qT", fndecl, atype);
12421 else if (SCALAR_FLOAT_TYPE_P (atype))
12422 warning_at (loc, OPT_Wabsolute_value,
12423 "using complex absolute value function %qD when "
12424 "argument is of floating-point type %qT",
12425 fndecl, atype);
12426 else
12427 gcc_unreachable ();
12429 return;
12431 break;
12433 case BUILT_IN_FABSD32:
12434 case BUILT_IN_FABSD64:
12435 case BUILT_IN_FABSD128:
12436 if (!DECIMAL_FLOAT_TYPE_P (atype))
12438 if (INTEGRAL_TYPE_P (atype))
12439 warning_at (loc, OPT_Wabsolute_value,
12440 "using decimal floating-point absolute value "
12441 "function %qD when argument is of integer type %qT",
12442 fndecl, atype);
12443 else if (SCALAR_FLOAT_TYPE_P (atype))
12444 warning_at (loc, OPT_Wabsolute_value,
12445 "using decimal floating-point absolute value "
12446 "function %qD when argument is of floating-point "
12447 "type %qT", fndecl, atype);
12448 else if (TREE_CODE (atype) == COMPLEX_TYPE)
12449 warning_at (loc, OPT_Wabsolute_value,
12450 "using decimal floating-point absolute value "
12451 "function %qD when argument is of complex type %qT",
12452 fndecl, atype);
12453 else
12454 gcc_unreachable ();
12455 return;
12457 break;
12459 default:
12460 return;
12463 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
12464 return;
12466 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
12467 if (TREE_CODE (atype) == COMPLEX_TYPE)
12469 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
12470 atype = TREE_TYPE (atype);
12471 ftype = TREE_TYPE (ftype);
12474 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
12475 warning_at (loc, OPT_Wabsolute_value,
12476 "absolute value function %qD given an argument of type %qT "
12477 "but has parameter of type %qT which may cause truncation "
12478 "of value", fndecl, atype, ftype);
12482 /* Parse a postfix expression after the initial primary or compound
12483 literal; that is, parse a series of postfix operators.
12485 EXPR_LOC is the location of the primary expression. */
12487 static struct c_expr
12488 c_parser_postfix_expression_after_primary (c_parser *parser,
12489 location_t expr_loc,
12490 struct c_expr expr)
12492 struct c_expr orig_expr;
12493 tree ident, idx, len;
12494 location_t sizeof_arg_loc[6], comp_loc;
12495 tree sizeof_arg[6];
12496 unsigned int literal_zero_mask;
12497 unsigned int i;
12498 vec<tree, va_gc> *exprlist;
12499 vec<tree, va_gc> *origtypes = NULL;
12500 vec<location_t> arg_loc = vNULL;
12501 location_t start;
12502 location_t finish;
12504 while (true)
12506 location_t op_loc = c_parser_peek_token (parser)->location;
12507 switch (c_parser_peek_token (parser)->type)
12509 case CPP_OPEN_SQUARE:
12510 /* Array reference. */
12511 c_parser_consume_token (parser);
12512 idx = len = NULL_TREE;
12513 if (!c_omp_array_section_p
12514 || c_parser_next_token_is_not (parser, CPP_COLON))
12515 idx = c_parser_expression (parser).value;
12517 if (c_omp_array_section_p
12518 && c_parser_next_token_is (parser, CPP_COLON))
12520 c_parser_consume_token (parser);
12521 if (c_parser_next_token_is_not (parser, CPP_CLOSE_SQUARE))
12522 len = c_parser_expression (parser).value;
12524 expr.value = build_omp_array_section (op_loc, expr.value, idx,
12525 len);
12527 else
12528 expr.value = build_array_ref (op_loc, expr.value, idx);
12530 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
12531 "expected %<]%>");
12533 start = expr.get_start ();
12534 finish = parser->tokens_buf[0].location;
12535 set_c_expr_source_range (&expr, start, finish);
12536 expr.original_code = ERROR_MARK;
12537 expr.original_type = NULL;
12538 expr.m_decimal = 0;
12539 break;
12540 case CPP_OPEN_PAREN:
12541 /* Function call. */
12543 matching_parens parens;
12544 parens.consume_open (parser);
12545 for (i = 0; i < 6; i++)
12547 sizeof_arg[i] = NULL_TREE;
12548 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
12550 literal_zero_mask = 0;
12551 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12552 exprlist = NULL;
12553 else if (TREE_CODE (expr.value) == FUNCTION_DECL
12554 && fndecl_built_in_p (expr.value, BUILT_IN_CLASSIFY_TYPE)
12555 && c_parser_next_tokens_start_typename (parser,
12556 cla_prefer_id))
12558 /* __builtin_classify_type (type) */
12559 c_inhibit_evaluation_warnings++;
12560 in_alignof++;
12561 struct c_type_name *type = c_parser_type_name (parser);
12562 c_inhibit_evaluation_warnings--;
12563 in_alignof--;
12564 struct c_typespec ret;
12565 ret.expr = NULL_TREE;
12566 ret.spec = error_mark_node;
12567 ret.expr_const_operands = false;
12568 if (type != NULL)
12569 ret.spec = groktypename (type, &ret.expr,
12570 &ret.expr_const_operands);
12571 parens.skip_until_found_close (parser);
12572 expr.value = build_int_cst (integer_type_node,
12573 type_to_class (ret.spec));
12574 break;
12576 else
12577 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
12578 sizeof_arg_loc, sizeof_arg,
12579 &arg_loc, &literal_zero_mask);
12580 parens.skip_until_found_close (parser);
12582 orig_expr = expr;
12583 mark_exp_read (expr.value);
12584 if (warn_sizeof_pointer_memaccess)
12585 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
12586 expr.value, exprlist,
12587 sizeof_arg,
12588 sizeof_ptr_memacc_comptypes);
12589 if (TREE_CODE (expr.value) == FUNCTION_DECL)
12591 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
12592 && vec_safe_length (exprlist) == 3)
12594 tree arg0 = (*exprlist)[0];
12595 tree arg2 = (*exprlist)[2];
12596 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
12598 if (warn_absolute_value
12599 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
12600 && vec_safe_length (exprlist) == 1)
12601 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
12602 if (parser->omp_for_parse_state
12603 && parser->omp_for_parse_state->in_intervening_code
12604 && omp_runtime_api_call (expr.value))
12606 error_at (expr_loc, "calls to the OpenMP runtime API are "
12607 "not permitted in intervening code");
12608 parser->omp_for_parse_state->fail = true;
12610 if (warn_calloc_transposed_args)
12611 if (tree attr = lookup_attribute ("alloc_size",
12612 TYPE_ATTRIBUTES
12613 (TREE_TYPE (expr.value))))
12614 if (TREE_VALUE (attr) && TREE_CHAIN (TREE_VALUE (attr)))
12615 warn_for_calloc (sizeof_arg_loc, expr.value, exprlist,
12616 sizeof_arg, attr);
12619 start = expr.get_start ();
12620 finish = parser->tokens_buf[0].get_finish ();
12621 expr.value
12622 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
12623 exprlist, origtypes);
12624 set_c_expr_source_range (&expr, start, finish);
12625 expr.m_decimal = 0;
12627 expr.original_code = ERROR_MARK;
12628 if (TREE_CODE (expr.value) == INTEGER_CST
12629 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
12630 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
12631 expr.original_code = C_MAYBE_CONST_EXPR;
12632 expr.original_type = NULL;
12633 if (exprlist)
12635 release_tree_vector (exprlist);
12636 release_tree_vector (origtypes);
12638 arg_loc.release ();
12639 break;
12640 case CPP_DOT:
12641 /* Structure element reference. */
12642 c_parser_consume_token (parser);
12643 expr = default_function_array_conversion (expr_loc, expr);
12644 if (c_parser_next_token_is (parser, CPP_NAME))
12646 c_token *comp_tok = c_parser_peek_token (parser);
12647 ident = comp_tok->value;
12648 comp_loc = comp_tok->location;
12650 else
12652 c_parser_error (parser, "expected identifier");
12653 expr.set_error ();
12654 expr.original_code = ERROR_MARK;
12655 expr.original_type = NULL;
12656 return expr;
12658 start = expr.get_start ();
12659 finish = c_parser_peek_token (parser)->get_finish ();
12660 c_parser_consume_token (parser);
12661 expr.value = build_component_ref (op_loc, expr.value, ident,
12662 comp_loc, UNKNOWN_LOCATION);
12663 set_c_expr_source_range (&expr, start, finish);
12664 expr.original_code = ERROR_MARK;
12665 if (TREE_CODE (expr.value) != COMPONENT_REF)
12666 expr.original_type = NULL;
12667 else
12669 /* Remember the original type of a bitfield. */
12670 tree field = TREE_OPERAND (expr.value, 1);
12671 if (TREE_CODE (field) != FIELD_DECL)
12672 expr.original_type = NULL;
12673 else
12674 expr.original_type = DECL_BIT_FIELD_TYPE (field);
12676 expr.m_decimal = 0;
12677 break;
12678 case CPP_DEREF:
12679 /* Structure element reference. */
12680 c_parser_consume_token (parser);
12681 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
12682 if (c_parser_next_token_is (parser, CPP_NAME))
12684 c_token *comp_tok = c_parser_peek_token (parser);
12685 ident = comp_tok->value;
12686 comp_loc = comp_tok->location;
12688 else
12690 c_parser_error (parser, "expected identifier");
12691 expr.set_error ();
12692 expr.original_code = ERROR_MARK;
12693 expr.original_type = NULL;
12694 return expr;
12696 start = expr.get_start ();
12697 finish = c_parser_peek_token (parser)->get_finish ();
12698 c_parser_consume_token (parser);
12699 expr.value = build_component_ref (op_loc,
12700 build_indirect_ref (op_loc,
12701 expr.value,
12702 RO_ARROW),
12703 ident, comp_loc,
12704 expr.get_location ());
12705 set_c_expr_source_range (&expr, start, finish);
12706 expr.original_code = ERROR_MARK;
12707 if (TREE_CODE (expr.value) != COMPONENT_REF)
12708 expr.original_type = NULL;
12709 else
12711 /* Remember the original type of a bitfield. */
12712 tree field = TREE_OPERAND (expr.value, 1);
12713 if (TREE_CODE (field) != FIELD_DECL)
12714 expr.original_type = NULL;
12715 else
12716 expr.original_type = DECL_BIT_FIELD_TYPE (field);
12718 expr.m_decimal = 0;
12719 break;
12720 case CPP_PLUS_PLUS:
12721 /* Postincrement. */
12722 start = expr.get_start ();
12723 finish = c_parser_peek_token (parser)->get_finish ();
12724 c_parser_consume_token (parser);
12725 expr = default_function_array_read_conversion (expr_loc, expr);
12726 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
12727 expr.value, false);
12728 set_c_expr_source_range (&expr, start, finish);
12729 expr.original_code = ERROR_MARK;
12730 expr.original_type = NULL;
12731 break;
12732 case CPP_MINUS_MINUS:
12733 /* Postdecrement. */
12734 start = expr.get_start ();
12735 finish = c_parser_peek_token (parser)->get_finish ();
12736 c_parser_consume_token (parser);
12737 expr = default_function_array_read_conversion (expr_loc, expr);
12738 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
12739 expr.value, false);
12740 set_c_expr_source_range (&expr, start, finish);
12741 expr.original_code = ERROR_MARK;
12742 expr.original_type = NULL;
12743 break;
12744 default:
12745 return expr;
12750 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
12752 expression:
12753 assignment-expression
12754 expression , assignment-expression
12757 static struct c_expr
12758 c_parser_expression (c_parser *parser)
12760 location_t tloc = c_parser_peek_token (parser)->location;
12761 struct c_expr expr;
12762 expr = c_parser_expr_no_commas (parser, NULL);
12763 if (c_parser_next_token_is (parser, CPP_COMMA))
12764 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
12765 while (c_parser_next_token_is (parser, CPP_COMMA))
12767 struct c_expr next;
12768 tree lhsval;
12769 location_t loc = c_parser_peek_token (parser)->location;
12770 location_t expr_loc;
12771 c_parser_consume_token (parser);
12772 expr_loc = c_parser_peek_token (parser)->location;
12773 lhsval = expr.value;
12774 while (TREE_CODE (lhsval) == COMPOUND_EXPR
12775 || TREE_CODE (lhsval) == NOP_EXPR)
12777 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
12778 lhsval = TREE_OPERAND (lhsval, 1);
12779 else
12780 lhsval = TREE_OPERAND (lhsval, 0);
12782 if (DECL_P (lhsval) || handled_component_p (lhsval))
12783 mark_exp_read (lhsval);
12784 next = c_parser_expr_no_commas (parser, NULL);
12785 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
12786 expr.value = build_compound_expr (loc, expr.value, next.value);
12787 expr.original_code = COMPOUND_EXPR;
12788 expr.original_type = next.original_type;
12789 expr.m_decimal = 0;
12791 return expr;
12794 /* Parse an expression and convert functions or arrays to pointers and
12795 lvalues to rvalues. */
12797 static struct c_expr
12798 c_parser_expression_conv (c_parser *parser)
12800 struct c_expr expr;
12801 location_t loc = c_parser_peek_token (parser)->location;
12802 expr = c_parser_expression (parser);
12803 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
12804 return expr;
12807 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
12808 argument is a literal zero alone and if so, set it in literal_zero_mask. */
12810 static inline void
12811 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
12812 unsigned int idx)
12814 if (idx >= HOST_BITS_PER_INT)
12815 return;
12817 c_token *tok = c_parser_peek_token (parser);
12818 switch (tok->type)
12820 case CPP_NUMBER:
12821 case CPP_CHAR:
12822 case CPP_WCHAR:
12823 case CPP_CHAR16:
12824 case CPP_CHAR32:
12825 case CPP_UTF8CHAR:
12826 /* If a parameter is literal zero alone, remember it
12827 for -Wmemset-transposed-args warning. */
12828 if (integer_zerop (tok->value)
12829 && !TREE_OVERFLOW (tok->value)
12830 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
12831 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
12832 *literal_zero_mask |= 1U << idx;
12833 default:
12834 break;
12838 /* Parse a non-empty list of expressions. If CONVERT_P, convert
12839 functions and arrays to pointers and lvalues to rvalues. If
12840 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
12841 locations of function arguments into this vector.
12843 nonempty-expr-list:
12844 assignment-expression
12845 nonempty-expr-list , assignment-expression
12848 static vec<tree, va_gc> *
12849 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
12850 vec<tree, va_gc> **p_orig_types,
12851 location_t *sizeof_arg_loc, tree *sizeof_arg,
12852 vec<location_t> *locations,
12853 unsigned int *literal_zero_mask)
12855 vec<tree, va_gc> *ret;
12856 vec<tree, va_gc> *orig_types;
12857 struct c_expr expr;
12858 unsigned int idx = 0;
12859 bool save_c_omp_array_section_p = c_omp_array_section_p;
12860 c_omp_array_section_p = false;
12862 ret = make_tree_vector ();
12863 if (p_orig_types == NULL)
12864 orig_types = NULL;
12865 else
12866 orig_types = make_tree_vector ();
12868 if (literal_zero_mask)
12869 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
12870 expr = c_parser_expr_no_commas (parser, NULL);
12871 if (convert_p)
12872 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
12873 if (fold_p)
12874 expr.value = c_fully_fold (expr.value, false, NULL);
12875 ret->quick_push (expr.value);
12876 if (orig_types)
12877 orig_types->quick_push (expr.original_type);
12878 if (locations)
12879 locations->safe_push (expr.get_location ());
12880 if (sizeof_arg != NULL
12881 && (expr.original_code == SIZEOF_EXPR
12882 || expr.original_code == PAREN_SIZEOF_EXPR))
12884 sizeof_arg[0] = c_last_sizeof_arg;
12885 sizeof_arg_loc[0] = c_last_sizeof_loc;
12887 while (c_parser_next_token_is (parser, CPP_COMMA))
12889 c_parser_consume_token (parser);
12890 if (literal_zero_mask)
12891 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
12892 expr = c_parser_expr_no_commas (parser, NULL);
12893 if (convert_p)
12894 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
12895 true);
12896 if (fold_p)
12897 expr.value = c_fully_fold (expr.value, false, NULL);
12898 vec_safe_push (ret, expr.value);
12899 if (orig_types)
12900 vec_safe_push (orig_types, expr.original_type);
12901 if (locations)
12902 locations->safe_push (expr.get_location ());
12903 if (++idx < 6
12904 && sizeof_arg != NULL
12905 && (expr.original_code == SIZEOF_EXPR
12906 || expr.original_code == PAREN_SIZEOF_EXPR))
12908 sizeof_arg[idx] = c_last_sizeof_arg;
12909 sizeof_arg_loc[idx] = c_last_sizeof_loc;
12912 if (orig_types)
12913 *p_orig_types = orig_types;
12914 c_omp_array_section_p = save_c_omp_array_section_p;
12915 return ret;
12918 /* Parse Objective-C-specific constructs. */
12920 /* Parse an objc-class-definition.
12922 objc-class-definition:
12923 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
12924 objc-class-instance-variables[opt] objc-methodprotolist @end
12925 @implementation identifier objc-superclass[opt]
12926 objc-class-instance-variables[opt]
12927 @interface identifier ( identifier ) objc-protocol-refs[opt]
12928 objc-methodprotolist @end
12929 @interface identifier ( ) objc-protocol-refs[opt]
12930 objc-methodprotolist @end
12931 @implementation identifier ( identifier )
12933 objc-superclass:
12934 : identifier
12936 "@interface identifier (" must start "@interface identifier (
12937 identifier ) ...": objc-methodprotolist in the first production may
12938 not start with a parenthesized identifier as a declarator of a data
12939 definition with no declaration specifiers if the objc-superclass,
12940 objc-protocol-refs and objc-class-instance-variables are omitted. */
12942 static void
12943 c_parser_objc_class_definition (c_parser *parser, tree attributes)
12945 bool iface_p;
12946 tree id1;
12947 tree superclass;
12948 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
12949 iface_p = true;
12950 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
12951 iface_p = false;
12952 else
12953 gcc_unreachable ();
12955 c_parser_consume_token (parser);
12956 if (c_parser_next_token_is_not (parser, CPP_NAME))
12958 c_parser_error (parser, "expected identifier");
12959 return;
12961 id1 = c_parser_peek_token (parser)->value;
12962 location_t loc1 = c_parser_peek_token (parser)->location;
12963 c_parser_consume_token (parser);
12964 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12966 /* We have a category or class extension. */
12967 tree id2;
12968 tree proto = NULL_TREE;
12969 matching_parens parens;
12970 parens.consume_open (parser);
12971 if (c_parser_next_token_is_not (parser, CPP_NAME))
12973 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12975 /* We have a class extension. */
12976 id2 = NULL_TREE;
12978 else
12980 c_parser_error (parser, "expected identifier or %<)%>");
12981 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
12982 return;
12985 else
12987 id2 = c_parser_peek_token (parser)->value;
12988 c_parser_consume_token (parser);
12990 parens.skip_until_found_close (parser);
12991 if (!iface_p)
12993 objc_start_category_implementation (id1, id2);
12994 return;
12996 if (c_parser_next_token_is (parser, CPP_LESS))
12997 proto = c_parser_objc_protocol_refs (parser);
12998 objc_start_category_interface (id1, id2, proto, attributes);
12999 c_parser_objc_methodprotolist (parser);
13000 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13001 objc_finish_interface ();
13002 return;
13004 if (c_parser_next_token_is (parser, CPP_COLON))
13006 c_parser_consume_token (parser);
13007 if (c_parser_next_token_is_not (parser, CPP_NAME))
13009 c_parser_error (parser, "expected identifier");
13010 return;
13012 superclass = c_parser_peek_token (parser)->value;
13013 c_parser_consume_token (parser);
13015 else
13016 superclass = NULL_TREE;
13017 if (iface_p)
13019 tree proto = NULL_TREE;
13020 if (c_parser_next_token_is (parser, CPP_LESS))
13021 proto = c_parser_objc_protocol_refs (parser);
13022 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
13024 else
13025 objc_start_class_implementation (id1, superclass);
13026 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13027 c_parser_objc_class_instance_variables (parser);
13028 if (iface_p)
13030 objc_continue_interface ();
13031 c_parser_objc_methodprotolist (parser);
13032 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13033 objc_finish_interface ();
13035 else
13037 objc_continue_implementation ();
13038 return;
13042 /* Parse objc-class-instance-variables.
13044 objc-class-instance-variables:
13045 { objc-instance-variable-decl-list[opt] }
13047 objc-instance-variable-decl-list:
13048 objc-visibility-spec
13049 objc-instance-variable-decl ;
13051 objc-instance-variable-decl-list objc-visibility-spec
13052 objc-instance-variable-decl-list objc-instance-variable-decl ;
13053 objc-instance-variable-decl-list ;
13055 objc-visibility-spec:
13056 @private
13057 @protected
13058 @public
13060 objc-instance-variable-decl:
13061 struct-declaration
13064 static void
13065 c_parser_objc_class_instance_variables (c_parser *parser)
13067 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
13068 c_parser_consume_token (parser);
13069 while (c_parser_next_token_is_not (parser, CPP_EOF))
13071 tree decls;
13072 /* Parse any stray semicolon. */
13073 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
13075 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13076 "extra semicolon");
13077 c_parser_consume_token (parser);
13078 continue;
13080 /* Stop if at the end of the instance variables. */
13081 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
13083 c_parser_consume_token (parser);
13084 break;
13086 /* Parse any objc-visibility-spec. */
13087 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
13089 c_parser_consume_token (parser);
13090 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
13091 continue;
13093 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
13095 c_parser_consume_token (parser);
13096 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
13097 continue;
13099 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
13101 c_parser_consume_token (parser);
13102 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
13103 continue;
13105 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
13107 c_parser_consume_token (parser);
13108 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
13109 continue;
13111 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
13113 c_parser_pragma (parser, pragma_external, NULL);
13114 continue;
13117 /* Parse some comma-separated declarations. */
13118 decls = c_parser_struct_declaration (parser, NULL);
13119 if (decls == NULL)
13121 /* There is a syntax error. We want to skip the offending
13122 tokens up to the next ';' (included) or '}'
13123 (excluded). */
13125 /* First, skip manually a ')' or ']'. This is because they
13126 reduce the nesting level, so c_parser_skip_until_found()
13127 wouldn't be able to skip past them. */
13128 c_token *token = c_parser_peek_token (parser);
13129 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
13130 c_parser_consume_token (parser);
13132 /* Then, do the standard skipping. */
13133 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13135 /* We hopefully recovered. Start normal parsing again. */
13136 parser->error = false;
13137 continue;
13139 else
13141 /* Comma-separated instance variables are chained together
13142 in reverse order; add them one by one. */
13143 tree ivar = nreverse (decls);
13144 for (; ivar; ivar = DECL_CHAIN (ivar))
13145 objc_add_instance_variable (copy_node (ivar));
13147 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13151 /* Parse an objc-class-declaration.
13153 objc-class-declaration:
13154 @class identifier-list ;
13157 static void
13158 c_parser_objc_class_declaration (c_parser *parser)
13160 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
13161 c_parser_consume_token (parser);
13162 /* Any identifiers, including those declared as type names, are OK
13163 here. */
13164 while (true)
13166 tree id;
13167 if (c_parser_next_token_is_not (parser, CPP_NAME))
13169 c_parser_error (parser, "expected identifier");
13170 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13171 parser->error = false;
13172 return;
13174 id = c_parser_peek_token (parser)->value;
13175 objc_declare_class (id);
13176 c_parser_consume_token (parser);
13177 if (c_parser_next_token_is (parser, CPP_COMMA))
13178 c_parser_consume_token (parser);
13179 else
13180 break;
13182 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13185 /* Parse an objc-alias-declaration.
13187 objc-alias-declaration:
13188 @compatibility_alias identifier identifier ;
13191 static void
13192 c_parser_objc_alias_declaration (c_parser *parser)
13194 tree id1, id2;
13195 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
13196 c_parser_consume_token (parser);
13197 if (c_parser_next_token_is_not (parser, CPP_NAME))
13199 c_parser_error (parser, "expected identifier");
13200 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13201 return;
13203 id1 = c_parser_peek_token (parser)->value;
13204 c_parser_consume_token (parser);
13205 if (c_parser_next_token_is_not (parser, CPP_NAME))
13207 c_parser_error (parser, "expected identifier");
13208 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13209 return;
13211 id2 = c_parser_peek_token (parser)->value;
13212 c_parser_consume_token (parser);
13213 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13214 objc_declare_alias (id1, id2);
13217 /* Parse an objc-protocol-definition.
13219 objc-protocol-definition:
13220 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
13221 @protocol identifier-list ;
13223 "@protocol identifier ;" should be resolved as "@protocol
13224 identifier-list ;": objc-methodprotolist may not start with a
13225 semicolon in the first alternative if objc-protocol-refs are
13226 omitted. */
13228 static void
13229 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
13231 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
13233 c_parser_consume_token (parser);
13234 if (c_parser_next_token_is_not (parser, CPP_NAME))
13236 c_parser_error (parser, "expected identifier");
13237 return;
13239 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13240 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
13242 /* Any identifiers, including those declared as type names, are
13243 OK here. */
13244 while (true)
13246 tree id;
13247 if (c_parser_next_token_is_not (parser, CPP_NAME))
13249 c_parser_error (parser, "expected identifier");
13250 break;
13252 id = c_parser_peek_token (parser)->value;
13253 objc_declare_protocol (id, attributes);
13254 c_parser_consume_token (parser);
13255 if (c_parser_next_token_is (parser, CPP_COMMA))
13256 c_parser_consume_token (parser);
13257 else
13258 break;
13260 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13262 else
13264 tree id = c_parser_peek_token (parser)->value;
13265 tree proto = NULL_TREE;
13266 c_parser_consume_token (parser);
13267 if (c_parser_next_token_is (parser, CPP_LESS))
13268 proto = c_parser_objc_protocol_refs (parser);
13269 parser->objc_pq_context = true;
13270 objc_start_protocol (id, proto, attributes);
13271 c_parser_objc_methodprotolist (parser);
13272 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13273 parser->objc_pq_context = false;
13274 objc_finish_interface ();
13278 /* Parse an objc-method-type.
13280 objc-method-type:
13284 Return true if it is a class method (+) and false if it is
13285 an instance method (-).
13287 static inline bool
13288 c_parser_objc_method_type (c_parser *parser)
13290 switch (c_parser_peek_token (parser)->type)
13292 case CPP_PLUS:
13293 c_parser_consume_token (parser);
13294 return true;
13295 case CPP_MINUS:
13296 c_parser_consume_token (parser);
13297 return false;
13298 default:
13299 gcc_unreachable ();
13303 /* Parse an objc-method-definition.
13305 objc-method-definition:
13306 objc-method-type objc-method-decl ;[opt] compound-statement
13309 static void
13310 c_parser_objc_method_definition (c_parser *parser)
13312 bool is_class_method = c_parser_objc_method_type (parser);
13313 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
13314 parser->objc_pq_context = true;
13315 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
13316 &expr);
13317 if (decl == error_mark_node)
13318 return; /* Bail here. */
13320 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
13322 c_parser_consume_token (parser);
13323 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13324 "extra semicolon in method definition specified");
13327 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13329 c_parser_error (parser, "expected %<{%>");
13330 return;
13333 parser->objc_pq_context = false;
13334 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
13336 add_stmt (c_parser_compound_statement (parser));
13337 objc_finish_method_definition (current_function_decl);
13339 else
13341 /* This code is executed when we find a method definition
13342 outside of an @implementation context (or invalid for other
13343 reasons). Parse the method (to keep going) but do not emit
13344 any code.
13346 c_parser_compound_statement (parser);
13350 /* Parse an objc-methodprotolist.
13352 objc-methodprotolist:
13353 empty
13354 objc-methodprotolist objc-methodproto
13355 objc-methodprotolist declaration
13356 objc-methodprotolist ;
13357 @optional
13358 @required
13360 The declaration is a data definition, which may be missing
13361 declaration specifiers under the same rules and diagnostics as
13362 other data definitions outside functions, and the stray semicolon
13363 is diagnosed the same way as a stray semicolon outside a
13364 function. */
13366 static void
13367 c_parser_objc_methodprotolist (c_parser *parser)
13369 while (true)
13371 /* The list is terminated by @end. */
13372 switch (c_parser_peek_token (parser)->type)
13374 case CPP_SEMICOLON:
13375 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13376 "ISO C does not allow extra %<;%> outside of a function");
13377 c_parser_consume_token (parser);
13378 break;
13379 case CPP_PLUS:
13380 case CPP_MINUS:
13381 c_parser_objc_methodproto (parser);
13382 break;
13383 case CPP_PRAGMA:
13384 c_parser_pragma (parser, pragma_external, NULL);
13385 break;
13386 case CPP_EOF:
13387 return;
13388 default:
13389 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
13390 return;
13391 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
13392 c_parser_objc_at_property_declaration (parser);
13393 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
13395 objc_set_method_opt (true);
13396 c_parser_consume_token (parser);
13398 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
13400 objc_set_method_opt (false);
13401 c_parser_consume_token (parser);
13403 else
13404 c_parser_declaration_or_fndef (parser, false, false, true,
13405 false, true);
13406 break;
13411 /* Parse an objc-methodproto.
13413 objc-methodproto:
13414 objc-method-type objc-method-decl ;
13417 static void
13418 c_parser_objc_methodproto (c_parser *parser)
13420 bool is_class_method = c_parser_objc_method_type (parser);
13421 tree decl, attributes = NULL_TREE;
13423 /* Remember protocol qualifiers in prototypes. */
13424 parser->objc_pq_context = true;
13425 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
13426 NULL);
13427 /* Forget protocol qualifiers now. */
13428 parser->objc_pq_context = false;
13430 /* Do not allow the presence of attributes to hide an erroneous
13431 method implementation in the interface section. */
13432 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
13434 c_parser_error (parser, "expected %<;%>");
13435 return;
13438 if (decl != error_mark_node)
13439 objc_add_method_declaration (is_class_method, decl, attributes);
13441 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13444 /* If we are at a position that method attributes may be present, check that
13445 there are not any parsed already (a syntax error) and then collect any
13446 specified at the current location. Finally, if new attributes were present,
13447 check that the next token is legal ( ';' for decls and '{' for defs). */
13449 static bool
13450 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
13452 bool bad = false;
13453 if (*attributes)
13455 c_parser_error (parser,
13456 "method attributes must be specified at the end only");
13457 *attributes = NULL_TREE;
13458 bad = true;
13461 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
13462 *attributes = c_parser_gnu_attributes (parser);
13464 /* If there were no attributes here, just report any earlier error. */
13465 if (*attributes == NULL_TREE || bad)
13466 return bad;
13468 /* If the attributes are followed by a ; or {, then just report any earlier
13469 error. */
13470 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
13471 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13472 return bad;
13474 /* We've got attributes, but not at the end. */
13475 c_parser_error (parser,
13476 "expected %<;%> or %<{%> after method attribute definition");
13477 return true;
13480 /* Parse an objc-method-decl.
13482 objc-method-decl:
13483 ( objc-type-name ) objc-selector
13484 objc-selector
13485 ( objc-type-name ) objc-keyword-selector objc-optparmlist
13486 objc-keyword-selector objc-optparmlist
13487 gnu-attributes
13489 objc-keyword-selector:
13490 objc-keyword-decl
13491 objc-keyword-selector objc-keyword-decl
13493 objc-keyword-decl:
13494 objc-selector : ( objc-type-name ) identifier
13495 objc-selector : identifier
13496 : ( objc-type-name ) identifier
13497 : identifier
13499 objc-optparmlist:
13500 objc-optparms objc-optellipsis
13502 objc-optparms:
13503 empty
13504 objc-opt-parms , parameter-declaration
13506 objc-optellipsis:
13507 empty
13508 , ...
13511 static tree
13512 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
13513 tree *attributes, tree *expr)
13515 tree type = NULL_TREE;
13516 tree sel;
13517 tree parms = NULL_TREE;
13518 bool ellipsis = false;
13519 bool attr_err = false;
13521 *attributes = NULL_TREE;
13522 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13524 matching_parens parens;
13525 parens.consume_open (parser);
13526 type = c_parser_objc_type_name (parser);
13527 parens.skip_until_found_close (parser);
13529 sel = c_parser_objc_selector (parser);
13530 /* If there is no selector, or a colon follows, we have an
13531 objc-keyword-selector. If there is a selector, and a colon does
13532 not follow, that selector ends the objc-method-decl. */
13533 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
13535 tree tsel = sel;
13536 tree list = NULL_TREE;
13537 while (true)
13539 tree atype = NULL_TREE, id, keyworddecl;
13540 tree param_attr = NULL_TREE;
13541 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13542 break;
13543 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13545 c_parser_consume_token (parser);
13546 atype = c_parser_objc_type_name (parser);
13547 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
13548 "expected %<)%>");
13550 /* New ObjC allows attributes on method parameters. */
13551 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
13552 param_attr = c_parser_gnu_attributes (parser);
13553 if (c_parser_next_token_is_not (parser, CPP_NAME))
13555 c_parser_error (parser, "expected identifier");
13556 return error_mark_node;
13558 id = c_parser_peek_token (parser)->value;
13559 c_parser_consume_token (parser);
13560 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
13561 list = chainon (list, keyworddecl);
13562 tsel = c_parser_objc_selector (parser);
13563 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
13564 break;
13567 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
13569 /* Parse the optional parameter list. Optional Objective-C
13570 method parameters follow the C syntax, and may include '...'
13571 to denote a variable number of arguments. */
13572 parms = make_node (TREE_LIST);
13573 while (c_parser_next_token_is (parser, CPP_COMMA))
13575 struct c_parm *parm;
13576 c_parser_consume_token (parser);
13577 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
13579 ellipsis = true;
13580 c_parser_consume_token (parser);
13581 attr_err |= c_parser_objc_maybe_method_attributes
13582 (parser, attributes) ;
13583 break;
13585 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
13586 if (parm == NULL)
13587 break;
13588 parms = chainon (parms,
13589 build_tree_list (NULL_TREE, grokparm (parm, expr)));
13591 sel = list;
13593 else
13594 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
13596 if (sel == NULL)
13598 c_parser_error (parser, "objective-c method declaration is expected");
13599 return error_mark_node;
13602 if (attr_err)
13603 return error_mark_node;
13605 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
13608 /* Parse an objc-type-name.
13610 objc-type-name:
13611 objc-type-qualifiers[opt] type-name
13612 objc-type-qualifiers[opt]
13614 objc-type-qualifiers:
13615 objc-type-qualifier
13616 objc-type-qualifiers objc-type-qualifier
13618 objc-type-qualifier: one of
13619 in out inout bycopy byref oneway
13622 static tree
13623 c_parser_objc_type_name (c_parser *parser)
13625 tree quals = NULL_TREE;
13626 struct c_type_name *type_name = NULL;
13627 tree type = NULL_TREE;
13628 while (true)
13630 c_token *token = c_parser_peek_token (parser);
13631 if (token->type == CPP_KEYWORD
13632 && (token->keyword == RID_IN
13633 || token->keyword == RID_OUT
13634 || token->keyword == RID_INOUT
13635 || token->keyword == RID_BYCOPY
13636 || token->keyword == RID_BYREF
13637 || token->keyword == RID_ONEWAY))
13639 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
13640 c_parser_consume_token (parser);
13642 else
13643 break;
13645 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
13646 type_name = c_parser_type_name (parser);
13647 if (type_name)
13648 type = groktypename (type_name, NULL, NULL);
13650 /* If the type is unknown, and error has already been produced and
13651 we need to recover from the error. In that case, use NULL_TREE
13652 for the type, as if no type had been specified; this will use the
13653 default type ('id') which is good for error recovery. */
13654 if (type == error_mark_node)
13655 type = NULL_TREE;
13657 return build_tree_list (quals, type);
13660 /* Parse objc-protocol-refs.
13662 objc-protocol-refs:
13663 < identifier-list >
13666 static tree
13667 c_parser_objc_protocol_refs (c_parser *parser)
13669 tree list = NULL_TREE;
13670 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
13671 c_parser_consume_token (parser);
13672 /* Any identifiers, including those declared as type names, are OK
13673 here. */
13674 while (true)
13676 tree id;
13677 if (c_parser_next_token_is_not (parser, CPP_NAME))
13679 c_parser_error (parser, "expected identifier");
13680 break;
13682 id = c_parser_peek_token (parser)->value;
13683 list = chainon (list, build_tree_list (NULL_TREE, id));
13684 c_parser_consume_token (parser);
13685 if (c_parser_next_token_is (parser, CPP_COMMA))
13686 c_parser_consume_token (parser);
13687 else
13688 break;
13690 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
13691 return list;
13694 /* Parse an objc-try-catch-finally-statement.
13696 objc-try-catch-finally-statement:
13697 @try compound-statement objc-catch-list[opt]
13698 @try compound-statement objc-catch-list[opt] @finally compound-statement
13700 objc-catch-list:
13701 @catch ( objc-catch-parameter-declaration ) compound-statement
13702 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
13704 objc-catch-parameter-declaration:
13705 parameter-declaration
13706 '...'
13708 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
13710 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
13711 for C++. Keep them in sync. */
13713 static void
13714 c_parser_objc_try_catch_finally_statement (c_parser *parser)
13716 location_t location;
13717 tree stmt;
13719 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
13720 c_parser_consume_token (parser);
13721 location = c_parser_peek_token (parser)->location;
13722 objc_maybe_warn_exceptions (location);
13723 stmt = c_parser_compound_statement (parser);
13724 objc_begin_try_stmt (location, stmt);
13726 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
13728 struct c_parm *parm;
13729 tree parameter_declaration = error_mark_node;
13730 bool seen_open_paren = false;
13732 c_parser_consume_token (parser);
13733 matching_parens parens;
13734 if (!parens.require_open (parser))
13735 seen_open_paren = true;
13736 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
13738 /* We have "@catch (...)" (where the '...' are literally
13739 what is in the code). Skip the '...'.
13740 parameter_declaration is set to NULL_TREE, and
13741 objc_being_catch_clauses() knows that that means
13742 '...'. */
13743 c_parser_consume_token (parser);
13744 parameter_declaration = NULL_TREE;
13746 else
13748 /* We have "@catch (NSException *exception)" or something
13749 like that. Parse the parameter declaration. */
13750 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
13751 if (parm == NULL)
13752 parameter_declaration = error_mark_node;
13753 else
13754 parameter_declaration = grokparm (parm, NULL);
13756 if (seen_open_paren)
13757 parens.require_close (parser);
13758 else
13760 /* If there was no open parenthesis, we are recovering from
13761 an error, and we are trying to figure out what mistake
13762 the user has made. */
13764 /* If there is an immediate closing parenthesis, the user
13765 probably forgot the opening one (ie, they typed "@catch
13766 NSException *e)". Parse the closing parenthesis and keep
13767 going. */
13768 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
13769 c_parser_consume_token (parser);
13771 /* If these is no immediate closing parenthesis, the user
13772 probably doesn't know that parenthesis are required at
13773 all (ie, they typed "@catch NSException *e"). So, just
13774 forget about the closing parenthesis and keep going. */
13776 objc_begin_catch_clause (parameter_declaration);
13777 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
13778 c_parser_compound_statement_nostart (parser);
13779 objc_finish_catch_clause ();
13781 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
13783 c_parser_consume_token (parser);
13784 location = c_parser_peek_token (parser)->location;
13785 stmt = c_parser_compound_statement (parser);
13786 objc_build_finally_clause (location, stmt);
13788 objc_finish_try_stmt ();
13791 /* Parse an objc-synchronized-statement.
13793 objc-synchronized-statement:
13794 @synchronized ( expression ) compound-statement
13797 static void
13798 c_parser_objc_synchronized_statement (c_parser *parser)
13800 location_t loc;
13801 tree expr, stmt;
13802 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
13803 c_parser_consume_token (parser);
13804 loc = c_parser_peek_token (parser)->location;
13805 objc_maybe_warn_exceptions (loc);
13806 matching_parens parens;
13807 if (parens.require_open (parser))
13809 struct c_expr ce = c_parser_expression (parser);
13810 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
13811 expr = ce.value;
13812 expr = c_fully_fold (expr, false, NULL);
13813 parens.skip_until_found_close (parser);
13815 else
13816 expr = error_mark_node;
13817 stmt = c_parser_compound_statement (parser);
13818 objc_build_synchronized (loc, expr, stmt);
13821 /* Parse an objc-selector; return NULL_TREE without an error if the
13822 next token is not an objc-selector.
13824 objc-selector:
13825 identifier
13826 one of
13827 enum struct union if else while do for switch case default
13828 break continue return goto asm sizeof typeof typeof_unqual __alignof
13829 unsigned long const short volatile signed restrict _Complex
13830 in out inout bycopy byref oneway int char float double void _Bool
13831 _Atomic
13833 ??? Why this selection of keywords but not, for example, storage
13834 class specifiers? */
13836 static tree
13837 c_parser_objc_selector (c_parser *parser)
13839 c_token *token = c_parser_peek_token (parser);
13840 tree value = token->value;
13841 if (token->type == CPP_NAME)
13843 c_parser_consume_token (parser);
13844 return value;
13846 if (token->type != CPP_KEYWORD)
13847 return NULL_TREE;
13848 switch (token->keyword)
13850 case RID_ENUM:
13851 case RID_STRUCT:
13852 case RID_UNION:
13853 case RID_IF:
13854 case RID_ELSE:
13855 case RID_WHILE:
13856 case RID_DO:
13857 case RID_FOR:
13858 case RID_SWITCH:
13859 case RID_CASE:
13860 case RID_DEFAULT:
13861 case RID_BREAK:
13862 case RID_CONTINUE:
13863 case RID_RETURN:
13864 case RID_GOTO:
13865 case RID_ASM:
13866 case RID_SIZEOF:
13867 case RID_TYPEOF:
13868 case RID_TYPEOF_UNQUAL:
13869 case RID_ALIGNOF:
13870 case RID_UNSIGNED:
13871 case RID_LONG:
13872 case RID_CONST:
13873 case RID_SHORT:
13874 case RID_VOLATILE:
13875 case RID_SIGNED:
13876 case RID_RESTRICT:
13877 case RID_COMPLEX:
13878 case RID_IN:
13879 case RID_OUT:
13880 case RID_INOUT:
13881 case RID_BYCOPY:
13882 case RID_BYREF:
13883 case RID_ONEWAY:
13884 case RID_INT:
13885 case RID_CHAR:
13886 case RID_FLOAT:
13887 case RID_DOUBLE:
13888 CASE_RID_FLOATN_NX:
13889 case RID_VOID:
13890 case RID_BOOL:
13891 case RID_ATOMIC:
13892 case RID_AUTO_TYPE:
13893 case RID_INT_N_0:
13894 case RID_INT_N_1:
13895 case RID_INT_N_2:
13896 case RID_INT_N_3:
13897 c_parser_consume_token (parser);
13898 return value;
13899 default:
13900 return NULL_TREE;
13904 /* Parse an objc-selector-arg.
13906 objc-selector-arg:
13907 objc-selector
13908 objc-keywordname-list
13910 objc-keywordname-list:
13911 objc-keywordname
13912 objc-keywordname-list objc-keywordname
13914 objc-keywordname:
13915 objc-selector :
13919 static tree
13920 c_parser_objc_selector_arg (c_parser *parser)
13922 tree sel = c_parser_objc_selector (parser);
13923 tree list = NULL_TREE;
13924 if (sel
13925 && c_parser_next_token_is_not (parser, CPP_COLON)
13926 && c_parser_next_token_is_not (parser, CPP_SCOPE))
13927 return sel;
13928 while (true)
13930 if (c_parser_next_token_is (parser, CPP_SCOPE))
13932 c_parser_consume_token (parser);
13933 list = chainon (list, build_tree_list (sel, NULL_TREE));
13934 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
13936 else
13938 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13939 return list;
13940 list = chainon (list, build_tree_list (sel, NULL_TREE));
13942 sel = c_parser_objc_selector (parser);
13943 if (!sel
13944 && c_parser_next_token_is_not (parser, CPP_COLON)
13945 && c_parser_next_token_is_not (parser, CPP_SCOPE))
13946 break;
13948 return list;
13951 /* Parse an objc-receiver.
13953 objc-receiver:
13954 expression
13955 class-name
13956 type-name
13959 static tree
13960 c_parser_objc_receiver (c_parser *parser)
13962 location_t loc = c_parser_peek_token (parser)->location;
13964 if (c_parser_peek_token (parser)->type == CPP_NAME
13965 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
13966 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
13968 tree id = c_parser_peek_token (parser)->value;
13969 c_parser_consume_token (parser);
13970 return objc_get_class_reference (id);
13972 struct c_expr ce = c_parser_expression (parser);
13973 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
13974 return c_fully_fold (ce.value, false, NULL);
13977 /* Parse objc-message-args.
13979 objc-message-args:
13980 objc-selector
13981 objc-keywordarg-list
13983 objc-keywordarg-list:
13984 objc-keywordarg
13985 objc-keywordarg-list objc-keywordarg
13987 objc-keywordarg:
13988 objc-selector : objc-keywordexpr
13989 : objc-keywordexpr
13992 static tree
13993 c_parser_objc_message_args (c_parser *parser)
13995 tree sel = c_parser_objc_selector (parser);
13996 tree list = NULL_TREE;
13997 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
13998 return sel;
13999 while (true)
14001 tree keywordexpr;
14002 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14003 return error_mark_node;
14004 keywordexpr = c_parser_objc_keywordexpr (parser);
14005 list = chainon (list, build_tree_list (sel, keywordexpr));
14006 sel = c_parser_objc_selector (parser);
14007 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
14008 break;
14010 return list;
14013 /* Parse an objc-keywordexpr.
14015 objc-keywordexpr:
14016 nonempty-expr-list
14019 static tree
14020 c_parser_objc_keywordexpr (c_parser *parser)
14022 tree ret;
14023 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
14024 NULL, NULL, NULL, NULL);
14025 if (vec_safe_length (expr_list) == 1)
14027 /* Just return the expression, remove a level of
14028 indirection. */
14029 ret = (*expr_list)[0];
14031 else
14033 /* We have a comma expression, we will collapse later. */
14034 ret = build_tree_list_vec (expr_list);
14036 release_tree_vector (expr_list);
14037 return ret;
14040 /* A check, needed in several places, that ObjC interface, implementation or
14041 method definitions are not prefixed by incorrect items. */
14042 static bool
14043 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
14044 struct c_declspecs *specs)
14046 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
14047 || specs->typespec_kind != ctsk_none)
14049 c_parser_error (parser,
14050 "no type or storage class may be specified here,");
14051 c_parser_skip_to_end_of_block_or_statement (parser);
14052 return true;
14054 return false;
14057 /* Parse an Objective-C @property declaration. The syntax is:
14059 objc-property-declaration:
14060 '@property' objc-property-attributes[opt] struct-declaration ;
14062 objc-property-attributes:
14063 '(' objc-property-attribute-list ')'
14065 objc-property-attribute-list:
14066 objc-property-attribute
14067 objc-property-attribute-list, objc-property-attribute
14069 objc-property-attribute
14070 'getter' = identifier
14071 'setter' = identifier
14072 'readonly'
14073 'readwrite'
14074 'assign'
14075 'retain'
14076 'copy'
14077 'nonatomic'
14079 For example:
14080 @property NSString *name;
14081 @property (readonly) id object;
14082 @property (retain, nonatomic, getter=getTheName) id name;
14083 @property int a, b, c;
14085 PS: This function is identical to cp_parser_objc_at_propery_declaration
14086 for C++. Keep them in sync. */
14087 static void
14088 c_parser_objc_at_property_declaration (c_parser *parser)
14090 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
14091 location_t loc = c_parser_peek_token (parser)->location;
14092 c_parser_consume_token (parser); /* Eat '@property'. */
14094 /* Parse the optional attribute list.
14096 A list of parsed, but not verified, attributes. */
14097 vec<property_attribute_info *> prop_attr_list = vNULL;
14099 bool syntax_error = false;
14100 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14102 matching_parens parens;
14104 location_t attr_start = c_parser_peek_token (parser)->location;
14105 /* Eat the '(' */
14106 parens.consume_open (parser);
14108 /* Property attribute keywords are valid now. */
14109 parser->objc_property_attr_context = true;
14111 /* Allow @property (), with a warning. */
14112 location_t attr_end = c_parser_peek_token (parser)->location;
14114 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14116 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
14117 warning_at (attr_comb, OPT_Wattributes,
14118 "empty property attribute list");
14120 else
14121 while (true)
14123 c_token *token = c_parser_peek_token (parser);
14124 attr_start = token->location;
14125 attr_end = get_finish (token->location);
14126 location_t attr_comb = make_location (attr_start, attr_start,
14127 attr_end);
14129 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
14131 warning_at (attr_comb, OPT_Wattributes,
14132 "missing property attribute");
14133 if (token->type == CPP_CLOSE_PAREN)
14134 break;
14135 c_parser_consume_token (parser);
14136 continue;
14139 tree attr_name = NULL_TREE;
14140 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
14141 bool add_at = false;
14142 if (token->type == CPP_KEYWORD)
14144 keyword = token->keyword;
14145 if (OBJC_IS_AT_KEYWORD (keyword))
14147 /* For '@' keywords the token value has the keyword,
14148 prepend the '@' for diagnostics. */
14149 attr_name = token->value;
14150 add_at = true;
14152 else
14153 attr_name = ridpointers[(int)keyword];
14155 else if (token->type == CPP_NAME)
14156 attr_name = token->value;
14157 c_parser_consume_token (parser);
14159 enum objc_property_attribute_kind prop_kind
14160 = objc_prop_attr_kind_for_rid (keyword);
14161 property_attribute_info *prop
14162 = new property_attribute_info (attr_name, attr_comb, prop_kind);
14163 prop_attr_list.safe_push (prop);
14165 tree meth_name;
14166 switch (prop->prop_kind)
14168 default: break;
14169 case OBJC_PROPERTY_ATTR_UNKNOWN:
14170 if (attr_name)
14171 error_at (attr_comb, "unknown property attribute %<%s%s%>",
14172 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
14173 else
14174 error_at (attr_comb, "unknown property attribute");
14175 prop->parse_error = syntax_error = true;
14176 break;
14178 case OBJC_PROPERTY_ATTR_GETTER:
14179 case OBJC_PROPERTY_ATTR_SETTER:
14180 if (c_parser_next_token_is_not (parser, CPP_EQ))
14182 attr_comb = make_location (attr_end, attr_start, attr_end);
14183 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
14184 attr_name);
14185 prop->parse_error = syntax_error = true;
14186 break;
14188 token = c_parser_peek_token (parser);
14189 attr_end = token->location;
14190 c_parser_consume_token (parser); /* eat the = */
14191 if (c_parser_next_token_is_not (parser, CPP_NAME))
14193 attr_comb = make_location (attr_end, attr_start, attr_end);
14194 error_at (attr_comb, "expected %qE selector name",
14195 attr_name);
14196 prop->parse_error = syntax_error = true;
14197 break;
14199 /* Get the end of the method name, and consume the name. */
14200 token = c_parser_peek_token (parser);
14201 attr_end = get_finish (token->location);
14202 meth_name = token->value;
14203 c_parser_consume_token (parser);
14204 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
14206 if (c_parser_next_token_is_not (parser, CPP_COLON))
14208 attr_comb = make_location (attr_end, attr_start,
14209 attr_end);
14210 error_at (attr_comb, "setter method names must"
14211 " terminate with %<:%>");
14212 prop->parse_error = syntax_error = true;
14214 else
14216 attr_end = get_finish (c_parser_peek_token
14217 (parser)->location);
14218 c_parser_consume_token (parser);
14220 attr_comb = make_location (attr_start, attr_start,
14221 attr_end);
14223 else
14224 attr_comb = make_location (attr_start, attr_start,
14225 attr_end);
14226 prop->ident = meth_name;
14227 /* Updated location including all that was successfully
14228 parsed. */
14229 prop->prop_loc = attr_comb;
14230 break;
14233 /* If we see a comma here, then keep going - even if we already
14234 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
14235 this makes a more useful output and avoid spurious warnings about
14236 missing attributes that are, in fact, specified after the one with
14237 the syntax error. */
14238 if (c_parser_next_token_is (parser, CPP_COMMA))
14239 c_parser_consume_token (parser);
14240 else
14241 break;
14243 parser->objc_property_attr_context = false;
14245 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
14246 /* We don't really want to chew the whole of the file looking for a
14247 matching closing parenthesis, so we will try to read the decl and
14248 let the error handling for that close out the statement. */
14250 else
14251 syntax_error = false, parens.skip_until_found_close (parser);
14254 /* 'properties' is the list of properties that we read. Usually a
14255 single one, but maybe more (eg, in "@property int a, b, c;" there
14256 are three). */
14257 tree properties = c_parser_struct_declaration (parser, NULL);
14259 if (properties == error_mark_node)
14260 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14261 else
14263 if (properties == NULL_TREE)
14264 c_parser_error (parser, "expected identifier");
14265 else
14267 /* Comma-separated properties are chained together in reverse order;
14268 add them one by one. */
14269 properties = nreverse (properties);
14270 for (; properties; properties = TREE_CHAIN (properties))
14271 objc_add_property_declaration (loc, copy_node (properties),
14272 prop_attr_list);
14274 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14277 while (!prop_attr_list.is_empty())
14278 delete prop_attr_list.pop ();
14279 prop_attr_list.release ();
14280 parser->error = false;
14283 /* Parse an Objective-C @synthesize declaration. The syntax is:
14285 objc-synthesize-declaration:
14286 @synthesize objc-synthesize-identifier-list ;
14288 objc-synthesize-identifier-list:
14289 objc-synthesize-identifier
14290 objc-synthesize-identifier-list, objc-synthesize-identifier
14292 objc-synthesize-identifier
14293 identifier
14294 identifier = identifier
14296 For example:
14297 @synthesize MyProperty;
14298 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
14300 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
14301 for C++. Keep them in sync.
14303 static void
14304 c_parser_objc_at_synthesize_declaration (c_parser *parser)
14306 tree list = NULL_TREE;
14307 location_t loc;
14308 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
14309 loc = c_parser_peek_token (parser)->location;
14311 c_parser_consume_token (parser);
14312 while (true)
14314 tree property, ivar;
14315 if (c_parser_next_token_is_not (parser, CPP_NAME))
14317 c_parser_error (parser, "expected identifier");
14318 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14319 /* Once we find the semicolon, we can resume normal parsing.
14320 We have to reset parser->error manually because
14321 c_parser_skip_until_found() won't reset it for us if the
14322 next token is precisely a semicolon. */
14323 parser->error = false;
14324 return;
14326 property = c_parser_peek_token (parser)->value;
14327 c_parser_consume_token (parser);
14328 if (c_parser_next_token_is (parser, CPP_EQ))
14330 c_parser_consume_token (parser);
14331 if (c_parser_next_token_is_not (parser, CPP_NAME))
14333 c_parser_error (parser, "expected identifier");
14334 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14335 parser->error = false;
14336 return;
14338 ivar = c_parser_peek_token (parser)->value;
14339 c_parser_consume_token (parser);
14341 else
14342 ivar = NULL_TREE;
14343 list = chainon (list, build_tree_list (ivar, property));
14344 if (c_parser_next_token_is (parser, CPP_COMMA))
14345 c_parser_consume_token (parser);
14346 else
14347 break;
14349 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14350 objc_add_synthesize_declaration (loc, list);
14353 /* Parse an Objective-C @dynamic declaration. The syntax is:
14355 objc-dynamic-declaration:
14356 @dynamic identifier-list ;
14358 For example:
14359 @dynamic MyProperty;
14360 @dynamic MyProperty, AnotherProperty;
14362 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
14363 for C++. Keep them in sync.
14365 static void
14366 c_parser_objc_at_dynamic_declaration (c_parser *parser)
14368 tree list = NULL_TREE;
14369 location_t loc;
14370 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
14371 loc = c_parser_peek_token (parser)->location;
14373 c_parser_consume_token (parser);
14374 while (true)
14376 tree property;
14377 if (c_parser_next_token_is_not (parser, CPP_NAME))
14379 c_parser_error (parser, "expected identifier");
14380 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14381 parser->error = false;
14382 return;
14384 property = c_parser_peek_token (parser)->value;
14385 list = chainon (list, build_tree_list (NULL_TREE, property));
14386 c_parser_consume_token (parser);
14387 if (c_parser_next_token_is (parser, CPP_COMMA))
14388 c_parser_consume_token (parser);
14389 else
14390 break;
14392 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14393 objc_add_dynamic_declaration (loc, list);
14397 /* Parse a pragma GCC ivdep. */
14399 static bool
14400 c_parse_pragma_ivdep (c_parser *parser)
14402 c_parser_consume_pragma (parser);
14403 c_parser_skip_to_pragma_eol (parser);
14404 return true;
14407 /* Parse a pragma GCC novector. */
14409 static bool
14410 c_parse_pragma_novector (c_parser *parser)
14412 c_parser_consume_pragma (parser);
14413 c_parser_skip_to_pragma_eol (parser);
14414 return true;
14417 /* Parse a pragma GCC unroll. */
14419 static unsigned short
14420 c_parser_pragma_unroll (c_parser *parser)
14422 unsigned short unroll;
14423 c_parser_consume_pragma (parser);
14424 location_t location = c_parser_peek_token (parser)->location;
14425 tree expr = c_parser_expr_no_commas (parser, NULL).value;
14426 mark_exp_read (expr);
14427 expr = c_fully_fold (expr, false, NULL);
14428 HOST_WIDE_INT lunroll = 0;
14429 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14430 || TREE_CODE (expr) != INTEGER_CST
14431 || (lunroll = tree_to_shwi (expr)) < 0
14432 || lunroll >= USHRT_MAX)
14434 error_at (location, "%<#pragma GCC unroll%> requires an"
14435 " assignment-expression that evaluates to a non-negative"
14436 " integral constant less than %u", USHRT_MAX);
14437 unroll = 0;
14439 else
14441 unroll = (unsigned short)lunroll;
14442 if (unroll == 0)
14443 unroll = 1;
14446 c_parser_skip_to_pragma_eol (parser);
14447 return unroll;
14450 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
14451 should be considered, statements. ALLOW_STMT is true if we're within
14452 the context of a function and such pragmas are to be allowed. Returns
14453 true if we actually parsed such a pragma. */
14455 static bool
14456 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
14458 unsigned int id;
14459 const char *construct = NULL;
14461 input_location = c_parser_peek_token (parser)->location;
14462 id = c_parser_peek_token (parser)->pragma_kind;
14463 gcc_assert (id != PRAGMA_NONE);
14464 if (parser->omp_for_parse_state
14465 && parser->omp_for_parse_state->in_intervening_code
14466 && id >= PRAGMA_OMP__START_
14467 && id <= PRAGMA_OMP__LAST_)
14469 error_at (input_location,
14470 "intervening code must not contain OpenMP directives");
14471 parser->omp_for_parse_state->fail = true;
14472 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14473 return false;
14476 switch (id)
14478 case PRAGMA_OACC_DECLARE:
14479 c_parser_oacc_declare (parser);
14480 return false;
14482 case PRAGMA_OACC_ENTER_DATA:
14483 if (context != pragma_compound)
14485 construct = "acc enter data";
14486 in_compound:
14487 if (context == pragma_stmt)
14489 error_at (c_parser_peek_token (parser)->location,
14490 "%<#pragma %s%> may only be used in compound "
14491 "statements", construct);
14492 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14493 return true;
14495 goto bad_stmt;
14497 c_parser_oacc_enter_exit_data (parser, true);
14498 return false;
14500 case PRAGMA_OACC_EXIT_DATA:
14501 if (context != pragma_compound)
14503 construct = "acc exit data";
14504 goto in_compound;
14506 c_parser_oacc_enter_exit_data (parser, false);
14507 return false;
14509 case PRAGMA_OACC_ROUTINE:
14510 if (context != pragma_external)
14512 error_at (c_parser_peek_token (parser)->location,
14513 "%<#pragma acc routine%> must be at file scope");
14514 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14515 return false;
14517 c_parser_oacc_routine (parser, context);
14518 return false;
14520 case PRAGMA_OACC_UPDATE:
14521 if (context != pragma_compound)
14523 construct = "acc update";
14524 goto in_compound;
14526 c_parser_oacc_update (parser);
14527 return false;
14529 case PRAGMA_OMP_BARRIER:
14530 if (context != pragma_compound)
14532 construct = "omp barrier";
14533 goto in_compound;
14535 c_parser_omp_barrier (parser);
14536 return false;
14538 case PRAGMA_OMP_DEPOBJ:
14539 if (context != pragma_compound)
14541 construct = "omp depobj";
14542 goto in_compound;
14544 c_parser_omp_depobj (parser);
14545 return false;
14547 case PRAGMA_OMP_FLUSH:
14548 if (context != pragma_compound)
14550 construct = "omp flush";
14551 goto in_compound;
14553 c_parser_omp_flush (parser);
14554 return false;
14556 case PRAGMA_OMP_TASKWAIT:
14557 if (context != pragma_compound)
14559 construct = "omp taskwait";
14560 goto in_compound;
14562 c_parser_omp_taskwait (parser);
14563 return false;
14565 case PRAGMA_OMP_TASKYIELD:
14566 if (context != pragma_compound)
14568 construct = "omp taskyield";
14569 goto in_compound;
14571 c_parser_omp_taskyield (parser);
14572 return false;
14574 case PRAGMA_OMP_CANCEL:
14575 if (context != pragma_compound)
14577 construct = "omp cancel";
14578 goto in_compound;
14580 c_parser_omp_cancel (parser);
14581 return false;
14583 case PRAGMA_OMP_CANCELLATION_POINT:
14584 return c_parser_omp_cancellation_point (parser, context);
14586 case PRAGMA_OMP_THREADPRIVATE:
14587 c_parser_omp_threadprivate (parser);
14588 return false;
14590 case PRAGMA_OMP_TARGET:
14591 return c_parser_omp_target (parser, context, if_p);
14593 case PRAGMA_OMP_BEGIN:
14594 c_parser_omp_begin (parser);
14595 return false;
14597 case PRAGMA_OMP_END:
14598 c_parser_omp_end (parser);
14599 return false;
14601 case PRAGMA_OMP_SCAN:
14602 error_at (c_parser_peek_token (parser)->location,
14603 "%<#pragma omp scan%> may only be used in "
14604 "a loop construct with %<inscan%> %<reduction%> clause");
14605 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14606 return false;
14608 case PRAGMA_OMP_SECTION:
14609 error_at (c_parser_peek_token (parser)->location,
14610 "%<#pragma omp section%> may only be used in "
14611 "%<#pragma omp sections%> construct");
14612 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14613 return false;
14615 case PRAGMA_OMP_DECLARE:
14616 return c_parser_omp_declare (parser, context);
14618 case PRAGMA_OMP_REQUIRES:
14619 if (context != pragma_external)
14621 error_at (c_parser_peek_token (parser)->location,
14622 "%<#pragma %s%> may only be used at file scope",
14623 "omp requires");
14624 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14625 return false;
14627 c_parser_omp_requires (parser);
14628 return false;
14630 case PRAGMA_OMP_ALLOCATE:
14631 c_parser_omp_allocate (parser);
14632 return false;
14634 case PRAGMA_OMP_ASSUMES:
14635 if (context != pragma_external)
14637 error_at (c_parser_peek_token (parser)->location,
14638 "%<#pragma %s%> may only be used at file scope",
14639 "omp assumes");
14640 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14641 return false;
14643 c_parser_omp_assumes (parser);
14644 return false;
14646 case PRAGMA_OMP_NOTHING:
14647 c_parser_omp_nothing (parser);
14648 return false;
14650 case PRAGMA_OMP_ERROR:
14651 return c_parser_omp_error (parser, context);
14653 case PRAGMA_OMP_ORDERED:
14654 return c_parser_omp_ordered (parser, context, if_p);
14656 case PRAGMA_NOVECTOR:
14657 case PRAGMA_UNROLL:
14658 case PRAGMA_IVDEP:
14660 bool novector = false;
14661 unsigned short unroll = 0;
14662 bool ivdep = false;
14664 switch (id)
14666 case PRAGMA_NOVECTOR:
14667 novector = c_parse_pragma_novector (parser);
14668 break;
14669 case PRAGMA_UNROLL:
14670 unroll = c_parser_pragma_unroll (parser);
14671 break;
14672 case PRAGMA_IVDEP:
14673 ivdep = c_parse_pragma_ivdep (parser);
14674 break;
14675 default:
14676 gcc_unreachable ();
14679 c_token *tok = c_parser_peek_token (parser);
14680 bool has_more = tok->type == CPP_PRAGMA;
14681 while (has_more)
14683 switch (tok->pragma_kind)
14685 case PRAGMA_IVDEP:
14686 ivdep = c_parse_pragma_ivdep (parser);
14687 break;
14688 case PRAGMA_UNROLL:
14689 unroll = c_parser_pragma_unroll (parser);
14690 break;
14691 case PRAGMA_NOVECTOR:
14692 novector = c_parse_pragma_novector (parser);
14693 break;
14694 default:
14695 has_more = false;
14696 break;
14698 tok = c_parser_peek_token (parser);
14699 has_more = has_more && tok->type == CPP_PRAGMA;
14701 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
14702 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
14703 && !c_parser_next_token_is_keyword (parser, RID_DO))
14705 c_parser_error (parser, "for, while or do statement expected");
14706 return false;
14708 if (c_parser_next_token_is_keyword (parser, RID_FOR))
14709 c_parser_for_statement (parser, ivdep, unroll, novector, if_p);
14710 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
14711 c_parser_while_statement (parser, ivdep, unroll, novector, if_p);
14712 else
14713 c_parser_do_statement (parser, ivdep, unroll, novector);
14715 return true;
14717 case PRAGMA_GCC_PCH_PREPROCESS:
14718 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
14719 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14720 return false;
14722 case PRAGMA_OACC_WAIT:
14723 if (context != pragma_compound)
14725 construct = "acc wait";
14726 goto in_compound;
14728 /* FALL THROUGH. */
14730 default:
14731 if (id < PRAGMA_FIRST_EXTERNAL)
14733 if (context != pragma_stmt && context != pragma_compound)
14735 bad_stmt:
14736 c_parser_error (parser, "expected declaration specifiers");
14737 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14738 return false;
14740 c_parser_omp_construct (parser, if_p);
14741 return true;
14743 break;
14746 c_parser_consume_pragma (parser);
14747 c_invoke_pragma_handler (id);
14749 /* Skip to EOL, but suppress any error message. Those will have been
14750 generated by the handler routine through calling error, as opposed
14751 to calling c_parser_error. */
14752 parser->error = true;
14753 c_parser_skip_to_pragma_eol (parser);
14755 return false;
14758 /* The interface the pragma parsers have to the lexer. */
14760 enum cpp_ttype
14761 pragma_lex (tree *value, location_t *loc)
14763 c_token *tok = c_parser_peek_token (the_parser);
14764 enum cpp_ttype ret = tok->type;
14766 *value = tok->value;
14767 if (loc)
14768 *loc = tok->location;
14770 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
14771 ret = CPP_EOF;
14772 else if (ret == CPP_STRING)
14773 *value = c_parser_string_literal (the_parser, false, false).value;
14774 else
14776 if (ret == CPP_KEYWORD)
14777 ret = CPP_NAME;
14778 c_parser_consume_token (the_parser);
14781 return ret;
14784 void
14785 pragma_lex_discard_to_eol ()
14787 cpp_ttype type;
14790 type = c_parser_peek_token (the_parser)->type;
14791 gcc_assert (type != CPP_EOF);
14792 c_parser_consume_token (the_parser);
14793 } while (type != CPP_PRAGMA_EOL);
14796 static void
14797 c_parser_pragma_pch_preprocess (c_parser *parser)
14799 tree name = NULL;
14801 parser->lex_joined_string = true;
14802 c_parser_consume_pragma (parser);
14803 if (c_parser_next_token_is (parser, CPP_STRING))
14805 name = c_parser_peek_token (parser)->value;
14806 c_parser_consume_token (parser);
14808 else
14809 c_parser_error (parser, "expected string literal");
14810 c_parser_skip_to_pragma_eol (parser);
14811 parser->lex_joined_string = false;
14813 if (name)
14814 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
14817 /* OpenACC and OpenMP parsing routines. */
14819 /* Returns name of the next clause.
14820 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
14821 the token is not consumed. Otherwise appropriate pragma_omp_clause is
14822 returned and the token is consumed. */
14824 static pragma_omp_clause
14825 c_parser_omp_clause_name (c_parser *parser)
14827 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
14829 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14830 result = PRAGMA_OACC_CLAUSE_AUTO;
14831 else if (c_parser_next_token_is_keyword (parser, RID_IF))
14832 result = PRAGMA_OMP_CLAUSE_IF;
14833 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14834 result = PRAGMA_OMP_CLAUSE_DEFAULT;
14835 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
14836 result = PRAGMA_OMP_CLAUSE_FOR;
14837 else if (c_parser_next_token_is (parser, CPP_NAME))
14839 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14841 switch (p[0])
14843 case 'a':
14844 if (!strcmp ("affinity", p))
14845 result = PRAGMA_OMP_CLAUSE_AFFINITY;
14846 else if (!strcmp ("aligned", p))
14847 result = PRAGMA_OMP_CLAUSE_ALIGNED;
14848 else if (!strcmp ("allocate", p))
14849 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
14850 else if (!strcmp ("async", p))
14851 result = PRAGMA_OACC_CLAUSE_ASYNC;
14852 else if (!strcmp ("attach", p))
14853 result = PRAGMA_OACC_CLAUSE_ATTACH;
14854 break;
14855 case 'b':
14856 if (!strcmp ("bind", p))
14857 result = PRAGMA_OMP_CLAUSE_BIND;
14858 break;
14859 case 'c':
14860 if (!strcmp ("collapse", p))
14861 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
14862 else if (!strcmp ("copy", p))
14863 result = PRAGMA_OACC_CLAUSE_COPY;
14864 else if (!strcmp ("copyin", p))
14865 result = PRAGMA_OMP_CLAUSE_COPYIN;
14866 else if (!strcmp ("copyout", p))
14867 result = PRAGMA_OACC_CLAUSE_COPYOUT;
14868 else if (!strcmp ("copyprivate", p))
14869 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
14870 else if (!strcmp ("create", p))
14871 result = PRAGMA_OACC_CLAUSE_CREATE;
14872 break;
14873 case 'd':
14874 if (!strcmp ("defaultmap", p))
14875 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
14876 else if (!strcmp ("delete", p))
14877 result = PRAGMA_OACC_CLAUSE_DELETE;
14878 else if (!strcmp ("depend", p))
14879 result = PRAGMA_OMP_CLAUSE_DEPEND;
14880 else if (!strcmp ("detach", p))
14881 result = PRAGMA_OACC_CLAUSE_DETACH;
14882 else if (!strcmp ("device", p))
14883 result = PRAGMA_OMP_CLAUSE_DEVICE;
14884 else if (!strcmp ("deviceptr", p))
14885 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
14886 else if (!strcmp ("device_resident", p))
14887 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
14888 else if (!strcmp ("device_type", p))
14889 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
14890 else if (!strcmp ("dist_schedule", p))
14891 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
14892 else if (!strcmp ("doacross", p))
14893 result = PRAGMA_OMP_CLAUSE_DOACROSS;
14894 break;
14895 case 'e':
14896 if (!strcmp ("enter", p))
14897 result = PRAGMA_OMP_CLAUSE_ENTER;
14898 break;
14899 case 'f':
14900 if (!strcmp ("filter", p))
14901 result = PRAGMA_OMP_CLAUSE_FILTER;
14902 else if (!strcmp ("final", p))
14903 result = PRAGMA_OMP_CLAUSE_FINAL;
14904 else if (!strcmp ("finalize", p))
14905 result = PRAGMA_OACC_CLAUSE_FINALIZE;
14906 else if (!strcmp ("firstprivate", p))
14907 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
14908 else if (!strcmp ("from", p))
14909 result = PRAGMA_OMP_CLAUSE_FROM;
14910 break;
14911 case 'g':
14912 if (!strcmp ("gang", p))
14913 result = PRAGMA_OACC_CLAUSE_GANG;
14914 else if (!strcmp ("grainsize", p))
14915 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
14916 break;
14917 case 'h':
14918 if (!strcmp ("has_device_addr", p))
14919 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
14920 else if (!strcmp ("hint", p))
14921 result = PRAGMA_OMP_CLAUSE_HINT;
14922 else if (!strcmp ("host", p))
14923 result = PRAGMA_OACC_CLAUSE_HOST;
14924 break;
14925 case 'i':
14926 if (!strcmp ("if_present", p))
14927 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
14928 else if (!strcmp ("in_reduction", p))
14929 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
14930 else if (!strcmp ("inbranch", p))
14931 result = PRAGMA_OMP_CLAUSE_INBRANCH;
14932 else if (!strcmp ("independent", p))
14933 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
14934 else if (!strcmp ("indirect", p))
14935 result = PRAGMA_OMP_CLAUSE_INDIRECT;
14936 else if (!strcmp ("is_device_ptr", p))
14937 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
14938 break;
14939 case 'l':
14940 if (!strcmp ("lastprivate", p))
14941 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
14942 else if (!strcmp ("linear", p))
14943 result = PRAGMA_OMP_CLAUSE_LINEAR;
14944 else if (!strcmp ("link", p))
14945 result = PRAGMA_OMP_CLAUSE_LINK;
14946 break;
14947 case 'm':
14948 if (!strcmp ("map", p))
14949 result = PRAGMA_OMP_CLAUSE_MAP;
14950 else if (!strcmp ("mergeable", p))
14951 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
14952 break;
14953 case 'n':
14954 if (!strcmp ("no_create", p))
14955 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
14956 else if (!strcmp ("nogroup", p))
14957 result = PRAGMA_OMP_CLAUSE_NOGROUP;
14958 else if (!strcmp ("nohost", p))
14959 result = PRAGMA_OACC_CLAUSE_NOHOST;
14960 else if (!strcmp ("nontemporal", p))
14961 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
14962 else if (!strcmp ("notinbranch", p))
14963 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
14964 else if (!strcmp ("nowait", p))
14965 result = PRAGMA_OMP_CLAUSE_NOWAIT;
14966 else if (!strcmp ("num_gangs", p))
14967 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
14968 else if (!strcmp ("num_tasks", p))
14969 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
14970 else if (!strcmp ("num_teams", p))
14971 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
14972 else if (!strcmp ("num_threads", p))
14973 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
14974 else if (!strcmp ("num_workers", p))
14975 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
14976 break;
14977 case 'o':
14978 if (!strcmp ("ordered", p))
14979 result = PRAGMA_OMP_CLAUSE_ORDERED;
14980 else if (!strcmp ("order", p))
14981 result = PRAGMA_OMP_CLAUSE_ORDER;
14982 break;
14983 case 'p':
14984 if (!strcmp ("parallel", p))
14985 result = PRAGMA_OMP_CLAUSE_PARALLEL;
14986 else if (!strcmp ("present", p))
14987 result = PRAGMA_OACC_CLAUSE_PRESENT;
14988 /* As of OpenACC 2.5, these are now aliases of the non-present_or
14989 clauses. */
14990 else if (!strcmp ("present_or_copy", p)
14991 || !strcmp ("pcopy", p))
14992 result = PRAGMA_OACC_CLAUSE_COPY;
14993 else if (!strcmp ("present_or_copyin", p)
14994 || !strcmp ("pcopyin", p))
14995 result = PRAGMA_OACC_CLAUSE_COPYIN;
14996 else if (!strcmp ("present_or_copyout", p)
14997 || !strcmp ("pcopyout", p))
14998 result = PRAGMA_OACC_CLAUSE_COPYOUT;
14999 else if (!strcmp ("present_or_create", p)
15000 || !strcmp ("pcreate", p))
15001 result = PRAGMA_OACC_CLAUSE_CREATE;
15002 else if (!strcmp ("priority", p))
15003 result = PRAGMA_OMP_CLAUSE_PRIORITY;
15004 else if (!strcmp ("private", p))
15005 result = PRAGMA_OMP_CLAUSE_PRIVATE;
15006 else if (!strcmp ("proc_bind", p))
15007 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
15008 break;
15009 case 'r':
15010 if (!strcmp ("reduction", p))
15011 result = PRAGMA_OMP_CLAUSE_REDUCTION;
15012 break;
15013 case 's':
15014 if (!strcmp ("safelen", p))
15015 result = PRAGMA_OMP_CLAUSE_SAFELEN;
15016 else if (!strcmp ("schedule", p))
15017 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
15018 else if (!strcmp ("sections", p))
15019 result = PRAGMA_OMP_CLAUSE_SECTIONS;
15020 else if (!strcmp ("self", p))
15021 result = PRAGMA_OACC_CLAUSE_SELF;
15022 else if (!strcmp ("seq", p))
15023 result = PRAGMA_OACC_CLAUSE_SEQ;
15024 else if (!strcmp ("shared", p))
15025 result = PRAGMA_OMP_CLAUSE_SHARED;
15026 else if (!strcmp ("simd", p))
15027 result = PRAGMA_OMP_CLAUSE_SIMD;
15028 else if (!strcmp ("simdlen", p))
15029 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
15030 break;
15031 case 't':
15032 if (!strcmp ("task_reduction", p))
15033 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
15034 else if (!strcmp ("taskgroup", p))
15035 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
15036 else if (!strcmp ("thread_limit", p))
15037 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
15038 else if (!strcmp ("threads", p))
15039 result = PRAGMA_OMP_CLAUSE_THREADS;
15040 else if (!strcmp ("tile", p))
15041 result = PRAGMA_OACC_CLAUSE_TILE;
15042 else if (!strcmp ("to", p))
15043 result = PRAGMA_OMP_CLAUSE_TO;
15044 break;
15045 case 'u':
15046 if (!strcmp ("uniform", p))
15047 result = PRAGMA_OMP_CLAUSE_UNIFORM;
15048 else if (!strcmp ("untied", p))
15049 result = PRAGMA_OMP_CLAUSE_UNTIED;
15050 else if (!strcmp ("use_device", p))
15051 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
15052 else if (!strcmp ("use_device_addr", p))
15053 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
15054 else if (!strcmp ("use_device_ptr", p))
15055 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
15056 break;
15057 case 'v':
15058 if (!strcmp ("vector", p))
15059 result = PRAGMA_OACC_CLAUSE_VECTOR;
15060 else if (!strcmp ("vector_length", p))
15061 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
15062 break;
15063 case 'w':
15064 if (!strcmp ("wait", p))
15065 result = PRAGMA_OACC_CLAUSE_WAIT;
15066 else if (!strcmp ("worker", p))
15067 result = PRAGMA_OACC_CLAUSE_WORKER;
15068 break;
15072 if (result != PRAGMA_OMP_CLAUSE_NONE)
15073 c_parser_consume_token (parser);
15075 return result;
15078 /* Validate that a clause of the given type does not already exist. */
15080 static void
15081 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
15082 const char *name)
15084 if (tree c = omp_find_clause (clauses, code))
15085 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
15088 /* OpenACC 2.0
15089 Parse wait clause or wait directive parameters. */
15091 static tree
15092 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
15094 vec<tree, va_gc> *args;
15095 tree t, args_tree;
15097 matching_parens parens;
15098 if (!parens.require_open (parser))
15099 return list;
15101 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
15102 args_tree = build_tree_list_vec (args);
15104 for (t = args_tree; t; t = TREE_CHAIN (t))
15106 tree targ = TREE_VALUE (t);
15108 if (targ != error_mark_node)
15110 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
15112 c_parser_error (parser, "expression must be integral");
15113 targ = error_mark_node;
15115 else
15117 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
15119 OMP_CLAUSE_DECL (c) = targ;
15120 OMP_CLAUSE_CHAIN (c) = list;
15121 list = c;
15126 release_tree_vector (args);
15127 parens.require_close (parser);
15128 return list;
15131 /* OpenACC 2.0, OpenMP 2.5:
15132 variable-list:
15133 identifier
15134 variable-list , identifier
15136 If KIND is nonzero, create the appropriate node and install the
15137 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
15138 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
15140 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
15141 return the list created.
15143 The optional ALLOW_DEREF argument is true if list items can use the deref
15144 (->) operator. */
15146 struct omp_dim
15148 tree low_bound, length;
15149 location_t loc;
15150 bool no_colon;
15151 omp_dim (tree lb, tree len, location_t lo, bool nc)
15152 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
15155 static tree
15156 c_parser_omp_variable_list (c_parser *parser,
15157 location_t clause_loc,
15158 enum omp_clause_code kind, tree list,
15159 bool map_lvalue = false)
15161 auto_vec<omp_dim> dims;
15162 bool array_section_p;
15163 auto_vec<c_token> tokens;
15164 unsigned int tokens_avail = 0;
15165 c_token *saved_tokens = NULL;
15166 bool first = true;
15168 while (1)
15170 tree t = NULL_TREE;
15172 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15174 if (c_parser_next_token_is_not (parser, CPP_NAME)
15175 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15177 struct c_expr expr;
15178 if (kind == OMP_CLAUSE_DEPEND
15179 && c_parser_next_token_is_keyword (parser,
15180 RID_OMP_ALL_MEMORY)
15181 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
15182 || (c_parser_peek_2nd_token (parser)->type
15183 == CPP_CLOSE_PAREN)))
15185 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
15186 c_parser_consume_token (parser);
15188 else
15189 expr = c_parser_expr_no_commas (parser, NULL);
15190 if (expr.value != error_mark_node)
15192 tree u = build_omp_clause (clause_loc, kind);
15193 OMP_CLAUSE_DECL (u) = expr.value;
15194 OMP_CLAUSE_CHAIN (u) = list;
15195 list = u;
15198 if (c_parser_next_token_is_not (parser, CPP_COMMA))
15199 break;
15201 c_parser_consume_token (parser);
15202 first = false;
15203 continue;
15206 tokens.truncate (0);
15207 unsigned int nesting_depth = 0;
15208 while (1)
15210 c_token *token = c_parser_peek_token (parser);
15211 switch (token->type)
15213 case CPP_EOF:
15214 case CPP_PRAGMA_EOL:
15215 break;
15216 case CPP_OPEN_BRACE:
15217 case CPP_OPEN_PAREN:
15218 case CPP_OPEN_SQUARE:
15219 ++nesting_depth;
15220 goto add;
15221 case CPP_CLOSE_BRACE:
15222 case CPP_CLOSE_PAREN:
15223 case CPP_CLOSE_SQUARE:
15224 if (nesting_depth-- == 0)
15225 break;
15226 goto add;
15227 case CPP_COMMA:
15228 if (nesting_depth == 0)
15229 break;
15230 goto add;
15231 default:
15232 add:
15233 tokens.safe_push (*token);
15234 c_parser_consume_token (parser);
15235 continue;
15237 break;
15240 /* Make sure nothing tries to read past the end of the tokens. */
15241 c_token eof_token;
15242 memset (&eof_token, 0, sizeof (eof_token));
15243 eof_token.type = CPP_EOF;
15244 tokens.safe_push (eof_token);
15245 tokens.safe_push (eof_token);
15247 saved_tokens = parser->tokens;
15248 tokens_avail = parser->tokens_avail;
15249 parser->tokens = tokens.address ();
15250 parser->tokens_avail = tokens.length ();
15252 else if (map_lvalue
15253 && (kind == OMP_CLAUSE_MAP
15254 || kind == OMP_CLAUSE_TO
15255 || kind == OMP_CLAUSE_FROM))
15257 location_t loc = c_parser_peek_token (parser)->location;
15258 bool save_c_omp_array_section_p = c_omp_array_section_p;
15259 c_omp_array_section_p = true;
15260 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15261 if (expr.value != error_mark_node)
15262 mark_exp_read (expr.value);
15263 c_omp_array_section_p = save_c_omp_array_section_p;
15264 tree decl = expr.value;
15266 /* This code rewrites a parsed expression containing various tree
15267 codes used to represent array accesses into a more uniform nest of
15268 OMP_ARRAY_SECTION nodes before it is processed by
15269 c-typeck.cc:handle_omp_array_sections_1. It might be more
15270 efficient to move this logic to that function instead, analysing
15271 the parsed expression directly rather than this preprocessed
15272 form. (See also equivalent code in cp/parser.cc,
15273 cp/semantics.cc). */
15274 dims.truncate (0);
15275 if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
15277 while (TREE_CODE (decl) == OMP_ARRAY_SECTION)
15279 tree low_bound = TREE_OPERAND (decl, 1);
15280 tree length = TREE_OPERAND (decl, 2);
15281 dims.safe_push (omp_dim (low_bound, length, loc, false));
15282 decl = TREE_OPERAND (decl, 0);
15285 while (TREE_CODE (decl) == ARRAY_REF
15286 || TREE_CODE (decl) == INDIRECT_REF
15287 || TREE_CODE (decl) == COMPOUND_EXPR)
15289 if (TREE_CODE (decl) == COMPOUND_EXPR)
15291 decl = TREE_OPERAND (decl, 1);
15292 STRIP_NOPS (decl);
15294 else if (TREE_CODE (decl) == INDIRECT_REF)
15296 dims.safe_push (omp_dim (integer_zero_node,
15297 integer_one_node, loc, true));
15298 decl = TREE_OPERAND (decl, 0);
15300 else /* ARRAY_REF. */
15302 tree index = TREE_OPERAND (decl, 1);
15303 dims.safe_push (omp_dim (index, integer_one_node, loc,
15304 true));
15305 decl = TREE_OPERAND (decl, 0);
15309 for (int i = dims.length () - 1; i >= 0; i--)
15310 decl = build_omp_array_section (loc, decl, dims[i].low_bound,
15311 dims[i].length);
15313 else if (TREE_CODE (decl) == INDIRECT_REF)
15315 /* Turn indirection of a pointer "*foo" into "foo[0:1]". */
15316 decl = TREE_OPERAND (decl, 0);
15317 STRIP_NOPS (decl);
15319 decl = build_omp_array_section (loc, decl, integer_zero_node,
15320 integer_one_node);
15322 else if (TREE_CODE (decl) == ARRAY_REF)
15324 tree idx = TREE_OPERAND (decl, 1);
15326 decl = TREE_OPERAND (decl, 0);
15327 STRIP_NOPS (decl);
15329 decl = build_omp_array_section (loc, decl, idx, integer_one_node);
15331 else if (TREE_CODE (decl) == NON_LVALUE_EXPR
15332 || CONVERT_EXPR_P (decl))
15333 decl = TREE_OPERAND (decl, 0);
15335 tree u = build_omp_clause (clause_loc, kind);
15336 OMP_CLAUSE_DECL (u) = decl;
15337 OMP_CLAUSE_CHAIN (u) = list;
15338 list = u;
15340 goto next_item;
15343 if (c_parser_next_token_is (parser, CPP_NAME)
15344 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15346 t = lookup_name (c_parser_peek_token (parser)->value);
15348 if (t == NULL_TREE)
15350 undeclared_variable (c_parser_peek_token (parser)->location,
15351 c_parser_peek_token (parser)->value);
15352 t = error_mark_node;
15355 c_parser_consume_token (parser);
15357 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
15358 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
15359 || (c_parser_peek_token (parser)->keyword
15360 == RID_PRETTY_FUNCTION_NAME)
15361 || (c_parser_peek_token (parser)->keyword
15362 == RID_C99_FUNCTION_NAME)))
15363 t = c_parser_predefined_identifier (parser).value;
15364 else
15366 if (first)
15367 c_parser_error (parser, "expected identifier");
15368 break;
15371 if (t == error_mark_node)
15373 else if (kind != 0)
15375 switch (kind)
15377 case OMP_CLAUSE__CACHE_:
15378 /* The OpenACC cache directive explicitly only allows "array
15379 elements or subarrays". */
15380 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
15382 c_parser_error (parser, "expected %<[%>");
15383 t = error_mark_node;
15384 break;
15386 /* FALLTHROUGH */
15387 case OMP_CLAUSE_MAP:
15388 case OMP_CLAUSE_FROM:
15389 case OMP_CLAUSE_TO:
15390 start_component_ref:
15391 while (c_parser_next_token_is (parser, CPP_DOT)
15392 || c_parser_next_token_is (parser, CPP_DEREF))
15394 location_t op_loc = c_parser_peek_token (parser)->location;
15395 location_t arrow_loc = UNKNOWN_LOCATION;
15396 if (c_parser_next_token_is (parser, CPP_DEREF))
15398 c_expr t_expr;
15399 t_expr.value = t;
15400 t_expr.original_code = ERROR_MARK;
15401 t_expr.original_type = NULL;
15402 set_c_expr_source_range (&t_expr, op_loc, op_loc);
15403 t_expr.m_decimal = 0;
15404 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
15405 true, false);
15406 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
15407 arrow_loc = t_expr.get_location ();
15409 c_parser_consume_token (parser);
15410 if (!c_parser_next_token_is (parser, CPP_NAME))
15412 c_parser_error (parser, "expected identifier");
15413 t = error_mark_node;
15414 break;
15417 c_token *comp_tok = c_parser_peek_token (parser);
15418 tree ident = comp_tok->value;
15419 location_t comp_loc = comp_tok->location;
15420 c_parser_consume_token (parser);
15421 t = build_component_ref (op_loc, t, ident, comp_loc,
15422 arrow_loc);
15424 /* FALLTHROUGH */
15425 case OMP_CLAUSE_AFFINITY:
15426 case OMP_CLAUSE_DEPEND:
15427 case OMP_CLAUSE_REDUCTION:
15428 case OMP_CLAUSE_IN_REDUCTION:
15429 case OMP_CLAUSE_TASK_REDUCTION:
15430 case OMP_CLAUSE_HAS_DEVICE_ADDR:
15431 array_section_p = false;
15432 dims.truncate (0);
15433 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
15435 location_t loc = UNKNOWN_LOCATION;
15436 tree low_bound = NULL_TREE, length = NULL_TREE;
15437 bool no_colon = false;
15439 c_parser_consume_token (parser);
15440 if (!c_parser_next_token_is (parser, CPP_COLON))
15442 location_t expr_loc
15443 = c_parser_peek_token (parser)->location;
15444 c_expr expr = c_parser_expression (parser);
15445 expr = convert_lvalue_to_rvalue (expr_loc, expr,
15446 false, true);
15447 low_bound = expr.value;
15448 loc = expr_loc;
15450 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
15452 length = integer_one_node;
15453 no_colon = true;
15455 else
15457 /* Look for `:'. */
15458 if (!c_parser_require (parser, CPP_COLON,
15459 "expected %<:%>"))
15461 t = error_mark_node;
15462 break;
15464 array_section_p = true;
15465 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
15467 location_t expr_loc
15468 = c_parser_peek_token (parser)->location;
15469 c_expr expr = c_parser_expression (parser);
15470 expr = convert_lvalue_to_rvalue (expr_loc, expr,
15471 false, true);
15472 length = expr.value;
15475 /* Look for the closing `]'. */
15476 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
15477 "expected %<]%>"))
15479 t = error_mark_node;
15480 break;
15483 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
15486 if (t != error_mark_node)
15488 if ((kind == OMP_CLAUSE_MAP
15489 || kind == OMP_CLAUSE_FROM
15490 || kind == OMP_CLAUSE_TO)
15491 && !array_section_p
15492 && (c_parser_next_token_is (parser, CPP_DOT)
15493 || c_parser_next_token_is (parser, CPP_DEREF)))
15495 for (unsigned i = 0; i < dims.length (); i++)
15497 gcc_assert (dims[i].length == integer_one_node);
15498 t = build_array_ref (dims[i].loc,
15499 t, dims[i].low_bound);
15501 goto start_component_ref;
15503 else
15504 for (unsigned i = 0; i < dims.length (); i++)
15505 t = build_omp_array_section (clause_loc, t,
15506 dims[i].low_bound,
15507 dims[i].length);
15510 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15511 && t != error_mark_node
15512 && parser->tokens_avail != 2)
15514 if (array_section_p)
15516 error_at (c_parser_peek_token (parser)->location,
15517 "expected %<)%> or %<,%>");
15518 t = error_mark_node;
15520 else
15522 parser->tokens = tokens.address ();
15523 parser->tokens_avail = tokens.length ();
15525 t = c_parser_expr_no_commas (parser, NULL).value;
15526 if (t != error_mark_node && parser->tokens_avail != 2)
15528 error_at (c_parser_peek_token (parser)->location,
15529 "expected %<)%> or %<,%>");
15530 t = error_mark_node;
15534 break;
15535 default:
15536 break;
15539 if (t != error_mark_node)
15541 tree u = build_omp_clause (clause_loc, kind);
15542 OMP_CLAUSE_DECL (u) = t;
15543 OMP_CLAUSE_CHAIN (u) = list;
15544 list = u;
15547 else
15548 list = tree_cons (t, NULL_TREE, list);
15550 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15552 parser->tokens = saved_tokens;
15553 parser->tokens_avail = tokens_avail;
15556 next_item:
15557 if (c_parser_next_token_is_not (parser, CPP_COMMA))
15558 break;
15560 c_parser_consume_token (parser);
15561 first = false;
15564 return list;
15567 /* Similarly, but expect leading and trailing parenthesis. This is a very
15568 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
15569 argument is true if list items can use the deref (->) operator. */
15571 static tree
15572 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
15573 tree list, bool map_lvalue = false)
15575 /* The clauses location. */
15576 location_t loc = c_parser_peek_token (parser)->location;
15578 if (parser->in_omp_decl_attribute)
15580 if (kind)
15582 tree u = build_omp_clause (loc, kind);
15583 OMP_CLAUSE_DECL (u) = parser->in_omp_decl_attribute;
15584 OMP_CLAUSE_CHAIN (u) = list;
15585 return u;
15587 else
15588 return tree_cons (parser->in_omp_decl_attribute, NULL_TREE, list);
15591 matching_parens parens;
15592 if (parens.require_open (parser))
15594 list = c_parser_omp_variable_list (parser, loc, kind, list, map_lvalue);
15595 parens.skip_until_found_close (parser);
15597 return list;
15600 /* OpenACC 2.0:
15601 copy ( variable-list )
15602 copyin ( variable-list )
15603 copyout ( variable-list )
15604 create ( variable-list )
15605 delete ( variable-list )
15606 present ( variable-list )
15608 OpenACC 2.6:
15609 no_create ( variable-list )
15610 attach ( variable-list )
15611 detach ( variable-list ) */
15613 static tree
15614 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
15615 tree list)
15617 enum gomp_map_kind kind;
15618 switch (c_kind)
15620 case PRAGMA_OACC_CLAUSE_ATTACH:
15621 kind = GOMP_MAP_ATTACH;
15622 break;
15623 case PRAGMA_OACC_CLAUSE_COPY:
15624 kind = GOMP_MAP_TOFROM;
15625 break;
15626 case PRAGMA_OACC_CLAUSE_COPYIN:
15627 kind = GOMP_MAP_TO;
15628 break;
15629 case PRAGMA_OACC_CLAUSE_COPYOUT:
15630 kind = GOMP_MAP_FROM;
15631 break;
15632 case PRAGMA_OACC_CLAUSE_CREATE:
15633 kind = GOMP_MAP_ALLOC;
15634 break;
15635 case PRAGMA_OACC_CLAUSE_DELETE:
15636 kind = GOMP_MAP_RELEASE;
15637 break;
15638 case PRAGMA_OACC_CLAUSE_DETACH:
15639 kind = GOMP_MAP_DETACH;
15640 break;
15641 case PRAGMA_OACC_CLAUSE_DEVICE:
15642 kind = GOMP_MAP_FORCE_TO;
15643 break;
15644 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
15645 kind = GOMP_MAP_DEVICE_RESIDENT;
15646 break;
15647 case PRAGMA_OACC_CLAUSE_LINK:
15648 kind = GOMP_MAP_LINK;
15649 break;
15650 case PRAGMA_OACC_CLAUSE_NO_CREATE:
15651 kind = GOMP_MAP_IF_PRESENT;
15652 break;
15653 case PRAGMA_OACC_CLAUSE_PRESENT:
15654 kind = GOMP_MAP_FORCE_PRESENT;
15655 break;
15656 case PRAGMA_OACC_CLAUSE_SELF:
15657 /* "The 'host' clause is a synonym for the 'self' clause." */
15658 case PRAGMA_OACC_CLAUSE_HOST:
15659 kind = GOMP_MAP_FORCE_FROM;
15660 break;
15661 default:
15662 gcc_unreachable ();
15664 tree nl, c;
15665 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, false);
15667 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15668 OMP_CLAUSE_SET_MAP_KIND (c, kind);
15670 return nl;
15673 /* OpenACC 2.0:
15674 deviceptr ( variable-list ) */
15676 static tree
15677 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
15679 location_t loc = c_parser_peek_token (parser)->location;
15680 tree vars, t;
15682 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
15683 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
15684 variable-list must only allow for pointer variables. */
15685 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
15686 for (t = vars; t && t; t = TREE_CHAIN (t))
15688 tree v = TREE_PURPOSE (t);
15690 /* FIXME diagnostics: Ideally we should keep individual
15691 locations for all the variables in the var list to make the
15692 following errors more precise. Perhaps
15693 c_parser_omp_var_list_parens() should construct a list of
15694 locations to go along with the var list. */
15696 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
15697 error_at (loc, "%qD is not a variable", v);
15698 else if (TREE_TYPE (v) == error_mark_node)
15700 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
15701 error_at (loc, "%qD is not a pointer variable", v);
15703 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
15704 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
15705 OMP_CLAUSE_DECL (u) = v;
15706 OMP_CLAUSE_CHAIN (u) = list;
15707 list = u;
15710 return list;
15713 /* OpenACC 2.0, OpenMP 3.0:
15714 collapse ( constant-expression ) */
15716 static tree
15717 c_parser_omp_clause_collapse (c_parser *parser, tree list)
15719 tree c, num = error_mark_node;
15720 HOST_WIDE_INT n;
15721 location_t loc;
15723 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
15724 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
15726 loc = c_parser_peek_token (parser)->location;
15727 matching_parens parens;
15728 if (parens.require_open (parser))
15730 num = c_parser_expr_no_commas (parser, NULL).value;
15731 parens.skip_until_found_close (parser);
15733 if (num == error_mark_node)
15734 return list;
15735 mark_exp_read (num);
15736 num = c_fully_fold (num, false, NULL);
15737 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
15738 || !tree_fits_shwi_p (num)
15739 || (n = tree_to_shwi (num)) <= 0
15740 || (int) n != n)
15742 error_at (loc,
15743 "collapse argument needs positive constant integer expression");
15744 return list;
15746 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
15747 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
15748 OMP_CLAUSE_CHAIN (c) = list;
15749 return c;
15752 /* OpenMP 2.5:
15753 copyin ( variable-list ) */
15755 static tree
15756 c_parser_omp_clause_copyin (c_parser *parser, tree list)
15758 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
15761 /* OpenMP 2.5:
15762 copyprivate ( variable-list ) */
15764 static tree
15765 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
15767 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
15770 /* OpenMP 2.5:
15771 default ( none | shared )
15773 OpenMP 5.1:
15774 default ( private | firstprivate )
15776 OpenACC:
15777 default ( none | present ) */
15779 static tree
15780 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
15782 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
15783 location_t loc = c_parser_peek_token (parser)->location;
15784 tree c;
15786 matching_parens parens;
15787 if (!parens.require_open (parser))
15788 return list;
15789 if (c_parser_next_token_is (parser, CPP_NAME))
15791 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15793 switch (p[0])
15795 case 'n':
15796 if (strcmp ("none", p) != 0)
15797 goto invalid_kind;
15798 kind = OMP_CLAUSE_DEFAULT_NONE;
15799 break;
15801 case 'p':
15802 if (is_oacc)
15804 if (strcmp ("present", p) != 0)
15805 goto invalid_kind;
15806 kind = OMP_CLAUSE_DEFAULT_PRESENT;
15808 else
15810 if (strcmp ("private", p) != 0)
15811 goto invalid_kind;
15812 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
15814 break;
15816 case 'f':
15817 if (strcmp ("firstprivate", p) != 0 || is_oacc)
15818 goto invalid_kind;
15819 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
15820 break;
15822 case 's':
15823 if (strcmp ("shared", p) != 0 || is_oacc)
15824 goto invalid_kind;
15825 kind = OMP_CLAUSE_DEFAULT_SHARED;
15826 break;
15828 default:
15829 goto invalid_kind;
15832 c_parser_consume_token (parser);
15834 else
15836 invalid_kind:
15837 if (is_oacc)
15838 c_parser_error (parser, "expected %<none%> or %<present%>");
15839 else
15840 c_parser_error (parser, "expected %<none%>, %<shared%>, "
15841 "%<private%> or %<firstprivate%>");
15843 parens.skip_until_found_close (parser);
15845 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
15846 return list;
15848 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
15849 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
15850 OMP_CLAUSE_CHAIN (c) = list;
15851 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
15853 return c;
15856 /* OpenMP 2.5:
15857 firstprivate ( variable-list ) */
15859 static tree
15860 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
15862 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
15865 /* OpenMP 3.1:
15866 final ( expression ) */
15868 static tree
15869 c_parser_omp_clause_final (c_parser *parser, tree list)
15871 location_t loc = c_parser_peek_token (parser)->location;
15872 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
15874 matching_parens parens;
15875 tree t, c;
15876 if (!parens.require_open (parser))
15877 t = error_mark_node;
15878 else
15880 location_t eloc = c_parser_peek_token (parser)->location;
15881 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15882 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
15883 t = c_objc_common_truthvalue_conversion (eloc, t);
15884 t = c_fully_fold (t, false, NULL);
15885 parens.skip_until_found_close (parser);
15888 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
15890 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
15891 OMP_CLAUSE_FINAL_EXPR (c) = t;
15892 OMP_CLAUSE_CHAIN (c) = list;
15893 list = c;
15895 else
15896 c_parser_error (parser, "expected %<(%>");
15898 return list;
15901 /* OpenMP 5.1:
15902 indirect [( expression )]
15905 static tree
15906 c_parser_omp_clause_indirect (c_parser *parser, tree list)
15908 location_t location = c_parser_peek_token (parser)->location;
15909 tree t;
15911 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
15913 matching_parens parens;
15914 if (!parens.require_open (parser))
15915 return list;
15917 location_t loc = c_parser_peek_token (parser)->location;
15918 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15919 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
15920 t = c_objc_common_truthvalue_conversion (loc, expr.value);
15921 t = c_fully_fold (t, false, NULL);
15922 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
15923 || TREE_CODE (t) != INTEGER_CST)
15925 c_parser_error (parser, "expected constant logical expression");
15926 return list;
15928 parens.skip_until_found_close (parser);
15930 else
15931 t = integer_one_node;
15933 check_no_duplicate_clause (list, OMP_CLAUSE_INDIRECT, "indirect");
15935 tree c = build_omp_clause (location, OMP_CLAUSE_INDIRECT);
15936 OMP_CLAUSE_INDIRECT_EXPR (c) = t;
15937 OMP_CLAUSE_CHAIN (c) = list;
15939 return c;
15942 /* OpenACC, OpenMP 2.5:
15943 if ( expression )
15945 OpenMP 4.5:
15946 if ( directive-name-modifier : expression )
15948 directive-name-modifier:
15949 parallel | task | taskloop | target data | target | target update
15950 | target enter data | target exit data
15952 OpenMP 5.0:
15953 directive-name-modifier:
15954 ... | simd | cancel */
15956 static tree
15957 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
15959 location_t location = c_parser_peek_token (parser)->location;
15960 enum tree_code if_modifier = ERROR_MARK;
15962 matching_parens parens;
15963 if (!parens.require_open (parser))
15964 return list;
15966 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
15968 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15969 int n = 2;
15970 if (strcmp (p, "cancel") == 0)
15971 if_modifier = VOID_CST;
15972 else if (strcmp (p, "parallel") == 0)
15973 if_modifier = OMP_PARALLEL;
15974 else if (strcmp (p, "simd") == 0)
15975 if_modifier = OMP_SIMD;
15976 else if (strcmp (p, "task") == 0)
15977 if_modifier = OMP_TASK;
15978 else if (strcmp (p, "taskloop") == 0)
15979 if_modifier = OMP_TASKLOOP;
15980 else if (strcmp (p, "target") == 0)
15982 if_modifier = OMP_TARGET;
15983 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
15985 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
15986 if (strcmp ("data", p) == 0)
15987 if_modifier = OMP_TARGET_DATA;
15988 else if (strcmp ("update", p) == 0)
15989 if_modifier = OMP_TARGET_UPDATE;
15990 else if (strcmp ("enter", p) == 0)
15991 if_modifier = OMP_TARGET_ENTER_DATA;
15992 else if (strcmp ("exit", p) == 0)
15993 if_modifier = OMP_TARGET_EXIT_DATA;
15994 if (if_modifier != OMP_TARGET)
15996 n = 3;
15997 c_parser_consume_token (parser);
15999 else
16001 location_t loc = c_parser_peek_2nd_token (parser)->location;
16002 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
16003 "or %<exit%>");
16004 if_modifier = ERROR_MARK;
16006 if (if_modifier == OMP_TARGET_ENTER_DATA
16007 || if_modifier == OMP_TARGET_EXIT_DATA)
16009 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
16011 p = IDENTIFIER_POINTER
16012 (c_parser_peek_2nd_token (parser)->value);
16013 if (strcmp ("data", p) == 0)
16014 n = 4;
16016 if (n == 4)
16017 c_parser_consume_token (parser);
16018 else
16020 location_t loc
16021 = c_parser_peek_2nd_token (parser)->location;
16022 error_at (loc, "expected %<data%>");
16023 if_modifier = ERROR_MARK;
16028 if (if_modifier != ERROR_MARK)
16030 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16032 c_parser_consume_token (parser);
16033 c_parser_consume_token (parser);
16035 else
16037 if (n > 2)
16039 location_t loc = c_parser_peek_2nd_token (parser)->location;
16040 error_at (loc, "expected %<:%>");
16042 if_modifier = ERROR_MARK;
16047 location_t loc = c_parser_peek_token (parser)->location;
16048 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16049 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
16050 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
16051 t = c_fully_fold (t, false, NULL);
16052 parens.skip_until_found_close (parser);
16054 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
16055 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
16057 if (if_modifier != ERROR_MARK
16058 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
16060 const char *p = NULL;
16061 switch (if_modifier)
16063 case VOID_CST: p = "cancel"; break;
16064 case OMP_PARALLEL: p = "parallel"; break;
16065 case OMP_SIMD: p = "simd"; break;
16066 case OMP_TASK: p = "task"; break;
16067 case OMP_TASKLOOP: p = "taskloop"; break;
16068 case OMP_TARGET_DATA: p = "target data"; break;
16069 case OMP_TARGET: p = "target"; break;
16070 case OMP_TARGET_UPDATE: p = "target update"; break;
16071 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
16072 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
16073 default: gcc_unreachable ();
16075 error_at (location, "too many %<if%> clauses with %qs modifier",
16077 return list;
16079 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
16081 if (!is_omp)
16082 error_at (location, "too many %<if%> clauses");
16083 else
16084 error_at (location, "too many %<if%> clauses without modifier");
16085 return list;
16087 else if (if_modifier == ERROR_MARK
16088 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
16090 error_at (location, "if any %<if%> clause has modifier, then all "
16091 "%<if%> clauses have to use modifier");
16092 return list;
16096 c = build_omp_clause (location, OMP_CLAUSE_IF);
16097 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
16098 OMP_CLAUSE_IF_EXPR (c) = t;
16099 OMP_CLAUSE_CHAIN (c) = list;
16100 return c;
16103 /* OpenMP 2.5:
16104 lastprivate ( variable-list )
16106 OpenMP 5.0:
16107 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
16109 static tree
16110 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
16112 /* The clauses location. */
16113 location_t loc = c_parser_peek_token (parser)->location;
16115 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
16117 bool conditional = false;
16118 if (c_parser_next_token_is (parser, CPP_NAME)
16119 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16121 const char *p
16122 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16123 if (strcmp (p, "conditional") == 0)
16125 conditional = true;
16126 c_parser_consume_token (parser);
16127 c_parser_consume_token (parser);
16130 tree nlist = c_parser_omp_variable_list (parser, loc,
16131 OMP_CLAUSE_LASTPRIVATE, list);
16132 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
16133 if (conditional)
16134 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
16135 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
16136 return nlist;
16138 return list;
16141 /* OpenMP 3.1:
16142 mergeable */
16144 static tree
16145 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
16147 tree c;
16149 /* FIXME: Should we allow duplicates? */
16150 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
16152 c = build_omp_clause (c_parser_peek_token (parser)->location,
16153 OMP_CLAUSE_MERGEABLE);
16154 OMP_CLAUSE_CHAIN (c) = list;
16156 return c;
16159 /* OpenMP 2.5:
16160 nowait */
16162 static tree
16163 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
16165 tree c;
16166 location_t loc = c_parser_peek_token (parser)->location;
16168 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
16170 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
16171 OMP_CLAUSE_CHAIN (c) = list;
16172 return c;
16175 /* OpenMP 2.5:
16176 num_threads ( expression ) */
16178 static tree
16179 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
16181 location_t num_threads_loc = c_parser_peek_token (parser)->location;
16182 matching_parens parens;
16183 if (parens.require_open (parser))
16185 location_t expr_loc = c_parser_peek_token (parser)->location;
16186 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16187 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16188 tree c, t = expr.value;
16189 t = c_fully_fold (t, false, NULL);
16191 parens.skip_until_found_close (parser);
16193 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16195 c_parser_error (parser, "expected integer expression");
16196 return list;
16199 /* Attempt to statically determine when the number isn't positive. */
16200 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16201 build_int_cst (TREE_TYPE (t), 0));
16202 protected_set_expr_location (c, expr_loc);
16203 if (c == boolean_true_node)
16205 warning_at (expr_loc, OPT_Wopenmp,
16206 "%<num_threads%> value must be positive");
16207 t = integer_one_node;
16210 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
16212 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
16213 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
16214 OMP_CLAUSE_CHAIN (c) = list;
16215 list = c;
16218 return list;
16221 /* OpenMP 4.5:
16222 num_tasks ( expression )
16224 OpenMP 5.1:
16225 num_tasks ( strict : expression ) */
16227 static tree
16228 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
16230 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
16231 matching_parens parens;
16232 if (parens.require_open (parser))
16234 bool strict = false;
16235 if (c_parser_next_token_is (parser, CPP_NAME)
16236 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
16237 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16238 "strict") == 0)
16240 strict = true;
16241 c_parser_consume_token (parser);
16242 c_parser_consume_token (parser);
16245 location_t expr_loc = c_parser_peek_token (parser)->location;
16246 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16247 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16248 tree c, t = expr.value;
16249 t = c_fully_fold (t, false, NULL);
16251 parens.skip_until_found_close (parser);
16253 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16255 c_parser_error (parser, "expected integer expression");
16256 return list;
16259 /* Attempt to statically determine when the number isn't positive. */
16260 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16261 build_int_cst (TREE_TYPE (t), 0));
16262 if (CAN_HAVE_LOCATION_P (c))
16263 SET_EXPR_LOCATION (c, expr_loc);
16264 if (c == boolean_true_node)
16266 warning_at (expr_loc, OPT_Wopenmp,
16267 "%<num_tasks%> value must be positive");
16268 t = integer_one_node;
16271 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
16273 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
16274 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
16275 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
16276 OMP_CLAUSE_CHAIN (c) = list;
16277 list = c;
16280 return list;
16283 /* OpenMP 4.5:
16284 grainsize ( expression )
16286 OpenMP 5.1:
16287 grainsize ( strict : expression ) */
16289 static tree
16290 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
16292 location_t grainsize_loc = c_parser_peek_token (parser)->location;
16293 matching_parens parens;
16294 if (parens.require_open (parser))
16296 bool strict = false;
16297 if (c_parser_next_token_is (parser, CPP_NAME)
16298 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
16299 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16300 "strict") == 0)
16302 strict = true;
16303 c_parser_consume_token (parser);
16304 c_parser_consume_token (parser);
16307 location_t expr_loc = c_parser_peek_token (parser)->location;
16308 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16309 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16310 tree c, t = expr.value;
16311 t = c_fully_fold (t, false, NULL);
16313 parens.skip_until_found_close (parser);
16315 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16317 c_parser_error (parser, "expected integer expression");
16318 return list;
16321 /* Attempt to statically determine when the number isn't positive. */
16322 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16323 build_int_cst (TREE_TYPE (t), 0));
16324 if (CAN_HAVE_LOCATION_P (c))
16325 SET_EXPR_LOCATION (c, expr_loc);
16326 if (c == boolean_true_node)
16328 warning_at (expr_loc, OPT_Wopenmp,
16329 "%<grainsize%> value must be positive");
16330 t = integer_one_node;
16333 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
16335 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
16336 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
16337 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
16338 OMP_CLAUSE_CHAIN (c) = list;
16339 list = c;
16342 return list;
16345 /* OpenMP 4.5:
16346 priority ( expression ) */
16348 static tree
16349 c_parser_omp_clause_priority (c_parser *parser, tree list)
16351 location_t priority_loc = c_parser_peek_token (parser)->location;
16352 matching_parens parens;
16353 if (parens.require_open (parser))
16355 location_t expr_loc = c_parser_peek_token (parser)->location;
16356 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16357 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16358 tree c, t = expr.value;
16359 t = c_fully_fold (t, false, NULL);
16361 parens.skip_until_found_close (parser);
16363 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16365 c_parser_error (parser, "expected integer expression");
16366 return list;
16369 /* Attempt to statically determine when the number isn't
16370 non-negative. */
16371 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
16372 build_int_cst (TREE_TYPE (t), 0));
16373 if (CAN_HAVE_LOCATION_P (c))
16374 SET_EXPR_LOCATION (c, expr_loc);
16375 if (c == boolean_true_node)
16377 warning_at (expr_loc, OPT_Wopenmp,
16378 "%<priority%> value must be non-negative");
16379 t = integer_one_node;
16382 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
16384 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
16385 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
16386 OMP_CLAUSE_CHAIN (c) = list;
16387 list = c;
16390 return list;
16393 /* OpenMP 4.5:
16394 hint ( expression ) */
16396 static tree
16397 c_parser_omp_clause_hint (c_parser *parser, tree list)
16399 location_t hint_loc = c_parser_peek_token (parser)->location;
16400 matching_parens parens;
16401 if (parens.require_open (parser))
16403 location_t expr_loc = c_parser_peek_token (parser)->location;
16404 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16405 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16406 tree c, t = expr.value;
16407 t = c_fully_fold (t, false, NULL);
16408 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
16409 || TREE_CODE (t) != INTEGER_CST
16410 || tree_int_cst_sgn (t) == -1)
16412 c_parser_error (parser, "expected constant integer expression "
16413 "with valid sync-hint value");
16414 return list;
16416 parens.skip_until_found_close (parser);
16417 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
16419 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
16420 OMP_CLAUSE_HINT_EXPR (c) = t;
16421 OMP_CLAUSE_CHAIN (c) = list;
16422 list = c;
16425 return list;
16428 /* OpenMP 5.1:
16429 filter ( integer-expression ) */
16431 static tree
16432 c_parser_omp_clause_filter (c_parser *parser, tree list)
16434 location_t hint_loc = c_parser_peek_token (parser)->location;
16435 matching_parens parens;
16436 if (parens.require_open (parser))
16438 location_t expr_loc = c_parser_peek_token (parser)->location;
16439 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16440 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16441 tree c, t = expr.value;
16442 t = c_fully_fold (t, false, NULL);
16443 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16445 c_parser_error (parser, "expected integer expression");
16446 return list;
16448 parens.skip_until_found_close (parser);
16449 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
16451 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
16452 OMP_CLAUSE_FILTER_EXPR (c) = t;
16453 OMP_CLAUSE_CHAIN (c) = list;
16454 list = c;
16457 return list;
16460 /* OpenMP 4.5:
16461 defaultmap ( tofrom : scalar )
16463 OpenMP 5.0:
16464 defaultmap ( implicit-behavior [ : variable-category ] ) */
16466 static tree
16467 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
16469 location_t loc = c_parser_peek_token (parser)->location;
16470 tree c;
16471 const char *p;
16472 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
16473 enum omp_clause_defaultmap_kind category
16474 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
16476 matching_parens parens;
16477 if (!parens.require_open (parser))
16478 return list;
16479 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
16480 p = "default";
16481 else if (!c_parser_next_token_is (parser, CPP_NAME))
16483 invalid_behavior:
16484 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
16485 "%<tofrom%>, %<firstprivate%>, %<none%> "
16486 "or %<default%>");
16487 goto out_err;
16489 else
16490 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16492 switch (p[0])
16494 case 'a':
16495 if (strcmp ("alloc", p) == 0)
16496 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
16497 else
16498 goto invalid_behavior;
16499 break;
16501 case 'd':
16502 if (strcmp ("default", p) == 0)
16503 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
16504 else
16505 goto invalid_behavior;
16506 break;
16508 case 'f':
16509 if (strcmp ("firstprivate", p) == 0)
16510 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
16511 else if (strcmp ("from", p) == 0)
16512 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
16513 else
16514 goto invalid_behavior;
16515 break;
16517 case 'n':
16518 if (strcmp ("none", p) == 0)
16519 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
16520 else
16521 goto invalid_behavior;
16522 break;
16524 case 'p':
16525 if (strcmp ("present", p) == 0)
16526 behavior = OMP_CLAUSE_DEFAULTMAP_PRESENT;
16527 else
16528 goto invalid_behavior;
16529 break;
16531 case 't':
16532 if (strcmp ("tofrom", p) == 0)
16533 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
16534 else if (strcmp ("to", p) == 0)
16535 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
16536 else
16537 goto invalid_behavior;
16538 break;
16540 default:
16541 goto invalid_behavior;
16543 c_parser_consume_token (parser);
16545 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16547 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16548 goto out_err;
16549 if (!c_parser_next_token_is (parser, CPP_NAME))
16551 invalid_category:
16552 c_parser_error (parser, "expected %<scalar%>, %<aggregate%>, "
16553 "%<pointer%> or %<all%>");
16554 goto out_err;
16556 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16557 switch (p[0])
16559 case 'a':
16560 if (strcmp ("aggregate", p) == 0)
16561 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
16562 else if (strcmp ("all", p) == 0)
16563 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
16564 else
16565 goto invalid_category;
16566 break;
16568 case 'p':
16569 if (strcmp ("pointer", p) == 0)
16570 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
16571 else
16572 goto invalid_category;
16573 break;
16575 case 's':
16576 if (strcmp ("scalar", p) == 0)
16577 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
16578 else
16579 goto invalid_category;
16580 break;
16582 default:
16583 goto invalid_category;
16586 c_parser_consume_token (parser);
16588 parens.skip_until_found_close (parser);
16590 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
16591 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
16592 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16593 || category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16594 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
16595 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16596 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
16597 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16598 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL)))
16600 enum omp_clause_defaultmap_kind cat = category;
16601 location_t loc = OMP_CLAUSE_LOCATION (c);
16602 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16603 || (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16604 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16605 != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
16606 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
16607 p = NULL;
16608 switch (cat)
16610 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
16611 p = NULL;
16612 break;
16613 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
16614 p = "all";
16615 break;
16616 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
16617 p = "aggregate";
16618 break;
16619 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
16620 p = "pointer";
16621 break;
16622 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
16623 p = "scalar";
16624 break;
16625 default:
16626 gcc_unreachable ();
16628 if (p)
16629 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
16631 else
16632 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
16633 "category");
16634 break;
16637 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
16638 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
16639 OMP_CLAUSE_CHAIN (c) = list;
16640 return c;
16642 out_err:
16643 parens.skip_until_found_close (parser);
16644 return list;
16647 /* OpenACC 2.0:
16648 use_device ( variable-list )
16650 OpenMP 4.5:
16651 use_device_ptr ( variable-list ) */
16653 static tree
16654 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
16656 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
16657 list);
16660 /* OpenMP 5.0:
16661 use_device_addr ( variable-list ) */
16663 static tree
16664 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
16666 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
16667 list);
16670 /* OpenMP 5.1:
16671 has_device_addr ( variable-list ) */
16673 static tree
16674 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
16676 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
16677 list);
16680 /* OpenMP 4.5:
16681 is_device_ptr ( variable-list ) */
16683 static tree
16684 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
16686 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
16689 /* OpenACC:
16690 num_gangs ( expression )
16691 num_workers ( expression )
16692 vector_length ( expression ) */
16694 static tree
16695 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
16696 tree list)
16698 location_t loc = c_parser_peek_token (parser)->location;
16700 matching_parens parens;
16701 if (!parens.require_open (parser))
16702 return list;
16704 location_t expr_loc = c_parser_peek_token (parser)->location;
16705 c_expr expr = c_parser_expression (parser);
16706 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16707 tree c, t = expr.value;
16708 t = c_fully_fold (t, false, NULL);
16710 parens.skip_until_found_close (parser);
16712 if (t == error_mark_node)
16713 return list;
16714 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16716 error_at (expr_loc, "%qs expression must be integral",
16717 omp_clause_code_name[code]);
16718 return list;
16721 /* Attempt to statically determine when the number isn't positive. */
16722 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16723 build_int_cst (TREE_TYPE (t), 0));
16724 protected_set_expr_location (c, expr_loc);
16725 if (c == boolean_true_node)
16727 warning_at (expr_loc, 0,
16728 "%qs value must be positive",
16729 omp_clause_code_name[code]);
16730 t = integer_one_node;
16733 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
16735 c = build_omp_clause (loc, code);
16736 OMP_CLAUSE_OPERAND (c, 0) = t;
16737 OMP_CLAUSE_CHAIN (c) = list;
16738 return c;
16741 /* OpenACC:
16743 gang [( gang-arg-list )]
16744 worker [( [num:] int-expr )]
16745 vector [( [length:] int-expr )]
16747 where gang-arg is one of:
16749 [num:] int-expr
16750 static: size-expr
16752 and size-expr may be:
16755 int-expr
16758 static tree
16759 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
16760 omp_clause_code kind,
16761 const char *str, tree list)
16763 const char *id = "num";
16764 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
16766 if (kind == OMP_CLAUSE_VECTOR)
16767 id = "length";
16769 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
16771 c_parser_consume_token (parser);
16775 c_token *next = c_parser_peek_token (parser);
16776 int idx = 0;
16778 /* Gang static argument. */
16779 if (kind == OMP_CLAUSE_GANG
16780 && c_parser_next_token_is_keyword (parser, RID_STATIC))
16782 c_parser_consume_token (parser);
16784 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16785 goto cleanup_error;
16787 idx = 1;
16788 if (ops[idx] != NULL_TREE)
16790 c_parser_error (parser, "too many %<static%> arguments");
16791 goto cleanup_error;
16794 /* Check for the '*' argument. */
16795 if (c_parser_next_token_is (parser, CPP_MULT)
16796 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
16797 || c_parser_peek_2nd_token (parser)->type
16798 == CPP_CLOSE_PAREN))
16800 c_parser_consume_token (parser);
16801 ops[idx] = integer_minus_one_node;
16803 if (c_parser_next_token_is (parser, CPP_COMMA))
16805 c_parser_consume_token (parser);
16806 continue;
16808 else
16809 break;
16812 /* Worker num: argument and vector length: arguments. */
16813 else if (c_parser_next_token_is (parser, CPP_NAME)
16814 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
16815 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16817 c_parser_consume_token (parser); /* id */
16818 c_parser_consume_token (parser); /* ':' */
16821 /* Now collect the actual argument. */
16822 if (ops[idx] != NULL_TREE)
16824 c_parser_error (parser, "unexpected argument");
16825 goto cleanup_error;
16828 location_t expr_loc = c_parser_peek_token (parser)->location;
16829 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
16830 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
16831 tree expr = cexpr.value;
16832 if (expr == error_mark_node)
16833 goto cleanup_error;
16835 expr = c_fully_fold (expr, false, NULL);
16837 /* Attempt to statically determine when the number isn't a
16838 positive integer. */
16840 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
16842 c_parser_error (parser, "expected integer expression");
16843 return list;
16846 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
16847 build_int_cst (TREE_TYPE (expr), 0));
16848 if (c == boolean_true_node)
16850 warning_at (loc, 0,
16851 "%qs value must be positive", str);
16852 expr = integer_one_node;
16855 ops[idx] = expr;
16857 if (kind == OMP_CLAUSE_GANG
16858 && c_parser_next_token_is (parser, CPP_COMMA))
16860 c_parser_consume_token (parser);
16861 continue;
16863 break;
16865 while (1);
16867 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
16868 goto cleanup_error;
16871 check_no_duplicate_clause (list, kind, str);
16873 c = build_omp_clause (loc, kind);
16875 if (ops[1])
16876 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
16878 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
16879 OMP_CLAUSE_CHAIN (c) = list;
16881 return c;
16883 cleanup_error:
16884 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
16885 return list;
16888 /* OpenACC 2.5:
16889 auto
16890 finalize
16891 independent
16892 nohost
16893 seq */
16895 static tree
16896 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
16897 tree list)
16899 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
16901 tree c = build_omp_clause (loc, code);
16902 OMP_CLAUSE_CHAIN (c) = list;
16904 return c;
16907 /* OpenACC:
16908 async [( int-expr )] */
16910 static tree
16911 c_parser_oacc_clause_async (c_parser *parser, tree list)
16913 tree c, t;
16914 location_t loc = c_parser_peek_token (parser)->location;
16916 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
16918 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
16920 c_parser_consume_token (parser);
16922 t = c_parser_expr_no_commas (parser, NULL).value;
16923 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16924 c_parser_error (parser, "expected integer expression");
16925 else if (t == error_mark_node
16926 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
16927 return list;
16929 else
16930 t = c_fully_fold (t, false, NULL);
16932 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
16934 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
16935 OMP_CLAUSE_ASYNC_EXPR (c) = t;
16936 OMP_CLAUSE_CHAIN (c) = list;
16937 list = c;
16939 return list;
16942 /* OpenACC 2.0:
16943 tile ( size-expr-list ) */
16945 static tree
16946 c_parser_oacc_clause_tile (c_parser *parser, tree list)
16948 tree c, expr = error_mark_node;
16949 location_t loc;
16950 tree tile = NULL_TREE;
16952 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
16953 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
16955 loc = c_parser_peek_token (parser)->location;
16956 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
16957 return list;
16961 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
16962 return list;
16964 if (c_parser_next_token_is (parser, CPP_MULT)
16965 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
16966 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
16968 c_parser_consume_token (parser);
16969 expr = integer_zero_node;
16971 else
16973 location_t expr_loc = c_parser_peek_token (parser)->location;
16974 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
16975 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
16976 expr = cexpr.value;
16978 if (expr == error_mark_node)
16980 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16981 "expected %<)%>");
16982 return list;
16985 expr = c_fully_fold (expr, false, NULL);
16987 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
16988 || !tree_fits_shwi_p (expr)
16989 || tree_to_shwi (expr) <= 0)
16991 error_at (expr_loc, "%<tile%> argument needs positive"
16992 " integral constant");
16993 expr = integer_zero_node;
16997 tile = tree_cons (NULL_TREE, expr, tile);
16999 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
17001 /* Consume the trailing ')'. */
17002 c_parser_consume_token (parser);
17004 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
17005 tile = nreverse (tile);
17006 OMP_CLAUSE_TILE_LIST (c) = tile;
17007 OMP_CLAUSE_CHAIN (c) = list;
17008 return c;
17011 /* OpenACC:
17012 wait [( int-expr-list )] */
17014 static tree
17015 c_parser_oacc_clause_wait (c_parser *parser, tree list)
17017 location_t clause_loc = c_parser_peek_token (parser)->location;
17019 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17020 list = c_parser_oacc_wait_list (parser, clause_loc, list);
17021 else
17023 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
17025 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
17026 OMP_CLAUSE_CHAIN (c) = list;
17027 list = c;
17030 return list;
17033 /* OpenACC 2.7:
17034 self [( expression )] */
17036 static tree
17037 c_parser_oacc_compute_clause_self (c_parser *parser, tree list)
17039 tree t;
17040 location_t location = c_parser_peek_token (parser)->location;
17041 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17043 matching_parens parens;
17044 parens.consume_open (parser);
17046 location_t loc = c_parser_peek_token (parser)->location;
17047 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17048 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
17049 t = c_objc_common_truthvalue_conversion (loc, expr.value);
17050 t = c_fully_fold (t, false, NULL);
17051 parens.skip_until_found_close (parser);
17053 else
17054 t = truthvalue_true_node;
17056 for (tree c = list; c; c = OMP_CLAUSE_CHAIN (c))
17057 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
17059 error_at (location, "too many %<self%> clauses");
17060 return list;
17063 tree c = build_omp_clause (location, OMP_CLAUSE_SELF);
17064 OMP_CLAUSE_SELF_EXPR (c) = t;
17065 OMP_CLAUSE_CHAIN (c) = list;
17066 return c;
17069 /* OpenMP 5.0:
17070 order ( concurrent )
17072 OpenMP 5.1:
17073 order ( order-modifier : concurrent )
17075 order-modifier:
17076 reproducible
17077 unconstrained */
17079 static tree
17080 c_parser_omp_clause_order (c_parser *parser, tree list)
17082 location_t loc = c_parser_peek_token (parser)->location;
17083 tree c;
17084 const char *p;
17085 bool unconstrained = false;
17086 bool reproducible = false;
17088 matching_parens parens;
17089 if (!parens.require_open (parser))
17090 return list;
17091 if (c_parser_next_token_is (parser, CPP_NAME)
17092 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
17094 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17095 if (strcmp (p, "unconstrained") == 0)
17096 unconstrained = true;
17097 else if (strcmp (p, "reproducible") == 0)
17098 reproducible = true;
17099 else
17101 c_parser_error (parser, "expected %<reproducible%> or "
17102 "%<unconstrained%>");
17103 goto out_err;
17105 c_parser_consume_token (parser);
17106 c_parser_consume_token (parser);
17108 if (!c_parser_next_token_is (parser, CPP_NAME))
17110 c_parser_error (parser, "expected %<concurrent%>");
17111 goto out_err;
17113 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17114 if (strcmp (p, "concurrent") != 0)
17116 c_parser_error (parser, "expected %<concurrent%>");
17117 goto out_err;
17119 c_parser_consume_token (parser);
17120 parens.skip_until_found_close (parser);
17121 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
17122 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
17123 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
17124 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
17125 OMP_CLAUSE_CHAIN (c) = list;
17126 return c;
17128 out_err:
17129 parens.skip_until_found_close (parser);
17130 return list;
17134 /* OpenMP 5.0:
17135 bind ( teams | parallel | thread ) */
17137 static tree
17138 c_parser_omp_clause_bind (c_parser *parser, tree list)
17140 location_t loc = c_parser_peek_token (parser)->location;
17141 tree c;
17142 const char *p;
17143 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
17145 matching_parens parens;
17146 if (!parens.require_open (parser))
17147 return list;
17148 if (!c_parser_next_token_is (parser, CPP_NAME))
17150 invalid:
17151 c_parser_error (parser,
17152 "expected %<teams%>, %<parallel%> or %<thread%>");
17153 parens.skip_until_found_close (parser);
17154 return list;
17156 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17157 if (strcmp (p, "teams") == 0)
17158 kind = OMP_CLAUSE_BIND_TEAMS;
17159 else if (strcmp (p, "parallel") == 0)
17160 kind = OMP_CLAUSE_BIND_PARALLEL;
17161 else if (strcmp (p, "thread") != 0)
17162 goto invalid;
17163 c_parser_consume_token (parser);
17164 parens.skip_until_found_close (parser);
17165 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
17166 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
17167 OMP_CLAUSE_BIND_KIND (c) = kind;
17168 OMP_CLAUSE_CHAIN (c) = list;
17169 return c;
17173 /* OpenMP 2.5:
17174 ordered
17176 OpenMP 4.5:
17177 ordered ( constant-expression ) */
17179 static tree
17180 c_parser_omp_clause_ordered (c_parser *parser, tree list)
17182 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
17184 tree c, num = NULL_TREE;
17185 HOST_WIDE_INT n;
17186 location_t loc = c_parser_peek_token (parser)->location;
17187 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17189 matching_parens parens;
17190 parens.consume_open (parser);
17191 num = c_parser_expr_no_commas (parser, NULL).value;
17192 parens.skip_until_found_close (parser);
17194 if (num == error_mark_node)
17195 return list;
17196 if (num)
17198 mark_exp_read (num);
17199 num = c_fully_fold (num, false, NULL);
17200 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
17201 || !tree_fits_shwi_p (num)
17202 || (n = tree_to_shwi (num)) <= 0
17203 || (int) n != n)
17205 error_at (loc, "ordered argument needs positive "
17206 "constant integer expression");
17207 return list;
17210 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
17211 OMP_CLAUSE_ORDERED_EXPR (c) = num;
17212 OMP_CLAUSE_CHAIN (c) = list;
17213 return c;
17216 /* OpenMP 2.5:
17217 private ( variable-list ) */
17219 static tree
17220 c_parser_omp_clause_private (c_parser *parser, tree list)
17222 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
17225 /* OpenMP 2.5:
17226 reduction ( reduction-operator : variable-list )
17228 reduction-operator:
17229 One of: + * - & ^ | && ||
17231 OpenMP 3.1:
17233 reduction-operator:
17234 One of: + * - & ^ | && || max min
17236 OpenMP 4.0:
17238 reduction-operator:
17239 One of: + * - & ^ | && ||
17240 identifier
17242 OpenMP 5.0:
17243 reduction ( reduction-modifier, reduction-operator : variable-list )
17244 in_reduction ( reduction-operator : variable-list )
17245 task_reduction ( reduction-operator : variable-list ) */
17247 static tree
17248 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
17249 bool is_omp, tree list)
17251 location_t clause_loc = c_parser_peek_token (parser)->location;
17252 matching_parens parens;
17253 if (parens.require_open (parser))
17255 bool task = false;
17256 bool inscan = false;
17257 enum tree_code code = ERROR_MARK;
17258 tree reduc_id = NULL_TREE;
17260 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
17262 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
17263 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
17265 c_parser_consume_token (parser);
17266 c_parser_consume_token (parser);
17268 else if (c_parser_next_token_is (parser, CPP_NAME)
17269 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
17271 const char *p
17272 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17273 if (strcmp (p, "task") == 0)
17274 task = true;
17275 else if (strcmp (p, "inscan") == 0)
17276 inscan = true;
17277 if (task || inscan)
17279 c_parser_consume_token (parser);
17280 c_parser_consume_token (parser);
17285 switch (c_parser_peek_token (parser)->type)
17287 case CPP_PLUS:
17288 code = PLUS_EXPR;
17289 break;
17290 case CPP_MULT:
17291 code = MULT_EXPR;
17292 break;
17293 case CPP_MINUS:
17294 code = MINUS_EXPR;
17295 break;
17296 case CPP_AND:
17297 code = BIT_AND_EXPR;
17298 break;
17299 case CPP_XOR:
17300 code = BIT_XOR_EXPR;
17301 break;
17302 case CPP_OR:
17303 code = BIT_IOR_EXPR;
17304 break;
17305 case CPP_AND_AND:
17306 code = TRUTH_ANDIF_EXPR;
17307 break;
17308 case CPP_OR_OR:
17309 code = TRUTH_ORIF_EXPR;
17310 break;
17311 case CPP_NAME:
17313 const char *p
17314 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17315 if (strcmp (p, "min") == 0)
17317 code = MIN_EXPR;
17318 break;
17320 if (strcmp (p, "max") == 0)
17322 code = MAX_EXPR;
17323 break;
17325 reduc_id = c_parser_peek_token (parser)->value;
17326 break;
17328 default:
17329 c_parser_error (parser,
17330 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
17331 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
17332 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
17333 return list;
17335 c_parser_consume_token (parser);
17336 reduc_id = c_omp_reduction_id (code, reduc_id);
17337 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
17339 tree nl, c;
17341 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
17342 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17344 tree d = OMP_CLAUSE_DECL (c), type;
17345 if (TREE_CODE (d) != OMP_ARRAY_SECTION)
17346 type = TREE_TYPE (d);
17347 else
17349 int cnt = 0;
17350 tree t;
17351 for (t = d;
17352 TREE_CODE (t) == OMP_ARRAY_SECTION;
17353 t = TREE_OPERAND (t, 0))
17354 cnt++;
17355 type = TREE_TYPE (t);
17356 while (cnt > 0)
17358 if (TREE_CODE (type) != POINTER_TYPE
17359 && TREE_CODE (type) != ARRAY_TYPE)
17360 break;
17361 type = TREE_TYPE (type);
17362 cnt--;
17365 while (TREE_CODE (type) == ARRAY_TYPE)
17366 type = TREE_TYPE (type);
17367 OMP_CLAUSE_REDUCTION_CODE (c) = code;
17368 if (task)
17369 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
17370 else if (inscan)
17371 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
17372 if (code == ERROR_MARK
17373 || !(INTEGRAL_TYPE_P (type)
17374 || SCALAR_FLOAT_TYPE_P (type)
17375 || TREE_CODE (type) == COMPLEX_TYPE))
17376 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
17377 = c_omp_reduction_lookup (reduc_id,
17378 TYPE_MAIN_VARIANT (type));
17381 list = nl;
17383 parens.skip_until_found_close (parser);
17385 return list;
17388 /* OpenMP 2.5:
17389 schedule ( schedule-kind )
17390 schedule ( schedule-kind , expression )
17392 schedule-kind:
17393 static | dynamic | guided | runtime | auto
17395 OpenMP 4.5:
17396 schedule ( schedule-modifier : schedule-kind )
17397 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
17399 schedule-modifier:
17400 simd
17401 monotonic
17402 nonmonotonic */
17404 static tree
17405 c_parser_omp_clause_schedule (c_parser *parser, tree list)
17407 tree c, t;
17408 location_t loc = c_parser_peek_token (parser)->location;
17409 int modifiers = 0, nmodifiers = 0;
17411 matching_parens parens;
17412 if (!parens.require_open (parser))
17413 return list;
17415 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
17417 location_t comma = UNKNOWN_LOCATION;
17418 while (c_parser_next_token_is (parser, CPP_NAME))
17420 tree kind = c_parser_peek_token (parser)->value;
17421 const char *p = IDENTIFIER_POINTER (kind);
17422 if (strcmp ("simd", p) == 0)
17423 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
17424 else if (strcmp ("monotonic", p) == 0)
17425 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
17426 else if (strcmp ("nonmonotonic", p) == 0)
17427 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
17428 else
17429 break;
17430 comma = UNKNOWN_LOCATION;
17431 c_parser_consume_token (parser);
17432 if (nmodifiers++ == 0
17433 && c_parser_next_token_is (parser, CPP_COMMA))
17435 comma = c_parser_peek_token (parser)->location;
17436 c_parser_consume_token (parser);
17438 else
17440 c_parser_require (parser, CPP_COLON, "expected %<:%>");
17441 break;
17444 if (comma != UNKNOWN_LOCATION)
17445 error_at (comma, "expected %<:%>");
17447 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
17448 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
17449 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
17450 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
17452 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
17453 "specified");
17454 modifiers = 0;
17457 if (c_parser_next_token_is (parser, CPP_NAME))
17459 tree kind = c_parser_peek_token (parser)->value;
17460 const char *p = IDENTIFIER_POINTER (kind);
17462 switch (p[0])
17464 case 'd':
17465 if (strcmp ("dynamic", p) != 0)
17466 goto invalid_kind;
17467 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
17468 break;
17470 case 'g':
17471 if (strcmp ("guided", p) != 0)
17472 goto invalid_kind;
17473 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
17474 break;
17476 case 'r':
17477 if (strcmp ("runtime", p) != 0)
17478 goto invalid_kind;
17479 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
17480 break;
17482 default:
17483 goto invalid_kind;
17486 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
17487 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
17488 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
17489 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
17490 else
17491 goto invalid_kind;
17493 c_parser_consume_token (parser);
17494 if (c_parser_next_token_is (parser, CPP_COMMA))
17496 location_t here;
17497 c_parser_consume_token (parser);
17499 here = c_parser_peek_token (parser)->location;
17500 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17501 expr = convert_lvalue_to_rvalue (here, expr, false, true);
17502 t = expr.value;
17503 t = c_fully_fold (t, false, NULL);
17505 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
17506 error_at (here, "schedule %<runtime%> does not take "
17507 "a %<chunk_size%> parameter");
17508 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
17509 error_at (here,
17510 "schedule %<auto%> does not take "
17511 "a %<chunk_size%> parameter");
17512 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
17513 || TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE)
17515 /* Attempt to statically determine when the number isn't
17516 positive. */
17517 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
17518 build_int_cst (TREE_TYPE (t), 0));
17519 protected_set_expr_location (s, loc);
17520 if (s == boolean_true_node)
17522 warning_at (loc, OPT_Wopenmp,
17523 "chunk size value must be positive");
17524 t = integer_one_node;
17526 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
17528 else
17529 c_parser_error (parser, "expected integer expression");
17531 parens.skip_until_found_close (parser);
17533 else
17534 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17535 "expected %<,%> or %<)%>");
17537 OMP_CLAUSE_SCHEDULE_KIND (c)
17538 = (enum omp_clause_schedule_kind)
17539 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
17541 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
17542 OMP_CLAUSE_CHAIN (c) = list;
17543 return c;
17545 invalid_kind:
17546 c_parser_error (parser, "invalid schedule kind");
17547 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
17548 return list;
17551 /* OpenMP 2.5:
17552 shared ( variable-list ) */
17554 static tree
17555 c_parser_omp_clause_shared (c_parser *parser, tree list)
17557 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
17560 /* OpenMP 3.0:
17561 untied */
17563 static tree
17564 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
17566 tree c;
17568 /* FIXME: Should we allow duplicates? */
17569 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
17571 c = build_omp_clause (c_parser_peek_token (parser)->location,
17572 OMP_CLAUSE_UNTIED);
17573 OMP_CLAUSE_CHAIN (c) = list;
17575 return c;
17578 /* OpenMP 4.0:
17579 inbranch
17580 notinbranch */
17582 static tree
17583 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
17584 enum omp_clause_code code, tree list)
17586 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
17588 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17589 OMP_CLAUSE_CHAIN (c) = list;
17591 return c;
17594 /* OpenMP 4.0:
17595 parallel
17597 sections
17598 taskgroup */
17600 static tree
17601 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
17602 enum omp_clause_code code, tree list)
17604 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17605 OMP_CLAUSE_CHAIN (c) = list;
17607 return c;
17610 /* OpenMP 4.5:
17611 nogroup */
17613 static tree
17614 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
17616 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
17617 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
17618 OMP_CLAUSE_NOGROUP);
17619 OMP_CLAUSE_CHAIN (c) = list;
17620 return c;
17623 /* OpenMP 4.5:
17624 simd
17625 threads */
17627 static tree
17628 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
17629 enum omp_clause_code code, tree list)
17631 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
17632 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17633 OMP_CLAUSE_CHAIN (c) = list;
17634 return c;
17637 /* OpenMP 4.0:
17638 num_teams ( expression )
17640 OpenMP 5.1:
17641 num_teams ( expression : expression ) */
17643 static tree
17644 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
17646 location_t num_teams_loc = c_parser_peek_token (parser)->location;
17647 matching_parens parens;
17648 if (parens.require_open (parser))
17650 location_t upper_loc = c_parser_peek_token (parser)->location;
17651 location_t lower_loc = UNKNOWN_LOCATION;
17652 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17653 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
17654 tree c, upper = expr.value, lower = NULL_TREE;
17655 upper = c_fully_fold (upper, false, NULL);
17657 if (c_parser_next_token_is (parser, CPP_COLON))
17659 c_parser_consume_token (parser);
17660 lower_loc = upper_loc;
17661 lower = upper;
17662 upper_loc = c_parser_peek_token (parser)->location;
17663 expr = c_parser_expr_no_commas (parser, NULL);
17664 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
17665 upper = expr.value;
17666 upper = c_fully_fold (upper, false, NULL);
17669 parens.skip_until_found_close (parser);
17671 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
17672 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
17674 c_parser_error (parser, "expected integer expression");
17675 return list;
17678 /* Attempt to statically determine when the number isn't positive. */
17679 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
17680 build_int_cst (TREE_TYPE (upper), 0));
17681 protected_set_expr_location (c, upper_loc);
17682 if (c == boolean_true_node)
17684 warning_at (upper_loc, OPT_Wopenmp,
17685 "%<num_teams%> value must be positive");
17686 upper = integer_one_node;
17688 if (lower)
17690 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
17691 build_int_cst (TREE_TYPE (lower), 0));
17692 protected_set_expr_location (c, lower_loc);
17693 if (c == boolean_true_node)
17695 warning_at (lower_loc, OPT_Wopenmp,
17696 "%<num_teams%> value must be positive");
17697 lower = NULL_TREE;
17699 else if (TREE_CODE (lower) == INTEGER_CST
17700 && TREE_CODE (upper) == INTEGER_CST
17701 && tree_int_cst_lt (upper, lower))
17703 warning_at (lower_loc, OPT_Wopenmp,
17704 "%<num_teams%> lower bound %qE bigger than upper "
17705 "bound %qE", lower, upper);
17706 lower = NULL_TREE;
17710 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
17712 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
17713 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
17714 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
17715 OMP_CLAUSE_CHAIN (c) = list;
17716 list = c;
17719 return list;
17722 /* OpenMP 4.0:
17723 thread_limit ( expression ) */
17725 static tree
17726 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
17728 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
17729 matching_parens parens;
17730 if (parens.require_open (parser))
17732 location_t expr_loc = c_parser_peek_token (parser)->location;
17733 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17734 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17735 tree c, t = expr.value;
17736 t = c_fully_fold (t, false, NULL);
17738 parens.skip_until_found_close (parser);
17740 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
17742 c_parser_error (parser, "expected integer expression");
17743 return list;
17746 /* Attempt to statically determine when the number isn't positive. */
17747 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
17748 build_int_cst (TREE_TYPE (t), 0));
17749 protected_set_expr_location (c, expr_loc);
17750 if (c == boolean_true_node)
17752 warning_at (expr_loc, OPT_Wopenmp,
17753 "%<thread_limit%> value must be positive");
17754 t = integer_one_node;
17757 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
17758 "thread_limit");
17760 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
17761 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
17762 OMP_CLAUSE_CHAIN (c) = list;
17763 list = c;
17766 return list;
17769 /* OpenMP 4.0:
17770 aligned ( variable-list )
17771 aligned ( variable-list : constant-expression ) */
17773 static tree
17774 c_parser_omp_clause_aligned (c_parser *parser, tree list)
17776 location_t clause_loc = c_parser_peek_token (parser)->location;
17777 tree nl, c;
17779 matching_parens parens;
17780 if (!parens.require_open (parser))
17781 return list;
17783 nl = c_parser_omp_variable_list (parser, clause_loc,
17784 OMP_CLAUSE_ALIGNED, list);
17786 if (c_parser_next_token_is (parser, CPP_COLON))
17788 c_parser_consume_token (parser);
17789 location_t expr_loc = c_parser_peek_token (parser)->location;
17790 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17791 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17792 tree alignment = expr.value;
17793 alignment = c_fully_fold (alignment, false, NULL);
17794 if (TREE_CODE (alignment) != INTEGER_CST
17795 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
17796 || tree_int_cst_sgn (alignment) != 1)
17798 error_at (clause_loc, "%<aligned%> clause alignment expression must "
17799 "be positive constant integer expression");
17800 alignment = NULL_TREE;
17803 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17804 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
17807 parens.skip_until_found_close (parser);
17808 return nl;
17811 /* OpenMP 5.0:
17812 allocate ( variable-list )
17813 allocate ( expression : variable-list )
17815 OpenMP 5.1:
17816 allocate ( allocator-modifier : variable-list )
17817 allocate ( allocator-modifier , allocator-modifier : variable-list )
17819 allocator-modifier:
17820 allocator ( expression )
17821 align ( expression ) */
17823 static tree
17824 c_parser_omp_clause_allocate (c_parser *parser, tree list)
17826 location_t clause_loc = c_parser_peek_token (parser)->location;
17827 tree nl, c;
17828 tree allocator = NULL_TREE;
17829 tree align = NULL_TREE;
17831 matching_parens parens;
17832 if (!parens.require_open (parser))
17833 return list;
17835 if ((c_parser_next_token_is_not (parser, CPP_NAME)
17836 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
17837 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
17838 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
17840 bool has_modifiers = false;
17841 tree orig_type = NULL_TREE;
17842 if (c_parser_next_token_is (parser, CPP_NAME)
17843 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
17845 unsigned int n = 3;
17846 const char *p
17847 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17848 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
17849 && c_parser_check_balanced_raw_token_sequence (parser, &n)
17850 && (c_parser_peek_nth_token_raw (parser, n)->type
17851 == CPP_CLOSE_PAREN))
17853 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
17854 == CPP_COLON)
17855 has_modifiers = true;
17856 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
17857 == CPP_COMMA
17858 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
17859 == CPP_NAME)
17860 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
17861 == CPP_OPEN_PAREN))
17863 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
17864 const char *q = IDENTIFIER_POINTER (tok->value);
17865 n += 4;
17866 if ((strcmp (q, "allocator") == 0
17867 || strcmp (q, "align") == 0)
17868 && c_parser_check_balanced_raw_token_sequence (parser,
17870 && (c_parser_peek_nth_token_raw (parser, n)->type
17871 == CPP_CLOSE_PAREN)
17872 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
17873 == CPP_COLON))
17874 has_modifiers = true;
17877 if (has_modifiers)
17879 c_parser_consume_token (parser);
17880 matching_parens parens2;;
17881 parens2.require_open (parser);
17882 location_t expr_loc = c_parser_peek_token (parser)->location;
17883 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17884 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17885 if (expr.value == error_mark_node)
17887 else if (strcmp (p, "allocator") == 0)
17889 allocator = expr.value;
17890 allocator = c_fully_fold (allocator, false, NULL);
17891 orig_type = expr.original_type
17892 ? expr.original_type : TREE_TYPE (allocator);
17893 orig_type = TYPE_MAIN_VARIANT (orig_type);
17895 else
17897 align = expr.value;
17898 align = c_fully_fold (align, false, NULL);
17900 parens2.skip_until_found_close (parser);
17901 if (c_parser_next_token_is (parser, CPP_COMMA))
17903 c_parser_consume_token (parser);
17904 c_token *tok = c_parser_peek_token (parser);
17905 const char *q = "";
17906 if (c_parser_next_token_is (parser, CPP_NAME))
17907 q = IDENTIFIER_POINTER (tok->value);
17908 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
17910 c_parser_error (parser, "expected %<allocator%> or "
17911 "%<align%>");
17912 parens.skip_until_found_close (parser);
17913 return list;
17915 else if (strcmp (p, q) == 0)
17917 error_at (tok->location, "duplicate %qs modifier", p);
17918 parens.skip_until_found_close (parser);
17919 return list;
17921 c_parser_consume_token (parser);
17922 if (!parens2.require_open (parser))
17924 parens.skip_until_found_close (parser);
17925 return list;
17927 expr_loc = c_parser_peek_token (parser)->location;
17928 expr = c_parser_expr_no_commas (parser, NULL);
17929 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
17930 true);
17931 if (strcmp (q, "allocator") == 0)
17933 allocator = expr.value;
17934 allocator = c_fully_fold (allocator, false, NULL);
17935 orig_type = expr.original_type
17936 ? expr.original_type : TREE_TYPE (allocator);
17937 orig_type = TYPE_MAIN_VARIANT (orig_type);
17939 else
17941 align = expr.value;
17942 align = c_fully_fold (align, false, NULL);
17944 parens2.skip_until_found_close (parser);
17948 if (!has_modifiers)
17950 location_t expr_loc = c_parser_peek_token (parser)->location;
17951 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17952 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17953 allocator = expr.value;
17954 allocator = c_fully_fold (allocator, false, NULL);
17955 orig_type = expr.original_type
17956 ? expr.original_type : TREE_TYPE (allocator);
17957 orig_type = TYPE_MAIN_VARIANT (orig_type);
17959 if (allocator
17960 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
17961 || TREE_CODE (orig_type) != ENUMERAL_TYPE
17962 || (TYPE_NAME (orig_type)
17963 != get_identifier ("omp_allocator_handle_t"))))
17965 error_at (clause_loc, "%<allocate%> clause allocator expression "
17966 "has type %qT rather than "
17967 "%<omp_allocator_handle_t%>",
17968 TREE_TYPE (allocator));
17969 allocator = NULL_TREE;
17971 if (align
17972 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
17973 || !tree_fits_uhwi_p (align)
17974 || !integer_pow2p (align)))
17976 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
17977 "argument needs to be positive constant "
17978 "power of two integer expression");
17979 align = NULL_TREE;
17981 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
17983 parens.skip_until_found_close (parser);
17984 return list;
17988 nl = c_parser_omp_variable_list (parser, clause_loc,
17989 OMP_CLAUSE_ALLOCATE, list);
17991 if (allocator || align)
17992 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17994 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
17995 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
17998 parens.skip_until_found_close (parser);
17999 return nl;
18002 /* OpenMP 4.0:
18003 linear ( variable-list )
18004 linear ( variable-list : expression )
18006 OpenMP 4.5:
18007 linear ( modifier ( variable-list ) )
18008 linear ( modifier ( variable-list ) : expression )
18010 modifier:
18013 OpenMP 5.2:
18014 linear ( variable-list : modifiers-list )
18016 modifiers:
18018 step ( expression ) */
18020 static tree
18021 c_parser_omp_clause_linear (c_parser *parser, tree list)
18023 location_t clause_loc = c_parser_peek_token (parser)->location;
18024 tree nl, c, step;
18025 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
18026 bool old_linear_modifier = false;
18028 matching_parens parens;
18029 if (!parens.require_open (parser))
18030 return list;
18032 if (c_parser_next_token_is (parser, CPP_NAME))
18034 c_token *tok = c_parser_peek_token (parser);
18035 const char *p = IDENTIFIER_POINTER (tok->value);
18036 if (strcmp ("val", p) == 0)
18037 kind = OMP_CLAUSE_LINEAR_VAL;
18038 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
18039 kind = OMP_CLAUSE_LINEAR_DEFAULT;
18040 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18042 old_linear_modifier = true;
18043 c_parser_consume_token (parser);
18044 c_parser_consume_token (parser);
18048 nl = c_parser_omp_variable_list (parser, clause_loc,
18049 OMP_CLAUSE_LINEAR, list);
18051 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18052 parens.skip_until_found_close (parser);
18054 if (c_parser_next_token_is (parser, CPP_COLON))
18056 c_parser_consume_token (parser);
18057 location_t expr_loc = c_parser_peek_token (parser)->location;
18058 bool has_modifiers = false;
18059 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
18060 && c_parser_next_token_is (parser, CPP_NAME))
18062 c_token *tok = c_parser_peek_token (parser);
18063 const char *p = IDENTIFIER_POINTER (tok->value);
18064 unsigned int pos = 0;
18065 if (strcmp ("val", p) == 0)
18066 pos = 2;
18067 else if (strcmp ("step", p) == 0
18068 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
18070 pos = 3;
18071 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
18072 && (c_parser_peek_nth_token_raw (parser, pos)->type
18073 == CPP_CLOSE_PAREN))
18074 ++pos;
18075 else
18076 pos = 0;
18078 if (pos)
18080 tok = c_parser_peek_nth_token_raw (parser, pos);
18081 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
18082 has_modifiers = true;
18085 if (has_modifiers)
18087 step = NULL_TREE;
18088 while (c_parser_next_token_is (parser, CPP_NAME))
18090 c_token *tok = c_parser_peek_token (parser);
18091 const char *p = IDENTIFIER_POINTER (tok->value);
18092 if (strcmp ("val", p) == 0)
18094 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18095 error_at (tok->location, "multiple linear modifiers");
18096 kind = OMP_CLAUSE_LINEAR_DEFAULT;
18097 c_parser_consume_token (parser);
18099 else if (strcmp ("step", p) == 0)
18101 c_parser_consume_token (parser);
18102 matching_parens parens2;
18103 if (parens2.require_open (parser))
18105 if (step)
18106 error_at (tok->location,
18107 "multiple %<step%> modifiers");
18108 expr_loc = c_parser_peek_token (parser)->location;
18109 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18110 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
18111 true);
18112 step = c_fully_fold (expr.value, false, NULL);
18113 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
18115 error_at (clause_loc, "%<linear%> clause step "
18116 "expression must be integral");
18117 step = integer_one_node;
18119 parens2.skip_until_found_close (parser);
18121 else
18122 break;
18124 else
18125 break;
18126 if (c_parser_next_token_is (parser, CPP_COMMA))
18128 c_parser_consume_token (parser);
18129 continue;
18131 break;
18133 if (!step)
18134 step = integer_one_node;
18136 else
18138 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18139 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18140 step = c_fully_fold (expr.value, false, NULL);
18141 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
18143 error_at (clause_loc, "%<linear%> clause step expression must "
18144 "be integral");
18145 step = integer_one_node;
18150 else
18151 step = integer_one_node;
18153 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18155 OMP_CLAUSE_LINEAR_STEP (c) = step;
18156 OMP_CLAUSE_LINEAR_KIND (c) = kind;
18157 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
18160 parens.skip_until_found_close (parser);
18161 return nl;
18164 /* OpenMP 5.0:
18165 nontemporal ( variable-list ) */
18167 static tree
18168 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
18170 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
18173 /* OpenMP 4.0:
18174 safelen ( constant-expression ) */
18176 static tree
18177 c_parser_omp_clause_safelen (c_parser *parser, tree list)
18179 location_t clause_loc = c_parser_peek_token (parser)->location;
18180 tree c, t;
18182 matching_parens parens;
18183 if (!parens.require_open (parser))
18184 return list;
18186 location_t expr_loc = c_parser_peek_token (parser)->location;
18187 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18188 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18189 t = expr.value;
18190 t = c_fully_fold (t, false, NULL);
18191 if (TREE_CODE (t) != INTEGER_CST
18192 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
18193 || tree_int_cst_sgn (t) != 1)
18195 error_at (clause_loc, "%<safelen%> clause expression must "
18196 "be positive constant integer expression");
18197 t = NULL_TREE;
18200 parens.skip_until_found_close (parser);
18201 if (t == NULL_TREE || t == error_mark_node)
18202 return list;
18204 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
18206 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
18207 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
18208 OMP_CLAUSE_CHAIN (c) = list;
18209 return c;
18212 /* OpenMP 4.0:
18213 simdlen ( constant-expression ) */
18215 static tree
18216 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
18218 location_t clause_loc = c_parser_peek_token (parser)->location;
18219 tree c, t;
18221 matching_parens parens;
18222 if (!parens.require_open (parser))
18223 return list;
18225 location_t expr_loc = c_parser_peek_token (parser)->location;
18226 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18227 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18228 t = expr.value;
18229 t = c_fully_fold (t, false, NULL);
18230 if (TREE_CODE (t) != INTEGER_CST
18231 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
18232 || tree_int_cst_sgn (t) != 1)
18234 error_at (clause_loc, "%<simdlen%> clause expression must "
18235 "be positive constant integer expression");
18236 t = NULL_TREE;
18239 parens.skip_until_found_close (parser);
18240 if (t == NULL_TREE || t == error_mark_node)
18241 return list;
18243 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
18245 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
18246 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
18247 OMP_CLAUSE_CHAIN (c) = list;
18248 return c;
18251 /* OpenMP 4.5:
18252 vec:
18253 identifier [+/- integer]
18254 vec , identifier [+/- integer]
18257 static tree
18258 c_parser_omp_clause_doacross_sink (c_parser *parser, location_t clause_loc,
18259 tree list, bool depend_p)
18261 tree vec = NULL;
18262 if (c_parser_next_token_is_not (parser, CPP_NAME)
18263 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
18265 c_parser_error (parser, "expected identifier");
18266 return list;
18269 if (!depend_p)
18271 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18272 if (strcmp (p, "omp_cur_iteration") == 0
18273 && c_parser_peek_2nd_token (parser)->type == CPP_MINUS
18274 && c_parser_peek_nth_token (parser, 3)->type == CPP_NUMBER
18275 && c_parser_peek_nth_token (parser, 4)->type == CPP_CLOSE_PAREN)
18277 tree val = c_parser_peek_nth_token (parser, 3)->value;
18278 if (integer_onep (val))
18280 c_parser_consume_token (parser);
18281 c_parser_consume_token (parser);
18282 c_parser_consume_token (parser);
18283 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18284 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
18285 OMP_CLAUSE_CHAIN (u) = list;
18286 return u;
18293 while (c_parser_next_token_is (parser, CPP_NAME)
18294 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
18296 tree t = lookup_name (c_parser_peek_token (parser)->value);
18297 tree addend = NULL;
18299 if (t == NULL_TREE)
18301 undeclared_variable (c_parser_peek_token (parser)->location,
18302 c_parser_peek_token (parser)->value);
18303 t = error_mark_node;
18306 c_parser_consume_token (parser);
18308 bool neg = false;
18309 if (c_parser_next_token_is (parser, CPP_MINUS))
18310 neg = true;
18311 else if (!c_parser_next_token_is (parser, CPP_PLUS))
18313 addend = integer_zero_node;
18314 neg = false;
18315 goto add_to_vector;
18317 c_parser_consume_token (parser);
18319 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
18321 c_parser_error (parser, "expected integer");
18322 return list;
18325 addend = c_parser_peek_token (parser)->value;
18326 if (TREE_CODE (addend) != INTEGER_CST)
18328 c_parser_error (parser, "expected integer");
18329 return list;
18331 c_parser_consume_token (parser);
18333 add_to_vector:
18334 if (t != error_mark_node)
18336 vec = tree_cons (addend, t, vec);
18337 if (neg)
18338 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
18341 if (c_parser_next_token_is_not (parser, CPP_COMMA)
18342 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
18343 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
18344 break;
18346 c_parser_consume_token (parser);
18349 if (vec == NULL_TREE)
18350 return list;
18352 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18353 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
18354 OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
18355 OMP_CLAUSE_DECL (u) = nreverse (vec);
18356 OMP_CLAUSE_CHAIN (u) = list;
18357 return u;
18360 /* OpenMP 5.0:
18361 iterators ( iterators-definition )
18363 iterators-definition:
18364 iterator-specifier
18365 iterator-specifier , iterators-definition
18367 iterator-specifier:
18368 identifier = range-specification
18369 iterator-type identifier = range-specification
18371 range-specification:
18372 begin : end
18373 begin : end : step */
18375 static tree
18376 c_parser_omp_iterators (c_parser *parser)
18378 tree ret = NULL_TREE, *last = &ret;
18379 c_parser_consume_token (parser);
18381 push_scope ();
18383 matching_parens parens;
18384 if (!parens.require_open (parser))
18385 return error_mark_node;
18389 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
18390 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
18392 struct c_type_name *type = c_parser_type_name (parser);
18393 if (type != NULL)
18394 iter_type = groktypename (type, &type_expr, NULL);
18396 if (iter_type == NULL_TREE)
18397 iter_type = integer_type_node;
18399 location_t loc = c_parser_peek_token (parser)->location;
18400 if (!c_parser_next_token_is (parser, CPP_NAME))
18402 c_parser_error (parser, "expected identifier");
18403 break;
18406 tree id = c_parser_peek_token (parser)->value;
18407 c_parser_consume_token (parser);
18409 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18410 break;
18412 location_t eloc = c_parser_peek_token (parser)->location;
18413 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18414 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18415 tree begin = expr.value;
18417 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18418 break;
18420 eloc = c_parser_peek_token (parser)->location;
18421 expr = c_parser_expr_no_commas (parser, NULL);
18422 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18423 tree end = expr.value;
18425 tree step = integer_one_node;
18426 if (c_parser_next_token_is (parser, CPP_COLON))
18428 c_parser_consume_token (parser);
18429 eloc = c_parser_peek_token (parser)->location;
18430 expr = c_parser_expr_no_commas (parser, NULL);
18431 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18432 step = expr.value;
18435 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
18436 DECL_ARTIFICIAL (iter_var) = 1;
18437 DECL_CONTEXT (iter_var) = current_function_decl;
18438 pushdecl (iter_var);
18440 *last = make_tree_vec (6);
18441 TREE_VEC_ELT (*last, 0) = iter_var;
18442 TREE_VEC_ELT (*last, 1) = begin;
18443 TREE_VEC_ELT (*last, 2) = end;
18444 TREE_VEC_ELT (*last, 3) = step;
18445 last = &TREE_CHAIN (*last);
18447 if (c_parser_next_token_is (parser, CPP_COMMA))
18449 c_parser_consume_token (parser);
18450 continue;
18452 break;
18454 while (1);
18456 parens.skip_until_found_close (parser);
18457 return ret ? ret : error_mark_node;
18460 /* OpenMP 5.0:
18461 affinity ( [aff-modifier :] variable-list )
18462 aff-modifier:
18463 iterator ( iterators-definition ) */
18465 static tree
18466 c_parser_omp_clause_affinity (c_parser *parser, tree list)
18468 location_t clause_loc = c_parser_peek_token (parser)->location;
18469 tree nl, iterators = NULL_TREE;
18471 matching_parens parens;
18472 if (!parens.require_open (parser))
18473 return list;
18475 if (c_parser_next_token_is (parser, CPP_NAME))
18477 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18478 bool parse_iter = ((strcmp ("iterator", p) == 0)
18479 && (c_parser_peek_2nd_token (parser)->type
18480 == CPP_OPEN_PAREN));
18481 if (parse_iter)
18483 unsigned n = 3;
18484 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
18485 && (c_parser_peek_nth_token_raw (parser, n)->type
18486 == CPP_CLOSE_PAREN)
18487 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
18488 == CPP_COLON));
18490 if (parse_iter)
18492 iterators = c_parser_omp_iterators (parser);
18493 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18495 if (iterators)
18496 pop_scope ();
18497 parens.skip_until_found_close (parser);
18498 return list;
18502 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
18503 list);
18504 if (iterators)
18506 tree block = pop_scope ();
18507 if (iterators != error_mark_node)
18509 TREE_VEC_ELT (iterators, 5) = block;
18510 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18511 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
18512 OMP_CLAUSE_DECL (c));
18516 parens.skip_until_found_close (parser);
18517 return nl;
18521 /* OpenMP 4.0:
18522 depend ( depend-kind: variable-list )
18524 depend-kind:
18525 in | out | inout
18527 OpenMP 4.5:
18528 depend ( source )
18530 depend ( sink : vec )
18532 OpenMP 5.0:
18533 depend ( depend-modifier , depend-kind: variable-list )
18535 depend-kind:
18536 in | out | inout | mutexinoutset | depobj | inoutset
18538 depend-modifier:
18539 iterator ( iterators-definition ) */
18541 static tree
18542 c_parser_omp_clause_depend (c_parser *parser, tree list)
18544 location_t clause_loc = c_parser_peek_token (parser)->location;
18545 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
18546 enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
18547 tree nl, c, iterators = NULL_TREE;
18549 matching_parens parens;
18550 if (!parens.require_open (parser))
18551 return list;
18555 if (c_parser_next_token_is_not (parser, CPP_NAME))
18556 goto invalid_kind;
18558 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18559 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
18561 iterators = c_parser_omp_iterators (parser);
18562 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
18563 continue;
18565 if (strcmp ("in", p) == 0)
18566 kind = OMP_CLAUSE_DEPEND_IN;
18567 else if (strcmp ("inout", p) == 0)
18568 kind = OMP_CLAUSE_DEPEND_INOUT;
18569 else if (strcmp ("inoutset", p) == 0)
18570 kind = OMP_CLAUSE_DEPEND_INOUTSET;
18571 else if (strcmp ("mutexinoutset", p) == 0)
18572 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
18573 else if (strcmp ("out", p) == 0)
18574 kind = OMP_CLAUSE_DEPEND_OUT;
18575 else if (strcmp ("depobj", p) == 0)
18576 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
18577 else if (strcmp ("sink", p) == 0)
18578 dkind = OMP_CLAUSE_DOACROSS_SINK;
18579 else if (strcmp ("source", p) == 0)
18580 dkind = OMP_CLAUSE_DOACROSS_SOURCE;
18581 else
18582 goto invalid_kind;
18583 break;
18585 while (1);
18587 c_parser_consume_token (parser);
18589 if (iterators
18590 && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
18591 || dkind == OMP_CLAUSE_DOACROSS_SINK))
18593 pop_scope ();
18594 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
18595 dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
18596 iterators = NULL_TREE;
18599 if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
18601 c = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18602 OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
18603 OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
18604 OMP_CLAUSE_DECL (c) = NULL_TREE;
18605 OMP_CLAUSE_CHAIN (c) = list;
18606 parens.skip_until_found_close (parser);
18607 return c;
18610 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18611 goto resync_fail;
18613 if (dkind == OMP_CLAUSE_DOACROSS_SINK)
18614 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, true);
18615 else
18617 nl = c_parser_omp_variable_list (parser, clause_loc,
18618 OMP_CLAUSE_DEPEND, list);
18620 if (iterators)
18622 tree block = pop_scope ();
18623 if (iterators == error_mark_node)
18624 iterators = NULL_TREE;
18625 else
18626 TREE_VEC_ELT (iterators, 5) = block;
18629 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18631 OMP_CLAUSE_DEPEND_KIND (c) = kind;
18632 if (iterators)
18633 OMP_CLAUSE_DECL (c)
18634 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
18638 parens.skip_until_found_close (parser);
18639 return nl;
18641 invalid_kind:
18642 c_parser_error (parser, "invalid depend kind");
18643 resync_fail:
18644 parens.skip_until_found_close (parser);
18645 if (iterators)
18646 pop_scope ();
18647 return list;
18650 /* OpenMP 5.2:
18651 doacross ( source : )
18652 doacross ( source : omp_cur_iteration )
18654 doacross ( sink : vec )
18655 doacross ( sink : omp_cur_iteration - logical_iteration ) */
18657 static tree
18658 c_parser_omp_clause_doacross (c_parser *parser, tree list)
18660 location_t clause_loc = c_parser_peek_token (parser)->location;
18661 enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
18662 tree nl;
18663 const char *p;
18665 matching_parens parens;
18666 if (!parens.require_open (parser))
18667 return list;
18669 if (c_parser_next_token_is_not (parser, CPP_NAME))
18670 goto invalid_kind;
18672 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18673 if (strcmp ("sink", p) == 0)
18674 kind = OMP_CLAUSE_DOACROSS_SINK;
18675 else if (strcmp ("source", p) == 0)
18676 kind = OMP_CLAUSE_DOACROSS_SOURCE;
18677 else
18678 goto invalid_kind;
18680 c_parser_consume_token (parser);
18682 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18683 goto resync_fail;
18685 if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
18687 if (c_parser_next_token_is (parser, CPP_NAME)
18688 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
18689 "omp_cur_iteration") == 0)
18690 c_parser_consume_token (parser);
18691 nl = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18692 OMP_CLAUSE_DOACROSS_KIND (nl) = OMP_CLAUSE_DOACROSS_SOURCE;
18693 OMP_CLAUSE_DECL (nl) = NULL_TREE;
18694 OMP_CLAUSE_CHAIN (nl) = list;
18696 else
18697 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, false);
18699 parens.skip_until_found_close (parser);
18700 return nl;
18702 invalid_kind:
18703 c_parser_error (parser, "invalid doacross kind");
18704 resync_fail:
18705 parens.skip_until_found_close (parser);
18706 return list;
18709 /* OpenMP 4.0:
18710 map ( map-kind: variable-list )
18711 map ( variable-list )
18713 map-kind:
18714 alloc | to | from | tofrom
18716 OpenMP 4.5:
18717 map-kind:
18718 alloc | to | from | tofrom | release | delete
18720 map ( always [,] map-kind: variable-list )
18722 OpenMP 5.0:
18723 map ( [map-type-modifier[,] ...] map-kind: variable-list )
18725 map-type-modifier:
18726 always | close */
18728 static tree
18729 c_parser_omp_clause_map (c_parser *parser, tree list)
18731 location_t clause_loc = c_parser_peek_token (parser)->location;
18732 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
18733 tree nl, c;
18735 matching_parens parens;
18736 if (!parens.require_open (parser))
18737 return list;
18739 int pos = 1;
18740 int map_kind_pos = 0;
18741 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
18743 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
18745 map_kind_pos = pos;
18746 break;
18749 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
18750 pos++;
18751 pos++;
18754 int always_modifier = 0;
18755 int close_modifier = 0;
18756 int present_modifier = 0;
18757 for (int pos = 1; pos < map_kind_pos; ++pos)
18759 c_token *tok = c_parser_peek_token (parser);
18761 if (tok->type == CPP_COMMA)
18763 c_parser_consume_token (parser);
18764 continue;
18767 const char *p = IDENTIFIER_POINTER (tok->value);
18768 if (strcmp ("always", p) == 0)
18770 if (always_modifier)
18772 c_parser_error (parser, "too many %<always%> modifiers");
18773 parens.skip_until_found_close (parser);
18774 return list;
18776 always_modifier++;
18778 else if (strcmp ("close", p) == 0)
18780 if (close_modifier)
18782 c_parser_error (parser, "too many %<close%> modifiers");
18783 parens.skip_until_found_close (parser);
18784 return list;
18786 close_modifier++;
18788 else if (strcmp ("present", p) == 0)
18790 if (present_modifier)
18792 c_parser_error (parser, "too many %<present%> modifiers");
18793 parens.skip_until_found_close (parser);
18794 return list;
18796 present_modifier++;
18798 else
18800 c_parser_error (parser, "%<map%> clause with map-type modifier other "
18801 "than %<always%>, %<close%> or %<present%>");
18802 parens.skip_until_found_close (parser);
18803 return list;
18806 c_parser_consume_token (parser);
18809 if (c_parser_next_token_is (parser, CPP_NAME)
18810 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
18812 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18813 int always_present_modifier = always_modifier && present_modifier;
18815 if (strcmp ("alloc", p) == 0)
18816 kind = present_modifier ? GOMP_MAP_PRESENT_ALLOC : GOMP_MAP_ALLOC;
18817 else if (strcmp ("to", p) == 0)
18818 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TO
18819 : present_modifier ? GOMP_MAP_PRESENT_TO
18820 : always_modifier ? GOMP_MAP_ALWAYS_TO
18821 : GOMP_MAP_TO);
18822 else if (strcmp ("from", p) == 0)
18823 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_FROM
18824 : present_modifier ? GOMP_MAP_PRESENT_FROM
18825 : always_modifier ? GOMP_MAP_ALWAYS_FROM
18826 : GOMP_MAP_FROM);
18827 else if (strcmp ("tofrom", p) == 0)
18828 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TOFROM
18829 : present_modifier ? GOMP_MAP_PRESENT_TOFROM
18830 : always_modifier ? GOMP_MAP_ALWAYS_TOFROM
18831 : GOMP_MAP_TOFROM);
18832 else if (strcmp ("release", p) == 0)
18833 kind = GOMP_MAP_RELEASE;
18834 else if (strcmp ("delete", p) == 0)
18835 kind = GOMP_MAP_DELETE;
18836 else
18838 c_parser_error (parser, "invalid map kind");
18839 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18840 "expected %<)%>");
18841 return list;
18843 c_parser_consume_token (parser);
18844 c_parser_consume_token (parser);
18847 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
18848 true);
18850 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18851 OMP_CLAUSE_SET_MAP_KIND (c, kind);
18853 parens.skip_until_found_close (parser);
18854 return nl;
18857 /* OpenMP 4.0:
18858 device ( expression )
18860 OpenMP 5.0:
18861 device ( [device-modifier :] integer-expression )
18863 device-modifier:
18864 ancestor | device_num */
18866 static tree
18867 c_parser_omp_clause_device (c_parser *parser, tree list)
18869 location_t clause_loc = c_parser_peek_token (parser)->location;
18870 location_t expr_loc;
18871 c_expr expr;
18872 tree c, t;
18873 bool ancestor = false;
18875 matching_parens parens;
18876 if (!parens.require_open (parser))
18877 return list;
18879 if (c_parser_next_token_is (parser, CPP_NAME)
18880 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
18882 c_token *tok = c_parser_peek_token (parser);
18883 const char *p = IDENTIFIER_POINTER (tok->value);
18884 if (strcmp ("ancestor", p) == 0)
18886 /* A requires directive with the reverse_offload clause must be
18887 specified. */
18888 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
18890 error_at (tok->location, "%<ancestor%> device modifier not "
18891 "preceded by %<requires%> directive "
18892 "with %<reverse_offload%> clause");
18893 parens.skip_until_found_close (parser);
18894 return list;
18896 ancestor = true;
18898 else if (strcmp ("device_num", p) == 0)
18900 else
18902 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
18903 parens.skip_until_found_close (parser);
18904 return list;
18906 c_parser_consume_token (parser);
18907 c_parser_consume_token (parser);
18910 expr_loc = c_parser_peek_token (parser)->location;
18911 expr = c_parser_expr_no_commas (parser, NULL);
18912 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18913 t = expr.value;
18914 t = c_fully_fold (t, false, NULL);
18916 parens.skip_until_found_close (parser);
18918 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
18920 c_parser_error (parser, "expected integer expression");
18921 return list;
18923 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
18925 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
18926 "%<1%>");
18927 return list;
18930 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
18932 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
18934 OMP_CLAUSE_DEVICE_ID (c) = t;
18935 OMP_CLAUSE_CHAIN (c) = list;
18936 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
18938 list = c;
18939 return list;
18942 /* OpenMP 4.0:
18943 dist_schedule ( static )
18944 dist_schedule ( static , expression ) */
18946 static tree
18947 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
18949 tree c, t = NULL_TREE;
18950 location_t loc = c_parser_peek_token (parser)->location;
18952 matching_parens parens;
18953 if (!parens.require_open (parser))
18954 return list;
18956 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
18958 c_parser_error (parser, "invalid dist_schedule kind");
18959 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18960 "expected %<)%>");
18961 return list;
18964 c_parser_consume_token (parser);
18965 if (c_parser_next_token_is (parser, CPP_COMMA))
18967 c_parser_consume_token (parser);
18969 location_t expr_loc = c_parser_peek_token (parser)->location;
18970 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18971 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18972 t = expr.value;
18973 t = c_fully_fold (t, false, NULL);
18974 parens.skip_until_found_close (parser);
18976 else
18977 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18978 "expected %<,%> or %<)%>");
18980 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
18981 "dist_schedule"); */
18982 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
18983 warning_at (loc, OPT_Wopenmp, "too many %qs clauses", "dist_schedule");
18984 if (t == error_mark_node)
18985 return list;
18987 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
18988 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
18989 OMP_CLAUSE_CHAIN (c) = list;
18990 return c;
18993 /* OpenMP 4.0:
18994 proc_bind ( proc-bind-kind )
18996 proc-bind-kind:
18997 primary | master | close | spread
18998 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
19000 static tree
19001 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
19003 location_t clause_loc = c_parser_peek_token (parser)->location;
19004 enum omp_clause_proc_bind_kind kind;
19005 tree c;
19007 matching_parens parens;
19008 if (!parens.require_open (parser))
19009 return list;
19011 if (c_parser_next_token_is (parser, CPP_NAME))
19013 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19014 if (strcmp ("primary", p) == 0)
19015 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
19016 else if (strcmp ("master", p) == 0)
19017 kind = OMP_CLAUSE_PROC_BIND_MASTER;
19018 else if (strcmp ("close", p) == 0)
19019 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
19020 else if (strcmp ("spread", p) == 0)
19021 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
19022 else
19023 goto invalid_kind;
19025 else
19026 goto invalid_kind;
19028 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
19029 c_parser_consume_token (parser);
19030 parens.skip_until_found_close (parser);
19031 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
19032 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
19033 OMP_CLAUSE_CHAIN (c) = list;
19034 return c;
19036 invalid_kind:
19037 c_parser_error (parser, "invalid proc_bind kind");
19038 parens.skip_until_found_close (parser);
19039 return list;
19042 /* OpenMP 5.0:
19043 device_type ( host | nohost | any ) */
19045 static tree
19046 c_parser_omp_clause_device_type (c_parser *parser, tree list)
19048 location_t clause_loc = c_parser_peek_token (parser)->location;
19049 enum omp_clause_device_type_kind kind;
19050 tree c;
19052 matching_parens parens;
19053 if (!parens.require_open (parser))
19054 return list;
19056 if (c_parser_next_token_is (parser, CPP_NAME))
19058 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19059 if (strcmp ("host", p) == 0)
19060 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
19061 else if (strcmp ("nohost", p) == 0)
19062 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
19063 else if (strcmp ("any", p) == 0)
19064 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
19065 else
19066 goto invalid_kind;
19068 else
19069 goto invalid_kind;
19071 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
19072 "device_type");
19073 c_parser_consume_token (parser);
19074 parens.skip_until_found_close (parser);
19075 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
19076 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
19077 OMP_CLAUSE_CHAIN (c) = list;
19078 return c;
19080 invalid_kind:
19081 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
19082 parens.skip_until_found_close (parser);
19083 return list;
19086 /* OpenMP 4.0:
19087 from ( variable-list )
19088 to ( variable-list )
19090 OpenMP 5.1:
19091 from ( [present :] variable-list )
19092 to ( [present :] variable-list ) */
19094 static tree
19095 c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
19096 tree list)
19098 location_t loc = c_parser_peek_token (parser)->location;
19099 matching_parens parens;
19100 if (!parens.require_open (parser))
19101 return list;
19103 bool present = false;
19104 c_token *token = c_parser_peek_token (parser);
19106 if (token->type == CPP_NAME
19107 && strcmp (IDENTIFIER_POINTER (token->value), "present") == 0
19108 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
19110 present = true;
19111 c_parser_consume_token (parser);
19112 c_parser_consume_token (parser);
19115 tree nl = c_parser_omp_variable_list (parser, loc, kind, list);
19116 parens.skip_until_found_close (parser);
19118 if (present)
19119 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
19120 OMP_CLAUSE_MOTION_PRESENT (c) = 1;
19122 return nl;
19125 /* OpenMP 4.0:
19126 uniform ( variable-list ) */
19128 static tree
19129 c_parser_omp_clause_uniform (c_parser *parser, tree list)
19131 /* The clauses location. */
19132 location_t loc = c_parser_peek_token (parser)->location;
19134 matching_parens parens;
19135 if (parens.require_open (parser))
19137 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
19138 list);
19139 parens.skip_until_found_close (parser);
19141 return list;
19144 /* OpenMP 5.0:
19145 detach ( event-handle ) */
19147 static tree
19148 c_parser_omp_clause_detach (c_parser *parser, tree list)
19150 matching_parens parens;
19151 location_t clause_loc = c_parser_peek_token (parser)->location;
19153 if (!parens.require_open (parser))
19154 return list;
19156 if (c_parser_next_token_is_not (parser, CPP_NAME)
19157 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
19159 c_parser_error (parser, "expected identifier");
19160 parens.skip_until_found_close (parser);
19161 return list;
19164 tree t = lookup_name (c_parser_peek_token (parser)->value);
19165 if (t == NULL_TREE)
19167 undeclared_variable (c_parser_peek_token (parser)->location,
19168 c_parser_peek_token (parser)->value);
19169 parens.skip_until_found_close (parser);
19170 return list;
19172 c_parser_consume_token (parser);
19174 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
19175 if (!INTEGRAL_TYPE_P (type)
19176 || TREE_CODE (type) != ENUMERAL_TYPE
19177 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
19179 error_at (clause_loc, "%<detach%> clause event handle "
19180 "has type %qT rather than "
19181 "%<omp_event_handle_t%>",
19182 type);
19183 parens.skip_until_found_close (parser);
19184 return list;
19187 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
19188 OMP_CLAUSE_DECL (u) = t;
19189 OMP_CLAUSE_CHAIN (u) = list;
19190 parens.skip_until_found_close (parser);
19191 return u;
19194 /* Parse all OpenACC clauses. The set clauses allowed by the directive
19195 is a bitmask in MASK. Return the list of clauses found. */
19197 static tree
19198 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
19199 const char *where, bool finish_p = true,
19200 bool target_p = false)
19202 tree clauses = NULL;
19203 bool first = true;
19205 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19207 location_t here;
19208 pragma_omp_clause c_kind;
19209 const char *c_name;
19210 tree prev = clauses;
19212 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
19213 c_parser_consume_token (parser);
19215 here = c_parser_peek_token (parser)->location;
19216 c_kind = c_parser_omp_clause_name (parser);
19218 switch (c_kind)
19220 case PRAGMA_OACC_CLAUSE_ASYNC:
19221 clauses = c_parser_oacc_clause_async (parser, clauses);
19222 c_name = "async";
19223 break;
19224 case PRAGMA_OACC_CLAUSE_AUTO:
19225 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
19226 clauses);
19227 c_name = "auto";
19228 break;
19229 case PRAGMA_OACC_CLAUSE_ATTACH:
19230 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19231 c_name = "attach";
19232 break;
19233 case PRAGMA_OACC_CLAUSE_COLLAPSE:
19234 clauses = c_parser_omp_clause_collapse (parser, clauses);
19235 c_name = "collapse";
19236 break;
19237 case PRAGMA_OACC_CLAUSE_COPY:
19238 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19239 c_name = "copy";
19240 break;
19241 case PRAGMA_OACC_CLAUSE_COPYIN:
19242 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19243 c_name = "copyin";
19244 break;
19245 case PRAGMA_OACC_CLAUSE_COPYOUT:
19246 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19247 c_name = "copyout";
19248 break;
19249 case PRAGMA_OACC_CLAUSE_CREATE:
19250 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19251 c_name = "create";
19252 break;
19253 case PRAGMA_OACC_CLAUSE_DELETE:
19254 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19255 c_name = "delete";
19256 break;
19257 case PRAGMA_OMP_CLAUSE_DEFAULT:
19258 clauses = c_parser_omp_clause_default (parser, clauses, true);
19259 c_name = "default";
19260 break;
19261 case PRAGMA_OACC_CLAUSE_DETACH:
19262 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19263 c_name = "detach";
19264 break;
19265 case PRAGMA_OACC_CLAUSE_DEVICE:
19266 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19267 c_name = "device";
19268 break;
19269 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
19270 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
19271 c_name = "deviceptr";
19272 break;
19273 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
19274 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19275 c_name = "device_resident";
19276 break;
19277 case PRAGMA_OACC_CLAUSE_FINALIZE:
19278 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
19279 clauses);
19280 c_name = "finalize";
19281 break;
19282 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
19283 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
19284 c_name = "firstprivate";
19285 break;
19286 case PRAGMA_OACC_CLAUSE_GANG:
19287 c_name = "gang";
19288 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
19289 c_name, clauses);
19290 break;
19291 case PRAGMA_OACC_CLAUSE_HOST:
19292 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19293 c_name = "host";
19294 break;
19295 case PRAGMA_OACC_CLAUSE_IF:
19296 clauses = c_parser_omp_clause_if (parser, clauses, false);
19297 c_name = "if";
19298 break;
19299 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
19300 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
19301 clauses);
19302 c_name = "if_present";
19303 break;
19304 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
19305 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
19306 clauses);
19307 c_name = "independent";
19308 break;
19309 case PRAGMA_OACC_CLAUSE_LINK:
19310 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19311 c_name = "link";
19312 break;
19313 case PRAGMA_OACC_CLAUSE_NO_CREATE:
19314 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19315 c_name = "no_create";
19316 break;
19317 case PRAGMA_OACC_CLAUSE_NOHOST:
19318 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
19319 clauses);
19320 c_name = "nohost";
19321 break;
19322 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
19323 clauses = c_parser_oacc_single_int_clause (parser,
19324 OMP_CLAUSE_NUM_GANGS,
19325 clauses);
19326 c_name = "num_gangs";
19327 break;
19328 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
19329 clauses = c_parser_oacc_single_int_clause (parser,
19330 OMP_CLAUSE_NUM_WORKERS,
19331 clauses);
19332 c_name = "num_workers";
19333 break;
19334 case PRAGMA_OACC_CLAUSE_PRESENT:
19335 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19336 c_name = "present";
19337 break;
19338 case PRAGMA_OACC_CLAUSE_PRIVATE:
19339 clauses = c_parser_omp_clause_private (parser, clauses);
19340 c_name = "private";
19341 break;
19342 case PRAGMA_OACC_CLAUSE_REDUCTION:
19343 clauses
19344 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
19345 false, clauses);
19346 c_name = "reduction";
19347 break;
19348 case PRAGMA_OACC_CLAUSE_SELF:
19349 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)) == 0)
19350 /* OpenACC compute construct */
19351 clauses = c_parser_oacc_compute_clause_self (parser, clauses);
19352 else
19353 /* OpenACC 'update' directive */
19354 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19355 c_name = "self";
19356 break;
19357 case PRAGMA_OACC_CLAUSE_SEQ:
19358 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
19359 clauses);
19360 c_name = "seq";
19361 break;
19362 case PRAGMA_OACC_CLAUSE_TILE:
19363 clauses = c_parser_oacc_clause_tile (parser, clauses);
19364 c_name = "tile";
19365 break;
19366 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
19367 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
19368 c_name = "use_device";
19369 break;
19370 case PRAGMA_OACC_CLAUSE_VECTOR:
19371 c_name = "vector";
19372 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
19373 c_name, clauses);
19374 break;
19375 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
19376 clauses = c_parser_oacc_single_int_clause (parser,
19377 OMP_CLAUSE_VECTOR_LENGTH,
19378 clauses);
19379 c_name = "vector_length";
19380 break;
19381 case PRAGMA_OACC_CLAUSE_WAIT:
19382 clauses = c_parser_oacc_clause_wait (parser, clauses);
19383 c_name = "wait";
19384 break;
19385 case PRAGMA_OACC_CLAUSE_WORKER:
19386 c_name = "worker";
19387 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
19388 c_name, clauses);
19389 break;
19390 default:
19391 c_parser_error (parser, "expected an OpenACC clause");
19392 goto saw_error;
19395 first = false;
19397 if (((mask >> c_kind) & 1) == 0)
19399 /* Remove the invalid clause(s) from the list to avoid
19400 confusing the rest of the compiler. */
19401 clauses = prev;
19402 error_at (here, "%qs is not valid for %qs", c_name, where);
19406 saw_error:
19407 c_parser_skip_to_pragma_eol (parser);
19409 if (finish_p)
19410 return c_finish_omp_clauses (clauses, target_p ? C_ORT_ACC_TARGET
19411 : C_ORT_ACC);
19413 return clauses;
19416 /* Parse all OpenMP clauses. The set clauses allowed by the directive
19417 is a bitmask in MASK. Return the list of clauses found.
19418 FINISH_P set if c_finish_omp_clauses should be called.
19419 NESTED non-zero if clauses should be terminated by closing paren instead
19420 of end of pragma. If it is 2, additionally commas are required in between
19421 the clauses. */
19423 static tree
19424 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
19425 const char *where, bool finish_p = true,
19426 int nested = 0)
19428 tree clauses = NULL;
19429 bool first = true;
19431 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19433 location_t here;
19434 pragma_omp_clause c_kind;
19435 const char *c_name;
19436 tree prev = clauses;
19438 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
19439 break;
19441 if (!first || nested != 2)
19443 if (c_parser_next_token_is (parser, CPP_COMMA))
19444 c_parser_consume_token (parser);
19445 else if (nested == 2)
19446 error_at (c_parser_peek_token (parser)->location,
19447 "clauses in %<simd%> trait should be separated "
19448 "by %<,%>");
19451 here = c_parser_peek_token (parser)->location;
19452 c_kind = c_parser_omp_clause_name (parser);
19454 switch (c_kind)
19456 case PRAGMA_OMP_CLAUSE_BIND:
19457 clauses = c_parser_omp_clause_bind (parser, clauses);
19458 c_name = "bind";
19459 break;
19460 case PRAGMA_OMP_CLAUSE_COLLAPSE:
19461 clauses = c_parser_omp_clause_collapse (parser, clauses);
19462 c_name = "collapse";
19463 break;
19464 case PRAGMA_OMP_CLAUSE_COPYIN:
19465 clauses = c_parser_omp_clause_copyin (parser, clauses);
19466 c_name = "copyin";
19467 break;
19468 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
19469 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
19470 c_name = "copyprivate";
19471 break;
19472 case PRAGMA_OMP_CLAUSE_DEFAULT:
19473 clauses = c_parser_omp_clause_default (parser, clauses, false);
19474 c_name = "default";
19475 break;
19476 case PRAGMA_OMP_CLAUSE_DETACH:
19477 clauses = c_parser_omp_clause_detach (parser, clauses);
19478 c_name = "detach";
19479 break;
19480 case PRAGMA_OMP_CLAUSE_FILTER:
19481 clauses = c_parser_omp_clause_filter (parser, clauses);
19482 c_name = "filter";
19483 break;
19484 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
19485 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
19486 c_name = "firstprivate";
19487 break;
19488 case PRAGMA_OMP_CLAUSE_FINAL:
19489 clauses = c_parser_omp_clause_final (parser, clauses);
19490 c_name = "final";
19491 break;
19492 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
19493 clauses = c_parser_omp_clause_grainsize (parser, clauses);
19494 c_name = "grainsize";
19495 break;
19496 case PRAGMA_OMP_CLAUSE_HINT:
19497 clauses = c_parser_omp_clause_hint (parser, clauses);
19498 c_name = "hint";
19499 break;
19500 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
19501 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
19502 c_name = "defaultmap";
19503 break;
19504 case PRAGMA_OMP_CLAUSE_IF:
19505 clauses = c_parser_omp_clause_if (parser, clauses, true);
19506 c_name = "if";
19507 break;
19508 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
19509 clauses
19510 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
19511 true, clauses);
19512 c_name = "in_reduction";
19513 break;
19514 case PRAGMA_OMP_CLAUSE_INDIRECT:
19515 clauses = c_parser_omp_clause_indirect (parser, clauses);
19516 c_name = "indirect";
19517 break;
19518 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
19519 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
19520 c_name = "lastprivate";
19521 break;
19522 case PRAGMA_OMP_CLAUSE_MERGEABLE:
19523 clauses = c_parser_omp_clause_mergeable (parser, clauses);
19524 c_name = "mergeable";
19525 break;
19526 case PRAGMA_OMP_CLAUSE_NOWAIT:
19527 clauses = c_parser_omp_clause_nowait (parser, clauses);
19528 c_name = "nowait";
19529 break;
19530 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
19531 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
19532 c_name = "num_tasks";
19533 break;
19534 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
19535 clauses = c_parser_omp_clause_num_threads (parser, clauses);
19536 c_name = "num_threads";
19537 break;
19538 case PRAGMA_OMP_CLAUSE_ORDER:
19539 clauses = c_parser_omp_clause_order (parser, clauses);
19540 c_name = "order";
19541 break;
19542 case PRAGMA_OMP_CLAUSE_ORDERED:
19543 clauses = c_parser_omp_clause_ordered (parser, clauses);
19544 c_name = "ordered";
19545 break;
19546 case PRAGMA_OMP_CLAUSE_PRIORITY:
19547 clauses = c_parser_omp_clause_priority (parser, clauses);
19548 c_name = "priority";
19549 break;
19550 case PRAGMA_OMP_CLAUSE_PRIVATE:
19551 clauses = c_parser_omp_clause_private (parser, clauses);
19552 c_name = "private";
19553 break;
19554 case PRAGMA_OMP_CLAUSE_REDUCTION:
19555 clauses
19556 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
19557 true, clauses);
19558 c_name = "reduction";
19559 break;
19560 case PRAGMA_OMP_CLAUSE_SCHEDULE:
19561 clauses = c_parser_omp_clause_schedule (parser, clauses);
19562 c_name = "schedule";
19563 break;
19564 case PRAGMA_OMP_CLAUSE_SHARED:
19565 clauses = c_parser_omp_clause_shared (parser, clauses);
19566 c_name = "shared";
19567 break;
19568 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
19569 clauses
19570 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
19571 true, clauses);
19572 c_name = "task_reduction";
19573 break;
19574 case PRAGMA_OMP_CLAUSE_UNTIED:
19575 clauses = c_parser_omp_clause_untied (parser, clauses);
19576 c_name = "untied";
19577 break;
19578 case PRAGMA_OMP_CLAUSE_INBRANCH:
19579 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
19580 clauses);
19581 c_name = "inbranch";
19582 break;
19583 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
19584 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
19585 c_name = "nontemporal";
19586 break;
19587 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
19588 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
19589 clauses);
19590 c_name = "notinbranch";
19591 break;
19592 case PRAGMA_OMP_CLAUSE_PARALLEL:
19593 clauses
19594 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
19595 clauses);
19596 c_name = "parallel";
19597 if (!first)
19599 clause_not_first:
19600 error_at (here, "%qs must be the first clause of %qs",
19601 c_name, where);
19602 clauses = prev;
19604 break;
19605 case PRAGMA_OMP_CLAUSE_FOR:
19606 clauses
19607 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
19608 clauses);
19609 c_name = "for";
19610 if (!first)
19611 goto clause_not_first;
19612 break;
19613 case PRAGMA_OMP_CLAUSE_SECTIONS:
19614 clauses
19615 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
19616 clauses);
19617 c_name = "sections";
19618 if (!first)
19619 goto clause_not_first;
19620 break;
19621 case PRAGMA_OMP_CLAUSE_TASKGROUP:
19622 clauses
19623 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
19624 clauses);
19625 c_name = "taskgroup";
19626 if (!first)
19627 goto clause_not_first;
19628 break;
19629 case PRAGMA_OMP_CLAUSE_LINK:
19630 clauses
19631 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
19632 c_name = "link";
19633 break;
19634 case PRAGMA_OMP_CLAUSE_TO:
19635 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
19637 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
19638 clauses);
19639 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
19640 OMP_CLAUSE_ENTER_TO (c) = 1;
19641 clauses = nl;
19643 else
19644 clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_TO,
19645 clauses);
19646 c_name = "to";
19647 break;
19648 case PRAGMA_OMP_CLAUSE_FROM:
19649 clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_FROM,
19650 clauses);
19651 c_name = "from";
19652 break;
19653 case PRAGMA_OMP_CLAUSE_UNIFORM:
19654 clauses = c_parser_omp_clause_uniform (parser, clauses);
19655 c_name = "uniform";
19656 break;
19657 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
19658 clauses = c_parser_omp_clause_num_teams (parser, clauses);
19659 c_name = "num_teams";
19660 break;
19661 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
19662 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
19663 c_name = "thread_limit";
19664 break;
19665 case PRAGMA_OMP_CLAUSE_ALIGNED:
19666 clauses = c_parser_omp_clause_aligned (parser, clauses);
19667 c_name = "aligned";
19668 break;
19669 case PRAGMA_OMP_CLAUSE_ALLOCATE:
19670 clauses = c_parser_omp_clause_allocate (parser, clauses);
19671 c_name = "allocate";
19672 break;
19673 case PRAGMA_OMP_CLAUSE_LINEAR:
19674 clauses = c_parser_omp_clause_linear (parser, clauses);
19675 c_name = "linear";
19676 break;
19677 case PRAGMA_OMP_CLAUSE_AFFINITY:
19678 clauses = c_parser_omp_clause_affinity (parser, clauses);
19679 c_name = "affinity";
19680 break;
19681 case PRAGMA_OMP_CLAUSE_DEPEND:
19682 clauses = c_parser_omp_clause_depend (parser, clauses);
19683 c_name = "depend";
19684 break;
19685 case PRAGMA_OMP_CLAUSE_DOACROSS:
19686 clauses = c_parser_omp_clause_doacross (parser, clauses);
19687 c_name = "doacross";
19688 break;
19689 case PRAGMA_OMP_CLAUSE_MAP:
19690 clauses = c_parser_omp_clause_map (parser, clauses);
19691 c_name = "map";
19692 break;
19693 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
19694 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
19695 c_name = "use_device_ptr";
19696 break;
19697 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
19698 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
19699 c_name = "use_device_addr";
19700 break;
19701 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
19702 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
19703 c_name = "has_device_addr";
19704 break;
19705 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
19706 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
19707 c_name = "is_device_ptr";
19708 break;
19709 case PRAGMA_OMP_CLAUSE_DEVICE:
19710 clauses = c_parser_omp_clause_device (parser, clauses);
19711 c_name = "device";
19712 break;
19713 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
19714 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
19715 c_name = "dist_schedule";
19716 break;
19717 case PRAGMA_OMP_CLAUSE_PROC_BIND:
19718 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
19719 c_name = "proc_bind";
19720 break;
19721 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
19722 clauses = c_parser_omp_clause_device_type (parser, clauses);
19723 c_name = "device_type";
19724 break;
19725 case PRAGMA_OMP_CLAUSE_SAFELEN:
19726 clauses = c_parser_omp_clause_safelen (parser, clauses);
19727 c_name = "safelen";
19728 break;
19729 case PRAGMA_OMP_CLAUSE_SIMDLEN:
19730 clauses = c_parser_omp_clause_simdlen (parser, clauses);
19731 c_name = "simdlen";
19732 break;
19733 case PRAGMA_OMP_CLAUSE_NOGROUP:
19734 clauses = c_parser_omp_clause_nogroup (parser, clauses);
19735 c_name = "nogroup";
19736 break;
19737 case PRAGMA_OMP_CLAUSE_THREADS:
19738 clauses
19739 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
19740 clauses);
19741 c_name = "threads";
19742 break;
19743 case PRAGMA_OMP_CLAUSE_SIMD:
19744 clauses
19745 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
19746 clauses);
19747 c_name = "simd";
19748 break;
19749 case PRAGMA_OMP_CLAUSE_ENTER:
19750 clauses
19751 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
19752 clauses);
19753 c_name = "enter";
19754 break;
19755 default:
19756 c_parser_error (parser, "expected an OpenMP clause");
19757 goto saw_error;
19760 first = false;
19762 if (((mask >> c_kind) & 1) == 0)
19764 /* Remove the invalid clause(s) from the list to avoid
19765 confusing the rest of the compiler. */
19766 clauses = prev;
19767 error_at (here, "%qs is not valid for %qs", c_name, where);
19771 saw_error:
19772 if (!nested)
19773 c_parser_skip_to_pragma_eol (parser);
19775 if (finish_p)
19777 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
19778 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
19779 return c_finish_omp_clauses (clauses, C_ORT_OMP);
19782 return clauses;
19785 /* OpenACC 2.0, OpenMP 2.5:
19786 structured-block:
19787 statement
19789 In practice, we're also interested in adding the statement to an
19790 outer node. So it is convenient if we work around the fact that
19791 c_parser_statement calls add_stmt. */
19793 static tree
19794 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
19796 tree stmt = push_stmt_list ();
19797 parser->omp_attrs_forbidden_p = true;
19798 c_parser_statement (parser, if_p);
19799 return pop_stmt_list (stmt);
19802 /* OpenACC 2.0:
19803 # pragma acc cache (variable-list) new-line
19805 LOC is the location of the #pragma token.
19808 static tree
19809 c_parser_oacc_cache (location_t loc, c_parser *parser)
19811 tree stmt, clauses;
19813 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
19814 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
19816 c_parser_skip_to_pragma_eol (parser);
19818 stmt = make_node (OACC_CACHE);
19819 TREE_TYPE (stmt) = void_type_node;
19820 OACC_CACHE_CLAUSES (stmt) = clauses;
19821 SET_EXPR_LOCATION (stmt, loc);
19822 add_stmt (stmt);
19824 return stmt;
19827 /* OpenACC 2.0:
19828 # pragma acc data oacc-data-clause[optseq] new-line
19829 structured-block
19831 LOC is the location of the #pragma token.
19834 #define OACC_DATA_CLAUSE_MASK \
19835 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
19841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19842 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
19844 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19846 static tree
19847 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
19849 tree stmt, clauses, block;
19851 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
19852 "#pragma acc data");
19854 block = c_begin_omp_parallel ();
19855 add_stmt (c_parser_omp_structured_block (parser, if_p));
19857 stmt = c_finish_oacc_data (loc, clauses, block);
19859 return stmt;
19862 /* OpenACC 2.0:
19863 # pragma acc declare oacc-data-clause[optseq] new-line
19866 #define OACC_DECLARE_CLAUSE_MASK \
19867 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19868 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19869 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19870 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19871 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19872 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
19873 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
19874 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19876 static void
19877 c_parser_oacc_declare (c_parser *parser)
19879 location_t pragma_loc = c_parser_peek_token (parser)->location;
19880 tree clauses, stmt, t, decl;
19882 bool error = false;
19884 c_parser_consume_pragma (parser);
19886 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
19887 "#pragma acc declare");
19888 if (!clauses)
19890 error_at (pragma_loc,
19891 "no valid clauses specified in %<#pragma acc declare%>");
19892 return;
19895 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
19897 location_t loc = OMP_CLAUSE_LOCATION (t);
19898 decl = OMP_CLAUSE_DECL (t);
19899 if (!DECL_P (decl))
19901 error_at (loc, "array section in %<#pragma acc declare%>");
19902 error = true;
19903 continue;
19906 switch (OMP_CLAUSE_MAP_KIND (t))
19908 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19909 case GOMP_MAP_ALLOC:
19910 case GOMP_MAP_TO:
19911 case GOMP_MAP_FORCE_DEVICEPTR:
19912 case GOMP_MAP_DEVICE_RESIDENT:
19913 break;
19915 case GOMP_MAP_LINK:
19916 if (!global_bindings_p ()
19917 && (TREE_STATIC (decl)
19918 || !DECL_EXTERNAL (decl)))
19920 error_at (loc,
19921 "%qD must be a global variable in "
19922 "%<#pragma acc declare link%>",
19923 decl);
19924 error = true;
19925 continue;
19927 break;
19929 default:
19930 if (global_bindings_p ())
19932 error_at (loc, "invalid OpenACC clause at file scope");
19933 error = true;
19934 continue;
19936 if (DECL_EXTERNAL (decl))
19938 error_at (loc,
19939 "invalid use of %<extern%> variable %qD "
19940 "in %<#pragma acc declare%>", decl);
19941 error = true;
19942 continue;
19944 else if (TREE_PUBLIC (decl))
19946 error_at (loc,
19947 "invalid use of %<global%> variable %qD "
19948 "in %<#pragma acc declare%>", decl);
19949 error = true;
19950 continue;
19952 break;
19955 if (!c_check_in_current_scope (decl))
19957 error_at (loc,
19958 "%qD must be a variable declared in the same scope as "
19959 "%<#pragma acc declare%>", decl);
19960 error = true;
19961 continue;
19964 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
19965 || lookup_attribute ("omp declare target link",
19966 DECL_ATTRIBUTES (decl)))
19968 error_at (loc, "variable %qD used more than once with "
19969 "%<#pragma acc declare%>", decl);
19970 error = true;
19971 continue;
19974 if (!error)
19976 tree id;
19978 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
19979 id = get_identifier ("omp declare target link");
19980 else
19981 id = get_identifier ("omp declare target");
19983 DECL_ATTRIBUTES (decl)
19984 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
19986 if (global_bindings_p ())
19988 symtab_node *node = symtab_node::get (decl);
19989 if (node != NULL)
19991 node->offloadable = 1;
19992 if (ENABLE_OFFLOADING)
19994 g->have_offload = true;
19995 if (is_a <varpool_node *> (node))
19996 vec_safe_push (offload_vars, decl);
20003 if (error || global_bindings_p ())
20004 return;
20006 stmt = make_node (OACC_DECLARE);
20007 TREE_TYPE (stmt) = void_type_node;
20008 OACC_DECLARE_CLAUSES (stmt) = clauses;
20009 SET_EXPR_LOCATION (stmt, pragma_loc);
20011 add_stmt (stmt);
20013 return;
20016 /* OpenACC 2.0:
20017 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
20021 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
20024 LOC is the location of the #pragma token.
20027 #define OACC_ENTER_DATA_CLAUSE_MASK \
20028 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20029 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20030 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20031 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20032 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20033 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20035 #define OACC_EXIT_DATA_CLAUSE_MASK \
20036 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20037 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20038 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20039 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
20040 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
20041 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
20042 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20044 static void
20045 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
20047 location_t loc = c_parser_peek_token (parser)->location;
20048 tree clauses, stmt;
20049 const char *p = "";
20051 c_parser_consume_pragma (parser);
20053 if (c_parser_next_token_is (parser, CPP_NAME))
20055 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20056 c_parser_consume_token (parser);
20059 if (strcmp (p, "data") != 0)
20061 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
20062 enter ? "enter" : "exit");
20063 parser->error = true;
20064 c_parser_skip_to_pragma_eol (parser);
20065 return;
20068 if (enter)
20069 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
20070 "#pragma acc enter data");
20071 else
20072 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
20073 "#pragma acc exit data");
20075 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
20077 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
20078 enter ? "enter" : "exit");
20079 return;
20082 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
20083 TREE_TYPE (stmt) = void_type_node;
20084 OMP_STANDALONE_CLAUSES (stmt) = clauses;
20085 SET_EXPR_LOCATION (stmt, loc);
20086 add_stmt (stmt);
20090 /* OpenACC 2.0:
20091 # pragma acc host_data oacc-data-clause[optseq] new-line
20092 structured-block
20095 #define OACC_HOST_DATA_CLAUSE_MASK \
20096 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
20097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20098 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
20100 static tree
20101 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
20103 tree stmt, clauses, block;
20105 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
20106 "#pragma acc host_data", false);
20107 if (!omp_find_clause (clauses, OMP_CLAUSE_USE_DEVICE_PTR))
20109 error_at (loc, "%<host_data%> construct requires %<use_device%> clause");
20110 return error_mark_node;
20112 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
20113 block = c_begin_omp_parallel ();
20114 add_stmt (c_parser_omp_structured_block (parser, if_p));
20115 stmt = c_finish_oacc_host_data (loc, clauses, block);
20116 return stmt;
20120 /* OpenACC 2.0:
20122 # pragma acc loop oacc-loop-clause[optseq] new-line
20123 structured-block
20125 LOC is the location of the #pragma token.
20128 #define OACC_LOOP_CLAUSE_MASK \
20129 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
20130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
20136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
20137 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20138 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
20139 static tree
20140 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
20141 omp_clause_mask mask, tree *cclauses, bool *if_p)
20143 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
20145 strcat (p_name, " loop");
20146 mask |= OACC_LOOP_CLAUSE_MASK;
20148 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
20149 /*finish_p=*/cclauses == NULL,
20150 /*target=*/is_parallel);
20151 if (cclauses)
20153 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
20154 if (*cclauses)
20155 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC_TARGET);
20156 if (clauses)
20157 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
20160 tree block = c_begin_compound_stmt (true);
20161 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
20162 if_p);
20163 block = c_end_compound_stmt (loc, block, true);
20164 add_stmt (block);
20166 return stmt;
20169 /* OpenACC 2.0:
20170 # pragma acc kernels oacc-kernels-clause[optseq] new-line
20171 structured-block
20175 # pragma acc parallel oacc-parallel-clause[optseq] new-line
20176 structured-block
20178 OpenACC 2.6:
20180 # pragma acc serial oacc-serial-clause[optseq] new-line
20181 structured-block
20183 LOC is the location of the #pragma token.
20186 #define OACC_KERNELS_CLAUSE_MASK \
20187 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20188 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20189 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20190 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20191 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20192 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20193 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20194 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20195 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20196 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20197 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20198 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20199 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20201 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20202 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20204 #define OACC_PARALLEL_CLAUSE_MASK \
20205 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20206 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20207 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20209 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20210 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20211 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20214 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20215 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20216 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20217 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20218 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20219 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20220 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20221 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20222 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20223 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20225 #define OACC_SERIAL_CLAUSE_MASK \
20226 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20227 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20228 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20229 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20230 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20231 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20232 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20233 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20235 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20236 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
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_WAIT) )
20243 static tree
20244 c_parser_oacc_compute (location_t loc, c_parser *parser,
20245 enum pragma_kind p_kind, char *p_name, bool *if_p)
20247 omp_clause_mask mask;
20248 enum tree_code code;
20249 switch (p_kind)
20251 case PRAGMA_OACC_KERNELS:
20252 strcat (p_name, " kernels");
20253 mask = OACC_KERNELS_CLAUSE_MASK;
20254 code = OACC_KERNELS;
20255 break;
20256 case PRAGMA_OACC_PARALLEL:
20257 strcat (p_name, " parallel");
20258 mask = OACC_PARALLEL_CLAUSE_MASK;
20259 code = OACC_PARALLEL;
20260 break;
20261 case PRAGMA_OACC_SERIAL:
20262 strcat (p_name, " serial");
20263 mask = OACC_SERIAL_CLAUSE_MASK;
20264 code = OACC_SERIAL;
20265 break;
20266 default:
20267 gcc_unreachable ();
20270 if (c_parser_next_token_is (parser, CPP_NAME))
20272 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20273 if (strcmp (p, "loop") == 0)
20275 c_parser_consume_token (parser);
20276 tree block = c_begin_omp_parallel ();
20277 tree clauses;
20278 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
20279 return c_finish_omp_construct (loc, code, block, clauses);
20283 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
20284 /*finish_p=*/true,
20285 /*target=*/true);
20287 tree block = c_begin_omp_parallel ();
20288 add_stmt (c_parser_omp_structured_block (parser, if_p));
20290 return c_finish_omp_construct (loc, code, block, clauses);
20293 /* OpenACC 2.0:
20294 # pragma acc routine oacc-routine-clause[optseq] new-line
20295 function-definition
20297 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
20300 #define OACC_ROUTINE_CLAUSE_MASK \
20301 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20304 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20305 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
20307 /* Parse an OpenACC routine directive. For named directives, we apply
20308 immediately to the named function. For unnamed ones we then parse
20309 a declaration or definition, which must be for a function. */
20311 static void
20312 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
20314 gcc_checking_assert (context == pragma_external);
20316 oacc_routine_data data;
20317 data.error_seen = false;
20318 data.fndecl_seen = false;
20319 data.loc = c_parser_peek_token (parser)->location;
20321 c_parser_consume_pragma (parser);
20323 /* Look for optional '( name )'. */
20324 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20326 c_parser_consume_token (parser); /* '(' */
20328 tree decl = NULL_TREE;
20329 c_token *name_token = c_parser_peek_token (parser);
20330 location_t name_loc = name_token->location;
20331 if (name_token->type == CPP_NAME
20332 && (name_token->id_kind == C_ID_ID
20333 || name_token->id_kind == C_ID_TYPENAME))
20335 decl = lookup_name (name_token->value);
20336 if (!decl)
20337 error_at (name_loc,
20338 "%qE has not been declared", name_token->value);
20339 c_parser_consume_token (parser);
20341 else
20342 c_parser_error (parser, "expected function name");
20344 if (!decl
20345 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20347 c_parser_skip_to_pragma_eol (parser, false);
20348 return;
20351 data.clauses
20352 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
20353 "#pragma acc routine");
20354 /* The clauses are in reverse order; fix that to make later diagnostic
20355 emission easier. */
20356 data.clauses = nreverse (data.clauses);
20358 if (TREE_CODE (decl) != FUNCTION_DECL)
20360 error_at (name_loc, "%qD does not refer to a function", decl);
20361 return;
20364 c_finish_oacc_routine (&data, decl, false);
20366 else /* No optional '( name )'. */
20368 data.clauses
20369 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
20370 "#pragma acc routine");
20371 /* The clauses are in reverse order; fix that to make later diagnostic
20372 emission easier. */
20373 data.clauses = nreverse (data.clauses);
20375 /* Emit a helpful diagnostic if there's another pragma following this
20376 one. Also don't allow a static assertion declaration, as in the
20377 following we'll just parse a *single* "declaration or function
20378 definition", and the static assertion counts an one. */
20379 if (c_parser_next_token_is (parser, CPP_PRAGMA)
20380 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
20382 error_at (data.loc,
20383 "%<#pragma acc routine%> not immediately followed by"
20384 " function declaration or definition");
20385 /* ..., and then just keep going. */
20386 return;
20389 /* We only have to consider the pragma_external case here. */
20390 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20391 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20393 int ext = disable_extension_diagnostics ();
20395 c_parser_consume_token (parser);
20396 while (c_parser_next_token_is (parser, CPP_KEYWORD)
20397 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20398 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20399 NULL, NULL, false, NULL, &data);
20400 restore_extension_diagnostics (ext);
20402 else
20403 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20404 NULL, NULL, false, NULL, &data);
20408 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
20409 IS_DEFN is true if we're applying it to the definition. */
20411 static void
20412 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
20413 bool is_defn)
20415 /* Keep going if we're in error reporting mode. */
20416 if (data->error_seen
20417 || fndecl == error_mark_node)
20418 return;
20420 if (data->fndecl_seen)
20422 error_at (data->loc,
20423 "%<#pragma acc routine%> not immediately followed by"
20424 " a single function declaration or definition");
20425 data->error_seen = true;
20426 return;
20428 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
20430 error_at (data->loc,
20431 "%<#pragma acc routine%> not immediately followed by"
20432 " function declaration or definition");
20433 data->error_seen = true;
20434 return;
20437 int compatible
20438 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
20439 "#pragma acc routine");
20440 if (compatible < 0)
20442 data->error_seen = true;
20443 return;
20445 if (compatible > 0)
20448 else
20450 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
20452 error_at (data->loc,
20453 TREE_USED (fndecl)
20454 ? G_("%<#pragma acc routine%> must be applied before use")
20455 : G_("%<#pragma acc routine%> must be applied before"
20456 " definition"));
20457 data->error_seen = true;
20458 return;
20461 /* Set the routine's level of parallelism. */
20462 tree dims = oacc_build_routine_dims (data->clauses);
20463 oacc_replace_fn_attrib (fndecl, dims);
20465 /* Add an "omp declare target" attribute. */
20466 DECL_ATTRIBUTES (fndecl)
20467 = tree_cons (get_identifier ("omp declare target"),
20468 data->clauses, DECL_ATTRIBUTES (fndecl));
20471 /* Remember that we've used this "#pragma acc routine". */
20472 data->fndecl_seen = true;
20475 /* OpenACC 2.0:
20476 # pragma acc update oacc-update-clause[optseq] new-line
20479 #define OACC_UPDATE_CLAUSE_MASK \
20480 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
20483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
20485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20486 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20488 static void
20489 c_parser_oacc_update (c_parser *parser)
20491 location_t loc = c_parser_peek_token (parser)->location;
20493 c_parser_consume_pragma (parser);
20495 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
20496 "#pragma acc update");
20497 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
20499 error_at (loc,
20500 "%<#pragma acc update%> must contain at least one "
20501 "%<device%> or %<host%> or %<self%> clause");
20502 return;
20505 if (parser->error)
20506 return;
20508 tree stmt = make_node (OACC_UPDATE);
20509 TREE_TYPE (stmt) = void_type_node;
20510 OACC_UPDATE_CLAUSES (stmt) = clauses;
20511 SET_EXPR_LOCATION (stmt, loc);
20512 add_stmt (stmt);
20515 /* OpenACC 2.0:
20516 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
20518 LOC is the location of the #pragma token.
20521 #define OACC_WAIT_CLAUSE_MASK \
20522 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
20524 static tree
20525 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
20527 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
20529 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
20530 list = c_parser_oacc_wait_list (parser, loc, list);
20532 strcpy (p_name, " wait");
20533 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
20534 stmt = c_finish_oacc_wait (loc, list, clauses);
20535 add_stmt (stmt);
20537 return stmt;
20540 struct c_omp_loc_tree
20542 location_t loc;
20543 tree var;
20546 /* Check whether the expression used in the allocator clause is declared or
20547 modified between the variable declaration and its allocate directive. */
20548 static tree
20549 c_check_omp_allocate_allocator_r (tree *tp, int *, void *data)
20551 tree var = ((struct c_omp_loc_tree *) data)->var;
20552 location_t loc = ((struct c_omp_loc_tree *) data)->loc;
20553 if (TREE_CODE (*tp) == VAR_DECL && c_check_in_current_scope (*tp))
20555 if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
20556 DECL_SOURCE_LOCATION (*tp)))
20558 error_at (loc, "variable %qD used in the %<allocator%> clause must "
20559 "be declared before %qD", *tp, var);
20560 inform (DECL_SOURCE_LOCATION (*tp), "declared here");
20561 inform (DECL_SOURCE_LOCATION (var),
20562 "to be allocated variable declared here");
20563 return *tp;
20565 else
20567 gcc_assert (cur_stmt_list
20568 && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
20570 tree_stmt_iterator l = tsi_last (cur_stmt_list);
20571 while (!tsi_end_p (l))
20573 if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
20574 DECL_SOURCE_LOCATION (var)))
20575 break;
20576 if (TREE_CODE (*l) == MODIFY_EXPR
20577 && TREE_OPERAND (*l, 0) == *tp)
20579 error_at (loc,
20580 "variable %qD used in the %<allocator%> clause "
20581 "must not be modified between declaration of %qD "
20582 "and its %<allocate%> directive", *tp, var);
20583 inform (EXPR_LOCATION (*l), "modified here");
20584 inform (DECL_SOURCE_LOCATION (var),
20585 "to be allocated variable declared here");
20586 return *tp;
20588 --l;
20592 return NULL_TREE;
20595 /* OpenMP 5.x:
20596 # pragma omp allocate (list) clauses
20598 OpenMP 5.0 clause:
20599 allocator (omp_allocator_handle_t expression)
20601 OpenMP 5.1 additional clause:
20602 align (constant-expression)] */
20604 static void
20605 c_parser_omp_allocate (c_parser *parser)
20607 tree alignment = NULL_TREE;
20608 tree allocator = NULL_TREE;
20609 c_parser_consume_pragma (parser);
20610 location_t loc = c_parser_peek_token (parser)->location;
20611 location_t allocator_loc = UNKNOWN_LOCATION;
20612 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
20615 if (c_parser_next_token_is (parser, CPP_COMMA)
20616 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
20617 c_parser_consume_token (parser);
20618 if (!c_parser_next_token_is (parser, CPP_NAME))
20619 break;
20620 matching_parens parens;
20621 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20622 c_parser_consume_token (parser);
20623 location_t expr_loc = c_parser_peek_token (parser)->location;
20624 if (strcmp ("align", p) != 0 && strcmp ("allocator", p) != 0)
20626 error_at (c_parser_peek_token (parser)->location,
20627 "expected %<allocator%> or %<align%>");
20628 break;
20630 if (!parens.require_open (parser))
20631 break;
20633 c_expr expr = c_parser_expr_no_commas (parser, NULL);
20634 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
20635 expr_loc = c_parser_peek_token (parser)->location;
20636 if (expr.value == error_mark_node)
20638 else if (p[2] == 'i' && alignment)
20640 error_at (expr_loc, "too many %qs clauses", "align");
20641 break;
20643 else if (p[2] == 'i')
20645 alignment = c_fully_fold (expr.value, false, NULL);
20646 if (TREE_CODE (alignment) != INTEGER_CST
20647 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
20648 || tree_int_cst_sgn (alignment) != 1
20649 || !integer_pow2p (alignment))
20651 error_at (expr_loc, "%<align%> clause argument needs to be "
20652 "positive constant power of two integer "
20653 "expression");
20654 alignment = NULL_TREE;
20657 else if (allocator)
20659 error_at (expr_loc, "too many %qs clauses", "allocator");
20660 break;
20662 else
20664 allocator = c_fully_fold (expr.value, false, NULL);
20665 allocator_loc = expr_loc;
20666 tree orig_type
20667 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
20668 orig_type = TYPE_MAIN_VARIANT (orig_type);
20669 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
20670 || TREE_CODE (orig_type) != ENUMERAL_TYPE
20671 || TYPE_NAME (orig_type)
20672 != get_identifier ("omp_allocator_handle_t"))
20674 error_at (expr_loc,
20675 "%<allocator%> clause allocator expression has type "
20676 "%qT rather than %<omp_allocator_handle_t%>",
20677 TREE_TYPE (allocator));
20678 allocator = NULL_TREE;
20681 parens.skip_until_found_close (parser);
20682 } while (true);
20683 c_parser_skip_to_pragma_eol (parser);
20685 c_mark_decl_jump_unsafe_in_current_scope ();
20686 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
20688 tree var = OMP_CLAUSE_DECL (c);
20689 if (TREE_CODE (var) == PARM_DECL)
20691 error_at (OMP_CLAUSE_LOCATION (nl),
20692 "function parameter %qD may not appear as list item in an "
20693 "%<allocate%> directive", var);
20694 continue;
20696 if (!c_check_in_current_scope (var))
20698 error_at (OMP_CLAUSE_LOCATION (nl),
20699 "%<allocate%> directive must be in the same scope as %qD",
20700 var);
20701 inform (DECL_SOURCE_LOCATION (var), "declared here");
20702 continue;
20704 if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var)))
20706 error_at (OMP_CLAUSE_LOCATION (nl),
20707 "%qD already appeared as list item in an "
20708 "%<allocate%> directive", var);
20709 continue;
20711 if (TREE_STATIC (var))
20713 if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION)
20714 error_at (loc, "%<allocator%> clause required for "
20715 "static variable %qD", var);
20716 else if (allocator
20717 && (wi::to_widest (allocator) < 1
20718 || wi::to_widest (allocator) > 8))
20719 /* 8 = largest predefined memory allocator. */
20720 error_at (allocator_loc,
20721 "%<allocator%> clause requires a predefined allocator as "
20722 "%qD is static", var);
20723 else
20724 sorry_at (OMP_CLAUSE_LOCATION (nl),
20725 "%<#pragma omp allocate%> for static variables like "
20726 "%qD not yet supported", var);
20727 continue;
20729 if (allocator)
20731 struct c_omp_loc_tree data
20732 = {EXPR_LOC_OR_LOC (allocator, OMP_CLAUSE_LOCATION (nl)), var};
20733 walk_tree (&allocator, c_check_omp_allocate_allocator_r, &data, NULL);
20735 DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"),
20736 build_tree_list (allocator, alignment),
20737 DECL_ATTRIBUTES (var));
20741 /* OpenMP 2.5:
20742 # pragma omp atomic new-line
20743 expression-stmt
20745 expression-stmt:
20746 x binop= expr | x++ | ++x | x-- | --x
20747 binop:
20748 +, *, -, /, &, ^, |, <<, >>
20750 where x is an lvalue expression with scalar type.
20752 OpenMP 3.1:
20753 # pragma omp atomic new-line
20754 update-stmt
20756 # pragma omp atomic read new-line
20757 read-stmt
20759 # pragma omp atomic write new-line
20760 write-stmt
20762 # pragma omp atomic update new-line
20763 update-stmt
20765 # pragma omp atomic capture new-line
20766 capture-stmt
20768 # pragma omp atomic capture new-line
20769 capture-block
20771 read-stmt:
20772 v = x
20773 write-stmt:
20774 x = expr
20775 update-stmt:
20776 expression-stmt | x = x binop expr
20777 capture-stmt:
20778 v = expression-stmt
20779 capture-block:
20780 { v = x; update-stmt; } | { update-stmt; v = x; }
20782 OpenMP 4.0:
20783 update-stmt:
20784 expression-stmt | x = x binop expr | x = expr binop x
20785 capture-stmt:
20786 v = update-stmt
20787 capture-block:
20788 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
20790 OpenMP 5.1:
20791 # pragma omp atomic compare new-line
20792 conditional-update-atomic
20794 # pragma omp atomic compare capture new-line
20795 conditional-update-capture-atomic
20797 conditional-update-atomic:
20798 cond-expr-stmt | cond-update-stmt
20799 cond-expr-stmt:
20800 x = expr ordop x ? expr : x;
20801 x = x ordop expr ? expr : x;
20802 x = x == e ? d : x;
20803 cond-update-stmt:
20804 if (expr ordop x) { x = expr; }
20805 if (x ordop expr) { x = expr; }
20806 if (x == e) { x = d; }
20807 ordop:
20808 <, >
20809 conditional-update-capture-atomic:
20810 v = cond-expr-stmt
20811 { v = x; cond-expr-stmt }
20812 { cond-expr-stmt v = x; }
20813 { v = x; cond-update-stmt }
20814 { cond-update-stmt v = x; }
20815 if (x == e) { x = d; } else { v = x; }
20816 { r = x == e; if (r) { x = d; } }
20817 { r = x == e; if (r) { x = d; } else { v = x; } }
20819 where x, r and v are lvalue expressions with scalar type,
20820 expr, e and d are expressions with scalar type and e might be
20821 the same as v.
20823 LOC is the location of the #pragma token. */
20825 static void
20826 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
20828 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
20829 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
20830 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
20831 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
20832 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
20833 struct c_expr expr;
20834 location_t eloc;
20835 bool structured_block = false;
20836 bool swapped = false;
20837 bool non_lvalue_p;
20838 tree clauses = NULL_TREE;
20839 bool capture = false;
20840 bool compare = false;
20841 bool weak = false;
20842 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
20843 bool no_semicolon = false;
20844 bool extra_scope = false;
20846 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20848 if (c_parser_next_token_is (parser, CPP_COMMA)
20849 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
20850 c_parser_consume_token (parser);
20852 if (c_parser_next_token_is (parser, CPP_NAME))
20854 const char *p
20855 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20856 location_t cloc = c_parser_peek_token (parser)->location;
20857 enum tree_code new_code = ERROR_MARK;
20858 enum omp_memory_order new_memory_order
20859 = OMP_MEMORY_ORDER_UNSPECIFIED;
20860 bool new_capture = false;
20861 bool new_compare = false;
20862 bool new_weak = false;
20863 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
20865 if (!strcmp (p, "read"))
20866 new_code = OMP_ATOMIC_READ;
20867 else if (!strcmp (p, "write"))
20868 new_code = NOP_EXPR;
20869 else if (!strcmp (p, "update"))
20870 new_code = OMP_ATOMIC;
20871 else if (openacc && !strcmp (p, "capture"))
20872 new_code = OMP_ATOMIC_CAPTURE_NEW;
20873 else if (openacc)
20875 p = NULL;
20876 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
20877 "or %<capture%> clause");
20879 else if (!strcmp (p, "capture"))
20880 new_capture = true;
20881 else if (!strcmp (p, "compare"))
20882 new_compare = true;
20883 else if (!strcmp (p, "weak"))
20884 new_weak = true;
20885 else if (!strcmp (p, "fail"))
20887 matching_parens parens;
20889 c_parser_consume_token (parser);
20890 if (!parens.require_open (parser))
20891 continue;
20893 if (c_parser_next_token_is (parser, CPP_NAME))
20895 const char *q
20896 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20898 if (!strcmp (q, "seq_cst"))
20899 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
20900 else if (!strcmp (q, "acquire"))
20901 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
20902 else if (!strcmp (q, "relaxed"))
20903 new_fail = OMP_MEMORY_ORDER_RELAXED;
20906 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
20908 c_parser_consume_token (parser);
20909 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
20910 error_at (cloc, "too many %qs clauses", "fail");
20911 else
20912 fail = new_fail;
20914 else
20915 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
20916 "or %<relaxed%>");
20917 parens.skip_until_found_close (parser);
20918 continue;
20920 else if (!strcmp (p, "seq_cst"))
20921 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
20922 else if (!strcmp (p, "acq_rel"))
20923 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
20924 else if (!strcmp (p, "release"))
20925 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
20926 else if (!strcmp (p, "acquire"))
20927 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
20928 else if (!strcmp (p, "relaxed"))
20929 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
20930 else if (!strcmp (p, "hint"))
20932 c_parser_consume_token (parser);
20933 clauses = c_parser_omp_clause_hint (parser, clauses);
20934 continue;
20936 else
20938 p = NULL;
20939 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
20940 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
20941 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
20942 "%<relaxed%> or %<hint%> clause");
20944 if (p)
20946 if (new_code != ERROR_MARK)
20948 /* OpenACC permits 'update capture'. */
20949 if (openacc
20950 && code == OMP_ATOMIC
20951 && new_code == OMP_ATOMIC_CAPTURE_NEW)
20952 code = new_code;
20953 else if (code != ERROR_MARK)
20954 error_at (cloc, "too many atomic clauses");
20955 else
20956 code = new_code;
20958 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
20960 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
20961 error_at (cloc, "too many memory order clauses");
20962 else
20963 memory_order = new_memory_order;
20965 else if (new_capture)
20967 if (capture)
20968 error_at (cloc, "too many %qs clauses", "capture");
20969 else
20970 capture = true;
20972 else if (new_compare)
20974 if (compare)
20975 error_at (cloc, "too many %qs clauses", "compare");
20976 else
20977 compare = true;
20979 else if (new_weak)
20981 if (weak)
20982 error_at (cloc, "too many %qs clauses", "weak");
20983 else
20984 weak = true;
20986 c_parser_consume_token (parser);
20987 continue;
20990 break;
20992 c_parser_skip_to_pragma_eol (parser);
20994 if (code == ERROR_MARK)
20995 code = OMP_ATOMIC;
20996 if (capture)
20998 if (code != OMP_ATOMIC)
20999 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
21000 "clauses", "capture");
21001 else
21002 code = OMP_ATOMIC_CAPTURE_NEW;
21004 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
21006 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
21007 "clauses", "compare");
21008 compare = false;
21010 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
21012 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
21013 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
21015 if (weak && !compare)
21017 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
21018 weak = false;
21020 if (openacc)
21021 memory_order = OMP_MEMORY_ORDER_RELAXED;
21022 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
21024 omp_requires_mask
21025 = (enum omp_requires) (omp_requires_mask
21026 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
21027 switch ((enum omp_memory_order)
21028 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
21030 case OMP_MEMORY_ORDER_UNSPECIFIED:
21031 case OMP_MEMORY_ORDER_RELAXED:
21032 memory_order = OMP_MEMORY_ORDER_RELAXED;
21033 break;
21034 case OMP_MEMORY_ORDER_SEQ_CST:
21035 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21036 break;
21037 case OMP_MEMORY_ORDER_ACQUIRE:
21038 if (code == NOP_EXPR) /* atomic write */
21040 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
21041 "%<acquire%> clause implicitly provided by a "
21042 "%<requires%> directive");
21043 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21045 else
21046 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21047 break;
21048 case OMP_MEMORY_ORDER_RELEASE:
21049 if (code == OMP_ATOMIC_READ)
21051 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
21052 "%<release%> clause implicitly provided by a "
21053 "%<requires%> directive");
21054 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21056 else
21057 memory_order = OMP_MEMORY_ORDER_RELEASE;
21058 break;
21059 case OMP_MEMORY_ORDER_ACQ_REL:
21060 switch (code)
21062 case OMP_ATOMIC_READ:
21063 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21064 break;
21065 case NOP_EXPR: /* atomic write */
21066 memory_order = OMP_MEMORY_ORDER_RELEASE;
21067 break;
21068 default:
21069 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
21070 break;
21072 break;
21073 default:
21074 gcc_unreachable ();
21077 else
21078 switch (code)
21080 case OMP_ATOMIC_READ:
21081 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
21083 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
21084 "%<release%> clause");
21085 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21087 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
21088 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21089 break;
21090 case NOP_EXPR: /* atomic write */
21091 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
21093 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
21094 "%<acquire%> clause");
21095 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21097 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
21098 memory_order = OMP_MEMORY_ORDER_RELEASE;
21099 break;
21100 default:
21101 break;
21103 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
21104 memory_order
21105 = (enum omp_memory_order) (memory_order
21106 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
21108 switch (code)
21110 case OMP_ATOMIC_READ:
21111 case NOP_EXPR: /* atomic write */
21112 v = c_parser_cast_expression (parser, NULL).value;
21113 non_lvalue_p = !lvalue_p (v);
21114 v = c_fully_fold (v, false, NULL, true);
21115 if (v == error_mark_node)
21116 goto saw_error;
21117 if (non_lvalue_p)
21118 v = non_lvalue (v);
21119 loc = c_parser_peek_token (parser)->location;
21120 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21121 goto saw_error;
21122 if (code == NOP_EXPR)
21124 lhs = c_parser_expression (parser).value;
21125 lhs = c_fully_fold (lhs, false, NULL);
21126 if (lhs == error_mark_node)
21127 goto saw_error;
21129 else
21131 lhs = c_parser_cast_expression (parser, NULL).value;
21132 non_lvalue_p = !lvalue_p (lhs);
21133 lhs = c_fully_fold (lhs, false, NULL, true);
21134 if (lhs == error_mark_node)
21135 goto saw_error;
21136 if (non_lvalue_p)
21137 lhs = non_lvalue (lhs);
21139 if (code == NOP_EXPR)
21141 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
21142 opcode. */
21143 code = OMP_ATOMIC;
21144 rhs = lhs;
21145 lhs = v;
21146 v = NULL_TREE;
21148 goto done;
21149 case OMP_ATOMIC_CAPTURE_NEW:
21150 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
21152 c_parser_consume_token (parser);
21153 structured_block = true;
21155 else if (compare
21156 && c_parser_next_token_is_keyword (parser, RID_IF))
21157 break;
21158 else
21160 v = c_parser_cast_expression (parser, NULL).value;
21161 non_lvalue_p = !lvalue_p (v);
21162 v = c_fully_fold (v, false, NULL, true);
21163 if (v == error_mark_node)
21164 goto saw_error;
21165 if (non_lvalue_p)
21166 v = non_lvalue (v);
21167 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21168 goto saw_error;
21169 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
21171 eloc = c_parser_peek_token (parser)->location;
21172 error_at (eloc, "expected expression");
21173 goto saw_error;
21176 break;
21177 default:
21178 break;
21181 /* For structured_block case we don't know yet whether
21182 old or new x should be captured. */
21183 restart:
21184 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
21186 c_parser_consume_token (parser);
21188 matching_parens parens;
21189 if (!parens.require_open (parser))
21190 goto saw_error;
21191 eloc = c_parser_peek_token (parser)->location;
21192 c_expr cmp_expr;
21193 if (r)
21195 cmp_expr = c_parser_cast_expression (parser, NULL);
21196 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
21198 else
21199 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
21200 parens.skip_until_found_close (parser);
21201 if (cmp_expr.value == error_mark_node)
21202 goto saw_error;
21203 if (r)
21205 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
21206 goto bad_if;
21207 cmp_expr.value = rhs1;
21208 rhs1 = NULL_TREE;
21209 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
21211 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21213 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
21215 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
21216 "expected %<==%> comparison in %<if%> condition");
21217 goto saw_error;
21219 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
21220 && TREE_CODE (cmp_expr.value) != LT_EXPR)
21222 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
21223 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
21224 "condition");
21225 goto saw_error;
21227 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21228 goto saw_error;
21230 extra_scope = true;
21231 eloc = c_parser_peek_token (parser)->location;
21232 expr = c_parser_cast_expression (parser, NULL);
21233 lhs = expr.value;
21234 expr = default_function_array_conversion (eloc, expr);
21235 unfolded_lhs = expr.value;
21236 lhs = c_fully_fold (lhs, false, NULL, true);
21237 orig_lhs = lhs;
21238 if (lhs == error_mark_node)
21239 goto saw_error;
21240 if (!lvalue_p (unfolded_lhs))
21241 lhs = non_lvalue (lhs);
21242 if (!c_parser_next_token_is (parser, CPP_EQ))
21244 c_parser_error (parser, "expected %<=%>");
21245 goto saw_error;
21247 c_parser_consume_token (parser);
21248 eloc = c_parser_peek_token (parser)->location;
21249 expr = c_parser_expr_no_commas (parser, NULL);
21250 rhs1 = expr.value;
21252 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21253 goto saw_error;
21255 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
21256 goto saw_error;
21258 extra_scope = false;
21259 no_semicolon = true;
21261 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
21263 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21265 opcode = COND_EXPR;
21266 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
21267 false, NULL, true);
21268 rhs1 = c_fully_fold (rhs1, false, NULL, true);
21270 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
21272 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
21273 ? MIN_EXPR : MAX_EXPR);
21274 rhs = c_fully_fold (rhs1, false, NULL, true);
21275 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
21276 false, NULL, true);
21278 else
21279 goto bad_if;
21281 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21282 goto bad_if;
21283 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
21284 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
21286 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
21287 ? MAX_EXPR : MIN_EXPR);
21288 rhs = c_fully_fold (rhs1, false, NULL, true);
21289 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
21290 false, NULL, true);
21292 else
21294 bad_if:
21295 c_parser_error (parser,
21296 "invalid form of %<#pragma omp atomic compare%>");
21297 goto saw_error;
21300 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
21302 if (code != OMP_ATOMIC_CAPTURE_NEW
21303 || (structured_block && r == NULL_TREE)
21304 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
21306 eloc = c_parser_peek_token (parser)->location;
21307 error_at (eloc, "unexpected %<else%>");
21308 goto saw_error;
21311 c_parser_consume_token (parser);
21313 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21314 goto saw_error;
21316 extra_scope = true;
21317 v = c_parser_cast_expression (parser, NULL).value;
21318 non_lvalue_p = !lvalue_p (v);
21319 v = c_fully_fold (v, false, NULL, true);
21320 if (v == error_mark_node)
21321 goto saw_error;
21322 if (non_lvalue_p)
21323 v = non_lvalue (v);
21324 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21325 goto saw_error;
21327 expr = c_parser_expr_no_commas (parser, NULL);
21329 if (!c_tree_equal (expr.value, unfolded_lhs))
21330 goto bad_if;
21332 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21333 goto saw_error;
21335 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
21336 goto saw_error;
21338 extra_scope = false;
21339 code = OMP_ATOMIC_CAPTURE_OLD;
21340 if (r == NULL_TREE)
21341 /* Signal to c_finish_omp_atomic that in
21342 if (x == e) { x = d; } else { v = x; }
21343 case the store to v should be conditional. */
21344 r = void_list_node;
21346 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21348 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
21349 goto saw_error;
21351 else if (code == OMP_ATOMIC_CAPTURE_NEW
21352 && r != NULL_TREE
21353 && v == NULL_TREE)
21354 code = OMP_ATOMIC;
21355 goto stmt_done;
21357 eloc = c_parser_peek_token (parser)->location;
21358 expr = c_parser_cast_expression (parser, NULL);
21359 lhs = expr.value;
21360 expr = default_function_array_conversion (eloc, expr);
21361 unfolded_lhs = expr.value;
21362 lhs = c_fully_fold (lhs, false, NULL, true);
21363 orig_lhs = lhs;
21364 switch (TREE_CODE (lhs))
21366 invalid_compare:
21367 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
21368 /* FALLTHRU */
21369 case ERROR_MARK:
21370 saw_error:
21371 c_parser_skip_to_end_of_block_or_statement (parser);
21372 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21373 c_parser_consume_token (parser);
21374 if (structured_block)
21376 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21377 c_parser_consume_token (parser);
21378 else if (code == OMP_ATOMIC_CAPTURE_NEW)
21380 c_parser_skip_to_end_of_block_or_statement (parser);
21381 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21382 c_parser_consume_token (parser);
21385 return;
21387 case POSTINCREMENT_EXPR:
21388 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21389 code = OMP_ATOMIC_CAPTURE_OLD;
21390 /* FALLTHROUGH */
21391 case PREINCREMENT_EXPR:
21392 lhs = TREE_OPERAND (lhs, 0);
21393 unfolded_lhs = NULL_TREE;
21394 opcode = PLUS_EXPR;
21395 rhs = integer_one_node;
21396 if (compare)
21397 goto invalid_compare;
21398 break;
21400 case POSTDECREMENT_EXPR:
21401 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21402 code = OMP_ATOMIC_CAPTURE_OLD;
21403 /* FALLTHROUGH */
21404 case PREDECREMENT_EXPR:
21405 lhs = TREE_OPERAND (lhs, 0);
21406 unfolded_lhs = NULL_TREE;
21407 opcode = MINUS_EXPR;
21408 rhs = integer_one_node;
21409 if (compare)
21410 goto invalid_compare;
21411 break;
21413 case COMPOUND_EXPR:
21414 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
21415 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
21416 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
21417 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
21418 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
21419 (TREE_OPERAND (lhs, 1), 0), 0))))
21420 /* Undo effects of boolean_increment for post {in,de}crement. */
21421 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
21422 /* FALLTHRU */
21423 case MODIFY_EXPR:
21424 if (TREE_CODE (lhs) == MODIFY_EXPR
21425 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))))
21427 /* Undo effects of boolean_increment. */
21428 if (integer_onep (TREE_OPERAND (lhs, 1)))
21430 /* This is pre or post increment. */
21431 rhs = TREE_OPERAND (lhs, 1);
21432 lhs = TREE_OPERAND (lhs, 0);
21433 unfolded_lhs = NULL_TREE;
21434 opcode = NOP_EXPR;
21435 if (code == OMP_ATOMIC_CAPTURE_NEW
21436 && !structured_block
21437 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
21438 code = OMP_ATOMIC_CAPTURE_OLD;
21439 if (compare)
21440 goto invalid_compare;
21441 break;
21443 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
21444 && TREE_OPERAND (lhs, 0)
21445 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
21447 /* This is pre or post decrement. */
21448 rhs = TREE_OPERAND (lhs, 1);
21449 lhs = TREE_OPERAND (lhs, 0);
21450 unfolded_lhs = NULL_TREE;
21451 opcode = NOP_EXPR;
21452 if (code == OMP_ATOMIC_CAPTURE_NEW
21453 && !structured_block
21454 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
21455 code = OMP_ATOMIC_CAPTURE_OLD;
21456 if (compare)
21457 goto invalid_compare;
21458 break;
21461 /* FALLTHRU */
21462 default:
21463 if (!lvalue_p (unfolded_lhs))
21464 lhs = non_lvalue (lhs);
21465 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
21467 c_parser_error (parser, "expected %<=%>");
21468 goto saw_error;
21470 switch (c_parser_peek_token (parser)->type)
21472 case CPP_MULT_EQ:
21473 opcode = MULT_EXPR;
21474 break;
21475 case CPP_DIV_EQ:
21476 opcode = TRUNC_DIV_EXPR;
21477 break;
21478 case CPP_PLUS_EQ:
21479 opcode = PLUS_EXPR;
21480 break;
21481 case CPP_MINUS_EQ:
21482 opcode = MINUS_EXPR;
21483 break;
21484 case CPP_LSHIFT_EQ:
21485 opcode = LSHIFT_EXPR;
21486 break;
21487 case CPP_RSHIFT_EQ:
21488 opcode = RSHIFT_EXPR;
21489 break;
21490 case CPP_AND_EQ:
21491 opcode = BIT_AND_EXPR;
21492 break;
21493 case CPP_OR_EQ:
21494 opcode = BIT_IOR_EXPR;
21495 break;
21496 case CPP_XOR_EQ:
21497 opcode = BIT_XOR_EXPR;
21498 break;
21499 case CPP_EQ:
21500 c_parser_consume_token (parser);
21501 eloc = c_parser_peek_token (parser)->location;
21502 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
21503 rhs1 = expr.value;
21504 switch (TREE_CODE (rhs1))
21506 case MULT_EXPR:
21507 case TRUNC_DIV_EXPR:
21508 case RDIV_EXPR:
21509 case PLUS_EXPR:
21510 case MINUS_EXPR:
21511 case LSHIFT_EXPR:
21512 case RSHIFT_EXPR:
21513 case BIT_AND_EXPR:
21514 case BIT_IOR_EXPR:
21515 case BIT_XOR_EXPR:
21516 if (compare)
21517 break;
21518 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
21520 opcode = TREE_CODE (rhs1);
21521 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21522 true);
21523 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
21524 true);
21525 goto stmt_done;
21527 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
21529 opcode = TREE_CODE (rhs1);
21530 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
21531 true);
21532 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21533 true);
21534 swapped = !commutative_tree_code (opcode);
21535 goto stmt_done;
21537 break;
21538 case COND_EXPR:
21539 if (!compare)
21540 break;
21541 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
21542 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
21543 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
21544 break;
21545 if (!TREE_OPERAND (rhs1, 1))
21546 break;
21547 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
21548 break;
21549 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
21550 unfolded_lhs))
21552 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
21554 opcode = COND_EXPR;
21555 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21556 0), 1),
21557 false, NULL, true);
21558 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
21559 NULL, true);
21560 goto stmt_done;
21562 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
21563 TREE_OPERAND (rhs1, 1)))
21565 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
21566 ? MIN_EXPR : MAX_EXPR);
21567 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21568 true);
21569 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21570 0), 0),
21571 false, NULL, true);
21572 goto stmt_done;
21575 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
21576 break;
21577 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
21578 unfolded_lhs))
21580 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
21581 TREE_OPERAND (rhs1, 1)))
21583 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
21584 ? MAX_EXPR : MIN_EXPR);
21585 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21586 true);
21587 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21588 0), 1),
21589 false, NULL, true);
21590 goto stmt_done;
21593 break;
21594 case EQ_EXPR:
21595 if (!compare
21596 || code != OMP_ATOMIC_CAPTURE_NEW
21597 || !structured_block
21598 || v
21599 || r)
21600 break;
21601 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
21602 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
21604 r = lhs;
21605 lhs = NULL_TREE;
21606 c_parser_consume_token (parser);
21607 goto restart;
21609 break;
21610 case ERROR_MARK:
21611 goto saw_error;
21612 default:
21613 break;
21615 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
21617 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
21619 code = OMP_ATOMIC_CAPTURE_OLD;
21620 v = lhs;
21621 lhs = NULL_TREE;
21622 expr = default_function_array_read_conversion (eloc, expr);
21623 unfolded_lhs1 = expr.value;
21624 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
21625 rhs1 = NULL_TREE;
21626 c_parser_consume_token (parser);
21627 goto restart;
21629 if (structured_block && !compare)
21631 opcode = NOP_EXPR;
21632 expr = default_function_array_read_conversion (eloc, expr);
21633 rhs = c_fully_fold (expr.value, false, NULL, true);
21634 rhs1 = NULL_TREE;
21635 goto stmt_done;
21638 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
21639 goto saw_error;
21640 default:
21641 c_parser_error (parser,
21642 "invalid operator for %<#pragma omp atomic%>");
21643 goto saw_error;
21646 /* Arrange to pass the location of the assignment operator to
21647 c_finish_omp_atomic. */
21648 loc = c_parser_peek_token (parser)->location;
21649 c_parser_consume_token (parser);
21650 eloc = c_parser_peek_token (parser)->location;
21651 expr = c_parser_expression (parser);
21652 expr = default_function_array_read_conversion (eloc, expr);
21653 rhs = expr.value;
21654 rhs = c_fully_fold (rhs, false, NULL, true);
21655 break;
21657 stmt_done:
21658 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
21660 if (!no_semicolon
21661 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21662 goto saw_error;
21663 no_semicolon = false;
21664 v = c_parser_cast_expression (parser, NULL).value;
21665 non_lvalue_p = !lvalue_p (v);
21666 v = c_fully_fold (v, false, NULL, true);
21667 if (v == error_mark_node)
21668 goto saw_error;
21669 if (non_lvalue_p)
21670 v = non_lvalue (v);
21671 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21672 goto saw_error;
21673 eloc = c_parser_peek_token (parser)->location;
21674 expr = c_parser_cast_expression (parser, NULL);
21675 lhs1 = expr.value;
21676 expr = default_function_array_read_conversion (eloc, expr);
21677 unfolded_lhs1 = expr.value;
21678 lhs1 = c_fully_fold (lhs1, false, NULL, true);
21679 if (lhs1 == error_mark_node)
21680 goto saw_error;
21681 if (!lvalue_p (unfolded_lhs1))
21682 lhs1 = non_lvalue (lhs1);
21684 if (structured_block)
21686 if (!no_semicolon)
21687 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
21688 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
21690 done:
21691 if (weak && opcode != COND_EXPR)
21693 error_at (loc, "%<weak%> clause requires atomic equality comparison");
21694 weak = false;
21696 if (unfolded_lhs && unfolded_lhs1
21697 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
21699 error ("%<#pragma omp atomic capture%> uses two different "
21700 "expressions for memory");
21701 stmt = error_mark_node;
21703 else
21704 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
21705 swapped, memory_order, weak);
21706 if (stmt != error_mark_node)
21707 add_stmt (stmt);
21709 if (!structured_block && !no_semicolon)
21710 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
21714 /* OpenMP 2.5:
21715 # pragma omp barrier new-line
21718 static void
21719 c_parser_omp_barrier (c_parser *parser)
21721 location_t loc = c_parser_peek_token (parser)->location;
21722 c_parser_consume_pragma (parser);
21723 c_parser_skip_to_pragma_eol (parser);
21725 c_finish_omp_barrier (loc);
21728 /* OpenMP 2.5:
21729 # pragma omp critical [(name)] new-line
21730 structured-block
21732 OpenMP 4.5:
21733 # pragma omp critical [(name) [hint(expression)]] new-line
21735 LOC is the location of the #pragma itself. */
21737 #define OMP_CRITICAL_CLAUSE_MASK \
21738 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
21740 static tree
21741 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
21743 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
21745 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21747 c_parser_consume_token (parser);
21748 if (c_parser_next_token_is (parser, CPP_NAME))
21750 name = c_parser_peek_token (parser)->value;
21751 c_parser_consume_token (parser);
21752 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
21754 else
21755 c_parser_error (parser, "expected identifier");
21757 if (c_parser_next_token_is (parser, CPP_COMMA)
21758 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
21759 c_parser_consume_token (parser);
21761 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
21762 "#pragma omp critical");
21763 stmt = c_parser_omp_structured_block (parser, if_p);
21764 return c_finish_omp_critical (loc, stmt, name, clauses);
21767 /* OpenMP 5.0:
21768 # pragma omp depobj ( depobj ) depobj-clause new-line
21770 depobj-clause:
21771 depend (dependence-type : locator)
21772 destroy
21773 update (dependence-type)
21775 OpenMP 5.2 additionally:
21776 destroy ( depobj )
21778 dependence-type:
21781 inout
21782 mutexinout */
21784 static void
21785 c_parser_omp_depobj (c_parser *parser)
21787 location_t loc = c_parser_peek_token (parser)->location;
21788 c_parser_consume_pragma (parser);
21789 matching_parens parens;
21790 if (!parens.require_open (parser))
21792 c_parser_skip_to_pragma_eol (parser);
21793 return;
21796 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
21797 if (depobj != error_mark_node)
21799 if (!lvalue_p (depobj))
21801 error_at (EXPR_LOC_OR_LOC (depobj, loc),
21802 "%<depobj%> expression is not lvalue expression");
21803 depobj = error_mark_node;
21805 else
21807 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
21808 depobj, false);
21809 if (addr == error_mark_node)
21810 depobj = error_mark_node;
21811 else
21812 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
21813 addr, RO_UNARY_STAR);
21817 parens.skip_until_found_close (parser);
21818 tree clause = NULL_TREE;
21819 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
21820 if (c_parser_next_token_is (parser, CPP_COMMA))
21821 c_parser_consume_token (parser);
21822 location_t c_loc = c_parser_peek_token (parser)->location;
21823 if (c_parser_next_token_is (parser, CPP_NAME))
21825 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21827 c_parser_consume_token (parser);
21828 if (!strcmp ("depend", p))
21830 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
21831 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
21832 if (!clause)
21833 clause = error_mark_node;
21835 else if (!strcmp ("destroy", p))
21837 matching_parens c_parens;
21838 kind = OMP_CLAUSE_DEPEND_LAST;
21839 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
21840 && c_parens.require_open (parser))
21842 tree destobj = c_parser_expr_no_commas (parser, NULL).value;
21843 if (!lvalue_p (destobj))
21844 error_at (EXPR_LOC_OR_LOC (destobj, c_loc),
21845 "%<destroy%> expression is not lvalue expression");
21846 else if (depobj != error_mark_node
21847 && !operand_equal_p (destobj, depobj,
21848 OEP_MATCH_SIDE_EFFECTS
21849 | OEP_LEXICOGRAPHIC))
21850 warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), OPT_Wopenmp,
21851 "the %<destroy%> expression %qE should be the same "
21852 "as the %<depobj%> argument %qE", destobj, depobj);
21853 c_parens.skip_until_found_close (parser);
21856 else if (!strcmp ("update", p))
21858 matching_parens c_parens;
21859 if (c_parens.require_open (parser))
21861 location_t c2_loc = c_parser_peek_token (parser)->location;
21862 if (c_parser_next_token_is (parser, CPP_NAME))
21864 const char *p2
21865 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21867 c_parser_consume_token (parser);
21868 if (!strcmp ("in", p2))
21869 kind = OMP_CLAUSE_DEPEND_IN;
21870 else if (!strcmp ("out", p2))
21871 kind = OMP_CLAUSE_DEPEND_OUT;
21872 else if (!strcmp ("inout", p2))
21873 kind = OMP_CLAUSE_DEPEND_INOUT;
21874 else if (!strcmp ("mutexinoutset", p2))
21875 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
21876 else if (!strcmp ("inoutset", p2))
21877 kind = OMP_CLAUSE_DEPEND_INOUTSET;
21879 if (kind == OMP_CLAUSE_DEPEND_INVALID)
21881 clause = error_mark_node;
21882 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
21883 "%<mutexinoutset%> or %<inoutset%>");
21885 c_parens.skip_until_found_close (parser);
21887 else
21888 clause = error_mark_node;
21891 if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
21893 clause = error_mark_node;
21894 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
21896 c_parser_skip_to_pragma_eol (parser);
21898 c_finish_omp_depobj (loc, depobj, kind, clause);
21902 /* OpenMP 2.5:
21903 # pragma omp flush flush-vars[opt] new-line
21905 flush-vars:
21906 ( variable-list )
21908 OpenMP 5.0:
21909 # pragma omp flush memory-order-clause new-line */
21911 static void
21912 c_parser_omp_flush (c_parser *parser)
21914 location_t loc = c_parser_peek_token (parser)->location;
21915 c_parser_consume_pragma (parser);
21916 enum memmodel mo = MEMMODEL_LAST;
21917 if (c_parser_next_token_is (parser, CPP_COMMA)
21918 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
21919 c_parser_consume_token (parser);
21920 if (c_parser_next_token_is (parser, CPP_NAME))
21922 const char *p
21923 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21925 if (!strcmp (p, "seq_cst"))
21926 mo = MEMMODEL_SEQ_CST;
21927 else if (!strcmp (p, "acq_rel"))
21928 mo = MEMMODEL_ACQ_REL;
21929 else if (!strcmp (p, "release"))
21930 mo = MEMMODEL_RELEASE;
21931 else if (!strcmp (p, "acquire"))
21932 mo = MEMMODEL_ACQUIRE;
21933 else
21934 error_at (c_parser_peek_token (parser)->location,
21935 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
21936 "%<acquire%>");
21937 c_parser_consume_token (parser);
21939 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21941 if (mo != MEMMODEL_LAST)
21942 error_at (c_parser_peek_token (parser)->location,
21943 "%<flush%> list specified together with memory order "
21944 "clause");
21945 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
21947 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21948 c_parser_error (parser, "expected %<(%> or end of line");
21949 c_parser_skip_to_pragma_eol (parser);
21951 c_finish_omp_flush (loc, mo);
21954 /* Return true if next tokens contain a standard attribute that contains
21955 omp::directive (DIRECTIVE). */
21957 static bool
21958 c_parser_omp_section_scan (c_parser *parser, const char *directive,
21959 bool tentative)
21961 if (!c_parser_nth_token_starts_std_attributes (parser, 1))
21962 return false;
21963 unsigned int n = 3;
21964 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
21965 return false;
21966 c_token *token = c_parser_peek_nth_token_raw (parser, n);
21967 if (token->type != CPP_CLOSE_SQUARE)
21968 return false;
21969 token = c_parser_peek_nth_token_raw (parser, n + 1);
21970 if (token->type != CPP_CLOSE_SQUARE)
21971 return false;
21972 if (n < 9)
21973 return false;
21974 if (c_parser_peek_nth_token_raw (parser, 3)->type == CPP_NAME
21975 && c_parser_peek_nth_token_raw (parser, 4)->type == CPP_OPEN_PAREN
21976 && c_parser_peek_nth_token_raw (parser, 5)->type == CPP_NAME)
21978 tree first = c_parser_peek_nth_token_raw (parser, 3)->value;
21979 tree second = c_parser_peek_nth_token_raw (parser, 5)->value;
21980 if (strcmp (IDENTIFIER_POINTER (first), "directive")
21981 && strcmp (IDENTIFIER_POINTER (first), "__directive__"))
21982 return false;
21983 if (strcmp (IDENTIFIER_POINTER (second), directive))
21984 return false;
21986 if (tentative)
21987 return true;
21988 location_t first_loc = c_parser_peek_token (parser)->location;
21989 location_t last_loc = c_parser_peek_nth_token_raw (parser, n + 1)->location;
21990 location_t middle_loc = UNKNOWN_LOCATION;
21991 tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
21992 bool seen = false;
21993 int cnt = 0;
21994 for (tree attr = std_attrs; attr; attr = TREE_CHAIN (attr))
21995 if (is_attribute_namespace_p ("omp", attr)
21996 && is_attribute_p ("directive", get_attribute_name (attr)))
21998 for (tree a = TREE_VALUE (attr); a; a = TREE_CHAIN (a))
22000 tree d = TREE_VALUE (a);
22001 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
22002 c_token *first = C_TOKEN_VEC_TOKENS (d)->address ();
22003 cnt++;
22004 if (first->type == CPP_NAME
22005 && strcmp (IDENTIFIER_POINTER (first->value),
22006 directive) == 0)
22008 seen = true;
22009 if (middle_loc == UNKNOWN_LOCATION)
22010 middle_loc = first->location;
22014 if (!seen)
22015 return false;
22016 if (cnt != 1 || TREE_CHAIN (std_attrs))
22018 error_at (make_location (first_loc, last_loc, middle_loc),
22019 "%<[[omp::directive(%s)]]%> must be the only specified "
22020 "attribute on a statement", directive);
22021 return false;
22023 c_parser_handle_statement_omp_attributes (parser, std_attrs, NULL);
22024 return true;
22027 /* Parse an OpenMP structured block sequence. KIND is the corresponding
22028 separating directive. */
22030 static tree
22031 c_parser_omp_structured_block_sequence (c_parser *parser,
22032 enum pragma_kind kind)
22034 tree stmt = push_stmt_list ();
22035 c_parser_statement (parser, NULL);
22038 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
22039 break;
22040 if (c_parser_next_token_is (parser, CPP_EOF))
22041 break;
22043 if (kind != PRAGMA_NONE
22044 && c_parser_peek_token (parser)->pragma_kind == kind)
22045 break;
22047 if (kind != PRAGMA_NONE
22048 && c_parser_omp_section_scan (parser,
22049 kind == PRAGMA_OMP_SCAN
22050 ? "scan" : "section", false))
22051 break;
22053 c_parser_statement (parser, NULL);
22055 while (1);
22056 return pop_stmt_list (stmt);
22059 /* OpenMP 5.0:
22061 scan-loop-body:
22062 { structured-block scan-directive structured-block } */
22064 static void
22065 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
22067 tree substmt;
22068 location_t loc;
22069 tree clauses = NULL_TREE;
22070 bool found_scan = false;
22072 loc = c_parser_peek_token (parser)->location;
22073 if (!open_brace_parsed
22074 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
22076 /* Avoid skipping until the end of the block. */
22077 parser->error = false;
22078 return;
22081 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SCAN)
22082 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
22083 else
22085 warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
22086 "%<#pragma omp scan%> with zero preceding executable "
22087 "statements");
22088 substmt = build_empty_stmt (loc);
22090 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
22091 SET_EXPR_LOCATION (substmt, loc);
22092 add_stmt (substmt);
22094 loc = c_parser_peek_token (parser)->location;
22095 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
22097 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
22098 found_scan = true;
22100 c_parser_consume_pragma (parser);
22102 if (c_parser_next_token_is (parser, CPP_COMMA))
22103 c_parser_consume_token (parser);
22105 if (c_parser_next_token_is (parser, CPP_NAME))
22107 const char *p
22108 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22109 if (strcmp (p, "inclusive") == 0)
22110 clause = OMP_CLAUSE_INCLUSIVE;
22111 else if (strcmp (p, "exclusive") == 0)
22112 clause = OMP_CLAUSE_EXCLUSIVE;
22114 if (clause != OMP_CLAUSE_ERROR)
22116 c_parser_consume_token (parser);
22117 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
22119 else
22120 c_parser_error (parser, "expected %<inclusive%> or "
22121 "%<exclusive%> clause");
22122 c_parser_skip_to_pragma_eol (parser);
22124 else
22125 error ("expected %<#pragma omp scan%>");
22127 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22128 if (!c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
22129 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
22130 else
22132 if (found_scan)
22133 warning_at (loc, OPT_Wopenmp,
22134 "%<#pragma omp scan%> with zero succeeding executable "
22135 "statements");
22136 substmt = build_empty_stmt (loc);
22138 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
22139 SET_EXPR_LOCATION (substmt, loc);
22140 add_stmt (substmt);
22142 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
22143 "expected %<}%>");
22147 /* This function parses a single level of a loop nest, invoking itself
22148 recursively if necessary.
22150 loop-nest :: for (...) loop-body
22151 loop-body :: loop-nest
22152 | { [intervening-code] loop-body [intervening-code] }
22153 | final-loop-body
22154 intervening-code :: structured-block-sequence
22155 final-loop-body :: structured-block
22157 For a collapsed loop nest, only a single OMP_FOR is built, pulling out
22158 all the iterator information from the inner loops into the
22159 parser->omp_for_parse_state structure.
22161 The iterator decl, init, cond, and incr are stored in vectors.
22163 Initialization code for iterator variables is collected into
22164 parser->omp_for_parse_state->pre_body and ends up inserted directly
22165 into the OMP_FOR structure. */
22167 static tree
22168 c_parser_omp_loop_nest (c_parser *parser, bool *if_p)
22170 tree decl, cond, incr, init;
22171 tree body = NULL_TREE;
22172 matching_parens parens;
22173 bool moreloops;
22174 unsigned char save_in_statement;
22175 tree loop_scope;
22176 location_t loc;
22177 struct omp_for_parse_data *omp_for_parse_state
22178 = parser->omp_for_parse_state;
22179 gcc_assert (omp_for_parse_state);
22180 int depth = omp_for_parse_state->depth;
22182 /* We have already matched the FOR token but not consumed it yet. */
22183 loc = c_parser_peek_token (parser)->location;
22184 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
22185 c_parser_consume_token (parser);
22187 /* Forbid break/continue in the loop initializer, condition, and
22188 increment expressions. */
22189 save_in_statement = in_statement;
22190 in_statement = IN_OMP_BLOCK;
22192 /* We are not in intervening code now. */
22193 omp_for_parse_state->in_intervening_code = false;
22195 if (!parens.require_open (parser))
22197 omp_for_parse_state->fail = true;
22198 return NULL_TREE;
22201 /* An implicit scope block surrounds each level of FOR loop, for
22202 declarations of iteration variables at this loop depth. */
22203 loop_scope = c_begin_compound_stmt (true);
22205 /* Parse the initialization declaration or expression. */
22206 if (c_parser_next_tokens_start_declaration (parser))
22208 /* This is a declaration, which must be added to the pre_body code. */
22209 tree this_pre_body = push_stmt_list ();
22210 c_in_omp_for = true;
22211 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
22212 c_in_omp_for = false;
22213 this_pre_body = pop_stmt_list (this_pre_body);
22214 append_to_statement_list_force (this_pre_body,
22215 &(omp_for_parse_state->pre_body));
22216 decl = check_for_loop_decls (omp_for_parse_state->for_loc, flag_isoc99);
22217 if (decl == NULL)
22218 goto error_init;
22219 if (DECL_INITIAL (decl) == error_mark_node)
22220 decl = error_mark_node;
22221 init = decl;
22223 else if (c_parser_next_token_is (parser, CPP_NAME)
22224 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
22226 struct c_expr decl_exp;
22227 struct c_expr init_exp;
22228 location_t init_loc;
22230 decl_exp = c_parser_postfix_expression (parser);
22231 decl = decl_exp.value;
22233 c_parser_require (parser, CPP_EQ, "expected %<=%>");
22235 init_loc = c_parser_peek_token (parser)->location;
22236 init_exp = c_parser_expr_no_commas (parser, NULL);
22237 init_exp = default_function_array_read_conversion (init_loc,
22238 init_exp);
22239 c_in_omp_for = true;
22240 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
22241 NOP_EXPR, init_loc, init_exp.value,
22242 init_exp.original_type);
22243 c_in_omp_for = false;
22244 init = c_process_expr_stmt (init_loc, init);
22246 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
22248 else
22250 error_init:
22251 c_parser_error (parser,
22252 "expected iteration declaration or initialization");
22253 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
22254 "expected %<)%>");
22255 omp_for_parse_state->fail = true;
22256 goto parse_next;
22259 /* Parse the loop condition. */
22260 cond = NULL_TREE;
22261 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
22263 location_t cond_loc = c_parser_peek_token (parser)->location;
22264 c_in_omp_for = true;
22265 struct c_expr cond_expr
22266 = c_parser_binary_expression (parser, NULL, NULL_TREE);
22267 c_in_omp_for = false;
22269 cond = cond_expr.value;
22270 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
22271 switch (cond_expr.original_code)
22273 case GT_EXPR:
22274 case GE_EXPR:
22275 case LT_EXPR:
22276 case LE_EXPR:
22277 break;
22278 case NE_EXPR:
22279 if (omp_for_parse_state->code != OACC_LOOP)
22280 break;
22281 /* FALLTHRU. */
22282 default:
22283 /* Can't be cond = error_mark_node, because we want to preserve
22284 the location until c_finish_omp_for. */
22285 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
22286 break;
22288 protected_set_expr_location (cond, cond_loc);
22290 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
22292 /* Parse the increment expression. */
22293 incr = NULL_TREE;
22294 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
22296 location_t incr_loc = c_parser_peek_token (parser)->location;
22298 incr = c_process_expr_stmt (incr_loc,
22299 c_parser_expression (parser).value);
22301 parens.skip_until_found_close (parser);
22303 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
22304 omp_for_parse_state->fail = true;
22305 else
22307 TREE_VEC_ELT (omp_for_parse_state->declv, depth) = decl;
22308 TREE_VEC_ELT (omp_for_parse_state->initv, depth) = init;
22309 TREE_VEC_ELT (omp_for_parse_state->condv, depth) = cond;
22310 TREE_VEC_ELT (omp_for_parse_state->incrv, depth) = incr;
22313 parse_next:
22314 moreloops = depth < omp_for_parse_state->count - 1;
22315 omp_for_parse_state->want_nested_loop = moreloops;
22316 if (moreloops && c_parser_next_token_is_keyword (parser, RID_FOR))
22318 omp_for_parse_state->depth++;
22319 body = c_parser_omp_loop_nest (parser, if_p);
22320 omp_for_parse_state->depth--;
22322 else if (moreloops && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
22324 /* This is the open brace in the loop-body grammar production. Rather
22325 than trying to special-case braces, just parse it as a compound
22326 statement and handle the nested loop-body case there. Note that
22327 when we see a further open brace inside the compound statement
22328 loop-body, we don't know whether it is the start of intervening
22329 code that is a compound statement, or a level of braces
22330 surrounding a nested loop-body. Use the WANT_NESTED_LOOP state
22331 bit to ensure we have only one nested loop at each level. */
22332 omp_for_parse_state->in_intervening_code = true;
22333 body = c_parser_compound_statement (parser, NULL);
22334 omp_for_parse_state->in_intervening_code = false;
22335 if (omp_for_parse_state->want_nested_loop)
22337 /* We have already parsed the whole loop body and not found a
22338 nested loop. */
22339 error_at (omp_for_parse_state->for_loc,
22340 "not enough nested loops");
22341 omp_for_parse_state->fail = true;
22343 if_p = NULL;
22345 else
22347 /* This is the final-loop-body case in the grammar: we have
22348 something that is not a FOR and not an open brace. */
22349 if (moreloops)
22351 /* If we were expecting a nested loop, give an error and mark
22352 that parsing has failed, and try to recover by parsing the
22353 body as regular code without further collapsing. */
22354 error_at (omp_for_parse_state->for_loc,
22355 "not enough nested loops");
22356 omp_for_parse_state->fail = true;
22358 in_statement = IN_OMP_FOR;
22359 parser->omp_for_parse_state = NULL;
22360 body = push_stmt_list ();
22361 if (omp_for_parse_state->inscan)
22362 c_parser_omp_scan_loop_body (parser, false);
22363 else
22364 add_stmt (c_parser_c99_block_statement (parser, if_p));
22365 body = pop_stmt_list (body);
22366 parser->omp_for_parse_state = omp_for_parse_state;
22368 in_statement = save_in_statement;
22369 omp_for_parse_state->want_nested_loop = false;
22370 omp_for_parse_state->in_intervening_code = true;
22372 /* Pop and return the implicit scope surrounding this level of loop.
22373 If the iteration variable at this depth was bound in the for loop,
22374 pull out and save the binding. Later in c_parser_omp_for_loop,
22375 these bindings will be moved to the scope surrounding the entire
22376 OMP_FOR. That keeps the gimplifier happy later on, and meanwhile
22377 we have already resolved all references to the iteration variable
22378 in its true scope. */
22379 add_stmt (body);
22380 body = c_end_compound_stmt (loc, loop_scope, true);
22381 if (decl && TREE_CODE (body) == BIND_EXPR)
22383 tree t = BIND_EXPR_VARS (body);
22384 tree prev = NULL_TREE, next = NULL_TREE;
22385 while (t)
22387 next = DECL_CHAIN (t);
22388 if (t == decl)
22390 if (prev)
22391 DECL_CHAIN (prev) = next;
22392 else
22394 BIND_EXPR_VARS (body) = next;
22395 BLOCK_VARS (BIND_EXPR_BLOCK (body)) = next;
22397 DECL_CHAIN (t) = omp_for_parse_state->bindings;
22398 omp_for_parse_state->bindings = t;
22399 break;
22401 else
22403 prev = t;
22404 t = next;
22407 if (BIND_EXPR_VARS (body) == NULL_TREE)
22408 body = BIND_EXPR_BODY (body);
22411 return body;
22414 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
22415 The real trick here is to determine the loop control variable early
22416 so that we can push a new decl if necessary to make it private.
22417 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
22418 respectively. */
22420 static tree
22421 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
22422 tree clauses, tree *cclauses, bool *if_p)
22424 tree body, stmt, cl;
22425 tree ret = NULL_TREE;
22426 tree ordered_cl = NULL_TREE;
22427 int i, collapse = 1, ordered = 0, count;
22428 bool tiling = false;
22429 bool inscan = false;
22430 struct omp_for_parse_data data;
22431 struct omp_for_parse_data *save_data = parser->omp_for_parse_state;
22433 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
22434 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
22435 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
22436 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
22438 tiling = true;
22439 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
22441 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
22442 && OMP_CLAUSE_ORDERED_EXPR (cl))
22444 ordered_cl = cl;
22445 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
22447 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
22448 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
22449 && (code == OMP_SIMD || code == OMP_FOR))
22450 inscan = true;
22452 if (ordered && ordered < collapse)
22454 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
22455 "%<ordered%> clause parameter is less than %<collapse%>");
22456 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
22457 = build_int_cst (NULL_TREE, collapse);
22458 ordered = collapse;
22461 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
22462 count = ordered ? ordered : collapse;
22464 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
22466 c_parser_error (parser, "for statement expected");
22467 return NULL;
22470 /* Initialize parse state for recursive descent. */
22471 data.declv = make_tree_vec (count);
22472 data.initv = make_tree_vec (count);
22473 data.condv = make_tree_vec (count);
22474 data.incrv = make_tree_vec (count);
22475 data.pre_body = NULL_TREE;;
22476 data.bindings = NULL_TREE;
22477 data.for_loc = c_parser_peek_token (parser)->location;
22478 data.count = count;
22479 data.depth = 0;
22480 data.want_nested_loop = true;
22481 data.ordered = ordered > 0;
22482 data.in_intervening_code = false;
22483 data.perfect_nesting_fail = false;
22484 data.fail = false;
22485 data.inscan = inscan;
22486 data.saw_intervening_code = false;
22487 data.code = code;
22488 parser->omp_for_parse_state = &data;
22490 body = c_parser_omp_loop_nest (parser, if_p);
22492 /* Add saved bindings for iteration variables that were declared in
22493 the nested for loop to the scope surrounding the entire loop. */
22494 for (tree t = data.bindings; t; )
22496 tree n = TREE_CHAIN (t);
22497 TREE_CHAIN (t) = NULL_TREE;
22498 pushdecl (t);
22499 t = n;
22502 /* Only bother calling c_finish_omp_for if we haven't already generated
22503 an error from the initialization parsing. */
22504 if (!data.fail)
22506 c_in_omp_for = true;
22507 stmt = c_finish_omp_for (loc, code, data.declv, NULL, data.initv,
22508 data.condv, data.incrv,
22509 body, data.pre_body, true);
22510 c_in_omp_for = false;
22512 /* Check for iterators appearing in lb, b or incr expressions. */
22513 if (stmt && !c_omp_check_loop_iv (stmt, data.declv, NULL))
22514 stmt = NULL_TREE;
22516 /* Check for errors involving lb/ub/incr expressions referencing
22517 variables declared in intervening code. */
22518 if (data.saw_intervening_code
22519 && !c_omp_check_loop_binding_exprs (stmt, NULL))
22520 stmt = NULL_TREE;
22522 if (stmt)
22524 add_stmt (stmt);
22526 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
22528 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
22529 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
22530 tree decl = TREE_OPERAND (init, 0);
22531 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
22532 gcc_assert (COMPARISON_CLASS_P (cond));
22533 gcc_assert (TREE_OPERAND (cond, 0) == decl);
22535 tree op0 = TREE_OPERAND (init, 1);
22536 if (!OMP_FOR_NON_RECTANGULAR (stmt)
22537 || TREE_CODE (op0) != TREE_VEC)
22538 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
22539 else
22541 TREE_VEC_ELT (op0, 1)
22542 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
22543 TREE_VEC_ELT (op0, 2)
22544 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
22547 tree op1 = TREE_OPERAND (cond, 1);
22548 if (!OMP_FOR_NON_RECTANGULAR (stmt)
22549 || TREE_CODE (op1) != TREE_VEC)
22550 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
22551 else
22553 TREE_VEC_ELT (op1, 1)
22554 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
22555 TREE_VEC_ELT (op1, 2)
22556 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
22560 if (cclauses != NULL
22561 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
22563 tree *c;
22564 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
22565 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
22566 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
22567 c = &OMP_CLAUSE_CHAIN (*c);
22568 else
22570 for (i = 0; i < count; i++)
22571 if (TREE_VEC_ELT (data.declv, i) == OMP_CLAUSE_DECL (*c))
22572 break;
22573 if (i == count)
22574 c = &OMP_CLAUSE_CHAIN (*c);
22575 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
22577 error_at (loc,
22578 "iteration variable %qD should not be firstprivate",
22579 OMP_CLAUSE_DECL (*c));
22580 *c = OMP_CLAUSE_CHAIN (*c);
22582 else
22584 /* Move lastprivate (decl) clause to
22585 OMP_FOR_CLAUSES. */
22586 tree l = *c;
22587 *c = OMP_CLAUSE_CHAIN (*c);
22588 if (code == OMP_SIMD)
22590 OMP_CLAUSE_CHAIN (l)
22591 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
22592 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
22594 else
22596 OMP_CLAUSE_CHAIN (l) = clauses;
22597 clauses = l;
22602 OMP_FOR_CLAUSES (stmt) = clauses;
22604 ret = stmt;
22607 parser->omp_for_parse_state = save_data;
22608 return ret;
22611 /* Helper function for OpenMP parsing, split clauses and call
22612 finish_omp_clauses on each of the set of clauses afterwards. */
22614 static void
22615 omp_split_clauses (location_t loc, enum tree_code code,
22616 omp_clause_mask mask, tree clauses, tree *cclauses)
22618 int i;
22619 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
22620 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
22621 if (cclauses[i])
22622 cclauses[i] = c_finish_omp_clauses (cclauses[i],
22623 i == C_OMP_CLAUSE_SPLIT_TARGET
22624 ? C_ORT_OMP_TARGET : C_ORT_OMP);
22627 /* OpenMP 5.0:
22628 #pragma omp loop loop-clause[optseq] new-line
22629 for-loop
22631 LOC is the location of the #pragma token.
22634 #define OMP_LOOP_CLAUSE_MASK \
22635 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
22640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22642 static tree
22643 c_parser_omp_loop (location_t loc, c_parser *parser,
22644 char *p_name, omp_clause_mask mask, tree *cclauses,
22645 bool *if_p)
22647 tree block, clauses, ret;
22649 strcat (p_name, " loop");
22650 mask |= OMP_LOOP_CLAUSE_MASK;
22652 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22653 if (cclauses)
22655 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
22656 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
22659 block = c_begin_compound_stmt (true);
22660 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
22661 block = c_end_compound_stmt (loc, block, true);
22662 add_stmt (block);
22664 return ret;
22667 /* OpenMP 4.0:
22668 #pragma omp simd simd-clause[optseq] new-line
22669 for-loop
22671 LOC is the location of the #pragma token.
22674 #define OMP_SIMD_CLAUSE_MASK \
22675 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
22676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
22677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
22679 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22680 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22683 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22684 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
22685 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22687 static tree
22688 c_parser_omp_simd (location_t loc, c_parser *parser,
22689 char *p_name, omp_clause_mask mask, tree *cclauses,
22690 bool *if_p)
22692 tree block, clauses, ret;
22694 strcat (p_name, " simd");
22695 mask |= OMP_SIMD_CLAUSE_MASK;
22697 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22698 if (cclauses)
22700 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
22701 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
22704 block = c_begin_compound_stmt (true);
22705 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
22706 block = c_end_compound_stmt (loc, block, true);
22707 add_stmt (block);
22709 return ret;
22712 /* OpenMP 2.5:
22713 #pragma omp for for-clause[optseq] new-line
22714 for-loop
22716 OpenMP 4.0:
22717 #pragma omp for simd for-simd-clause[optseq] new-line
22718 for-loop
22720 LOC is the location of the #pragma token.
22723 #define OMP_FOR_CLAUSE_MASK \
22724 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22728 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22729 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
22730 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
22731 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22732 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
22733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22736 static tree
22737 c_parser_omp_for (location_t loc, c_parser *parser,
22738 char *p_name, omp_clause_mask mask, tree *cclauses,
22739 bool *if_p)
22741 tree block, clauses, ret;
22743 strcat (p_name, " for");
22744 mask |= OMP_FOR_CLAUSE_MASK;
22745 /* parallel for{, simd} disallows nowait clause, but for
22746 target {teams distribute ,}parallel for{, simd} it should be accepted. */
22747 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
22748 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
22749 /* Composite distribute parallel for{, simd} disallows ordered clause. */
22750 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
22751 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
22753 if (c_parser_next_token_is (parser, CPP_NAME))
22755 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22757 if (strcmp (p, "simd") == 0)
22759 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22760 if (cclauses == NULL)
22761 cclauses = cclauses_buf;
22763 c_parser_consume_token (parser);
22764 if (!flag_openmp) /* flag_openmp_simd */
22765 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22766 if_p);
22767 block = c_begin_compound_stmt (true);
22768 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22769 block = c_end_compound_stmt (loc, block, true);
22770 if (ret == NULL_TREE)
22771 return ret;
22772 ret = make_node (OMP_FOR);
22773 TREE_TYPE (ret) = void_type_node;
22774 OMP_FOR_BODY (ret) = block;
22775 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
22776 SET_EXPR_LOCATION (ret, loc);
22777 add_stmt (ret);
22778 return ret;
22781 if (!flag_openmp) /* flag_openmp_simd */
22783 c_parser_skip_to_pragma_eol (parser, false);
22784 return NULL_TREE;
22787 /* Composite distribute parallel for disallows linear clause. */
22788 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
22789 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
22791 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22792 if (cclauses)
22794 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
22795 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
22798 block = c_begin_compound_stmt (true);
22799 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
22800 block = c_end_compound_stmt (loc, block, true);
22801 add_stmt (block);
22803 return ret;
22806 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
22807 omp_clause_mask, tree *, bool *);
22809 /* OpenMP 2.5:
22810 # pragma omp master new-line
22811 structured-block
22813 LOC is the location of the #pragma token.
22816 static tree
22817 c_parser_omp_master (location_t loc, c_parser *parser,
22818 char *p_name, omp_clause_mask mask, tree *cclauses,
22819 bool *if_p)
22821 tree block, clauses, ret;
22823 strcat (p_name, " master");
22825 if (c_parser_next_token_is (parser, CPP_NAME))
22827 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22829 if (strcmp (p, "taskloop") == 0)
22831 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22832 if (cclauses == NULL)
22833 cclauses = cclauses_buf;
22835 c_parser_consume_token (parser);
22836 if (!flag_openmp) /* flag_openmp_simd */
22837 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22838 if_p);
22839 block = c_begin_compound_stmt (true);
22840 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22841 if_p);
22842 block = c_end_compound_stmt (loc, block, true);
22843 if (ret == NULL_TREE)
22844 return ret;
22845 ret = c_finish_omp_master (loc, block);
22846 OMP_MASTER_COMBINED (ret) = 1;
22847 return ret;
22850 if (!flag_openmp) /* flag_openmp_simd */
22852 c_parser_skip_to_pragma_eol (parser, false);
22853 return NULL_TREE;
22856 if (cclauses)
22858 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
22859 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
22861 else
22862 c_parser_skip_to_pragma_eol (parser);
22864 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
22865 if_p));
22868 /* OpenMP 5.1:
22869 # pragma omp masked masked-clauses new-line
22870 structured-block
22872 LOC is the location of the #pragma token.
22875 #define OMP_MASKED_CLAUSE_MASK \
22876 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
22878 static tree
22879 c_parser_omp_masked (location_t loc, c_parser *parser,
22880 char *p_name, omp_clause_mask mask, tree *cclauses,
22881 bool *if_p)
22883 tree block, clauses, ret;
22885 strcat (p_name, " masked");
22886 mask |= OMP_MASKED_CLAUSE_MASK;
22888 if (c_parser_next_token_is (parser, CPP_NAME))
22890 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22892 if (strcmp (p, "taskloop") == 0)
22894 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22895 if (cclauses == NULL)
22896 cclauses = cclauses_buf;
22898 c_parser_consume_token (parser);
22899 if (!flag_openmp) /* flag_openmp_simd */
22900 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22901 if_p);
22902 block = c_begin_compound_stmt (true);
22903 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
22904 if_p);
22905 block = c_end_compound_stmt (loc, block, true);
22906 if (ret == NULL_TREE)
22907 return ret;
22908 ret = c_finish_omp_masked (loc, block,
22909 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
22910 OMP_MASKED_COMBINED (ret) = 1;
22911 return ret;
22914 if (!flag_openmp) /* flag_openmp_simd */
22916 c_parser_skip_to_pragma_eol (parser, false);
22917 return NULL_TREE;
22920 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22921 if (cclauses)
22923 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
22924 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
22927 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
22928 if_p),
22929 clauses);
22932 /* OpenMP 2.5:
22933 # pragma omp ordered new-line
22934 structured-block
22936 OpenMP 4.5:
22937 # pragma omp ordered ordered-clauses new-line
22938 structured-block
22940 # pragma omp ordered depend-clauses new-line
22942 OpenMP 5.2
22943 # pragma omp ordered doacross-clauses new-line */
22945 #define OMP_ORDERED_CLAUSE_MASK \
22946 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
22947 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
22949 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
22950 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
22951 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
22953 static bool
22954 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
22955 bool *if_p)
22957 location_t loc = c_parser_peek_token (parser)->location;
22958 c_parser_consume_pragma (parser);
22960 if (context != pragma_stmt && context != pragma_compound)
22962 c_parser_error (parser, "expected declaration specifiers");
22963 c_parser_skip_to_pragma_eol (parser, false);
22964 return false;
22967 int n = 1;
22968 if (c_parser_next_token_is (parser, CPP_COMMA))
22969 n = 2;
22971 if (c_parser_peek_nth_token (parser, n)->type == CPP_NAME)
22973 const char *p
22974 = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser, n)->value);
22976 if (!strcmp ("depend", p) || !strcmp ("doacross", p))
22978 if (!flag_openmp) /* flag_openmp_simd */
22980 c_parser_skip_to_pragma_eol (parser, false);
22981 return false;
22983 if (context == pragma_stmt)
22985 error_at (loc,
22986 "%<#pragma omp ordered%> with %qs clause may "
22987 "only be used in compound statements", p);
22988 c_parser_skip_to_pragma_eol (parser, false);
22989 return true;
22992 tree clauses
22993 = c_parser_omp_all_clauses (parser,
22994 OMP_ORDERED_DEPEND_CLAUSE_MASK,
22995 "#pragma omp ordered");
22996 c_finish_omp_ordered (loc, clauses, NULL_TREE);
22997 return false;
23001 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
23002 "#pragma omp ordered");
23004 if (!flag_openmp /* flag_openmp_simd */
23005 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
23006 return false;
23008 c_finish_omp_ordered (loc, clauses,
23009 c_parser_omp_structured_block (parser, if_p));
23010 return true;
23013 /* OpenMP 2.5:
23015 section-scope:
23016 { section-sequence }
23018 section-sequence:
23019 section-directive[opt] structured-block
23020 section-sequence section-directive structured-block
23022 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
23024 SECTIONS_LOC is the location of the #pragma omp sections. */
23026 static tree
23027 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
23029 tree stmt, substmt;
23030 bool error_suppress = false;
23031 location_t loc;
23033 loc = c_parser_peek_token (parser)->location;
23034 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23036 /* Avoid skipping until the end of the block. */
23037 parser->error = false;
23038 return NULL_TREE;
23041 stmt = push_stmt_list ();
23043 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION
23044 && !c_parser_omp_section_scan (parser, "section", true))
23046 substmt = c_parser_omp_structured_block_sequence (parser,
23047 PRAGMA_OMP_SECTION);
23048 substmt = build1 (OMP_SECTION, void_type_node, substmt);
23049 SET_EXPR_LOCATION (substmt, loc);
23050 add_stmt (substmt);
23053 while (1)
23055 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
23056 break;
23057 if (c_parser_next_token_is (parser, CPP_EOF))
23058 break;
23060 loc = c_parser_peek_token (parser)->location;
23061 c_parser_omp_section_scan (parser, "section", false);
23062 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
23064 c_parser_consume_pragma (parser);
23065 c_parser_skip_to_pragma_eol (parser);
23066 error_suppress = false;
23068 else if (!error_suppress)
23070 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
23071 error_suppress = true;
23074 substmt = c_parser_omp_structured_block_sequence (parser,
23075 PRAGMA_OMP_SECTION);
23076 substmt = build1 (OMP_SECTION, void_type_node, substmt);
23077 SET_EXPR_LOCATION (substmt, loc);
23078 add_stmt (substmt);
23080 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
23081 "expected %<#pragma omp section%> or %<}%>");
23083 substmt = pop_stmt_list (stmt);
23085 stmt = make_node (OMP_SECTIONS);
23086 SET_EXPR_LOCATION (stmt, sections_loc);
23087 TREE_TYPE (stmt) = void_type_node;
23088 OMP_SECTIONS_BODY (stmt) = substmt;
23090 return add_stmt (stmt);
23093 /* OpenMP 2.5:
23094 # pragma omp sections sections-clause[optseq] newline
23095 sections-scope
23097 LOC is the location of the #pragma token.
23100 #define OMP_SECTIONS_CLAUSE_MASK \
23101 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23102 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23103 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23104 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23105 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23106 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23108 static tree
23109 c_parser_omp_sections (location_t loc, c_parser *parser,
23110 char *p_name, omp_clause_mask mask, tree *cclauses)
23112 tree block, clauses, ret;
23114 strcat (p_name, " sections");
23115 mask |= OMP_SECTIONS_CLAUSE_MASK;
23116 if (cclauses)
23117 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
23119 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23120 if (cclauses)
23122 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
23123 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
23126 block = c_begin_compound_stmt (true);
23127 ret = c_parser_omp_sections_scope (loc, parser);
23128 if (ret)
23129 OMP_SECTIONS_CLAUSES (ret) = clauses;
23130 block = c_end_compound_stmt (loc, block, true);
23131 add_stmt (block);
23133 return ret;
23136 /* OpenMP 2.5:
23137 # pragma omp parallel parallel-clause[optseq] new-line
23138 structured-block
23139 # pragma omp parallel for parallel-for-clause[optseq] new-line
23140 structured-block
23141 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
23142 structured-block
23144 OpenMP 4.0:
23145 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
23146 structured-block
23148 LOC is the location of the #pragma token.
23151 #define OMP_PARALLEL_CLAUSE_MASK \
23152 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
23158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
23160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
23163 static tree
23164 c_parser_omp_parallel (location_t loc, c_parser *parser,
23165 char *p_name, omp_clause_mask mask, tree *cclauses,
23166 bool *if_p)
23168 tree stmt, clauses, block;
23170 strcat (p_name, " parallel");
23171 mask |= OMP_PARALLEL_CLAUSE_MASK;
23172 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
23173 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
23174 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
23175 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
23177 if (c_parser_next_token_is_keyword (parser, RID_FOR))
23179 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23180 if (cclauses == NULL)
23181 cclauses = cclauses_buf;
23183 c_parser_consume_token (parser);
23184 if (!flag_openmp) /* flag_openmp_simd */
23185 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
23186 block = c_begin_omp_parallel ();
23187 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
23188 stmt
23189 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23190 block);
23191 if (ret == NULL_TREE)
23192 return ret;
23193 OMP_PARALLEL_COMBINED (stmt) = 1;
23194 return stmt;
23196 /* When combined with distribute, parallel has to be followed by for.
23197 #pragma omp target parallel is allowed though. */
23198 else if (cclauses
23199 && (mask & (OMP_CLAUSE_MASK_1
23200 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
23202 error_at (loc, "expected %<for%> after %qs", p_name);
23203 c_parser_skip_to_pragma_eol (parser);
23204 return NULL_TREE;
23206 else if (c_parser_next_token_is (parser, CPP_NAME))
23208 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23209 if (cclauses == NULL && strcmp (p, "masked") == 0)
23211 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23212 cclauses = cclauses_buf;
23214 c_parser_consume_token (parser);
23215 if (!flag_openmp) /* flag_openmp_simd */
23216 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
23217 if_p);
23218 block = c_begin_omp_parallel ();
23219 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
23220 if_p);
23221 stmt = c_finish_omp_parallel (loc,
23222 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23223 block);
23224 if (ret == NULL)
23225 return ret;
23226 /* masked does have just filter clause, but during gimplification
23227 isn't represented by a gimplification omp context, so for
23228 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
23229 so that
23230 #pragma omp parallel masked
23231 #pragma omp taskloop simd lastprivate (x)
23232 isn't confused with
23233 #pragma omp parallel masked taskloop simd lastprivate (x) */
23234 if (OMP_MASKED_COMBINED (ret))
23235 OMP_PARALLEL_COMBINED (stmt) = 1;
23236 return stmt;
23238 else if (cclauses == NULL && strcmp (p, "master") == 0)
23240 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23241 cclauses = cclauses_buf;
23243 c_parser_consume_token (parser);
23244 if (!flag_openmp) /* flag_openmp_simd */
23245 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
23246 if_p);
23247 block = c_begin_omp_parallel ();
23248 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
23249 if_p);
23250 stmt = c_finish_omp_parallel (loc,
23251 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23252 block);
23253 if (ret == NULL)
23254 return ret;
23255 /* master doesn't have any clauses and during gimplification
23256 isn't represented by a gimplification omp context, so for
23257 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
23258 so that
23259 #pragma omp parallel master
23260 #pragma omp taskloop simd lastprivate (x)
23261 isn't confused with
23262 #pragma omp parallel master taskloop simd lastprivate (x) */
23263 if (OMP_MASTER_COMBINED (ret))
23264 OMP_PARALLEL_COMBINED (stmt) = 1;
23265 return stmt;
23267 else if (strcmp (p, "loop") == 0)
23269 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23270 if (cclauses == NULL)
23271 cclauses = cclauses_buf;
23273 c_parser_consume_token (parser);
23274 if (!flag_openmp) /* flag_openmp_simd */
23275 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23276 if_p);
23277 block = c_begin_omp_parallel ();
23278 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23279 if_p);
23280 stmt
23281 = c_finish_omp_parallel (loc,
23282 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23283 block);
23284 if (ret == NULL_TREE)
23285 return ret;
23286 OMP_PARALLEL_COMBINED (stmt) = 1;
23287 return stmt;
23289 else if (!flag_openmp) /* flag_openmp_simd */
23291 c_parser_skip_to_pragma_eol (parser, false);
23292 return NULL_TREE;
23294 else if (cclauses == NULL && strcmp (p, "sections") == 0)
23296 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23297 cclauses = cclauses_buf;
23299 c_parser_consume_token (parser);
23300 block = c_begin_omp_parallel ();
23301 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
23302 stmt = c_finish_omp_parallel (loc,
23303 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23304 block);
23305 OMP_PARALLEL_COMBINED (stmt) = 1;
23306 return stmt;
23309 else if (!flag_openmp) /* flag_openmp_simd */
23311 c_parser_skip_to_pragma_eol (parser, false);
23312 return NULL_TREE;
23315 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23316 if (cclauses)
23318 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
23319 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
23322 block = c_begin_omp_parallel ();
23323 parser->omp_attrs_forbidden_p = true;
23324 c_parser_statement (parser, if_p);
23325 stmt = c_finish_omp_parallel (loc, clauses, block);
23327 return stmt;
23330 /* OpenMP 2.5:
23331 # pragma omp single single-clause[optseq] new-line
23332 structured-block
23334 LOC is the location of the #pragma.
23337 #define OMP_SINGLE_CLAUSE_MASK \
23338 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23339 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23340 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
23341 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23342 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23344 static tree
23345 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
23347 tree stmt = make_node (OMP_SINGLE);
23348 SET_EXPR_LOCATION (stmt, loc);
23349 TREE_TYPE (stmt) = void_type_node;
23351 OMP_SINGLE_CLAUSES (stmt)
23352 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
23353 "#pragma omp single");
23354 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
23356 return add_stmt (stmt);
23359 /* OpenMP 5.1:
23360 # pragma omp scope scope-clause[optseq] new-line
23361 structured-block
23363 LOC is the location of the #pragma.
23366 #define OMP_SCOPE_CLAUSE_MASK \
23367 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23368 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23369 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23370 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23371 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23373 static tree
23374 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
23376 tree stmt = make_node (OMP_SCOPE);
23377 SET_EXPR_LOCATION (stmt, loc);
23378 TREE_TYPE (stmt) = void_type_node;
23380 OMP_SCOPE_CLAUSES (stmt)
23381 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
23382 "#pragma omp scope");
23383 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
23385 return add_stmt (stmt);
23388 /* OpenMP 3.0:
23389 # pragma omp task task-clause[optseq] new-line
23391 LOC is the location of the #pragma.
23394 #define OMP_TASK_CLAUSE_MASK \
23395 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23396 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23397 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23398 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23399 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23400 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23401 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23404 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
23407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
23408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
23410 static tree
23411 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
23413 tree clauses, block;
23415 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
23416 "#pragma omp task");
23418 block = c_begin_omp_task ();
23419 parser->omp_attrs_forbidden_p = true;
23420 c_parser_statement (parser, if_p);
23421 return c_finish_omp_task (loc, clauses, block);
23424 /* OpenMP 3.0:
23425 # pragma omp taskwait new-line
23427 OpenMP 5.0:
23428 # pragma omp taskwait taskwait-clause[optseq] new-line
23431 #define OMP_TASKWAIT_CLAUSE_MASK \
23432 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23433 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23435 static void
23436 c_parser_omp_taskwait (c_parser *parser)
23438 location_t loc = c_parser_peek_token (parser)->location;
23439 c_parser_consume_pragma (parser);
23441 tree clauses
23442 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
23443 "#pragma omp taskwait");
23445 if (clauses)
23447 tree stmt = make_node (OMP_TASK);
23448 TREE_TYPE (stmt) = void_node;
23449 OMP_TASK_CLAUSES (stmt) = clauses;
23450 OMP_TASK_BODY (stmt) = NULL_TREE;
23451 SET_EXPR_LOCATION (stmt, loc);
23452 add_stmt (stmt);
23454 else
23455 c_finish_omp_taskwait (loc);
23458 /* OpenMP 3.1:
23459 # pragma omp taskyield new-line
23462 static void
23463 c_parser_omp_taskyield (c_parser *parser)
23465 location_t loc = c_parser_peek_token (parser)->location;
23466 c_parser_consume_pragma (parser);
23467 c_parser_skip_to_pragma_eol (parser);
23469 c_finish_omp_taskyield (loc);
23472 /* OpenMP 4.0:
23473 # pragma omp taskgroup new-line
23475 OpenMP 5.0:
23476 # pragma omp taskgroup taskgroup-clause[optseq] new-line
23479 #define OMP_TASKGROUP_CLAUSE_MASK \
23480 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
23483 static tree
23484 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
23486 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
23487 "#pragma omp taskgroup");
23489 tree body = c_parser_omp_structured_block (parser, if_p);
23490 return c_finish_omp_taskgroup (loc, body, clauses);
23493 /* OpenMP 4.0:
23494 # pragma omp cancel cancel-clause[optseq] new-line
23496 LOC is the location of the #pragma.
23499 #define OMP_CANCEL_CLAUSE_MASK \
23500 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23503 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
23504 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
23506 static void
23507 c_parser_omp_cancel (c_parser *parser)
23509 location_t loc = c_parser_peek_token (parser)->location;
23511 c_parser_consume_pragma (parser);
23512 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
23513 "#pragma omp cancel");
23515 c_finish_omp_cancel (loc, clauses);
23518 /* OpenMP 4.0:
23519 # pragma omp cancellation point cancelpt-clause[optseq] new-line
23521 LOC is the location of the #pragma.
23524 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
23525 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23526 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23527 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23528 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
23530 static bool
23531 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
23533 location_t loc = c_parser_peek_token (parser)->location;
23534 tree clauses;
23535 bool point_seen = false;
23537 c_parser_consume_pragma (parser);
23538 if (c_parser_next_token_is (parser, CPP_NAME))
23540 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23541 if (strcmp (p, "point") == 0)
23543 c_parser_consume_token (parser);
23544 point_seen = true;
23547 if (!point_seen)
23549 c_parser_error (parser, "expected %<point%>");
23550 c_parser_skip_to_pragma_eol (parser);
23551 return false;
23554 if (context != pragma_compound)
23556 if (context == pragma_stmt)
23557 error_at (loc,
23558 "%<#pragma %s%> may only be used in compound statements",
23559 "omp cancellation point");
23560 else
23561 c_parser_error (parser, "expected declaration specifiers");
23562 c_parser_skip_to_pragma_eol (parser, false);
23563 return true;
23566 clauses
23567 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
23568 "#pragma omp cancellation point");
23570 c_finish_omp_cancellation_point (loc, clauses);
23571 return true;
23574 /* OpenMP 4.0:
23575 #pragma omp distribute distribute-clause[optseq] new-line
23576 for-loop */
23578 #define OMP_DISTRIBUTE_CLAUSE_MASK \
23579 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23581 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23582 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
23583 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23584 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23585 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23587 static tree
23588 c_parser_omp_distribute (location_t loc, c_parser *parser,
23589 char *p_name, omp_clause_mask mask, tree *cclauses,
23590 bool *if_p)
23592 tree clauses, block, ret;
23594 strcat (p_name, " distribute");
23595 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
23597 if (c_parser_next_token_is (parser, CPP_NAME))
23599 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23600 bool simd = false;
23601 bool parallel = false;
23603 if (strcmp (p, "simd") == 0)
23604 simd = true;
23605 else
23606 parallel = strcmp (p, "parallel") == 0;
23607 if (parallel || simd)
23609 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23610 if (cclauses == NULL)
23611 cclauses = cclauses_buf;
23612 c_parser_consume_token (parser);
23613 if (!flag_openmp) /* flag_openmp_simd */
23615 if (simd)
23616 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23617 if_p);
23618 else
23619 return c_parser_omp_parallel (loc, parser, p_name, mask,
23620 cclauses, if_p);
23622 block = c_begin_compound_stmt (true);
23623 if (simd)
23624 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23625 if_p);
23626 else
23627 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
23628 if_p);
23629 block = c_end_compound_stmt (loc, block, true);
23630 if (ret == NULL)
23631 return ret;
23632 ret = make_node (OMP_DISTRIBUTE);
23633 TREE_TYPE (ret) = void_type_node;
23634 OMP_FOR_BODY (ret) = block;
23635 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
23636 SET_EXPR_LOCATION (ret, loc);
23637 add_stmt (ret);
23638 return ret;
23641 if (!flag_openmp) /* flag_openmp_simd */
23643 c_parser_skip_to_pragma_eol (parser, false);
23644 return NULL_TREE;
23647 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23648 if (cclauses)
23650 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
23651 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
23654 block = c_begin_compound_stmt (true);
23655 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
23656 if_p);
23657 block = c_end_compound_stmt (loc, block, true);
23658 add_stmt (block);
23660 return ret;
23663 /* OpenMP 4.0:
23664 # pragma omp teams teams-clause[optseq] new-line
23665 structured-block */
23667 #define OMP_TEAMS_CLAUSE_MASK \
23668 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23669 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23670 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23671 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23672 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
23673 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
23674 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23675 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
23677 static tree
23678 c_parser_omp_teams (location_t loc, c_parser *parser,
23679 char *p_name, omp_clause_mask mask, tree *cclauses,
23680 bool *if_p)
23682 tree clauses, block, ret;
23684 strcat (p_name, " teams");
23685 mask |= OMP_TEAMS_CLAUSE_MASK;
23687 if (c_parser_next_token_is (parser, CPP_NAME))
23689 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23690 if (strcmp (p, "distribute") == 0)
23692 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23693 if (cclauses == NULL)
23694 cclauses = cclauses_buf;
23696 c_parser_consume_token (parser);
23697 if (!flag_openmp) /* flag_openmp_simd */
23698 return c_parser_omp_distribute (loc, parser, p_name, mask,
23699 cclauses, if_p);
23700 block = c_begin_omp_parallel ();
23701 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
23702 if_p);
23703 block = c_end_compound_stmt (loc, block, true);
23704 if (ret == NULL)
23705 return ret;
23706 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
23707 ret = make_node (OMP_TEAMS);
23708 TREE_TYPE (ret) = void_type_node;
23709 OMP_TEAMS_CLAUSES (ret) = clauses;
23710 OMP_TEAMS_BODY (ret) = block;
23711 OMP_TEAMS_COMBINED (ret) = 1;
23712 SET_EXPR_LOCATION (ret, loc);
23713 return add_stmt (ret);
23715 else if (strcmp (p, "loop") == 0)
23717 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23718 if (cclauses == NULL)
23719 cclauses = cclauses_buf;
23721 c_parser_consume_token (parser);
23722 if (!flag_openmp) /* flag_openmp_simd */
23723 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23724 if_p);
23725 block = c_begin_omp_parallel ();
23726 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
23727 block = c_end_compound_stmt (loc, block, true);
23728 if (ret == NULL)
23729 return ret;
23730 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
23731 ret = make_node (OMP_TEAMS);
23732 TREE_TYPE (ret) = void_type_node;
23733 OMP_TEAMS_CLAUSES (ret) = clauses;
23734 OMP_TEAMS_BODY (ret) = block;
23735 OMP_TEAMS_COMBINED (ret) = 1;
23736 SET_EXPR_LOCATION (ret, loc);
23737 return add_stmt (ret);
23740 if (!flag_openmp) /* flag_openmp_simd */
23742 c_parser_skip_to_pragma_eol (parser, false);
23743 return NULL_TREE;
23746 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23747 if (cclauses)
23749 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
23750 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
23753 tree stmt = make_node (OMP_TEAMS);
23754 TREE_TYPE (stmt) = void_type_node;
23755 OMP_TEAMS_CLAUSES (stmt) = clauses;
23756 block = c_begin_omp_parallel ();
23757 add_stmt (c_parser_omp_structured_block (parser, if_p));
23758 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
23759 SET_EXPR_LOCATION (stmt, loc);
23761 return add_stmt (stmt);
23764 /* OpenMP 4.0:
23765 # pragma omp target data target-data-clause[optseq] new-line
23766 structured-block */
23768 #define OMP_TARGET_DATA_CLAUSE_MASK \
23769 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23770 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23771 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23772 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
23773 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
23775 static tree
23776 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
23778 if (flag_openmp)
23779 omp_requires_mask
23780 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
23782 tree clauses
23783 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
23784 "#pragma omp target data");
23785 c_omp_adjust_map_clauses (clauses, false);
23786 int map_seen = 0;
23787 for (tree *pc = &clauses; *pc;)
23789 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
23790 switch (OMP_CLAUSE_MAP_KIND (*pc))
23792 case GOMP_MAP_TO:
23793 case GOMP_MAP_ALWAYS_TO:
23794 case GOMP_MAP_PRESENT_TO:
23795 case GOMP_MAP_ALWAYS_PRESENT_TO:
23796 case GOMP_MAP_FROM:
23797 case GOMP_MAP_ALWAYS_FROM:
23798 case GOMP_MAP_PRESENT_FROM:
23799 case GOMP_MAP_ALWAYS_PRESENT_FROM:
23800 case GOMP_MAP_TOFROM:
23801 case GOMP_MAP_ALWAYS_TOFROM:
23802 case GOMP_MAP_PRESENT_TOFROM:
23803 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
23804 case GOMP_MAP_ALLOC:
23805 case GOMP_MAP_PRESENT_ALLOC:
23806 map_seen = 3;
23807 break;
23808 case GOMP_MAP_FIRSTPRIVATE_POINTER:
23809 case GOMP_MAP_ALWAYS_POINTER:
23810 case GOMP_MAP_ATTACH_DETACH:
23811 case GOMP_MAP_ATTACH:
23812 break;
23813 default:
23814 map_seen |= 1;
23815 error_at (OMP_CLAUSE_LOCATION (*pc),
23816 "%<#pragma omp target data%> with map-type other "
23817 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
23818 "on %<map%> clause");
23819 *pc = OMP_CLAUSE_CHAIN (*pc);
23820 continue;
23822 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
23823 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
23824 map_seen = 3;
23825 pc = &OMP_CLAUSE_CHAIN (*pc);
23828 if (map_seen != 3)
23830 if (map_seen == 0)
23831 error_at (loc,
23832 "%<#pragma omp target data%> must contain at least "
23833 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
23834 "clause");
23835 return NULL_TREE;
23838 tree stmt = make_node (OMP_TARGET_DATA);
23839 TREE_TYPE (stmt) = void_type_node;
23840 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
23841 keep_next_level ();
23842 tree block = c_begin_compound_stmt (true);
23843 add_stmt (c_parser_omp_structured_block (parser, if_p));
23844 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
23846 SET_EXPR_LOCATION (stmt, loc);
23847 return add_stmt (stmt);
23850 /* OpenMP 4.0:
23851 # pragma omp target update target-update-clause[optseq] new-line */
23853 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
23854 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
23855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
23856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23858 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23861 static bool
23862 c_parser_omp_target_update (location_t loc, c_parser *parser,
23863 enum pragma_context context)
23865 if (context == pragma_stmt)
23867 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
23868 "omp target update");
23869 c_parser_skip_to_pragma_eol (parser, false);
23870 return true;
23873 tree clauses
23874 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
23875 "#pragma omp target update");
23876 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
23877 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
23879 error_at (loc,
23880 "%<#pragma omp target update%> must contain at least one "
23881 "%<from%> or %<to%> clauses");
23882 return false;
23885 if (flag_openmp)
23886 omp_requires_mask
23887 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
23889 tree stmt = make_node (OMP_TARGET_UPDATE);
23890 TREE_TYPE (stmt) = void_type_node;
23891 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
23892 SET_EXPR_LOCATION (stmt, loc);
23893 add_stmt (stmt);
23894 return false;
23897 /* OpenMP 4.5:
23898 # pragma omp target enter data target-data-clause[optseq] new-line */
23900 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
23901 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23907 static bool
23908 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
23909 enum pragma_context context)
23911 bool data_seen = false;
23912 if (c_parser_next_token_is (parser, CPP_NAME))
23914 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23915 if (strcmp (p, "data") == 0)
23917 c_parser_consume_token (parser);
23918 data_seen = true;
23921 if (!data_seen)
23923 c_parser_error (parser, "expected %<data%>");
23924 c_parser_skip_to_pragma_eol (parser);
23925 return false;
23928 if (context == pragma_stmt)
23930 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
23931 "omp target enter data");
23932 c_parser_skip_to_pragma_eol (parser, false);
23933 return true;
23936 if (flag_openmp)
23937 omp_requires_mask
23938 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
23940 tree clauses
23941 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
23942 "#pragma omp target enter data");
23943 c_omp_adjust_map_clauses (clauses, false);
23944 int map_seen = 0;
23945 for (tree *pc = &clauses; *pc;)
23947 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
23948 switch (OMP_CLAUSE_MAP_KIND (*pc))
23950 case GOMP_MAP_TO:
23951 case GOMP_MAP_ALWAYS_TO:
23952 case GOMP_MAP_PRESENT_TO:
23953 case GOMP_MAP_ALWAYS_PRESENT_TO:
23954 case GOMP_MAP_ALLOC:
23955 case GOMP_MAP_PRESENT_ALLOC:
23956 map_seen = 3;
23957 break;
23958 case GOMP_MAP_TOFROM:
23959 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
23960 map_seen = 3;
23961 break;
23962 case GOMP_MAP_ALWAYS_TOFROM:
23963 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
23964 map_seen = 3;
23965 break;
23966 case GOMP_MAP_PRESENT_TOFROM:
23967 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_TO);
23968 map_seen = 3;
23969 break;
23970 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
23971 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_TO);
23972 map_seen = 3;
23973 break;
23974 case GOMP_MAP_FIRSTPRIVATE_POINTER:
23975 case GOMP_MAP_ALWAYS_POINTER:
23976 case GOMP_MAP_ATTACH_DETACH:
23977 case GOMP_MAP_ATTACH:
23978 break;
23979 default:
23980 map_seen |= 1;
23981 error_at (OMP_CLAUSE_LOCATION (*pc),
23982 "%<#pragma omp target enter data%> with map-type other "
23983 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
23984 *pc = OMP_CLAUSE_CHAIN (*pc);
23985 continue;
23987 pc = &OMP_CLAUSE_CHAIN (*pc);
23990 if (map_seen != 3)
23992 if (map_seen == 0)
23993 error_at (loc,
23994 "%<#pragma omp target enter data%> must contain at least "
23995 "one %<map%> clause");
23996 return true;
23999 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
24000 TREE_TYPE (stmt) = void_type_node;
24001 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
24002 SET_EXPR_LOCATION (stmt, loc);
24003 add_stmt (stmt);
24004 return true;
24007 /* OpenMP 4.5:
24008 # pragma omp target exit data target-data-clause[optseq] new-line */
24010 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
24011 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24012 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24013 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24014 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24015 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24017 static bool
24018 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
24019 enum pragma_context context)
24021 bool data_seen = false;
24022 if (c_parser_next_token_is (parser, CPP_NAME))
24024 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24025 if (strcmp (p, "data") == 0)
24027 c_parser_consume_token (parser);
24028 data_seen = true;
24031 if (!data_seen)
24033 c_parser_error (parser, "expected %<data%>");
24034 c_parser_skip_to_pragma_eol (parser);
24035 return false;
24038 if (context == pragma_stmt)
24040 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
24041 "omp target exit data");
24042 c_parser_skip_to_pragma_eol (parser, false);
24043 return true;
24046 if (flag_openmp)
24047 omp_requires_mask
24048 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24050 tree clauses
24051 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
24052 "#pragma omp target exit data", false);
24053 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP_EXIT_DATA);
24054 c_omp_adjust_map_clauses (clauses, false);
24055 int map_seen = 0;
24056 for (tree *pc = &clauses; *pc;)
24058 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24059 switch (OMP_CLAUSE_MAP_KIND (*pc))
24061 case GOMP_MAP_FROM:
24062 case GOMP_MAP_ALWAYS_FROM:
24063 case GOMP_MAP_PRESENT_FROM:
24064 case GOMP_MAP_ALWAYS_PRESENT_FROM:
24065 case GOMP_MAP_RELEASE:
24066 case GOMP_MAP_DELETE:
24067 map_seen = 3;
24068 break;
24069 case GOMP_MAP_TOFROM:
24070 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
24071 map_seen = 3;
24072 break;
24073 case GOMP_MAP_ALWAYS_TOFROM:
24074 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
24075 map_seen = 3;
24076 break;
24077 case GOMP_MAP_PRESENT_TOFROM:
24078 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_FROM);
24079 map_seen = 3;
24080 break;
24081 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24082 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_FROM);
24083 map_seen = 3;
24084 break;
24085 case GOMP_MAP_FIRSTPRIVATE_POINTER:
24086 case GOMP_MAP_ALWAYS_POINTER:
24087 case GOMP_MAP_ATTACH_DETACH:
24088 case GOMP_MAP_DETACH:
24089 break;
24090 default:
24091 map_seen |= 1;
24092 error_at (OMP_CLAUSE_LOCATION (*pc),
24093 "%<#pragma omp target exit data%> with map-type other "
24094 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
24095 "on %<map%> clause");
24096 *pc = OMP_CLAUSE_CHAIN (*pc);
24097 continue;
24099 pc = &OMP_CLAUSE_CHAIN (*pc);
24102 if (map_seen != 3)
24104 if (map_seen == 0)
24105 error_at (loc,
24106 "%<#pragma omp target exit data%> must contain at least one "
24107 "%<map%> clause");
24108 return true;
24111 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
24112 TREE_TYPE (stmt) = void_type_node;
24113 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
24114 SET_EXPR_LOCATION (stmt, loc);
24115 add_stmt (stmt);
24116 return true;
24119 /* OpenMP 4.0:
24120 # pragma omp target target-clause[optseq] new-line
24121 structured-block */
24123 #define OMP_TARGET_CLAUSE_MASK \
24124 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24126 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24127 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24128 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
24129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
24130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
24131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
24132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
24133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
24134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
24135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
24136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
24138 static bool
24139 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
24141 location_t loc = c_parser_peek_token (parser)->location;
24142 c_parser_consume_pragma (parser);
24143 tree *pc = NULL, stmt, block;
24145 if (context != pragma_stmt && context != pragma_compound)
24147 c_parser_error (parser, "expected declaration specifiers");
24148 c_parser_skip_to_pragma_eol (parser);
24149 return false;
24152 if (flag_openmp)
24153 omp_requires_mask
24154 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24156 if (c_parser_next_token_is (parser, CPP_NAME))
24158 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24159 enum tree_code ccode = ERROR_MARK;
24161 if (strcmp (p, "teams") == 0)
24162 ccode = OMP_TEAMS;
24163 else if (strcmp (p, "parallel") == 0)
24164 ccode = OMP_PARALLEL;
24165 else if (strcmp (p, "simd") == 0)
24166 ccode = OMP_SIMD;
24167 if (ccode != ERROR_MARK)
24169 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
24170 char p_name[sizeof ("#pragma omp target teams distribute "
24171 "parallel for simd")];
24173 c_parser_consume_token (parser);
24174 strcpy (p_name, "#pragma omp target");
24175 if (!flag_openmp) /* flag_openmp_simd */
24177 tree stmt;
24178 switch (ccode)
24180 case OMP_TEAMS:
24181 stmt = c_parser_omp_teams (loc, parser, p_name,
24182 OMP_TARGET_CLAUSE_MASK,
24183 cclauses, if_p);
24184 break;
24185 case OMP_PARALLEL:
24186 stmt = c_parser_omp_parallel (loc, parser, p_name,
24187 OMP_TARGET_CLAUSE_MASK,
24188 cclauses, if_p);
24189 break;
24190 case OMP_SIMD:
24191 stmt = c_parser_omp_simd (loc, parser, p_name,
24192 OMP_TARGET_CLAUSE_MASK,
24193 cclauses, if_p);
24194 break;
24195 default:
24196 gcc_unreachable ();
24198 return stmt != NULL_TREE;
24200 keep_next_level ();
24201 tree block = c_begin_compound_stmt (true), ret;
24202 switch (ccode)
24204 case OMP_TEAMS:
24205 ret = c_parser_omp_teams (loc, parser, p_name,
24206 OMP_TARGET_CLAUSE_MASK, cclauses,
24207 if_p);
24208 break;
24209 case OMP_PARALLEL:
24210 ret = c_parser_omp_parallel (loc, parser, p_name,
24211 OMP_TARGET_CLAUSE_MASK, cclauses,
24212 if_p);
24213 break;
24214 case OMP_SIMD:
24215 ret = c_parser_omp_simd (loc, parser, p_name,
24216 OMP_TARGET_CLAUSE_MASK, cclauses,
24217 if_p);
24218 break;
24219 default:
24220 gcc_unreachable ();
24222 block = c_end_compound_stmt (loc, block, true);
24223 if (ret == NULL_TREE)
24224 return false;
24225 if (ccode == OMP_TEAMS)
24226 /* For combined target teams, ensure the num_teams and
24227 thread_limit clause expressions are evaluated on the host,
24228 before entering the target construct. */
24229 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
24230 c; c = OMP_CLAUSE_CHAIN (c))
24231 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
24232 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
24233 for (int i = 0;
24234 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
24235 if (OMP_CLAUSE_OPERAND (c, i)
24236 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
24238 tree expr = OMP_CLAUSE_OPERAND (c, i);
24239 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
24240 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
24241 expr, NULL_TREE, NULL_TREE);
24242 add_stmt (expr);
24243 OMP_CLAUSE_OPERAND (c, i) = expr;
24244 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
24245 OMP_CLAUSE_FIRSTPRIVATE);
24246 OMP_CLAUSE_DECL (tc) = tmp;
24247 OMP_CLAUSE_CHAIN (tc)
24248 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
24249 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
24251 tree stmt = make_node (OMP_TARGET);
24252 TREE_TYPE (stmt) = void_type_node;
24253 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
24254 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
24255 OMP_TARGET_BODY (stmt) = block;
24256 OMP_TARGET_COMBINED (stmt) = 1;
24257 SET_EXPR_LOCATION (stmt, loc);
24258 add_stmt (stmt);
24259 pc = &OMP_TARGET_CLAUSES (stmt);
24260 goto check_clauses;
24262 else if (!flag_openmp) /* flag_openmp_simd */
24264 c_parser_skip_to_pragma_eol (parser, false);
24265 return false;
24267 else if (strcmp (p, "data") == 0)
24269 c_parser_consume_token (parser);
24270 c_parser_omp_target_data (loc, parser, if_p);
24271 return true;
24273 else if (strcmp (p, "enter") == 0)
24275 c_parser_consume_token (parser);
24276 return c_parser_omp_target_enter_data (loc, parser, context);
24278 else if (strcmp (p, "exit") == 0)
24280 c_parser_consume_token (parser);
24281 return c_parser_omp_target_exit_data (loc, parser, context);
24283 else if (strcmp (p, "update") == 0)
24285 c_parser_consume_token (parser);
24286 return c_parser_omp_target_update (loc, parser, context);
24289 if (!flag_openmp) /* flag_openmp_simd */
24291 c_parser_skip_to_pragma_eol (parser, false);
24292 return false;
24295 stmt = make_node (OMP_TARGET);
24296 TREE_TYPE (stmt) = void_type_node;
24298 OMP_TARGET_CLAUSES (stmt)
24299 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
24300 "#pragma omp target", false);
24301 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
24302 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
24304 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
24305 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
24306 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
24307 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
24308 OMP_CLAUSE_CHAIN (c) = nc;
24310 OMP_TARGET_CLAUSES (stmt)
24311 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
24312 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
24314 pc = &OMP_TARGET_CLAUSES (stmt);
24315 keep_next_level ();
24316 block = c_begin_compound_stmt (true);
24317 add_stmt (c_parser_omp_structured_block (parser, if_p));
24318 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
24320 SET_EXPR_LOCATION (stmt, loc);
24321 add_stmt (stmt);
24323 check_clauses:
24324 while (*pc)
24326 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24327 switch (OMP_CLAUSE_MAP_KIND (*pc))
24329 case GOMP_MAP_TO:
24330 case GOMP_MAP_ALWAYS_TO:
24331 case GOMP_MAP_PRESENT_TO:
24332 case GOMP_MAP_ALWAYS_PRESENT_TO:
24333 case GOMP_MAP_FROM:
24334 case GOMP_MAP_ALWAYS_FROM:
24335 case GOMP_MAP_PRESENT_FROM:
24336 case GOMP_MAP_ALWAYS_PRESENT_FROM:
24337 case GOMP_MAP_TOFROM:
24338 case GOMP_MAP_ALWAYS_TOFROM:
24339 case GOMP_MAP_PRESENT_TOFROM:
24340 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24341 case GOMP_MAP_ALLOC:
24342 case GOMP_MAP_PRESENT_ALLOC:
24343 case GOMP_MAP_FIRSTPRIVATE_POINTER:
24344 case GOMP_MAP_ALWAYS_POINTER:
24345 case GOMP_MAP_POINTER:
24346 case GOMP_MAP_ATTACH_DETACH:
24347 case GOMP_MAP_ATTACH:
24348 break;
24349 default:
24350 error_at (OMP_CLAUSE_LOCATION (*pc),
24351 "%<#pragma omp target%> with map-type other "
24352 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
24353 "on %<map%> clause");
24354 *pc = OMP_CLAUSE_CHAIN (*pc);
24355 continue;
24357 pc = &OMP_CLAUSE_CHAIN (*pc);
24359 cfun->has_omp_target = true;
24360 return true;
24363 /* OpenMP 4.0:
24364 # pragma omp declare simd declare-simd-clauses[optseq] new-line
24366 OpenMP 5.0:
24367 # pragma omp declare variant (identifier) match(context-selector) new-line
24370 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
24371 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
24372 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
24373 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
24374 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
24375 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
24376 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
24378 static void
24379 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
24381 c_token *token = c_parser_peek_token (parser);
24382 gcc_assert (token->type == CPP_NAME);
24383 tree kind = token->value;
24384 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
24385 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
24387 auto_vec<c_token> clauses;
24388 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
24390 c_token *token = c_parser_peek_token (parser);
24391 if (token->type == CPP_EOF)
24393 c_parser_skip_to_pragma_eol (parser);
24394 return;
24396 clauses.safe_push (*token);
24397 c_parser_consume_token (parser);
24399 clauses.safe_push (*c_parser_peek_token (parser));
24400 c_parser_skip_to_pragma_eol (parser);
24402 while (c_parser_next_token_is (parser, CPP_PRAGMA))
24404 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
24405 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
24406 || c_parser_peek_2nd_token (parser)->value != kind)
24408 error ("%<#pragma omp declare %s%> must be followed by "
24409 "function declaration or definition or another "
24410 "%<#pragma omp declare %s%>",
24411 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
24412 return;
24414 c_parser_consume_pragma (parser);
24415 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
24417 c_token *token = c_parser_peek_token (parser);
24418 if (token->type == CPP_EOF)
24420 c_parser_skip_to_pragma_eol (parser);
24421 return;
24423 clauses.safe_push (*token);
24424 c_parser_consume_token (parser);
24426 clauses.safe_push (*c_parser_peek_token (parser));
24427 c_parser_skip_to_pragma_eol (parser);
24430 /* Make sure nothing tries to read past the end of the tokens. */
24431 c_token eof_token;
24432 memset (&eof_token, 0, sizeof (eof_token));
24433 eof_token.type = CPP_EOF;
24434 clauses.safe_push (eof_token);
24435 clauses.safe_push (eof_token);
24437 switch (context)
24439 case pragma_external:
24440 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24441 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
24443 int ext = disable_extension_diagnostics ();
24445 c_parser_consume_token (parser);
24446 while (c_parser_next_token_is (parser, CPP_KEYWORD)
24447 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
24448 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
24449 NULL, &clauses);
24450 restore_extension_diagnostics (ext);
24452 else
24453 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
24454 NULL, &clauses);
24455 break;
24456 case pragma_struct:
24457 case pragma_param:
24458 case pragma_stmt:
24459 error ("%<#pragma omp declare %s%> must be followed by "
24460 "function declaration or definition",
24461 IDENTIFIER_POINTER (kind));
24462 break;
24463 case pragma_compound:
24464 bool have_std_attrs;
24465 tree std_attrs;
24466 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
24467 if (have_std_attrs)
24468 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
24469 else
24470 std_attrs = NULL_TREE;
24471 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24472 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
24474 int ext = disable_extension_diagnostics ();
24476 c_parser_consume_token (parser);
24477 while (c_parser_next_token_is (parser, CPP_KEYWORD)
24478 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
24479 if (c_parser_next_tokens_start_declaration (parser)
24480 || c_parser_nth_token_starts_std_attributes (parser, 1))
24482 c_parser_declaration_or_fndef (parser, true, true, true, true,
24483 true, NULL, &clauses,
24484 have_std_attrs, std_attrs);
24485 restore_extension_diagnostics (ext);
24486 break;
24488 restore_extension_diagnostics (ext);
24490 else if (c_parser_next_tokens_start_declaration (parser))
24492 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
24493 NULL, &clauses, have_std_attrs,
24494 std_attrs);
24495 break;
24497 error ("%<#pragma omp declare %s%> must be followed by "
24498 "function declaration or definition",
24499 IDENTIFIER_POINTER (kind));
24500 break;
24501 default:
24502 gcc_unreachable ();
24506 /* OpenMP 5.0:
24508 trait-selector:
24509 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
24511 trait-score:
24512 score(score-expression)
24514 Note that this function returns a list of trait selectors for the
24515 trait-selector-set SET. */
24517 static tree
24518 c_parser_omp_context_selector (c_parser *parser, enum omp_tss_code set,
24519 tree parms)
24521 tree ret = NULL_TREE;
24524 tree selector;
24525 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24526 || c_parser_next_token_is (parser, CPP_NAME))
24527 selector = c_parser_peek_token (parser)->value;
24528 else
24530 c_parser_error (parser, "expected trait selector name");
24531 return error_mark_node;
24533 enum omp_ts_code sel
24534 = omp_lookup_ts_code (set, IDENTIFIER_POINTER (selector));
24536 if (sel == OMP_TRAIT_INVALID)
24538 /* Per the spec, "Implementations can ignore specified selectors
24539 that are not those described in this section"; however, we
24540 must record such selectors because they cause match failures. */
24541 warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
24542 "unknown selector %qs for context selector set %qs",
24543 IDENTIFIER_POINTER (selector), omp_tss_map[set]);
24544 c_parser_consume_token (parser);
24545 ret = make_trait_selector (sel, NULL_TREE, NULL_TREE, ret);
24546 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
24547 c_parser_balanced_token_sequence (parser);
24548 if (c_parser_next_token_is (parser, CPP_COMMA))
24550 c_parser_consume_token (parser);
24551 continue;
24553 else
24554 break;
24557 c_parser_consume_token (parser);
24559 tree properties = NULL_TREE;
24560 tree scoreval = NULL_TREE;
24561 enum omp_tp_type property_kind = omp_ts_map[sel].tp_type;
24562 bool allow_score = omp_ts_map[sel].allow_score;
24563 tree t;
24565 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
24567 if (property_kind == OMP_TRAIT_PROPERTY_NONE)
24569 error_at (c_parser_peek_token (parser)->location,
24570 "selector %qs does not accept any properties",
24571 IDENTIFIER_POINTER (selector));
24572 return error_mark_node;
24575 matching_parens parens;
24576 parens.require_open (parser);
24578 c_token *token = c_parser_peek_token (parser);
24579 if (c_parser_next_token_is (parser, CPP_NAME)
24580 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
24581 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
24583 c_parser_consume_token (parser);
24585 matching_parens parens2;
24586 parens2.require_open (parser);
24587 tree score = c_parser_expr_no_commas (parser, NULL).value;
24588 parens2.skip_until_found_close (parser);
24589 c_parser_require (parser, CPP_COLON, "expected %<:%>");
24590 if (!allow_score)
24591 error_at (token->location,
24592 "%<score%> cannot be specified in traits "
24593 "in the %qs trait-selector-set",
24594 omp_tss_map[set]);
24595 else if (score != error_mark_node)
24597 mark_exp_read (score);
24598 score = c_fully_fold (score, false, NULL);
24599 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
24600 || TREE_CODE (score) != INTEGER_CST)
24601 error_at (token->location, "%<score%> argument must "
24602 "be constant integer expression");
24603 else if (tree_int_cst_sgn (score) < 0)
24604 error_at (token->location, "%<score%> argument must "
24605 "be non-negative");
24606 else
24607 scoreval = score;
24609 token = c_parser_peek_token (parser);
24612 switch (property_kind)
24614 case OMP_TRAIT_PROPERTY_ID:
24615 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24616 || c_parser_next_token_is (parser, CPP_NAME))
24618 tree prop = c_parser_peek_token (parser)->value;
24619 c_parser_consume_token (parser);
24620 properties = make_trait_property (prop, NULL_TREE,
24621 properties);
24623 else
24625 c_parser_error (parser, "expected identifier");
24626 return error_mark_node;
24628 break;
24629 case OMP_TRAIT_PROPERTY_NAME_LIST:
24632 tree prop = OMP_TP_NAMELIST_NODE;
24633 tree value = NULL_TREE;
24634 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24635 || c_parser_next_token_is (parser, CPP_NAME))
24637 value = c_parser_peek_token (parser)->value;
24638 c_parser_consume_token (parser);
24640 else if (c_parser_next_token_is (parser, CPP_STRING))
24641 value = c_parser_string_literal (parser, false,
24642 false).value;
24643 else
24645 c_parser_error (parser, "expected identifier or "
24646 "string literal");
24647 return error_mark_node;
24650 properties = make_trait_property (prop, value, properties);
24652 if (c_parser_next_token_is (parser, CPP_COMMA))
24653 c_parser_consume_token (parser);
24654 else
24655 break;
24657 while (1);
24658 break;
24659 case OMP_TRAIT_PROPERTY_EXPR:
24660 t = c_parser_expr_no_commas (parser, NULL).value;
24661 if (t != error_mark_node)
24663 mark_exp_read (t);
24664 t = c_fully_fold (t, false, NULL);
24665 /* FIXME: this is bogus, both device_num and
24666 condition selectors allow arbitrary expressions. */
24667 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
24668 || !tree_fits_shwi_p (t))
24669 error_at (token->location, "property must be "
24670 "constant integer expression");
24671 else
24672 properties = make_trait_property (NULL_TREE, t,
24673 properties);
24675 else
24676 return error_mark_node;
24677 break;
24678 case OMP_TRAIT_PROPERTY_CLAUSE_LIST:
24679 if (sel == OMP_TRAIT_CONSTRUCT_SIMD)
24681 if (parms == NULL_TREE)
24683 error_at (token->location, "properties for %<simd%> "
24684 "selector may not be specified in "
24685 "%<metadirective%>");
24686 return error_mark_node;
24688 tree c;
24689 c = c_parser_omp_all_clauses (parser,
24690 OMP_DECLARE_SIMD_CLAUSE_MASK,
24691 "simd", true, 2);
24692 c = c_omp_declare_simd_clauses_to_numbers (parms
24693 == error_mark_node
24694 ? NULL_TREE : parms,
24696 properties = c;
24698 else if (sel == OMP_TRAIT_IMPLEMENTATION_REQUIRES)
24700 /* FIXME: The "requires" selector was added in OpenMP 5.1.
24701 Currently only the now-deprecated syntax
24702 from OpenMP 5.0 is supported. */
24703 sorry_at (token->location,
24704 "%<requires%> selector is not supported yet");
24705 return error_mark_node;
24707 else
24708 gcc_unreachable ();
24709 break;
24710 default:
24711 gcc_unreachable ();
24714 parens.skip_until_found_close (parser);
24715 properties = nreverse (properties);
24717 else if (property_kind != OMP_TRAIT_PROPERTY_NONE
24718 && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST
24719 && property_kind != OMP_TRAIT_PROPERTY_EXTENSION)
24721 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
24722 return error_mark_node;
24725 ret = make_trait_selector (sel, scoreval, properties, ret);
24727 if (c_parser_next_token_is (parser, CPP_COMMA))
24728 c_parser_consume_token (parser);
24729 else
24730 break;
24732 while (1);
24734 return nreverse (ret);
24737 /* OpenMP 5.0:
24739 trait-set-selector[,trait-set-selector[,...]]
24741 trait-set-selector:
24742 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
24744 trait-set-selector-name:
24745 constructor
24746 device
24747 implementation
24748 user */
24750 static tree
24751 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
24753 tree ret = NULL_TREE;
24756 const char *setp = "";
24757 if (c_parser_next_token_is (parser, CPP_NAME))
24758 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24759 enum omp_tss_code set = omp_lookup_tss_code (setp);
24761 if (set == OMP_TRAIT_SET_INVALID)
24763 c_parser_error (parser, "expected context selector set name");
24764 return error_mark_node;
24767 c_parser_consume_token (parser);
24769 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
24770 return error_mark_node;
24772 matching_braces braces;
24773 if (!braces.require_open (parser))
24774 return error_mark_node;
24776 tree selectors = c_parser_omp_context_selector (parser, set, parms);
24777 if (selectors == error_mark_node)
24778 ret = error_mark_node;
24779 else if (ret != error_mark_node)
24780 ret = make_trait_set_selector (set, selectors, ret);
24782 braces.skip_until_found_close (parser);
24784 if (c_parser_next_token_is (parser, CPP_COMMA))
24785 c_parser_consume_token (parser);
24786 else
24787 break;
24789 while (1);
24791 if (ret == error_mark_node)
24792 return ret;
24793 return nreverse (ret);
24796 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
24797 that into "omp declare variant base" attribute. */
24799 static void
24800 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
24802 matching_parens parens;
24803 if (!parens.require_open (parser))
24805 fail:
24806 c_parser_skip_to_pragma_eol (parser, false);
24807 return;
24810 if (c_parser_next_token_is_not (parser, CPP_NAME)
24811 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
24813 c_parser_error (parser, "expected identifier");
24814 goto fail;
24817 c_token *token = c_parser_peek_token (parser);
24818 tree variant = lookup_name (token->value);
24820 if (variant == NULL_TREE)
24822 undeclared_variable (token->location, token->value);
24823 variant = error_mark_node;
24826 c_parser_consume_token (parser);
24828 parens.require_close (parser);
24830 if (c_parser_next_token_is (parser, CPP_COMMA)
24831 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
24832 c_parser_consume_token (parser);
24834 const char *clause = "";
24835 location_t match_loc = c_parser_peek_token (parser)->location;
24836 if (c_parser_next_token_is (parser, CPP_NAME))
24837 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24838 if (strcmp (clause, "match"))
24840 c_parser_error (parser, "expected %<match%>");
24841 goto fail;
24844 c_parser_consume_token (parser);
24846 if (!parens.require_open (parser))
24847 goto fail;
24849 if (parms == NULL_TREE)
24850 parms = error_mark_node;
24852 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
24853 if (ctx == error_mark_node)
24854 goto fail;
24855 ctx = omp_check_context_selector (match_loc, ctx);
24856 if (ctx != error_mark_node && variant != error_mark_node)
24858 if (TREE_CODE (variant) != FUNCTION_DECL)
24860 error_at (token->location, "variant %qD is not a function", variant);
24861 variant = error_mark_node;
24863 else if (!omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
24864 OMP_TRAIT_CONSTRUCT_SIMD)
24865 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
24867 error_at (token->location, "variant %qD and base %qD have "
24868 "incompatible types", variant, fndecl);
24869 variant = error_mark_node;
24871 else if (fndecl_built_in_p (variant)
24872 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
24873 "__builtin_", strlen ("__builtin_")) == 0
24874 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
24875 "__sync_", strlen ("__sync_")) == 0
24876 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
24877 "__atomic_", strlen ("__atomic_")) == 0))
24879 error_at (token->location, "variant %qD is a built-in", variant);
24880 variant = error_mark_node;
24882 if (variant != error_mark_node)
24884 C_DECL_USED (variant) = 1;
24885 tree construct
24886 = omp_get_context_selector_list (ctx, OMP_TRAIT_SET_CONSTRUCT);
24887 omp_mark_declare_variant (match_loc, variant, construct);
24888 if (omp_context_selector_matches (ctx))
24890 tree attr
24891 = tree_cons (get_identifier ("omp declare variant base"),
24892 build_tree_list (variant, ctx),
24893 DECL_ATTRIBUTES (fndecl));
24894 DECL_ATTRIBUTES (fndecl) = attr;
24899 parens.require_close (parser);
24900 c_parser_skip_to_pragma_eol (parser);
24903 /* Finalize #pragma omp declare simd or #pragma omp declare variant
24904 clauses after FNDECL has been parsed, and put that into "omp declare simd"
24905 or "omp declare variant base" attribute. */
24907 static void
24908 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
24909 vec<c_token> *pclauses)
24911 vec<c_token> &clauses = *pclauses;
24913 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
24914 indicates error has been reported and CPP_PRAGMA that
24915 c_finish_omp_declare_simd has already processed the tokens. */
24916 if (clauses.exists () && clauses[0].type == CPP_EOF)
24917 return;
24918 const char *kind = "simd";
24919 if (clauses.exists ()
24920 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
24921 kind = IDENTIFIER_POINTER (clauses[0].value);
24922 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
24923 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
24925 error ("%<#pragma omp declare %s%> not immediately followed by "
24926 "a function declaration or definition", kind);
24927 clauses[0].type = CPP_EOF;
24928 return;
24930 if (clauses.exists () && clauses[0].type != CPP_NAME)
24932 error_at (DECL_SOURCE_LOCATION (fndecl),
24933 "%<#pragma omp declare %s%> not immediately followed by "
24934 "a single function declaration or definition", kind);
24935 clauses[0].type = CPP_EOF;
24936 return;
24939 if (parms == NULL_TREE)
24940 parms = DECL_ARGUMENTS (fndecl);
24942 unsigned int tokens_avail = parser->tokens_avail;
24943 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
24945 parser->tokens = clauses.address ();
24946 parser->tokens_avail = clauses.length ();
24948 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
24949 while (parser->tokens_avail > 3)
24951 c_token *token = c_parser_peek_token (parser);
24952 gcc_assert (token->type == CPP_NAME);
24953 kind = IDENTIFIER_POINTER (token->value);
24954 c_parser_consume_token (parser);
24955 parser->in_pragma = true;
24957 if (strcmp (kind, "simd") == 0)
24959 tree c;
24960 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
24961 "#pragma omp declare simd");
24962 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
24963 if (c != NULL_TREE)
24964 c = tree_cons (NULL_TREE, c, NULL_TREE);
24965 c = build_tree_list (get_identifier ("omp declare simd"), c);
24966 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
24967 DECL_ATTRIBUTES (fndecl) = c;
24969 else
24971 gcc_assert (strcmp (kind, "variant") == 0);
24972 c_finish_omp_declare_variant (parser, fndecl, parms);
24976 parser->tokens = &parser->tokens_buf[0];
24977 parser->tokens_avail = tokens_avail;
24978 if (clauses.exists ())
24979 clauses[0].type = CPP_PRAGMA;
24982 /* D should be C_TOKEN_VEC from omp::decl attribute. If it contains
24983 a threadprivate, groupprivate, allocate or declare target directive,
24984 return true and parse it for DECL. */
24986 bool
24987 c_maybe_parse_omp_decl (tree decl, tree d)
24989 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
24990 vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
24991 c_token *first = toks->address ();
24992 c_token *last = first + toks->length ();
24993 const char *directive[3] = {};
24994 for (int j = 0; j < 3; j++)
24996 tree id = NULL_TREE;
24997 if (first + j == last)
24998 break;
24999 if (first[j].type == CPP_NAME)
25000 id = first[j].value;
25001 else if (first[j].type == CPP_KEYWORD)
25002 id = ridpointers[(int) first[j].keyword];
25003 else
25004 break;
25005 directive[j] = IDENTIFIER_POINTER (id);
25007 const c_omp_directive *dir = NULL;
25008 if (directive[0])
25009 dir = c_omp_categorize_directive (directive[0], directive[1],
25010 directive[2]);
25011 if (dir == NULL)
25013 error_at (first->location,
25014 "unknown OpenMP directive name in "
25015 "%qs attribute argument", "omp::decl");
25016 return false;
25018 if (dir->id != PRAGMA_OMP_THREADPRIVATE
25019 /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
25020 && dir->id != PRAGMA_OMP_ALLOCATE
25021 && (dir->id != PRAGMA_OMP_DECLARE
25022 || strcmp (directive[1], "target") != 0))
25023 return false;
25025 if (!flag_openmp && !dir->simd)
25026 return true;
25028 c_parser *parser = the_parser;
25029 unsigned int tokens_avail = parser->tokens_avail;
25030 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
25031 toks = NULL;
25032 vec_safe_reserve (toks, last - first + 2, true);
25033 c_token tok = {};
25034 tok.type = CPP_PRAGMA;
25035 tok.keyword = RID_MAX;
25036 tok.pragma_kind = pragma_kind (dir->id);
25037 tok.location = first->location;
25038 toks->quick_push (tok);
25039 while (++first < last)
25040 toks->quick_push (*first);
25041 tok = {};
25042 tok.type = CPP_PRAGMA_EOL;
25043 tok.keyword = RID_MAX;
25044 tok.location = last[-1].location;
25045 toks->quick_push (tok);
25046 tok = {};
25047 tok.type = CPP_EOF;
25048 tok.keyword = RID_MAX;
25049 tok.location = last[-1].location;
25050 tok.flags = tokens_avail;
25051 toks->quick_push (tok);
25052 parser->in_omp_decl_attribute = decl;
25053 parser->tokens = toks->address ();
25054 parser->tokens_avail = toks->length ();
25055 parser->in_omp_attribute_pragma = toks;
25056 c_parser_pragma (parser, pragma_external, NULL);
25057 parser->in_omp_decl_attribute = NULL_TREE;
25058 return true;
25061 /* OpenMP 4.0:
25062 # pragma omp declare target new-line
25063 declarations and definitions
25064 # pragma omp end declare target new-line
25066 OpenMP 4.5:
25067 # pragma omp declare target ( extended-list ) new-line
25069 # pragma omp declare target declare-target-clauses[seq] new-line */
25071 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
25072 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
25073 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
25074 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
25075 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25078 static void
25079 c_parser_omp_declare_target (c_parser *parser)
25081 tree clauses = NULL_TREE;
25082 int device_type = 0;
25083 bool indirect = false;
25084 bool only_device_type_or_indirect = true;
25085 if (c_parser_next_token_is (parser, CPP_NAME)
25086 || (c_parser_next_token_is (parser, CPP_COMMA)
25087 && c_parser_peek_2nd_token (parser)->type == CPP_NAME))
25088 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
25089 "#pragma omp declare target");
25090 else if (parser->in_omp_decl_attribute
25091 || c_parser_next_token_is (parser, CPP_OPEN_PAREN))
25093 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
25094 clauses);
25095 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
25096 c_parser_skip_to_pragma_eol (parser);
25098 else
25100 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25101 c_parser_skip_to_pragma_eol (parser);
25102 c_omp_declare_target_attr attr = { attr_syntax, -1, 0 };
25103 vec_safe_push (current_omp_declare_target_attribute, attr);
25104 return;
25106 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25108 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
25109 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
25110 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25111 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
25113 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25115 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE
25116 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25117 continue;
25118 tree t = OMP_CLAUSE_DECL (c), id;
25119 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
25120 tree at2 = lookup_attribute ("omp declare target link",
25121 DECL_ATTRIBUTES (t));
25122 only_device_type_or_indirect = false;
25123 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
25125 id = get_identifier ("omp declare target link");
25126 std::swap (at1, at2);
25128 else
25129 id = get_identifier ("omp declare target");
25130 if (at2)
25132 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
25133 error_at (OMP_CLAUSE_LOCATION (c),
25134 "%qD specified both in declare target %<link%> and %qs"
25135 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
25136 else
25137 error_at (OMP_CLAUSE_LOCATION (c),
25138 "%qD specified both in declare target %<link%> and "
25139 "%<to%> or %<enter%> clauses", t);
25140 continue;
25142 if (!at1)
25144 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25145 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
25146 continue;
25148 symtab_node *node = symtab_node::get (t);
25149 if (node != NULL)
25151 node->offloadable = 1;
25152 if (ENABLE_OFFLOADING)
25154 g->have_offload = true;
25155 if (is_a <varpool_node *> (node))
25156 vec_safe_push (offload_vars, t);
25160 if (TREE_CODE (t) != FUNCTION_DECL)
25161 continue;
25162 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
25164 tree at3 = lookup_attribute ("omp declare target host",
25165 DECL_ATTRIBUTES (t));
25166 if (at3 == NULL_TREE)
25168 id = get_identifier ("omp declare target host");
25169 DECL_ATTRIBUTES (t)
25170 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25173 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
25175 tree at3 = lookup_attribute ("omp declare target nohost",
25176 DECL_ATTRIBUTES (t));
25177 if (at3 == NULL_TREE)
25179 id = get_identifier ("omp declare target nohost");
25180 DECL_ATTRIBUTES (t)
25181 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25184 if (indirect)
25186 tree at4 = lookup_attribute ("omp declare target indirect",
25187 DECL_ATTRIBUTES (t));
25188 if (at4 == NULL_TREE)
25190 id = get_identifier ("omp declare target indirect");
25191 DECL_ATTRIBUTES (t)
25192 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25196 if ((device_type || indirect) && only_device_type_or_indirect)
25197 error_at (OMP_CLAUSE_LOCATION (clauses),
25198 "directive with only %<device_type%> or %<indirect%> clauses");
25199 if (indirect && device_type && device_type != OMP_CLAUSE_DEVICE_TYPE_ANY)
25200 error_at (OMP_CLAUSE_LOCATION (clauses),
25201 "%<device_type%> clause must specify 'any' when used with "
25202 "an %<indirect%> clause");
25205 /* OpenMP 5.1
25206 #pragma omp begin assumes clauses[optseq] new-line
25208 #pragma omp begin declare target clauses[optseq] new-line */
25210 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
25211 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25214 static void
25215 c_parser_omp_begin (c_parser *parser)
25217 const char *p = "";
25218 c_parser_consume_pragma (parser);
25219 if (c_parser_next_token_is (parser, CPP_NAME))
25220 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25221 if (strcmp (p, "declare") == 0)
25223 c_parser_consume_token (parser);
25224 p = "";
25225 if (c_parser_next_token_is (parser, CPP_NAME))
25226 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25227 if (strcmp (p, "target") == 0)
25229 c_parser_consume_token (parser);
25230 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25231 tree clauses
25232 = c_parser_omp_all_clauses (parser,
25233 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
25234 "#pragma omp begin declare target");
25235 int device_type = 0;
25236 int indirect = 0;
25237 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25239 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
25240 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
25241 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25242 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
25244 c_omp_declare_target_attr attr = { attr_syntax, device_type,
25245 indirect };
25246 vec_safe_push (current_omp_declare_target_attribute, attr);
25248 else
25250 c_parser_error (parser, "expected %<target%>");
25251 c_parser_skip_to_pragma_eol (parser);
25254 else if (strcmp (p, "assumes") == 0)
25256 c_parser_consume_token (parser);
25257 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25258 c_parser_omp_assumption_clauses (parser, false);
25259 struct c_omp_begin_assumes_data a = { attr_syntax };
25260 vec_safe_push (current_omp_begin_assumes, a);
25262 else
25264 c_parser_error (parser, "expected %<declare target%> or %<assumes%>");
25265 c_parser_skip_to_pragma_eol (parser);
25269 /* OpenMP 4.0
25270 #pragma omp end declare target
25272 OpenMP 5.1
25273 #pragma omp end assumes */
25275 static void
25276 c_parser_omp_end (c_parser *parser)
25278 location_t loc = c_parser_peek_token (parser)->location;
25279 const char *p = "";
25280 c_parser_consume_pragma (parser);
25281 if (c_parser_next_token_is (parser, CPP_NAME))
25282 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25283 if (strcmp (p, "declare") == 0)
25285 c_parser_consume_token (parser);
25286 if (c_parser_next_token_is (parser, CPP_NAME)
25287 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
25288 "target") == 0)
25289 c_parser_consume_token (parser);
25290 else
25292 c_parser_error (parser, "expected %<target%>");
25293 c_parser_skip_to_pragma_eol (parser);
25294 return;
25296 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25297 c_parser_skip_to_pragma_eol (parser);
25298 if (!vec_safe_length (current_omp_declare_target_attribute))
25299 error_at (loc, "%<#pragma omp end declare target%> without "
25300 "corresponding %<#pragma omp declare target%> or "
25301 "%<#pragma omp begin declare target%>");
25302 else
25304 c_omp_declare_target_attr
25305 a = current_omp_declare_target_attribute->pop ();
25306 if (a.attr_syntax != attr_syntax)
25308 if (a.attr_syntax)
25309 error_at (loc,
25310 "%qs in attribute syntax terminated "
25311 "with %qs in pragma syntax",
25312 a.device_type >= 0 ? "begin declare target"
25313 : "declare target",
25314 "end declare target");
25315 else
25316 error_at (loc,
25317 "%qs in pragma syntax terminated "
25318 "with %qs in attribute syntax",
25319 a.device_type >= 0 ? "begin declare target"
25320 : "declare target",
25321 "end declare target");
25325 else if (strcmp (p, "assumes") == 0)
25327 c_parser_consume_token (parser);
25328 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25329 c_parser_skip_to_pragma_eol (parser);
25330 if (!vec_safe_length (current_omp_begin_assumes))
25331 error_at (loc, "%qs without corresponding %qs",
25332 "#pragma omp end assumes", "#pragma omp begin assumes");
25333 else
25335 c_omp_begin_assumes_data
25336 a = current_omp_begin_assumes->pop ();
25337 if (a.attr_syntax != attr_syntax)
25339 if (a.attr_syntax)
25340 error_at (loc,
25341 "%qs in attribute syntax terminated "
25342 "with %qs in pragma syntax",
25343 "begin assumes", "end assumes");
25344 else
25345 error_at (loc,
25346 "%qs in pragma syntax terminated "
25347 "with %qs in attribute syntax",
25348 "begin assumes", "end assumes");
25352 else
25354 c_parser_error (parser, "expected %<declare%> or %<assumes%>");
25355 c_parser_skip_to_pragma_eol (parser);
25359 /* OpenMP 4.0
25360 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25361 initializer-clause[opt] new-line
25363 initializer-clause:
25364 initializer (omp_priv = initializer)
25365 initializer (function-name (argument-list)) */
25367 static void
25368 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
25370 unsigned int tokens_avail = 0, i;
25371 c_token *saved_tokens = NULL;
25372 vec<tree> types = vNULL;
25373 vec<c_token> clauses = vNULL;
25374 enum tree_code reduc_code = ERROR_MARK;
25375 tree reduc_id = NULL_TREE;
25376 tree type;
25377 location_t rloc = c_parser_peek_token (parser)->location;
25379 if (context == pragma_struct || context == pragma_param)
25381 error ("%<#pragma omp declare reduction%> not at file or block scope");
25382 goto fail;
25385 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
25386 goto fail;
25388 switch (c_parser_peek_token (parser)->type)
25390 case CPP_PLUS:
25391 reduc_code = PLUS_EXPR;
25392 break;
25393 case CPP_MULT:
25394 reduc_code = MULT_EXPR;
25395 break;
25396 case CPP_MINUS:
25397 reduc_code = MINUS_EXPR;
25398 break;
25399 case CPP_AND:
25400 reduc_code = BIT_AND_EXPR;
25401 break;
25402 case CPP_XOR:
25403 reduc_code = BIT_XOR_EXPR;
25404 break;
25405 case CPP_OR:
25406 reduc_code = BIT_IOR_EXPR;
25407 break;
25408 case CPP_AND_AND:
25409 reduc_code = TRUTH_ANDIF_EXPR;
25410 break;
25411 case CPP_OR_OR:
25412 reduc_code = TRUTH_ORIF_EXPR;
25413 break;
25414 case CPP_NAME:
25415 const char *p;
25416 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25417 if (strcmp (p, "min") == 0)
25419 reduc_code = MIN_EXPR;
25420 break;
25422 if (strcmp (p, "max") == 0)
25424 reduc_code = MAX_EXPR;
25425 break;
25427 reduc_id = c_parser_peek_token (parser)->value;
25428 break;
25429 default:
25430 c_parser_error (parser,
25431 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
25432 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
25433 goto fail;
25436 tree orig_reduc_id, reduc_decl;
25437 orig_reduc_id = reduc_id;
25438 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
25439 reduc_decl = c_omp_reduction_decl (reduc_id);
25440 c_parser_consume_token (parser);
25442 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
25443 goto fail;
25445 while (true)
25447 location_t loc = c_parser_peek_token (parser)->location;
25448 struct c_type_name *ctype = c_parser_type_name (parser);
25449 if (ctype != NULL)
25451 type = groktypename (ctype, NULL, NULL);
25452 if (type == error_mark_node)
25454 else if ((INTEGRAL_TYPE_P (type)
25455 || SCALAR_FLOAT_TYPE_P (type)
25456 || TREE_CODE (type) == COMPLEX_TYPE)
25457 && orig_reduc_id == NULL_TREE)
25458 error_at (loc, "predeclared arithmetic type in "
25459 "%<#pragma omp declare reduction%>");
25460 else if (TREE_CODE (type) == FUNCTION_TYPE
25461 || TREE_CODE (type) == ARRAY_TYPE)
25462 error_at (loc, "function or array type in "
25463 "%<#pragma omp declare reduction%>");
25464 else if (TYPE_ATOMIC (type))
25465 error_at (loc, "%<_Atomic%> qualified type in "
25466 "%<#pragma omp declare reduction%>");
25467 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
25468 error_at (loc, "const, volatile or restrict qualified type in "
25469 "%<#pragma omp declare reduction%>");
25470 else
25472 tree t;
25473 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
25474 if (comptypes (TREE_PURPOSE (t), type))
25476 error_at (loc, "redeclaration of %qs "
25477 "%<#pragma omp declare reduction%> for "
25478 "type %qT",
25479 IDENTIFIER_POINTER (reduc_id)
25480 + sizeof ("omp declare reduction ") - 1,
25481 type);
25482 location_t ploc
25483 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
25484 0));
25485 error_at (ploc, "previous %<#pragma omp declare "
25486 "reduction%>");
25487 break;
25489 if (t == NULL_TREE)
25490 types.safe_push (type);
25492 if (c_parser_next_token_is (parser, CPP_COMMA))
25493 c_parser_consume_token (parser);
25494 else
25495 break;
25497 else
25498 break;
25501 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
25502 || types.is_empty ())
25504 fail:
25505 clauses.release ();
25506 types.release ();
25507 while (true)
25509 c_token *token = c_parser_peek_token (parser);
25510 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
25511 break;
25512 c_parser_consume_token (parser);
25514 c_parser_skip_to_pragma_eol (parser);
25515 return;
25518 if (types.length () > 1)
25520 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
25522 c_token *token = c_parser_peek_token (parser);
25523 if (token->type == CPP_EOF)
25524 goto fail;
25525 clauses.safe_push (*token);
25526 c_parser_consume_token (parser);
25528 clauses.safe_push (*c_parser_peek_token (parser));
25529 c_parser_skip_to_pragma_eol (parser);
25531 /* Make sure nothing tries to read past the end of the tokens. */
25532 c_token eof_token;
25533 memset (&eof_token, 0, sizeof (eof_token));
25534 eof_token.type = CPP_EOF;
25535 clauses.safe_push (eof_token);
25536 clauses.safe_push (eof_token);
25539 int errs = errorcount;
25540 FOR_EACH_VEC_ELT (types, i, type)
25542 saved_tokens = parser->tokens;
25543 tokens_avail = parser->tokens_avail;
25544 if (!clauses.is_empty ())
25546 parser->tokens = clauses.address ();
25547 parser->tokens_avail = clauses.length ();
25548 parser->in_pragma = true;
25551 bool nested = current_function_decl != NULL_TREE;
25552 if (nested)
25553 c_push_function_context ();
25554 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
25555 reduc_id, default_function_type);
25556 current_function_decl = fndecl;
25557 allocate_struct_function (fndecl, true);
25558 push_scope ();
25559 tree stmt = push_stmt_list ();
25560 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
25561 warn about these. */
25562 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
25563 get_identifier ("omp_out"), type);
25564 DECL_ARTIFICIAL (omp_out) = 1;
25565 DECL_CONTEXT (omp_out) = fndecl;
25566 pushdecl (omp_out);
25567 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
25568 get_identifier ("omp_in"), type);
25569 DECL_ARTIFICIAL (omp_in) = 1;
25570 DECL_CONTEXT (omp_in) = fndecl;
25571 pushdecl (omp_in);
25572 struct c_expr combiner = c_parser_expression (parser);
25573 struct c_expr initializer;
25574 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
25575 bool bad = false;
25576 initializer.set_error ();
25577 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
25578 bad = true;
25579 else if (c_parser_next_token_is (parser, CPP_COMMA)
25580 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
25581 c_parser_consume_token (parser);
25582 if (!bad
25583 && (c_parser_next_token_is (parser, CPP_NAME)
25584 && strcmp (IDENTIFIER_POINTER
25585 (c_parser_peek_token (parser)->value),
25586 "initializer") == 0))
25588 c_parser_consume_token (parser);
25589 pop_scope ();
25590 push_scope ();
25591 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
25592 get_identifier ("omp_priv"), type);
25593 DECL_ARTIFICIAL (omp_priv) = 1;
25594 DECL_INITIAL (omp_priv) = error_mark_node;
25595 DECL_CONTEXT (omp_priv) = fndecl;
25596 pushdecl (omp_priv);
25597 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
25598 get_identifier ("omp_orig"), type);
25599 DECL_ARTIFICIAL (omp_orig) = 1;
25600 DECL_CONTEXT (omp_orig) = fndecl;
25601 pushdecl (omp_orig);
25602 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
25603 bad = true;
25604 else if (!c_parser_next_token_is (parser, CPP_NAME))
25606 c_parser_error (parser, "expected %<omp_priv%> or "
25607 "function-name");
25608 bad = true;
25610 else if (strcmp (IDENTIFIER_POINTER
25611 (c_parser_peek_token (parser)->value),
25612 "omp_priv") != 0)
25614 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
25615 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
25617 c_parser_error (parser, "expected function-name %<(%>");
25618 bad = true;
25620 else
25621 initializer = c_parser_postfix_expression (parser);
25622 if (initializer.value
25623 && TREE_CODE (initializer.value) == CALL_EXPR)
25625 int j;
25626 tree c = initializer.value;
25627 for (j = 0; j < call_expr_nargs (c); j++)
25629 tree a = CALL_EXPR_ARG (c, j);
25630 STRIP_NOPS (a);
25631 if (TREE_CODE (a) == ADDR_EXPR
25632 && TREE_OPERAND (a, 0) == omp_priv)
25633 break;
25635 if (j == call_expr_nargs (c))
25636 error ("one of the initializer call arguments should be "
25637 "%<&omp_priv%>");
25640 else
25642 c_parser_consume_token (parser);
25643 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
25644 bad = true;
25645 else
25647 tree st = push_stmt_list ();
25648 location_t loc = c_parser_peek_token (parser)->location;
25649 rich_location richloc (line_table, loc);
25650 start_init (omp_priv, NULL_TREE, false, false, &richloc);
25651 struct c_expr init = c_parser_initializer (parser, omp_priv);
25652 finish_init ();
25653 finish_decl (omp_priv, loc, init.value,
25654 init.original_type, NULL_TREE);
25655 pop_stmt_list (st);
25658 if (!bad
25659 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
25660 bad = true;
25663 if (!bad)
25665 c_parser_skip_to_pragma_eol (parser);
25667 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
25668 DECL_INITIAL (reduc_decl));
25669 DECL_INITIAL (reduc_decl) = t;
25670 DECL_SOURCE_LOCATION (omp_out) = rloc;
25671 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
25672 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
25673 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
25674 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
25675 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
25676 if (omp_priv)
25678 DECL_SOURCE_LOCATION (omp_priv) = rloc;
25679 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
25680 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
25681 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
25682 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
25683 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
25684 walk_tree (&DECL_INITIAL (omp_priv),
25685 c_check_omp_declare_reduction_r,
25686 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
25690 pop_stmt_list (stmt);
25691 pop_scope ();
25692 if (cfun->language != NULL)
25694 ggc_free (cfun->language);
25695 cfun->language = NULL;
25697 set_cfun (NULL);
25698 current_function_decl = NULL_TREE;
25699 if (nested)
25700 c_pop_function_context ();
25702 if (!clauses.is_empty ())
25704 parser->tokens = saved_tokens;
25705 parser->tokens_avail = tokens_avail;
25707 if (bad)
25708 goto fail;
25709 if (errs != errorcount)
25710 break;
25713 clauses.release ();
25714 types.release ();
25718 /* OpenMP 4.0
25719 #pragma omp declare simd declare-simd-clauses[optseq] new-line
25720 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25721 initializer-clause[opt] new-line
25722 #pragma omp declare target new-line
25724 OpenMP 5.0
25725 #pragma omp declare variant (identifier) match (context-selector) */
25727 static bool
25728 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
25730 c_parser_consume_pragma (parser);
25731 if (c_parser_next_token_is (parser, CPP_NAME))
25733 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25734 if (strcmp (p, "simd") == 0)
25736 /* c_parser_consume_token (parser); done in
25737 c_parser_omp_declare_simd. */
25738 c_parser_omp_declare_simd (parser, context);
25739 return true;
25741 if (strcmp (p, "reduction") == 0)
25743 c_parser_consume_token (parser);
25744 c_parser_omp_declare_reduction (parser, context);
25745 return false;
25747 if (!flag_openmp) /* flag_openmp_simd */
25749 c_parser_skip_to_pragma_eol (parser, false);
25750 return false;
25752 if (strcmp (p, "target") == 0)
25754 c_parser_consume_token (parser);
25755 c_parser_omp_declare_target (parser);
25756 return false;
25758 if (strcmp (p, "variant") == 0)
25760 /* c_parser_consume_token (parser); done in
25761 c_parser_omp_declare_simd. */
25762 c_parser_omp_declare_simd (parser, context);
25763 return true;
25767 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
25768 "%<target%> or %<variant%>");
25769 c_parser_skip_to_pragma_eol (parser);
25770 return false;
25773 /* OpenMP 5.0
25774 #pragma omp requires clauses[optseq] new-line */
25776 static void
25777 c_parser_omp_requires (c_parser *parser)
25779 enum omp_requires new_req = (enum omp_requires) 0;
25781 c_parser_consume_pragma (parser);
25783 location_t loc = c_parser_peek_token (parser)->location;
25784 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
25786 if (c_parser_next_token_is (parser, CPP_COMMA)
25787 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
25788 c_parser_consume_token (parser);
25790 if (c_parser_next_token_is (parser, CPP_NAME))
25792 const char *p
25793 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25794 location_t cloc = c_parser_peek_token (parser)->location;
25795 enum omp_requires this_req = (enum omp_requires) 0;
25797 if (!strcmp (p, "unified_address"))
25798 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
25799 else if (!strcmp (p, "unified_shared_memory"))
25800 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
25801 else if (!strcmp (p, "dynamic_allocators"))
25802 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
25803 else if (!strcmp (p, "reverse_offload"))
25804 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
25805 else if (!strcmp (p, "atomic_default_mem_order"))
25807 c_parser_consume_token (parser);
25809 matching_parens parens;
25810 if (parens.require_open (parser))
25812 if (c_parser_next_token_is (parser, CPP_NAME))
25814 tree v = c_parser_peek_token (parser)->value;
25815 p = IDENTIFIER_POINTER (v);
25817 if (!strcmp (p, "seq_cst"))
25818 this_req
25819 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
25820 else if (!strcmp (p, "relaxed"))
25821 this_req
25822 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
25823 else if (!strcmp (p, "release"))
25824 this_req
25825 = (enum omp_requires) OMP_MEMORY_ORDER_RELEASE;
25826 else if (!strcmp (p, "acq_rel"))
25827 this_req
25828 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
25829 else if (!strcmp (p, "acquire"))
25830 this_req
25831 = (enum omp_requires) OMP_MEMORY_ORDER_ACQUIRE;
25833 if (this_req == 0)
25835 error_at (c_parser_peek_token (parser)->location,
25836 "expected %<acq_rel%>, %<acquire%>, "
25837 "%<relaxed%>, %<release%> or %<seq_cst%>");
25838 switch (c_parser_peek_token (parser)->type)
25840 case CPP_EOF:
25841 case CPP_PRAGMA_EOL:
25842 case CPP_CLOSE_PAREN:
25843 break;
25844 default:
25845 if (c_parser_peek_2nd_token (parser)->type
25846 == CPP_CLOSE_PAREN)
25847 c_parser_consume_token (parser);
25848 break;
25851 else
25852 c_parser_consume_token (parser);
25854 parens.skip_until_found_close (parser);
25855 if (this_req == 0)
25857 c_parser_skip_to_pragma_eol (parser, false);
25858 return;
25861 p = NULL;
25863 else
25865 error_at (cloc, "expected %<unified_address%>, "
25866 "%<unified_shared_memory%>, "
25867 "%<dynamic_allocators%>, "
25868 "%<reverse_offload%> "
25869 "or %<atomic_default_mem_order%> clause");
25870 c_parser_skip_to_pragma_eol (parser, false);
25871 return;
25873 if (p)
25874 c_parser_consume_token (parser);
25875 if (this_req)
25877 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
25879 if ((this_req & new_req) != 0)
25880 error_at (cloc, "too many %qs clauses", p);
25881 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
25882 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
25883 error_at (cloc, "%qs clause used lexically after first "
25884 "target construct or offloading API", p);
25886 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
25888 error_at (cloc, "too many %qs clauses",
25889 "atomic_default_mem_order");
25890 this_req = (enum omp_requires) 0;
25892 else if ((omp_requires_mask
25893 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
25895 error_at (cloc, "more than one %<atomic_default_mem_order%>"
25896 " clause in a single compilation unit");
25897 this_req
25898 = (enum omp_requires)
25899 (omp_requires_mask
25900 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
25902 else if ((omp_requires_mask
25903 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
25904 error_at (cloc, "%<atomic_default_mem_order%> clause used "
25905 "lexically after first %<atomic%> construct "
25906 "without memory order clause");
25907 new_req = (enum omp_requires) (new_req | this_req);
25908 omp_requires_mask
25909 = (enum omp_requires) (omp_requires_mask | this_req);
25910 continue;
25913 break;
25915 c_parser_skip_to_pragma_eol (parser);
25917 if (new_req == 0)
25918 error_at (loc, "%<pragma omp requires%> requires at least one clause");
25921 /* Helper function for c_parser_omp_taskloop.
25922 Disallow zero sized or potentially zero sized task reductions. */
25924 static tree
25925 c_finish_taskloop_clauses (tree clauses)
25927 tree *pc = &clauses;
25928 for (tree c = clauses; c; c = *pc)
25930 bool remove = false;
25931 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
25933 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
25934 if (integer_zerop (TYPE_SIZE_UNIT (type)))
25936 error_at (OMP_CLAUSE_LOCATION (c),
25937 "zero sized type %qT in %<reduction%> clause", type);
25938 remove = true;
25940 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
25942 error_at (OMP_CLAUSE_LOCATION (c),
25943 "variable sized type %qT in %<reduction%> clause",
25944 type);
25945 remove = true;
25948 if (remove)
25949 *pc = OMP_CLAUSE_CHAIN (c);
25950 else
25951 pc = &OMP_CLAUSE_CHAIN (c);
25953 return clauses;
25956 /* OpenMP 4.5:
25957 #pragma omp taskloop taskloop-clause[optseq] new-line
25958 for-loop
25960 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
25961 for-loop */
25963 #define OMP_TASKLOOP_CLAUSE_MASK \
25964 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
25965 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
25966 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
25967 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
25968 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
25969 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
25970 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
25971 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
25972 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
25973 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
25974 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
25975 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
25976 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
25977 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
25978 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
25979 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
25980 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
25982 static tree
25983 c_parser_omp_taskloop (location_t loc, c_parser *parser,
25984 char *p_name, omp_clause_mask mask, tree *cclauses,
25985 bool *if_p)
25987 tree clauses, block, ret;
25989 strcat (p_name, " taskloop");
25990 mask |= OMP_TASKLOOP_CLAUSE_MASK;
25991 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
25992 clause. */
25993 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
25994 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
25996 if (c_parser_next_token_is (parser, CPP_NAME))
25998 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26000 if (strcmp (p, "simd") == 0)
26002 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
26003 if (cclauses == NULL)
26004 cclauses = cclauses_buf;
26005 c_parser_consume_token (parser);
26006 if (!flag_openmp) /* flag_openmp_simd */
26007 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
26008 if_p);
26009 block = c_begin_compound_stmt (true);
26010 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
26011 block = c_end_compound_stmt (loc, block, true);
26012 if (ret == NULL)
26013 return ret;
26014 ret = make_node (OMP_TASKLOOP);
26015 TREE_TYPE (ret) = void_type_node;
26016 OMP_FOR_BODY (ret) = block;
26017 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
26018 OMP_FOR_CLAUSES (ret)
26019 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
26020 SET_EXPR_LOCATION (ret, loc);
26021 add_stmt (ret);
26022 return ret;
26025 if (!flag_openmp) /* flag_openmp_simd */
26027 c_parser_skip_to_pragma_eol (parser, false);
26028 return NULL_TREE;
26031 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
26032 if (cclauses)
26034 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
26035 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
26038 clauses = c_finish_taskloop_clauses (clauses);
26039 block = c_begin_compound_stmt (true);
26040 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
26041 block = c_end_compound_stmt (loc, block, true);
26042 add_stmt (block);
26044 return ret;
26047 /* OpenMP 5.1
26048 #pragma omp nothing new-line */
26050 static void
26051 c_parser_omp_nothing (c_parser *parser)
26053 c_parser_consume_pragma (parser);
26054 c_parser_skip_to_pragma_eol (parser);
26057 /* OpenMP 5.1
26058 #pragma omp error clauses[optseq] new-line */
26060 static bool
26061 c_parser_omp_error (c_parser *parser, enum pragma_context context)
26063 int at_compilation = -1;
26064 int severity_fatal = -1;
26065 tree message = NULL_TREE;
26066 bool bad = false;
26067 location_t loc = c_parser_peek_token (parser)->location;
26069 c_parser_consume_pragma (parser);
26071 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
26073 if (c_parser_next_token_is (parser, CPP_COMMA)
26074 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
26075 c_parser_consume_token (parser);
26077 if (!c_parser_next_token_is (parser, CPP_NAME))
26078 break;
26080 const char *p
26081 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26082 location_t cloc = c_parser_peek_token (parser)->location;
26083 static const char *args[] = {
26084 "execution", "compilation", "warning", "fatal"
26086 int *v = NULL;
26087 int idx = 0, n = -1;
26088 tree m = NULL_TREE;
26090 if (!strcmp (p, "at"))
26091 v = &at_compilation;
26092 else if (!strcmp (p, "severity"))
26094 v = &severity_fatal;
26095 idx += 2;
26097 else if (strcmp (p, "message"))
26099 error_at (cloc,
26100 "expected %<at%>, %<severity%> or %<message%> clause");
26101 c_parser_skip_to_pragma_eol (parser, false);
26102 return false;
26105 c_parser_consume_token (parser);
26107 matching_parens parens;
26108 if (parens.require_open (parser))
26110 if (v == NULL)
26112 location_t expr_loc = c_parser_peek_token (parser)->location;
26113 c_expr expr = c_parser_expr_no_commas (parser, NULL);
26114 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
26115 m = convert (const_string_type_node, expr.value);
26116 m = c_fully_fold (m, false, NULL);
26118 else
26120 if (c_parser_next_token_is (parser, CPP_NAME))
26122 tree val = c_parser_peek_token (parser)->value;
26123 const char *q = IDENTIFIER_POINTER (val);
26125 if (!strcmp (q, args[idx]))
26126 n = 0;
26127 else if (!strcmp (q, args[idx + 1]))
26128 n = 1;
26130 if (n == -1)
26132 error_at (c_parser_peek_token (parser)->location,
26133 "expected %qs or %qs", args[idx], args[idx + 1]);
26134 bad = true;
26135 switch (c_parser_peek_token (parser)->type)
26137 case CPP_EOF:
26138 case CPP_PRAGMA_EOL:
26139 case CPP_CLOSE_PAREN:
26140 break;
26141 default:
26142 if (c_parser_peek_2nd_token (parser)->type
26143 == CPP_CLOSE_PAREN)
26144 c_parser_consume_token (parser);
26145 break;
26148 else
26149 c_parser_consume_token (parser);
26152 parens.skip_until_found_close (parser);
26154 if (v == NULL)
26156 if (message)
26158 error_at (cloc, "too many %qs clauses", p);
26159 bad = true;
26161 else
26162 message = m;
26164 else if (n != -1)
26166 if (*v != -1)
26168 error_at (cloc, "too many %qs clauses", p);
26169 bad = true;
26171 else
26172 *v = n;
26175 else
26176 bad = true;
26178 c_parser_skip_to_pragma_eol (parser);
26179 if (bad)
26180 return true;
26182 if (at_compilation == -1)
26183 at_compilation = 1;
26184 if (severity_fatal == -1)
26185 severity_fatal = 1;
26186 if (!at_compilation)
26188 if (context != pragma_compound)
26190 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
26191 "may only be used in compound statements");
26192 return true;
26194 tree fndecl
26195 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
26196 : BUILT_IN_GOMP_WARNING);
26197 if (!message)
26198 message = build_zero_cst (const_string_type_node);
26199 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
26200 build_all_ones_cst (size_type_node));
26201 add_stmt (stmt);
26202 return true;
26204 const char *msg = NULL;
26205 if (message)
26207 msg = c_getstr (message);
26208 if (msg == NULL)
26209 msg = _("<message unknown at compile time>");
26211 if (msg)
26212 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
26213 "%<pragma omp error%> encountered: %s", msg);
26214 else
26215 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
26216 "%<pragma omp error%> encountered");
26217 return false;
26220 /* Assumption clauses:
26221 OpenMP 5.1
26222 absent (directive-name-list)
26223 contains (directive-name-list)
26224 holds (expression)
26225 no_openmp
26226 no_openmp_routines
26227 no_parallelism */
26229 static void
26230 c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
26232 bool no_openmp = false;
26233 bool no_openmp_routines = false;
26234 bool no_parallelism = false;
26235 bitmap_head absent_head, contains_head;
26237 bitmap_obstack_initialize (NULL);
26238 bitmap_initialize (&absent_head, &bitmap_default_obstack);
26239 bitmap_initialize (&contains_head, &bitmap_default_obstack);
26241 if (c_parser_next_token_is (parser, CPP_PRAGMA_EOL))
26242 error_at (c_parser_peek_token (parser)->location,
26243 "expected at least one assumption clause");
26245 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
26247 if (c_parser_next_token_is (parser, CPP_COMMA)
26248 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
26249 c_parser_consume_token (parser);
26251 if (!c_parser_next_token_is (parser, CPP_NAME))
26252 break;
26254 const char *p
26255 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26256 location_t cloc = c_parser_peek_token (parser)->location;
26258 if (!strcmp (p, "no_openmp"))
26260 c_parser_consume_token (parser);
26261 if (no_openmp)
26262 error_at (cloc, "too many %qs clauses", "no_openmp");
26263 no_openmp = true;
26265 else if (!strcmp (p, "no_openmp_routines"))
26267 c_parser_consume_token (parser);
26268 if (no_openmp_routines)
26269 error_at (cloc, "too many %qs clauses", "no_openmp_routines");
26270 no_openmp_routines = true;
26272 else if (!strcmp (p, "no_parallelism"))
26274 c_parser_consume_token (parser);
26275 if (no_parallelism)
26276 error_at (cloc, "too many %qs clauses", "no_parallelism");
26277 no_parallelism = true;
26279 else if (!strcmp (p, "holds"))
26281 c_parser_consume_token (parser);
26282 matching_parens parens;
26283 if (parens.require_open (parser))
26285 location_t eloc = c_parser_peek_token (parser)->location;
26286 c_expr expr = c_parser_expr_no_commas (parser, NULL);
26287 tree t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
26288 t = c_objc_common_truthvalue_conversion (eloc, t);
26289 t = c_fully_fold (t, false, NULL);
26290 if (is_assume && t != error_mark_node)
26292 tree fn = build_call_expr_internal_loc (eloc, IFN_ASSUME,
26293 void_type_node, 1,
26295 add_stmt (fn);
26297 parens.skip_until_found_close (parser);
26300 else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
26302 c_parser_consume_token (parser);
26303 matching_parens parens;
26304 if (parens.require_open (parser))
26308 const char *directive[3] = {};
26309 int i;
26310 location_t dloc = c_parser_peek_token (parser)->location;
26311 for (i = 0; i < 3; i++)
26313 tree id;
26314 if (c_parser_peek_nth_token (parser, i + 1)->type
26315 == CPP_NAME)
26316 id = c_parser_peek_nth_token (parser, i + 1)->value;
26317 else if (c_parser_peek_nth_token (parser, i + 1)->keyword
26318 != RID_MAX)
26320 enum rid rid
26321 = c_parser_peek_nth_token (parser, i + 1)->keyword;
26322 id = ridpointers[rid];
26324 else
26325 break;
26326 directive[i] = IDENTIFIER_POINTER (id);
26328 if (i == 0)
26329 error_at (dloc, "expected directive name");
26330 else
26332 const struct c_omp_directive *dir
26333 = c_omp_categorize_directive (directive[0],
26334 directive[1],
26335 directive[2]);
26336 if (dir == NULL
26337 || dir->kind == C_OMP_DIR_DECLARATIVE
26338 || dir->kind == C_OMP_DIR_INFORMATIONAL
26339 || dir->id == PRAGMA_OMP_END
26340 || (!dir->second && directive[1])
26341 || (!dir->third && directive[2]))
26342 error_at (dloc, "unknown OpenMP directive name in "
26343 "%qs clause argument", p);
26344 else
26346 int id = dir - c_omp_directives;
26347 if (bitmap_bit_p (p[0] == 'a' ? &contains_head
26348 : &absent_head, id))
26349 error_at (dloc, "%<%s%s%s%s%s%> directive "
26350 "mentioned in both %<absent%> and "
26351 "%<contains%> clauses",
26352 directive[0],
26353 directive[1] ? " " : "",
26354 directive[1] ? directive[1] : "",
26355 directive[2] ? " " : "",
26356 directive[2] ? directive[2] : "");
26357 else if (!bitmap_set_bit (p[0] == 'a'
26358 ? &absent_head
26359 : &contains_head, id))
26360 error_at (dloc, "%<%s%s%s%s%s%> directive "
26361 "mentioned multiple times in %qs "
26362 "clauses",
26363 directive[0],
26364 directive[1] ? " " : "",
26365 directive[1] ? directive[1] : "",
26366 directive[2] ? " " : "",
26367 directive[2] ? directive[2] : "", p);
26369 for (; i; --i)
26370 c_parser_consume_token (parser);
26372 if (c_parser_next_token_is (parser, CPP_COMMA))
26373 c_parser_consume_token (parser);
26374 else
26375 break;
26377 while (1);
26378 parens.skip_until_found_close (parser);
26381 else if (startswith (p, "ext_"))
26383 warning_at (cloc, OPT_Wopenmp, "unknown assumption clause %qs", p);
26384 c_parser_consume_token (parser);
26385 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
26387 matching_parens parens;
26388 parens.consume_open (parser);
26389 c_parser_balanced_token_sequence (parser);
26390 parens.require_close (parser);
26393 else
26395 c_parser_consume_token (parser);
26396 error_at (cloc, "expected assumption clause");
26397 break;
26400 c_parser_skip_to_pragma_eol (parser);
26403 /* OpenMP 5.1
26404 #pragma omp assume clauses[optseq] new-line */
26406 static void
26407 c_parser_omp_assume (c_parser *parser, bool *if_p)
26409 c_parser_omp_assumption_clauses (parser, true);
26410 add_stmt (c_parser_omp_structured_block (parser, if_p));
26413 /* OpenMP 5.1
26414 #pragma omp assumes clauses[optseq] new-line */
26416 static void
26417 c_parser_omp_assumes (c_parser *parser)
26419 c_parser_consume_pragma (parser);
26420 c_parser_omp_assumption_clauses (parser, false);
26423 /* Main entry point to parsing most OpenMP pragmas. */
26425 static void
26426 c_parser_omp_construct (c_parser *parser, bool *if_p)
26428 enum pragma_kind p_kind;
26429 location_t loc;
26430 tree stmt;
26431 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
26432 omp_clause_mask mask (0);
26434 loc = c_parser_peek_token (parser)->location;
26435 p_kind = c_parser_peek_token (parser)->pragma_kind;
26436 c_parser_consume_pragma (parser);
26438 switch (p_kind)
26440 case PRAGMA_OACC_ATOMIC:
26441 c_parser_omp_atomic (loc, parser, true);
26442 return;
26443 case PRAGMA_OACC_CACHE:
26444 strcpy (p_name, "#pragma acc");
26445 stmt = c_parser_oacc_cache (loc, parser);
26446 break;
26447 case PRAGMA_OACC_DATA:
26448 stmt = c_parser_oacc_data (loc, parser, if_p);
26449 break;
26450 case PRAGMA_OACC_HOST_DATA:
26451 stmt = c_parser_oacc_host_data (loc, parser, if_p);
26452 break;
26453 case PRAGMA_OACC_KERNELS:
26454 case PRAGMA_OACC_PARALLEL:
26455 case PRAGMA_OACC_SERIAL:
26456 strcpy (p_name, "#pragma acc");
26457 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
26458 break;
26459 case PRAGMA_OACC_LOOP:
26460 strcpy (p_name, "#pragma acc");
26461 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
26462 break;
26463 case PRAGMA_OACC_WAIT:
26464 strcpy (p_name, "#pragma wait");
26465 stmt = c_parser_oacc_wait (loc, parser, p_name);
26466 break;
26467 case PRAGMA_OMP_ATOMIC:
26468 c_parser_omp_atomic (loc, parser, false);
26469 return;
26470 case PRAGMA_OMP_CRITICAL:
26471 stmt = c_parser_omp_critical (loc, parser, if_p);
26472 break;
26473 case PRAGMA_OMP_DISTRIBUTE:
26474 strcpy (p_name, "#pragma omp");
26475 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
26476 break;
26477 case PRAGMA_OMP_FOR:
26478 strcpy (p_name, "#pragma omp");
26479 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
26480 break;
26481 case PRAGMA_OMP_LOOP:
26482 strcpy (p_name, "#pragma omp");
26483 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
26484 break;
26485 case PRAGMA_OMP_MASKED:
26486 strcpy (p_name, "#pragma omp");
26487 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
26488 break;
26489 case PRAGMA_OMP_MASTER:
26490 strcpy (p_name, "#pragma omp");
26491 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
26492 break;
26493 case PRAGMA_OMP_PARALLEL:
26494 strcpy (p_name, "#pragma omp");
26495 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
26496 break;
26497 case PRAGMA_OMP_SCOPE:
26498 stmt = c_parser_omp_scope (loc, parser, if_p);
26499 break;
26500 case PRAGMA_OMP_SECTIONS:
26501 strcpy (p_name, "#pragma omp");
26502 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
26503 break;
26504 case PRAGMA_OMP_SIMD:
26505 strcpy (p_name, "#pragma omp");
26506 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
26507 break;
26508 case PRAGMA_OMP_SINGLE:
26509 stmt = c_parser_omp_single (loc, parser, if_p);
26510 break;
26511 case PRAGMA_OMP_TASK:
26512 stmt = c_parser_omp_task (loc, parser, if_p);
26513 break;
26514 case PRAGMA_OMP_TASKGROUP:
26515 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
26516 break;
26517 case PRAGMA_OMP_TASKLOOP:
26518 strcpy (p_name, "#pragma omp");
26519 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
26520 break;
26521 case PRAGMA_OMP_TEAMS:
26522 strcpy (p_name, "#pragma omp");
26523 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
26524 break;
26525 case PRAGMA_OMP_ASSUME:
26526 c_parser_omp_assume (parser, if_p);
26527 return;
26528 default:
26529 gcc_unreachable ();
26532 if (stmt && stmt != error_mark_node)
26533 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
26537 /* OpenMP 2.5:
26538 # pragma omp threadprivate (variable-list) */
26540 static void
26541 c_parser_omp_threadprivate (c_parser *parser)
26543 tree vars, t;
26544 location_t loc;
26546 c_parser_consume_pragma (parser);
26547 loc = c_parser_peek_token (parser)->location;
26548 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
26550 /* Mark every variable in VARS to be assigned thread local storage. */
26551 for (t = vars; t; t = TREE_CHAIN (t))
26553 tree v = TREE_PURPOSE (t);
26555 /* FIXME diagnostics: Ideally we should keep individual
26556 locations for all the variables in the var list to make the
26557 following errors more precise. Perhaps
26558 c_parser_omp_var_list_parens() should construct a list of
26559 locations to go along with the var list. */
26561 /* If V had already been marked threadprivate, it doesn't matter
26562 whether it had been used prior to this point. */
26563 if (!VAR_P (v))
26564 error_at (loc, "%qD is not a variable", v);
26565 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
26566 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
26567 else if (! is_global_var (v))
26568 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
26569 else if (TREE_TYPE (v) == error_mark_node)
26571 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
26572 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
26573 else
26575 if (! DECL_THREAD_LOCAL_P (v))
26577 set_decl_tls_model (v, decl_default_tls_model (v));
26578 /* If rtl has been already set for this var, call
26579 make_decl_rtl once again, so that encode_section_info
26580 has a chance to look at the new decl flags. */
26581 if (DECL_RTL_SET_P (v))
26582 make_decl_rtl (v);
26584 C_DECL_THREADPRIVATE_P (v) = 1;
26588 c_parser_skip_to_pragma_eol (parser);
26591 /* Parse a transaction attribute (GCC Extension).
26593 transaction-attribute:
26594 gnu-attributes
26595 attribute-specifier
26598 static tree
26599 c_parser_transaction_attributes (c_parser *parser)
26601 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
26602 return c_parser_gnu_attributes (parser);
26604 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
26605 return NULL_TREE;
26606 return c_parser_std_attribute_specifier (parser, true);
26609 /* Parse a __transaction_atomic or __transaction_relaxed statement
26610 (GCC Extension).
26612 transaction-statement:
26613 __transaction_atomic transaction-attribute[opt] compound-statement
26614 __transaction_relaxed compound-statement
26616 Note that the only valid attribute is: "outer".
26619 static tree
26620 c_parser_transaction (c_parser *parser, enum rid keyword)
26622 unsigned int old_in = parser->in_transaction;
26623 unsigned int this_in = 1, new_in;
26624 location_t loc = c_parser_peek_token (parser)->location;
26625 tree stmt, attrs;
26627 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
26628 || keyword == RID_TRANSACTION_RELAXED)
26629 && c_parser_next_token_is_keyword (parser, keyword));
26630 c_parser_consume_token (parser);
26632 if (keyword == RID_TRANSACTION_RELAXED)
26633 this_in |= TM_STMT_ATTR_RELAXED;
26634 else
26636 attrs = c_parser_transaction_attributes (parser);
26637 if (attrs)
26638 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
26641 /* Keep track if we're in the lexical scope of an outer transaction. */
26642 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
26644 parser->in_transaction = new_in;
26645 stmt = c_parser_compound_statement (parser);
26646 parser->in_transaction = old_in;
26648 if (flag_tm)
26649 stmt = c_finish_transaction (loc, stmt, this_in);
26650 else
26651 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
26652 "%<__transaction_atomic%> without transactional memory support enabled"
26653 : "%<__transaction_relaxed %> "
26654 "without transactional memory support enabled"));
26656 return stmt;
26659 /* Parse a __transaction_atomic or __transaction_relaxed expression
26660 (GCC Extension).
26662 transaction-expression:
26663 __transaction_atomic ( expression )
26664 __transaction_relaxed ( expression )
26667 static struct c_expr
26668 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
26670 struct c_expr ret;
26671 unsigned int old_in = parser->in_transaction;
26672 unsigned int this_in = 1;
26673 location_t loc = c_parser_peek_token (parser)->location;
26674 tree attrs;
26676 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
26677 || keyword == RID_TRANSACTION_RELAXED)
26678 && c_parser_next_token_is_keyword (parser, keyword));
26679 c_parser_consume_token (parser);
26681 if (keyword == RID_TRANSACTION_RELAXED)
26682 this_in |= TM_STMT_ATTR_RELAXED;
26683 else
26685 attrs = c_parser_transaction_attributes (parser);
26686 if (attrs)
26687 this_in |= parse_tm_stmt_attr (attrs, 0);
26690 parser->in_transaction = this_in;
26691 matching_parens parens;
26692 if (parens.require_open (parser))
26694 tree expr = c_parser_expression (parser).value;
26695 ret.original_type = TREE_TYPE (expr);
26696 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
26697 if (this_in & TM_STMT_ATTR_RELAXED)
26698 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
26699 SET_EXPR_LOCATION (ret.value, loc);
26700 ret.original_code = TRANSACTION_EXPR;
26701 ret.m_decimal = 0;
26702 if (!parens.require_close (parser))
26704 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
26705 goto error;
26708 else
26710 error:
26711 ret.set_error ();
26712 ret.original_code = ERROR_MARK;
26713 ret.original_type = NULL;
26715 parser->in_transaction = old_in;
26717 if (!flag_tm)
26718 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
26719 "%<__transaction_atomic%> without transactional memory support enabled"
26720 : "%<__transaction_relaxed %> "
26721 "without transactional memory support enabled"));
26723 set_c_expr_source_range (&ret, loc, loc);
26725 return ret;
26728 /* Parse a __transaction_cancel statement (GCC Extension).
26730 transaction-cancel-statement:
26731 __transaction_cancel transaction-attribute[opt] ;
26733 Note that the only valid attribute is "outer".
26736 static tree
26737 c_parser_transaction_cancel (c_parser *parser)
26739 location_t loc = c_parser_peek_token (parser)->location;
26740 tree attrs;
26741 bool is_outer = false;
26743 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
26744 c_parser_consume_token (parser);
26746 attrs = c_parser_transaction_attributes (parser);
26747 if (attrs)
26748 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
26750 if (!flag_tm)
26752 error_at (loc, "%<__transaction_cancel%> without "
26753 "transactional memory support enabled");
26754 goto ret_error;
26756 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
26758 error_at (loc, "%<__transaction_cancel%> within a "
26759 "%<__transaction_relaxed%>");
26760 goto ret_error;
26762 else if (is_outer)
26764 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
26765 && !is_tm_may_cancel_outer (current_function_decl))
26767 error_at (loc, "outer %<__transaction_cancel%> not "
26768 "within outer %<__transaction_atomic%> or "
26769 "a %<transaction_may_cancel_outer%> function");
26770 goto ret_error;
26773 else if (parser->in_transaction == 0)
26775 error_at (loc, "%<__transaction_cancel%> not within "
26776 "%<__transaction_atomic%>");
26777 goto ret_error;
26780 return add_stmt (build_tm_abort_call (loc, is_outer));
26782 ret_error:
26783 return build1 (NOP_EXPR, void_type_node, error_mark_node);
26786 /* Parse a single source file. */
26788 void
26789 c_parse_file (void)
26791 /* Use local storage to begin. If the first token is a pragma, parse it.
26792 If it is #pragma GCC pch_preprocess, then this will load a PCH file
26793 which will cause garbage collection. */
26794 c_parser tparser;
26796 memset (&tparser, 0, sizeof tparser);
26797 tparser.translate_strings_p = true;
26798 tparser.tokens = &tparser.tokens_buf[0];
26799 the_parser = &tparser;
26801 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
26802 c_parser_pragma_pch_preprocess (&tparser);
26803 else
26804 c_common_no_more_pch ();
26806 the_parser = ggc_alloc<c_parser> ();
26807 *the_parser = tparser;
26808 if (tparser.tokens == &tparser.tokens_buf[0])
26809 the_parser->tokens = &the_parser->tokens_buf[0];
26811 /* Initialize EH, if we've been told to do so. */
26812 if (flag_exceptions)
26813 using_eh_for_cleanups ();
26815 c_parser_translation_unit (the_parser);
26816 the_parser = NULL;
26819 void
26820 c_init_preprocess (void)
26822 /* Create a parser for use by pragma_lex during preprocessing. */
26823 the_parser = ggc_alloc<c_parser> ();
26824 memset (the_parser, 0, sizeof (c_parser));
26825 the_parser->tokens = &the_parser->tokens_buf[0];
26828 /* Parse the body of a function declaration marked with "__RTL".
26830 The RTL parser works on the level of characters read from a
26831 FILE *, whereas c_parser works at the level of tokens.
26832 Square this circle by consuming all of the tokens up to and
26833 including the closing brace, recording the start/end of the RTL
26834 fragment, and reopening the file and re-reading the relevant
26835 lines within the RTL parser.
26837 This requires the opening and closing braces of the C function
26838 to be on separate lines from the RTL they wrap.
26840 Take ownership of START_WITH_PASS, if non-NULL. */
26842 location_t
26843 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
26845 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
26847 free (start_with_pass);
26848 return c_parser_peek_token (parser)->location;
26851 location_t start_loc = c_parser_peek_token (parser)->location;
26853 /* Consume all tokens, up to the closing brace, handling
26854 matching pairs of braces in the rtl dump. */
26855 int num_open_braces = 1;
26856 while (1)
26858 switch (c_parser_peek_token (parser)->type)
26860 case CPP_OPEN_BRACE:
26861 num_open_braces++;
26862 break;
26863 case CPP_CLOSE_BRACE:
26864 if (--num_open_braces == 0)
26865 goto found_closing_brace;
26866 break;
26867 case CPP_EOF:
26868 error_at (start_loc, "no closing brace");
26869 free (start_with_pass);
26870 return c_parser_peek_token (parser)->location;
26871 default:
26872 break;
26874 c_parser_consume_token (parser);
26877 found_closing_brace:
26878 /* At the closing brace; record its location. */
26879 location_t end_loc = c_parser_peek_token (parser)->location;
26881 /* Consume the closing brace. */
26882 c_parser_consume_token (parser);
26884 /* Invoke the RTL parser. */
26885 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
26887 free (start_with_pass);
26888 return end_loc;
26891 /* Run the backend on the cfun created above, transferring ownership of
26892 START_WITH_PASS. */
26893 run_rtl_passes (start_with_pass);
26894 return end_loc;
26897 #include "gt-c-c-parser.h"