Internal-fn: Only allow modes describe types for internal fn[PR115961]
[official-gcc.git] / gcc / c / c-parser.cc
blob9b9284b1ba4db7a69c4dba8cecdc0d1ced30d7bf
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 (*global_dc, 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)
1537 /* Similarly for warn_c23_c2y_compat. */
1538 | ((warn_c23_c2y_compat == 1) << 13)
1539 | ((warn_c23_c2y_compat == -1) << 14)
1541 cpp_opts->cpp_pedantic = pedantic = 0;
1542 warn_pointer_arith = 0;
1543 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1544 flag_iso = 0;
1545 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1546 warn_cxx_compat = 0;
1547 warn_overlength_strings = 0;
1548 warn_c90_c99_compat = 0;
1549 warn_c99_c11_compat = 0;
1550 warn_c11_c23_compat = 0;
1551 warn_c23_c2y_compat = 0;
1552 return ret;
1555 /* Restore the warning flags which are controlled by __extension__.
1556 FLAGS is the return value from disable_extension_diagnostics. */
1558 static inline void
1559 restore_extension_diagnostics (int flags)
1561 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1562 warn_pointer_arith = (flags >> 1) & 1;
1563 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1564 flag_iso = (flags >> 3) & 1;
1565 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1566 warn_cxx_compat = (flags >> 5) & 1;
1567 warn_overlength_strings = (flags >> 6) & 1;
1568 /* See above for why is this needed. */
1569 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1570 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1571 warn_c11_c23_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1572 warn_c23_c2y_compat = (flags >> 13) & 1 ? 1 : ((flags >> 14) & 1 ? -1 : 0);
1575 /* Helper data structure for parsing #pragma acc routine. */
1576 struct oacc_routine_data {
1577 bool error_seen; /* Set if error has been reported. */
1578 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1579 tree clauses;
1580 location_t loc;
1583 /* Used for parsing objc foreach statements. */
1584 static tree objc_foreach_break_label, objc_foreach_continue_label;
1586 /* Used for parsing OMP for loops.
1588 Some notes on flags used for context:
1589 parser->omp_for_parse_state is non-null anywhere inside the OMP FOR
1590 construct, except for the final-loop-body.
1591 The want_nested_loop flag is true if inside a {} sequence where
1592 a loop-nest (or another {} sequence containing a loop-nest) is expected,
1593 but has not yet been seen. It's false when parsing intervening code
1594 statements or their substatements that cannot contain a loop-nest.
1595 The in_intervening_code flag is true when parsing any intervening code,
1596 including substatements, and whether or not want_nested_loop is true.
1598 And, about error handling:
1599 The saw_intervening_code flag is set if the loop is not perfectly
1600 nested, even in the usual case where this is not an error.
1601 perfect_nesting_fail is set if an error has been diagnosed because an
1602 imperfectly-nested loop was found where a perfectly-nested one is
1603 required (we diagnose this only once).
1604 fail is set if any kind of structural error in the loop nest
1605 has been found and diagnosed.
1607 struct omp_for_parse_data {
1608 enum tree_code code;
1609 tree declv, condv, incrv, initv;
1610 tree pre_body;
1611 tree bindings;
1612 int count; /* Expected nesting depth. */
1613 int depth; /* Current nesting depth. */
1614 location_t for_loc;
1615 bool ordered : 1;
1616 bool inscan : 1;
1617 bool want_nested_loop : 1;
1618 bool in_intervening_code : 1;
1619 bool saw_intervening_code: 1;
1620 bool perfect_nesting_fail : 1;
1621 bool fail : 1;
1624 struct attr_state
1626 /* True if we parsed a musttail attribute for return. */
1627 bool musttail_p;
1630 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1631 unsigned int);
1632 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1633 static void c_parser_external_declaration (c_parser *);
1634 static void c_parser_asm_definition (c_parser *);
1635 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1636 bool, bool, tree * = NULL,
1637 vec<c_token> * = NULL,
1638 bool have_attrs = false,
1639 tree attrs = NULL,
1640 struct oacc_routine_data * = NULL,
1641 bool * = NULL);
1642 static bool c_parser_handle_statement_omp_attributes (c_parser *, tree &,
1643 bool *);
1644 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1645 static void c_parser_static_assert_declaration (c_parser *);
1646 static struct c_typespec c_parser_enum_specifier (c_parser *);
1647 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1648 static tree c_parser_struct_declaration (c_parser *, tree *);
1649 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1650 static tree c_parser_alignas_specifier (c_parser *);
1651 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1652 c_dtr_syn, bool *);
1653 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1654 bool,
1655 struct c_declarator *);
1656 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1657 bool);
1658 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1659 tree, bool);
1660 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1661 static tree c_parser_simple_asm_expr (c_parser *);
1662 static tree c_parser_gnu_attributes (c_parser *);
1663 static struct c_expr c_parser_initializer (c_parser *, tree);
1664 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1665 struct obstack *, tree);
1666 static void c_parser_initelt (c_parser *, struct obstack *);
1667 static void c_parser_initval (c_parser *, struct c_expr *,
1668 struct obstack *);
1669 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1670 static location_t c_parser_compound_statement_nostart (c_parser *);
1671 static void c_parser_label (c_parser *, tree);
1672 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1673 static void c_parser_statement_after_labels (c_parser *, bool *,
1674 vec<tree> * = NULL,
1675 attr_state = {});
1676 static tree c_parser_c99_block_statement (c_parser *, bool *,
1677 location_t * = NULL);
1678 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1679 static void c_parser_switch_statement (c_parser *, bool *);
1680 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool,
1681 bool *);
1682 static void c_parser_do_statement (c_parser *, bool, unsigned short, bool);
1683 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool,
1684 bool *);
1685 static tree c_parser_asm_statement (c_parser *);
1686 static tree c_parser_asm_operands (c_parser *);
1687 static tree c_parser_asm_goto_operands (c_parser *);
1688 static tree c_parser_asm_clobbers (c_parser *);
1689 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1690 tree = NULL_TREE);
1691 static struct c_expr c_parser_conditional_expression (c_parser *,
1692 struct c_expr *, tree);
1693 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1694 tree);
1695 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1696 static struct c_expr c_parser_unary_expression (c_parser *);
1697 static struct c_expr c_parser_sizeof_expression (c_parser *);
1698 static struct c_expr c_parser_alignof_expression (c_parser *);
1699 static struct c_expr c_parser_postfix_expression (c_parser *);
1700 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1701 struct c_declspecs *,
1702 struct c_type_name *,
1703 location_t);
1704 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1705 location_t loc,
1706 struct c_expr);
1707 static tree c_parser_transaction (c_parser *, enum rid);
1708 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1709 static tree c_parser_transaction_cancel (c_parser *);
1710 static struct c_expr c_parser_expression (c_parser *);
1711 static struct c_expr c_parser_expression_conv (c_parser *);
1712 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1713 vec<tree, va_gc> **, location_t *,
1714 tree *, vec<location_t> *,
1715 unsigned int * = NULL);
1716 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1718 static void c_parser_oacc_declare (c_parser *);
1719 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1720 static void c_parser_oacc_update (c_parser *);
1721 static void c_parser_omp_construct (c_parser *, bool *);
1722 static void c_parser_omp_threadprivate (c_parser *);
1723 static void c_parser_omp_barrier (c_parser *);
1724 static void c_parser_omp_depobj (c_parser *);
1725 static void c_parser_omp_flush (c_parser *);
1726 static bool c_parser_omp_next_tokens_can_be_canon_loop (c_parser *,
1727 enum tree_code, bool);
1728 static tree c_parser_omp_loop_nest (c_parser *, bool *);
1729 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1730 tree, tree *, bool *);
1731 static void c_parser_omp_taskwait (c_parser *);
1732 static void c_parser_omp_taskyield (c_parser *);
1733 static void c_parser_omp_cancel (c_parser *);
1734 static void c_parser_omp_nothing (c_parser *);
1736 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1737 pragma_stmt, pragma_compound };
1738 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1739 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1740 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1741 static void c_parser_omp_begin (c_parser *);
1742 static void c_parser_omp_end (c_parser *);
1743 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1744 static void c_parser_omp_requires (c_parser *);
1745 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1746 static void c_parser_omp_assumption_clauses (c_parser *, bool);
1747 static void c_parser_omp_allocate (c_parser *);
1748 static void c_parser_omp_assumes (c_parser *);
1749 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1750 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1752 /* These Objective-C parser functions are only ever called when
1753 compiling Objective-C. */
1754 static void c_parser_objc_class_definition (c_parser *, tree);
1755 static void c_parser_objc_class_instance_variables (c_parser *);
1756 static void c_parser_objc_class_declaration (c_parser *);
1757 static void c_parser_objc_alias_declaration (c_parser *);
1758 static void c_parser_objc_protocol_definition (c_parser *, tree);
1759 static bool c_parser_objc_method_type (c_parser *);
1760 static void c_parser_objc_method_definition (c_parser *);
1761 static void c_parser_objc_methodprotolist (c_parser *);
1762 static void c_parser_objc_methodproto (c_parser *);
1763 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1764 static tree c_parser_objc_type_name (c_parser *);
1765 static tree c_parser_objc_protocol_refs (c_parser *);
1766 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1767 static void c_parser_objc_synchronized_statement (c_parser *);
1768 static tree c_parser_objc_selector (c_parser *);
1769 static tree c_parser_objc_selector_arg (c_parser *);
1770 static tree c_parser_objc_receiver (c_parser *);
1771 static tree c_parser_objc_message_args (c_parser *);
1772 static tree c_parser_objc_keywordexpr (c_parser *);
1773 static void c_parser_objc_at_property_declaration (c_parser *);
1774 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1775 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1776 static bool c_parser_objc_diagnose_bad_element_prefix
1777 (c_parser *, struct c_declspecs *);
1778 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1780 #if ENABLE_ANALYZER
1782 namespace ana {
1784 /* Concrete implementation of ana::translation_unit for the C frontend. */
1786 class c_translation_unit : public translation_unit
1788 public:
1789 /* Implementation of translation_unit::lookup_constant_by_id for use by the
1790 analyzer to look up named constants in the user's source code. */
1791 tree lookup_constant_by_id (tree id) const final override
1793 /* Consider decls. */
1794 if (tree decl = lookup_name (id))
1795 if (TREE_CODE (decl) == CONST_DECL)
1796 if (tree value = DECL_INITIAL (decl))
1797 if (TREE_CODE (value) == INTEGER_CST)
1798 return value;
1800 /* Consider macros. */
1801 cpp_hashnode *hashnode = C_CPP_HASHNODE (id);
1802 if (cpp_macro_p (hashnode))
1803 if (tree value = consider_macro (hashnode->value.macro))
1804 return value;
1806 return NULL_TREE;
1809 tree
1810 lookup_type_by_id (tree id) const final override
1812 if (tree type_decl = lookup_name (id))
1813 if (TREE_CODE (type_decl) == TYPE_DECL)
1815 tree record_type = TREE_TYPE (type_decl);
1816 if (TREE_CODE (record_type) == RECORD_TYPE)
1817 return record_type;
1820 return NULL_TREE;
1823 tree
1824 lookup_global_var_by_id (tree id) const final override
1826 if (tree var_decl = lookup_name (id))
1827 if (TREE_CODE (var_decl) == VAR_DECL)
1828 return var_decl;
1830 return NULL_TREE;
1833 private:
1834 /* Attempt to get an INTEGER_CST from MACRO.
1835 Only handle the simplest cases: where MACRO's definition is a single
1836 token containing a number, by lexing the number again.
1837 This will handle e.g.
1838 #define NAME 42
1839 and other bases but not negative numbers, parentheses or e.g.
1840 #define NAME 1 << 7
1841 as doing so would require a parser. */
1842 tree consider_macro (cpp_macro *macro) const
1844 if (macro->paramc > 0)
1845 return NULL_TREE;
1846 if (macro->kind != cmk_macro)
1847 return NULL_TREE;
1848 if (macro->count != 1)
1849 return NULL_TREE;
1850 const cpp_token &tok = macro->exp.tokens[0];
1851 if (tok.type != CPP_NUMBER)
1852 return NULL_TREE;
1854 cpp_reader *old_parse_in = parse_in;
1855 parse_in = cpp_create_reader (CLK_GNUC89, NULL, line_table);
1857 pretty_printer pp;
1858 pp_string (&pp, (const char *) tok.val.str.text);
1859 pp_newline (&pp);
1860 cpp_push_buffer (parse_in,
1861 (const unsigned char *) pp_formatted_text (&pp),
1862 strlen (pp_formatted_text (&pp)),
1865 tree value;
1866 location_t loc;
1867 unsigned char cpp_flags;
1868 c_lex_with_flags (&value, &loc, &cpp_flags, 0);
1870 cpp_destroy (parse_in);
1871 parse_in = old_parse_in;
1873 if (value && TREE_CODE (value) == INTEGER_CST)
1874 return value;
1876 return NULL_TREE;
1880 } // namespace ana
1882 #endif /* #if ENABLE_ANALYZER */
1884 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1886 translation-unit:
1887 external-declarations
1889 external-declarations:
1890 external-declaration
1891 external-declarations external-declaration
1893 GNU extensions:
1895 translation-unit:
1896 empty
1899 static void
1900 c_parser_translation_unit (c_parser *parser)
1902 if (c_parser_next_token_is (parser, CPP_EOF))
1904 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1905 "ISO C forbids an empty translation unit");
1907 else
1909 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1910 mark_valid_location_for_stdc_pragma (false);
1913 ggc_collect ();
1914 c_parser_external_declaration (parser);
1915 obstack_free (&parser_obstack, obstack_position);
1917 while (c_parser_next_token_is_not (parser, CPP_EOF));
1920 unsigned int i;
1921 tree decl;
1922 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1923 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1924 error ("storage size of %q+D isn%'t known", decl);
1926 if (vec_safe_length (current_omp_declare_target_attribute))
1928 c_omp_declare_target_attr
1929 a = current_omp_declare_target_attribute->pop ();
1930 if (!errorcount)
1931 error ("%qs without corresponding %qs",
1932 a.device_type >= 0 ? "#pragma omp begin declare target"
1933 : "#pragma omp declare target",
1934 "#pragma omp end declare target");
1935 vec_safe_truncate (current_omp_declare_target_attribute, 0);
1937 if (vec_safe_length (current_omp_begin_assumes))
1939 if (!errorcount)
1940 error ("%qs without corresponding %qs",
1941 "#pragma omp begin assumes", "#pragma omp end assumes");
1942 vec_safe_truncate (current_omp_begin_assumes, 0);
1945 #if ENABLE_ANALYZER
1946 if (flag_analyzer)
1948 ana::c_translation_unit tu;
1949 ana::on_finish_translation_unit (tu);
1951 #endif
1954 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1956 external-declaration:
1957 function-definition
1958 declaration
1960 GNU extensions:
1962 external-declaration:
1963 asm-definition
1965 __extension__ external-declaration
1967 Objective-C:
1969 external-declaration:
1970 objc-class-definition
1971 objc-class-declaration
1972 objc-alias-declaration
1973 objc-protocol-definition
1974 objc-method-definition
1975 @end
1978 static void
1979 c_parser_external_declaration (c_parser *parser)
1981 int ext;
1982 switch (c_parser_peek_token (parser)->type)
1984 case CPP_KEYWORD:
1985 switch (c_parser_peek_token (parser)->keyword)
1987 case RID_EXTENSION:
1988 ext = disable_extension_diagnostics ();
1989 c_parser_consume_token (parser);
1990 c_parser_external_declaration (parser);
1991 restore_extension_diagnostics (ext);
1992 break;
1993 case RID_ASM:
1994 c_parser_asm_definition (parser);
1995 break;
1996 case RID_AT_INTERFACE:
1997 case RID_AT_IMPLEMENTATION:
1998 gcc_assert (c_dialect_objc ());
1999 c_parser_objc_class_definition (parser, NULL_TREE);
2000 break;
2001 case RID_AT_CLASS:
2002 gcc_assert (c_dialect_objc ());
2003 c_parser_objc_class_declaration (parser);
2004 break;
2005 case RID_AT_ALIAS:
2006 gcc_assert (c_dialect_objc ());
2007 c_parser_objc_alias_declaration (parser);
2008 break;
2009 case RID_AT_PROTOCOL:
2010 gcc_assert (c_dialect_objc ());
2011 c_parser_objc_protocol_definition (parser, NULL_TREE);
2012 break;
2013 case RID_AT_PROPERTY:
2014 gcc_assert (c_dialect_objc ());
2015 c_parser_objc_at_property_declaration (parser);
2016 break;
2017 case RID_AT_SYNTHESIZE:
2018 gcc_assert (c_dialect_objc ());
2019 c_parser_objc_at_synthesize_declaration (parser);
2020 break;
2021 case RID_AT_DYNAMIC:
2022 gcc_assert (c_dialect_objc ());
2023 c_parser_objc_at_dynamic_declaration (parser);
2024 break;
2025 case RID_AT_END:
2026 gcc_assert (c_dialect_objc ());
2027 c_parser_consume_token (parser);
2028 objc_finish_implementation ();
2029 break;
2030 default:
2031 goto decl_or_fndef;
2033 break;
2034 case CPP_SEMICOLON:
2035 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
2036 "ISO C does not allow extra %<;%> outside of a function");
2037 c_parser_consume_token (parser);
2038 break;
2039 case CPP_PRAGMA:
2040 mark_valid_location_for_stdc_pragma (true);
2041 c_parser_pragma (parser, pragma_external, NULL);
2042 mark_valid_location_for_stdc_pragma (false);
2043 break;
2044 case CPP_PLUS:
2045 case CPP_MINUS:
2046 if (c_dialect_objc ())
2048 c_parser_objc_method_definition (parser);
2049 break;
2051 /* Else fall through, and yield a syntax error trying to parse
2052 as a declaration or function definition. */
2053 /* FALLTHRU */
2054 default:
2055 decl_or_fndef:
2056 /* A declaration or a function definition (or, in Objective-C,
2057 an @interface or @protocol with prefix attributes). We can
2058 only tell which after parsing the declaration specifiers, if
2059 any, and the first declarator. */
2060 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
2061 break;
2065 static void c_parser_handle_directive_omp_attributes (tree &, vec<c_token> *&,
2066 vec<c_token> *);
2067 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
2068 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
2070 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
2072 static void
2073 add_debug_begin_stmt (location_t loc)
2075 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
2076 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
2077 return;
2079 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
2080 SET_EXPR_LOCATION (stmt, loc);
2081 add_stmt (stmt);
2084 /* Helper function for c_parser_declaration_or_fndef and
2085 Handle assume attribute(s). */
2087 static tree
2088 handle_assume_attribute (location_t here, tree attrs, bool nested)
2090 if (nested)
2091 for (tree attr = lookup_attribute ("gnu", "assume", attrs); attr;
2092 attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
2094 tree args = TREE_VALUE (attr);
2095 int nargs = list_length (args);
2096 if (nargs != 1)
2098 error_at (here, "wrong number of arguments specified "
2099 "for %qE attribute",
2100 get_attribute_name (attr));
2101 inform (here, "expected %i, found %i", 1, nargs);
2103 else
2105 tree arg = TREE_VALUE (args);
2106 arg = c_objc_common_truthvalue_conversion (here, arg);
2107 arg = c_fully_fold (arg, false, NULL);
2108 if (arg != error_mark_node)
2110 tree fn = build_call_expr_internal_loc (here, IFN_ASSUME,
2111 void_type_node, 1,
2112 arg);
2113 add_stmt (fn);
2117 else
2118 pedwarn (here, OPT_Wattributes,
2119 "%<assume%> attribute at top level");
2121 return remove_attribute ("gnu", "assume", attrs);
2124 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
2125 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
2126 is accepted; otherwise (old-style parameter declarations) only other
2127 declarations are accepted. If STATIC_ASSERT_OK is true, a static
2128 assertion is accepted; otherwise (old-style parameter declarations)
2129 it is not. If NESTED is true, we are inside a function or parsing
2130 old-style parameter declarations; any functions encountered are
2131 nested functions and declaration specifiers are required; otherwise
2132 we are at top level and functions are normal functions and
2133 declaration specifiers may be optional. If EMPTY_OK is true, empty
2134 declarations are OK (subject to all other constraints); otherwise
2135 (old-style parameter declarations) they are diagnosed. If
2136 START_ATTR_OK is true, the declaration specifiers may start with
2137 attributes (GNU or standard); otherwise they may not.
2138 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
2139 declaration when parsing an Objective-C foreach statement.
2140 FALLTHRU_ATTR_P is used to signal whether this function parsed
2141 "__attribute__((fallthrough));". ATTRS are any standard attributes
2142 parsed in the caller (in contexts where such attributes had to be
2143 parsed to determine whether what follows is a declaration or a
2144 statement); HAVE_ATTRS says whether there were any such attributes
2145 (even empty).
2147 declaration:
2148 declaration-specifiers init-declarator-list[opt] ;
2149 static_assert-declaration
2151 function-definition:
2152 declaration-specifiers[opt] declarator declaration-list[opt]
2153 compound-statement
2155 declaration-list:
2156 declaration
2157 declaration-list declaration
2159 init-declarator-list:
2160 init-declarator
2161 init-declarator-list , init-declarator
2163 init-declarator:
2164 declarator simple-asm-expr[opt] gnu-attributes[opt]
2165 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
2167 GNU extensions:
2169 nested-function-definition:
2170 declaration-specifiers declarator declaration-list[opt]
2171 compound-statement
2173 attribute ;
2175 Objective-C:
2176 gnu-attributes objc-class-definition
2177 gnu-attributes objc-category-definition
2178 gnu-attributes objc-protocol-definition
2180 The simple-asm-expr and gnu-attributes are GNU extensions.
2182 This function does not handle __extension__; that is handled in its
2183 callers. ??? Following the old parser, __extension__ may start
2184 external declarations, declarations in functions and declarations
2185 at the start of "for" loops, but not old-style parameter
2186 declarations.
2188 C99 requires declaration specifiers in a function definition; the
2189 absence is diagnosed through the diagnosis of implicit int. In GNU
2190 C we also allow but diagnose declarations without declaration
2191 specifiers, but only at top level (elsewhere they conflict with
2192 other syntax).
2194 In Objective-C, declarations of the looping variable in a foreach
2195 statement are exceptionally terminated by 'in' (for example, 'for
2196 (NSObject *object in array) { ... }').
2198 OpenMP:
2200 declaration:
2201 threadprivate-directive
2203 GIMPLE:
2205 gimple-function-definition:
2206 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
2207 declaration-list[opt] compound-statement
2209 rtl-function-definition:
2210 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
2211 declaration-list[opt] compound-statement */
2213 static void
2214 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
2215 bool static_assert_ok, bool empty_ok,
2216 bool nested, bool start_attr_ok,
2217 tree *objc_foreach_object_declaration
2218 /* = NULL */,
2219 vec<c_token> *omp_declare_simd_clauses
2220 /* = NULL */,
2221 bool have_attrs /* = false */,
2222 tree attrs /* = NULL_TREE */,
2223 struct oacc_routine_data *oacc_routine_data
2224 /* = NULL */,
2225 bool *fallthru_attr_p /* = NULL */)
2227 struct c_declspecs *specs;
2228 tree prefix_attrs;
2229 tree all_prefix_attrs;
2230 bool diagnosed_no_specs = false;
2231 location_t here = c_parser_peek_token (parser)->location;
2233 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
2235 if (static_assert_ok
2236 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
2238 c_parser_static_assert_declaration (parser);
2239 return;
2241 specs = build_null_declspecs ();
2243 /* Handle any standard attributes parsed in the caller. */
2244 if (have_attrs)
2246 declspecs_add_attrs (here, specs, attrs);
2247 specs->non_std_attrs_seen_p = false;
2250 /* Try to detect an unknown type name when we have "A B" or "A *B". */
2251 if (c_parser_peek_token (parser)->type == CPP_NAME
2252 && c_parser_peek_token (parser)->id_kind == C_ID_ID
2253 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
2254 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
2255 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
2257 tree name = c_parser_peek_token (parser)->value;
2259 /* Issue a warning about NAME being an unknown type name, perhaps
2260 with some kind of hint.
2261 If the user forgot a "struct" etc, suggest inserting
2262 it. Otherwise, attempt to look for misspellings. */
2263 gcc_rich_location richloc (here);
2264 if (tag_exists_p (RECORD_TYPE, name))
2266 /* This is not C++ with its implicit typedef. */
2267 richloc.add_fixit_insert_before ("struct ");
2268 error_at (&richloc,
2269 "unknown type name %qE;"
2270 " use %<struct%> keyword to refer to the type",
2271 name);
2273 else if (tag_exists_p (UNION_TYPE, name))
2275 richloc.add_fixit_insert_before ("union ");
2276 error_at (&richloc,
2277 "unknown type name %qE;"
2278 " use %<union%> keyword to refer to the type",
2279 name);
2281 else if (tag_exists_p (ENUMERAL_TYPE, name))
2283 richloc.add_fixit_insert_before ("enum ");
2284 error_at (&richloc,
2285 "unknown type name %qE;"
2286 " use %<enum%> keyword to refer to the type",
2287 name);
2289 else
2291 auto_diagnostic_group d;
2292 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
2293 here);
2294 if (const char *suggestion = hint.suggestion ())
2296 richloc.add_fixit_replace (suggestion);
2297 error_at (&richloc,
2298 "unknown type name %qE; did you mean %qs?",
2299 name, suggestion);
2301 else
2302 error_at (here, "unknown type name %qE", name);
2305 /* Parse declspecs normally to get a correct pointer type, but avoid
2306 a further "fails to be a type name" error. Refuse nested functions
2307 since it is not how the user likely wants us to recover. */
2308 c_parser_peek_token (parser)->type = CPP_KEYWORD;
2309 c_parser_peek_token (parser)->keyword = RID_VOID;
2310 c_parser_peek_token (parser)->value = error_mark_node;
2311 fndef_ok = !nested;
2314 /* When there are standard attributes at the start of the
2315 declaration (to apply to the entity being declared), an
2316 init-declarator-list or function definition must be present. */
2317 if (c_parser_nth_token_starts_std_attributes (parser, 1))
2318 have_attrs = true;
2320 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2321 true, true, start_attr_ok, true, cla_nonabstract_decl);
2322 if (parser->error)
2324 c_parser_skip_to_end_of_block_or_statement (parser);
2325 return;
2327 if (nested && !specs->declspecs_seen_p)
2329 c_parser_error (parser, "expected declaration specifiers");
2330 c_parser_skip_to_end_of_block_or_statement (parser);
2331 return;
2334 finish_declspecs (specs);
2335 bool gnu_auto_type_p = specs->typespec_word == cts_auto_type;
2336 bool std_auto_type_p = specs->c23_auto_p;
2337 bool any_auto_type_p = gnu_auto_type_p || std_auto_type_p;
2338 gcc_assert (!(gnu_auto_type_p && std_auto_type_p));
2339 const char *auto_type_keyword = gnu_auto_type_p ? "__auto_type" : "auto";
2340 if (specs->constexpr_p)
2342 /* An underspecified declaration may not declare tags or members
2343 or structures or unions; it is undefined behavior to declare
2344 the members of an enumeration. Where the structure, union or
2345 enumeration type is declared within an initializer, this is
2346 diagnosed elsewhere. Diagnose here the case of declaring
2347 such a type in the type specifiers of a constexpr
2348 declaration. */
2349 switch (specs->typespec_kind)
2351 case ctsk_tagfirstref:
2352 case ctsk_tagfirstref_attrs:
2353 error_at (here, "%qT declared in underspecified object declaration",
2354 specs->type);
2355 break;
2357 case ctsk_tagdef:
2358 error_at (here, "%qT defined in underspecified object declaration",
2359 specs->type);
2360 break;
2362 default:
2363 break;
2366 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2368 bool handled_assume = false;
2369 if (specs->attrs
2370 && !nested
2371 && specs->typespec_kind == ctsk_none
2372 && c_parser_handle_statement_omp_attributes (parser, specs->attrs,
2373 NULL))
2375 if (specs->attrs)
2376 c_warn_unused_attributes (specs->attrs);
2377 while (parser->in_omp_attribute_pragma)
2379 gcc_assert (c_parser_next_token_is (parser, CPP_PRAGMA));
2380 c_parser_pragma (parser, pragma_external, NULL);
2382 c_parser_consume_token (parser);
2383 return;
2385 if (specs->typespec_kind == ctsk_none
2386 && lookup_attribute ("gnu", "assume", specs->attrs))
2388 handled_assume = true;
2389 specs->attrs
2390 = handle_assume_attribute (here, specs->attrs, nested);
2392 if (any_auto_type_p)
2393 error_at (here, "%qs in empty declaration", auto_type_keyword);
2394 else if (specs->typespec_kind == ctsk_none
2395 && attribute_fallthrough_p (specs->attrs))
2397 if (fallthru_attr_p != NULL)
2398 *fallthru_attr_p = true;
2399 if (nested)
2401 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2402 void_type_node, 0);
2403 add_stmt (fn);
2405 else
2406 pedwarn (here, OPT_Wattributes,
2407 "%<fallthrough%> attribute at top level");
2409 else if (empty_ok
2410 && !(have_attrs && specs->non_std_attrs_seen_p)
2411 && !handled_assume)
2412 shadow_tag (specs);
2413 else
2415 shadow_tag_warned (specs, 1);
2416 if (!handled_assume)
2417 pedwarn (here, 0, "empty declaration");
2419 /* We still have to evaluate size expressions. */
2420 if (specs->expr)
2421 add_stmt (fold_convert (void_type_node, specs->expr));
2422 c_parser_consume_token (parser);
2423 if (oacc_routine_data)
2424 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2425 return;
2428 /* Provide better error recovery. Note that a type name here is usually
2429 better diagnosed as a redeclaration. */
2430 if (empty_ok
2431 && specs->typespec_kind == ctsk_tagdef
2432 && c_parser_next_token_starts_declspecs (parser)
2433 && !c_parser_next_token_is (parser, CPP_NAME))
2435 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2436 parser->error = false;
2437 shadow_tag_warned (specs, 1);
2438 return;
2440 else if (c_dialect_objc () && !any_auto_type_p)
2442 /* Prefix attributes are an error on method decls. */
2443 switch (c_parser_peek_token (parser)->type)
2445 case CPP_PLUS:
2446 case CPP_MINUS:
2447 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2448 return;
2449 if (specs->attrs)
2451 warning_at (c_parser_peek_token (parser)->location,
2452 OPT_Wattributes,
2453 "prefix attributes are ignored for methods");
2454 specs->attrs = NULL_TREE;
2456 if (fndef_ok)
2457 c_parser_objc_method_definition (parser);
2458 else
2459 c_parser_objc_methodproto (parser);
2460 return;
2461 break;
2462 default:
2463 break;
2465 /* This is where we parse 'attributes @interface ...',
2466 'attributes @implementation ...', 'attributes @protocol ...'
2467 (where attributes could be, for example, __attribute__
2468 ((deprecated)).
2470 switch (c_parser_peek_token (parser)->keyword)
2472 case RID_AT_INTERFACE:
2474 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2475 return;
2476 c_parser_objc_class_definition (parser, specs->attrs);
2477 return;
2479 break;
2480 case RID_AT_IMPLEMENTATION:
2482 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2483 return;
2484 if (specs->attrs)
2486 warning_at (c_parser_peek_token (parser)->location,
2487 OPT_Wattributes,
2488 "prefix attributes are ignored for implementations");
2489 specs->attrs = NULL_TREE;
2491 c_parser_objc_class_definition (parser, NULL_TREE);
2492 return;
2494 break;
2495 case RID_AT_PROTOCOL:
2497 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2498 return;
2499 c_parser_objc_protocol_definition (parser, specs->attrs);
2500 return;
2502 break;
2503 case RID_AT_ALIAS:
2504 case RID_AT_CLASS:
2505 case RID_AT_END:
2506 case RID_AT_PROPERTY:
2507 if (specs->attrs)
2509 c_parser_error (parser, "unexpected attribute");
2510 specs->attrs = NULL;
2512 break;
2513 default:
2514 break;
2517 else if (attribute_fallthrough_p (specs->attrs))
2518 warning_at (here, OPT_Wattributes,
2519 "%<fallthrough%> attribute not followed by %<;%>");
2520 else if (lookup_attribute ("gnu", "assume", specs->attrs))
2521 warning_at (here, OPT_Wattributes,
2522 "%<assume%> attribute not followed by %<;%>");
2524 auto_vec<c_token> omp_declare_simd_attr_clauses;
2525 c_parser_handle_directive_omp_attributes (specs->attrs,
2526 omp_declare_simd_clauses,
2527 &omp_declare_simd_attr_clauses);
2528 pending_xref_error ();
2529 prefix_attrs = specs->attrs;
2530 all_prefix_attrs = prefix_attrs;
2531 specs->attrs = NULL_TREE;
2532 while (true)
2534 struct c_declarator *declarator;
2535 bool dummy = false;
2536 timevar_id_t tv;
2537 tree fnbody = NULL_TREE;
2538 tree underspec_name = NULL_TREE;
2539 auto_vec<c_token> omp_dsimd_idattr_clauses;
2540 /* Declaring either one or more declarators (in which case we
2541 should diagnose if there were no declaration specifiers) or a
2542 function definition (in which case the diagnostic for
2543 implicit int suffices). */
2544 declarator = c_parser_declarator (parser,
2545 specs->typespec_kind != ctsk_none,
2546 C_DTR_NORMAL, &dummy);
2547 if (declarator == NULL)
2549 if (omp_declare_simd_clauses)
2550 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2551 omp_declare_simd_clauses);
2552 if (oacc_routine_data)
2553 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2554 c_parser_skip_to_end_of_block_or_statement (parser);
2555 return;
2557 if (flag_openmp || flag_openmp_simd)
2559 struct c_declarator *d = declarator;
2560 while (d->kind != cdk_id)
2561 d = d->declarator;
2562 vec<c_token> *dummy = NULL;
2563 c_parser_handle_directive_omp_attributes (d->u.id.attrs, dummy,
2564 &omp_dsimd_idattr_clauses);
2566 if (gnu_auto_type_p && declarator->kind != cdk_id)
2568 error_at (here,
2569 "%<__auto_type%> requires a plain identifier"
2570 " as declarator");
2571 c_parser_skip_to_end_of_block_or_statement (parser);
2572 return;
2574 if (std_auto_type_p)
2576 struct c_declarator *d = declarator;
2577 while (d->kind == cdk_attrs)
2578 d = d->declarator;
2579 if (d->kind != cdk_id)
2581 error_at (here,
2582 "%<auto%> requires a plain identifier, possibly with"
2583 " attributes, as declarator");
2584 c_parser_skip_to_end_of_block_or_statement (parser);
2585 return;
2587 underspec_name = d->u.id.id;
2589 else if (specs->constexpr_p)
2591 struct c_declarator *d = declarator;
2592 while (d->kind != cdk_id)
2593 d = d->declarator;
2594 underspec_name = d->u.id.id;
2596 if (c_parser_next_token_is (parser, CPP_EQ)
2597 || c_parser_next_token_is (parser, CPP_COMMA)
2598 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2599 || c_parser_next_token_is_keyword (parser, RID_ASM)
2600 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2601 || c_parser_next_token_is_keyword (parser, RID_IN))
2603 tree asm_name = NULL_TREE;
2604 tree postfix_attrs = NULL_TREE;
2605 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2607 diagnosed_no_specs = true;
2608 pedwarn (here, 0, "data definition has no type or storage class");
2610 /* Having seen a data definition, there cannot now be a
2611 function definition. */
2612 fndef_ok = false;
2613 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2614 asm_name = c_parser_simple_asm_expr (parser);
2615 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2617 postfix_attrs = c_parser_gnu_attributes (parser);
2618 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2620 /* This means there is an attribute specifier after
2621 the declarator in a function definition. Provide
2622 some more information for the user. */
2623 error_at (here, "attributes should be specified before the "
2624 "declarator in a function definition");
2625 c_parser_skip_to_end_of_block_or_statement (parser);
2626 return;
2629 if (c_parser_next_token_is (parser, CPP_EQ))
2631 tree d;
2632 struct c_expr init;
2633 location_t init_loc;
2634 c_parser_consume_token (parser);
2635 if (any_auto_type_p)
2637 init_loc = c_parser_peek_token (parser)->location;
2638 rich_location richloc (line_table, init_loc);
2639 unsigned int underspec_state = 0;
2640 if (std_auto_type_p)
2641 underspec_state =
2642 start_underspecified_init (init_loc, underspec_name);
2643 start_init (NULL_TREE, asm_name,
2644 (global_bindings_p ()
2645 || specs->storage_class == csc_static
2646 || specs->constexpr_p),
2647 specs->constexpr_p, &richloc);
2648 /* A parameter is initialized, which is invalid. Don't
2649 attempt to instrument the initializer. */
2650 int flag_sanitize_save = flag_sanitize;
2651 if (nested && !empty_ok)
2652 flag_sanitize = 0;
2653 init = c_parser_expr_no_commas (parser, NULL);
2654 if (std_auto_type_p)
2655 finish_underspecified_init (underspec_name,
2656 underspec_state);
2657 flag_sanitize = flag_sanitize_save;
2658 if (gnu_auto_type_p
2659 && TREE_CODE (init.value) == COMPONENT_REF
2660 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2661 error_at (here,
2662 "%<__auto_type%> used with a bit-field"
2663 " initializer");
2664 init = convert_lvalue_to_rvalue (init_loc, init, true, true,
2665 true);
2666 tree init_type = TREE_TYPE (init.value);
2667 bool vm_type = c_type_variably_modified_p (init_type);
2668 if (vm_type)
2669 init.value = save_expr (init.value);
2670 finish_init ();
2671 specs->typespec_kind = ctsk_typeof;
2672 specs->locations[cdw_typedef] = init_loc;
2673 specs->typedef_p = true;
2674 specs->type = init_type;
2675 if (specs->postfix_attrs)
2677 /* Postfix [[]] attributes are valid with C23
2678 auto, although not with __auto_type, and
2679 modify the type given by the initializer. */
2680 specs->postfix_attrs =
2681 c_warn_type_attributes (specs->postfix_attrs);
2682 decl_attributes (&specs->type, specs->postfix_attrs, 0);
2683 specs->postfix_attrs = NULL_TREE;
2685 if (vm_type)
2687 bool maybe_const = true;
2688 tree type_expr = c_fully_fold (init.value, false,
2689 &maybe_const);
2690 specs->expr_const_operands &= maybe_const;
2691 if (specs->expr)
2692 specs->expr = build2 (COMPOUND_EXPR,
2693 TREE_TYPE (type_expr),
2694 specs->expr, type_expr);
2695 else
2696 specs->expr = type_expr;
2698 d = start_decl (declarator, specs, true,
2699 chainon (postfix_attrs, all_prefix_attrs));
2700 if (!d)
2701 d = error_mark_node;
2702 if (omp_declare_simd_clauses)
2703 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2704 omp_declare_simd_clauses);
2705 if (!omp_dsimd_idattr_clauses.is_empty ())
2706 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2707 &omp_dsimd_idattr_clauses);
2709 else
2711 /* The declaration of the variable is in effect while
2712 its initializer is parsed, except for a constexpr
2713 variable. */
2714 init_loc = c_parser_peek_token (parser)->location;
2715 rich_location richloc (line_table, init_loc);
2716 unsigned int underspec_state = 0;
2717 if (specs->constexpr_p)
2718 underspec_state =
2719 start_underspecified_init (init_loc, underspec_name);
2720 d = start_decl (declarator, specs, true,
2721 chainon (postfix_attrs,
2722 all_prefix_attrs),
2723 !specs->constexpr_p);
2724 if (!d)
2725 d = error_mark_node;
2726 if (!specs->constexpr_p && omp_declare_simd_clauses)
2727 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2728 omp_declare_simd_clauses);
2729 if (!specs->constexpr_p
2730 && !omp_dsimd_idattr_clauses.is_empty ())
2731 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2732 &omp_dsimd_idattr_clauses);
2733 start_init (d, asm_name,
2734 TREE_STATIC (d) || specs->constexpr_p,
2735 specs->constexpr_p, &richloc);
2736 /* A parameter is initialized, which is invalid. Don't
2737 attempt to instrument the initializer. */
2738 int flag_sanitize_save = flag_sanitize;
2739 if (TREE_CODE (d) == PARM_DECL)
2740 flag_sanitize = 0;
2741 init = c_parser_initializer (parser, d);
2742 flag_sanitize = flag_sanitize_save;
2743 if (specs->constexpr_p)
2745 finish_underspecified_init (underspec_name,
2746 underspec_state);
2747 d = pushdecl (d);
2748 if (omp_declare_simd_clauses)
2749 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2750 omp_declare_simd_clauses);
2751 if (!specs->constexpr_p
2752 && !omp_dsimd_idattr_clauses.is_empty ())
2753 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2754 &omp_dsimd_idattr_clauses);
2756 finish_init ();
2758 if (oacc_routine_data)
2759 c_finish_oacc_routine (oacc_routine_data, d, false);
2760 if (d != error_mark_node)
2762 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2763 finish_decl (d, init_loc, init.value,
2764 init.original_type, asm_name);
2767 else
2769 if (any_auto_type_p || specs->constexpr_p)
2771 error_at (here,
2772 "%qs requires an initialized data declaration",
2773 any_auto_type_p ? auto_type_keyword : "constexpr");
2774 c_parser_skip_to_end_of_block_or_statement (parser);
2775 return;
2778 location_t lastloc = UNKNOWN_LOCATION;
2779 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2780 tree d = start_decl (declarator, specs, false, attrs, true,
2781 &lastloc);
2782 if (d && TREE_CODE (d) == FUNCTION_DECL)
2784 /* Find the innermost declarator that is neither cdk_id
2785 nor cdk_attrs. */
2786 const struct c_declarator *decl = declarator;
2787 const struct c_declarator *last_non_id_attrs = NULL;
2789 while (decl)
2790 switch (decl->kind)
2792 case cdk_array:
2793 case cdk_function:
2794 case cdk_pointer:
2795 last_non_id_attrs = decl;
2796 decl = decl->declarator;
2797 break;
2799 case cdk_attrs:
2800 decl = decl->declarator;
2801 break;
2803 case cdk_id:
2804 decl = 0;
2805 break;
2807 default:
2808 gcc_unreachable ();
2811 /* If it exists and is cdk_function declaration whose
2812 arguments have not been set yet, use its arguments. */
2813 if (last_non_id_attrs
2814 && last_non_id_attrs->kind == cdk_function)
2816 tree parms = last_non_id_attrs->u.arg_info->parms;
2817 if (DECL_ARGUMENTS (d) == NULL_TREE
2818 && DECL_INITIAL (d) == NULL_TREE)
2819 DECL_ARGUMENTS (d) = parms;
2821 warn_parm_array_mismatch (lastloc, d, parms);
2824 if (omp_declare_simd_clauses
2825 || !omp_dsimd_idattr_clauses.is_empty ())
2827 tree parms = NULL_TREE;
2828 if (d && TREE_CODE (d) == FUNCTION_DECL)
2830 struct c_declarator *ce = declarator;
2831 while (ce != NULL)
2832 if (ce->kind == cdk_function)
2834 parms = ce->u.arg_info->parms;
2835 break;
2837 else
2838 ce = ce->declarator;
2840 if (parms)
2841 temp_store_parm_decls (d, parms);
2842 if (omp_declare_simd_clauses)
2843 c_finish_omp_declare_simd (parser, d, parms,
2844 omp_declare_simd_clauses);
2845 if (!specs->constexpr_p
2846 && !omp_dsimd_idattr_clauses.is_empty ())
2847 c_finish_omp_declare_simd (parser, d, parms,
2848 &omp_dsimd_idattr_clauses);
2849 if (parms)
2850 temp_pop_parm_decls ();
2852 if (oacc_routine_data)
2853 c_finish_oacc_routine (oacc_routine_data, d, false);
2854 if (d)
2855 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2856 NULL_TREE, asm_name);
2858 if (c_parser_next_token_is_keyword (parser, RID_IN))
2860 if (d)
2861 *objc_foreach_object_declaration = d;
2862 else
2863 *objc_foreach_object_declaration = error_mark_node;
2866 if (c_parser_next_token_is (parser, CPP_COMMA))
2868 if (any_auto_type_p || specs->constexpr_p)
2870 error_at (here,
2871 "%qs may only be used with a single declarator",
2872 any_auto_type_p ? auto_type_keyword : "constexpr");
2873 c_parser_skip_to_end_of_block_or_statement (parser);
2874 return;
2876 c_parser_consume_token (parser);
2877 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2878 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2879 prefix_attrs);
2880 else
2881 all_prefix_attrs = prefix_attrs;
2882 continue;
2884 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2886 c_parser_consume_token (parser);
2887 return;
2889 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2891 /* This can only happen in Objective-C: we found the
2892 'in' that terminates the declaration inside an
2893 Objective-C foreach statement. Do not consume the
2894 token, so that the caller can use it to determine
2895 that this indeed is a foreach context. */
2896 return;
2898 else
2900 c_parser_error (parser, "expected %<,%> or %<;%>");
2901 c_parser_skip_to_end_of_block_or_statement (parser);
2902 return;
2905 else if (any_auto_type_p || specs->constexpr_p)
2907 error_at (here,
2908 "%qs requires an initialized data declaration",
2909 any_auto_type_p ? auto_type_keyword : "constexpr");
2910 c_parser_skip_to_end_of_block_or_statement (parser);
2911 return;
2913 else if (!fndef_ok)
2915 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2916 "%<asm%> or %<__attribute__%>");
2917 c_parser_skip_to_end_of_block_or_statement (parser);
2918 return;
2920 /* Function definition (nested or otherwise). */
2921 if (nested)
2923 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2924 c_push_function_context ();
2926 if (!start_function (specs, declarator, all_prefix_attrs))
2928 /* At this point we've consumed:
2929 declaration-specifiers declarator
2930 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2931 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2932 but the
2933 declaration-specifiers declarator
2934 aren't grokkable as a function definition, so we have
2935 an error. */
2936 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2937 if (c_parser_next_token_starts_declspecs (parser))
2939 /* If we have
2940 declaration-specifiers declarator decl-specs
2941 then assume we have a missing semicolon, which would
2942 give us:
2943 declaration-specifiers declarator decl-specs
2946 <~~~~~~~~~ declaration ~~~~~~~~~~>
2947 Use c_parser_require to get an error with a fix-it hint. */
2948 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2949 parser->error = false;
2951 else
2953 /* This can appear in many cases looking nothing like a
2954 function definition, so we don't give a more specific
2955 error suggesting there was one. */
2956 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2957 "or %<__attribute__%>");
2959 if (nested)
2960 c_pop_function_context ();
2961 break;
2964 if (DECL_DECLARED_INLINE_P (current_function_decl))
2965 tv = TV_PARSE_INLINE;
2966 else
2967 tv = TV_PARSE_FUNC;
2968 auto_timevar at (g_timer, tv);
2970 /* Parse old-style parameter declarations. ??? Attributes are
2971 not allowed to start declaration specifiers here because of a
2972 syntax conflict between a function declaration with attribute
2973 suffix and a function definition with an attribute prefix on
2974 first old-style parameter declaration. Following the old
2975 parser, they are not accepted on subsequent old-style
2976 parameter declarations either. However, there is no
2977 ambiguity after the first declaration, nor indeed on the
2978 first as long as we don't allow postfix attributes after a
2979 declarator with a nonempty identifier list in a definition;
2980 and postfix attributes have never been accepted here in
2981 function definitions either. */
2982 int save_debug_nonbind_markers_p = debug_nonbind_markers_p;
2983 debug_nonbind_markers_p = 0;
2984 while (c_parser_next_token_is_not (parser, CPP_EOF)
2985 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2986 c_parser_declaration_or_fndef (parser, false, false, false,
2987 true, false);
2988 debug_nonbind_markers_p = save_debug_nonbind_markers_p;
2989 store_parm_decls ();
2990 if (omp_declare_simd_clauses)
2991 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2992 omp_declare_simd_clauses);
2993 if (!omp_dsimd_idattr_clauses.is_empty ())
2994 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2995 &omp_dsimd_idattr_clauses);
2996 if (oacc_routine_data)
2997 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2998 location_t startloc = c_parser_peek_token (parser)->location;
2999 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
3000 = startloc;
3001 location_t endloc = startloc;
3003 /* If the definition was marked with __RTL, use the RTL parser now,
3004 consuming the function body. */
3005 if (specs->declspec_il == cdil_rtl)
3007 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
3009 /* Normally, store_parm_decls sets next_is_function_body,
3010 anticipating a function body. We need a push_scope/pop_scope
3011 pair to flush out this state, or subsequent function parsing
3012 will go wrong. */
3013 push_scope ();
3014 pop_scope ();
3016 finish_function (endloc);
3017 return;
3019 /* If the definition was marked with __GIMPLE then parse the
3020 function body as GIMPLE. */
3021 else if (specs->declspec_il != cdil_none)
3023 bool saved = in_late_binary_op;
3024 in_late_binary_op = true;
3025 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
3026 specs->declspec_il,
3027 specs->entry_bb_count);
3028 in_late_binary_op = saved;
3030 else
3031 fnbody = c_parser_compound_statement (parser, &endloc);
3032 tree fndecl = current_function_decl;
3033 if (nested)
3035 tree decl = current_function_decl;
3036 /* Mark nested functions as needing static-chain initially.
3037 lower_nested_functions will recompute it but the
3038 DECL_STATIC_CHAIN flag is also used before that happens,
3039 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
3040 DECL_STATIC_CHAIN (decl) = 1;
3041 add_stmt (fnbody);
3042 finish_function (endloc);
3043 c_pop_function_context ();
3044 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
3046 else
3048 if (fnbody)
3049 add_stmt (fnbody);
3050 finish_function (endloc);
3052 /* Get rid of the empty stmt list for GIMPLE/RTL. */
3053 if (specs->declspec_il != cdil_none)
3054 DECL_SAVED_TREE (fndecl) = NULL_TREE;
3056 break;
3060 /* Parse an asm-definition (asm() outside a function body). This is a
3061 GNU extension.
3063 asm-definition:
3064 simple-asm-expr ;
3067 static void
3068 c_parser_asm_definition (c_parser *parser)
3070 tree asm_str = c_parser_simple_asm_expr (parser);
3071 if (asm_str)
3072 symtab->finalize_toplevel_asm (asm_str);
3073 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
3076 /* Parse a static assertion (C11 6.7.10).
3078 static_assert-declaration:
3079 static_assert-declaration-no-semi ;
3082 static void
3083 c_parser_static_assert_declaration (c_parser *parser)
3085 c_parser_static_assert_declaration_no_semi (parser);
3086 if (parser->error
3087 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
3088 c_parser_skip_to_end_of_block_or_statement (parser);
3091 /* Parse a static assertion (C11 6.7.10), without the trailing
3092 semicolon.
3094 static_assert-declaration-no-semi:
3095 _Static_assert ( constant-expression , string-literal )
3097 C23:
3098 static_assert-declaration-no-semi:
3099 _Static_assert ( constant-expression )
3102 static void
3103 c_parser_static_assert_declaration_no_semi (c_parser *parser)
3105 location_t assert_loc, value_loc;
3106 tree value;
3107 tree string = NULL_TREE;
3109 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
3110 tree spelling = c_parser_peek_token (parser)->value;
3111 assert_loc = c_parser_peek_token (parser)->location;
3112 if (flag_isoc99)
3113 pedwarn_c99 (assert_loc, OPT_Wpedantic,
3114 "ISO C99 does not support %qE", spelling);
3115 else
3116 pedwarn_c99 (assert_loc, OPT_Wpedantic,
3117 "ISO C90 does not support %qE", spelling);
3118 c_parser_consume_token (parser);
3119 matching_parens parens;
3120 if (!parens.require_open (parser))
3121 return;
3122 location_t value_tok_loc = c_parser_peek_token (parser)->location;
3123 value = convert_lvalue_to_rvalue (value_tok_loc,
3124 c_parser_expr_no_commas (parser, NULL),
3125 true, true).value;
3126 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
3127 if (c_parser_next_token_is (parser, CPP_COMMA))
3129 c_parser_consume_token (parser);
3130 switch (c_parser_peek_token (parser)->type)
3132 case CPP_STRING:
3133 case CPP_STRING16:
3134 case CPP_STRING32:
3135 case CPP_WSTRING:
3136 case CPP_UTF8STRING:
3137 string = c_parser_string_literal (parser, false, true).value;
3138 break;
3139 default:
3140 c_parser_error (parser, "expected string literal");
3141 return;
3144 else if (flag_isoc11)
3145 /* If pedantic for pre-C11, the use of _Static_assert itself will
3146 have been diagnosed, so do not also diagnose the use of this
3147 new C23 feature of _Static_assert. */
3148 pedwarn_c11 (assert_loc, OPT_Wpedantic,
3149 "ISO C11 does not support omitting the string in "
3150 "%qE", spelling);
3151 parens.require_close (parser);
3153 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
3155 error_at (value_loc, "expression in static assertion is not an integer");
3156 return;
3158 if (TREE_CODE (value) != INTEGER_CST)
3160 value = c_fully_fold (value, false, NULL);
3161 /* Strip no-op conversions. */
3162 STRIP_TYPE_NOPS (value);
3163 if (TREE_CODE (value) == INTEGER_CST)
3164 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
3165 "is not an integer constant expression");
3167 if (TREE_CODE (value) != INTEGER_CST)
3169 error_at (value_loc, "expression in static assertion is not constant");
3170 return;
3172 constant_expression_warning (value);
3173 if (integer_zerop (value))
3175 if (string)
3176 error_at (assert_loc, "static assertion failed: %E", string);
3177 else
3178 error_at (assert_loc, "static assertion failed");
3182 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
3183 6.7, C11 6.7), adding them to SPECS (which may already include some).
3184 Storage class specifiers are accepted iff SCSPEC_OK; type
3185 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
3186 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
3187 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
3188 addition to the syntax shown, standard attributes are accepted at
3189 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
3190 unlike gnu-attributes, they are not accepted in the middle of the
3191 list. (This combines various different syntax productions in the C
3192 standard, and in some cases gnu-attributes and standard attributes
3193 at the start may already have been parsed before this function is
3194 called.)
3196 declaration-specifiers:
3197 storage-class-specifier declaration-specifiers[opt]
3198 type-specifier declaration-specifiers[opt]
3199 type-qualifier declaration-specifiers[opt]
3200 function-specifier declaration-specifiers[opt]
3201 alignment-specifier declaration-specifiers[opt]
3203 Function specifiers (inline) are from C99, and are currently
3204 handled as storage class specifiers, as is __thread. Alignment
3205 specifiers are from C11.
3207 C90 6.5.1, C99 6.7.1, C11 6.7.1:
3208 storage-class-specifier:
3209 typedef
3210 extern
3211 static
3212 auto
3213 register
3214 _Thread_local
3216 (_Thread_local is new in C11.)
3218 C99 6.7.4, C11 6.7.4:
3219 function-specifier:
3220 inline
3221 _Noreturn
3223 (_Noreturn is new in C11.)
3225 C90 6.5.2, C99 6.7.2, C11 6.7.2:
3226 type-specifier:
3227 void
3228 char
3229 short
3231 long
3232 float
3233 double
3234 signed
3235 unsigned
3236 _Bool
3237 _Complex
3238 [_Imaginary removed in C99 TC2]
3239 _BitInt ( constant-expression )
3240 struct-or-union-specifier
3241 enum-specifier
3242 typedef-name
3243 atomic-type-specifier
3245 (_Bool and _Complex are new in C99.)
3246 (atomic-type-specifier is new in C11.)
3247 (_BitInt is new in C23.)
3249 C90 6.5.3, C99 6.7.3, C11 6.7.3:
3251 type-qualifier:
3252 const
3253 restrict
3254 volatile
3255 address-space-qualifier
3256 _Atomic
3258 (restrict is new in C99.)
3259 (_Atomic is new in C11.)
3261 GNU extensions:
3263 declaration-specifiers:
3264 gnu-attributes declaration-specifiers[opt]
3266 type-qualifier:
3267 address-space
3269 address-space:
3270 identifier recognized by the target
3272 storage-class-specifier:
3273 __thread
3275 type-specifier:
3276 typeof-specifier
3277 __auto_type
3278 __intN
3279 _Decimal32
3280 _Decimal64
3281 _Decimal128
3282 _Fract
3283 _Accum
3284 _Sat
3286 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
3287 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
3289 atomic-type-specifier
3290 _Atomic ( type-name )
3292 Objective-C:
3294 type-specifier:
3295 class-name objc-protocol-refs[opt]
3296 typedef-name objc-protocol-refs
3297 objc-protocol-refs
3300 void
3301 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
3302 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
3303 bool alignspec_ok, bool auto_type_ok,
3304 bool start_std_attr_ok, bool end_std_attr_ok,
3305 enum c_lookahead_kind la)
3307 bool attrs_ok = start_attr_ok;
3308 bool seen_type = specs->typespec_kind != ctsk_none;
3310 if (!typespec_ok)
3311 gcc_assert (la == cla_prefer_id);
3313 if (start_std_attr_ok
3314 && c_parser_nth_token_starts_std_attributes (parser, 1))
3316 gcc_assert (!specs->non_std_attrs_seen_p);
3317 location_t loc = c_parser_peek_token (parser)->location;
3318 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
3319 declspecs_add_attrs (loc, specs, attrs);
3320 specs->non_std_attrs_seen_p = false;
3323 while (c_parser_next_token_is (parser, CPP_NAME)
3324 || c_parser_next_token_is (parser, CPP_KEYWORD)
3325 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
3327 struct c_typespec t;
3328 tree attrs;
3329 tree align;
3330 location_t loc = c_parser_peek_token (parser)->location;
3332 /* If we cannot accept a type, exit if the next token must start
3333 one. Also, if we already have seen a tagged definition,
3334 a typename would be an error anyway and likely the user
3335 has simply forgotten a semicolon, so we exit. */
3336 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
3337 && c_parser_next_tokens_start_typename (parser, la)
3338 && !c_parser_next_token_is_qualifier (parser)
3339 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
3340 break;
3342 if (c_parser_next_token_is (parser, CPP_NAME))
3344 c_token *name_token = c_parser_peek_token (parser);
3345 tree value = name_token->value;
3346 c_id_kind kind = name_token->id_kind;
3348 if (kind == C_ID_ADDRSPACE)
3350 addr_space_t as
3351 = name_token->keyword - RID_FIRST_ADDR_SPACE;
3352 declspecs_add_addrspace (name_token->location, specs, as);
3353 c_parser_consume_token (parser);
3354 attrs_ok = true;
3355 continue;
3358 gcc_assert (!c_parser_next_token_is_qualifier (parser));
3360 /* If we cannot accept a type, and the next token must start one,
3361 exit. Do the same if we already have seen a tagged definition,
3362 since it would be an error anyway and likely the user has simply
3363 forgotten a semicolon. */
3364 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
3365 break;
3367 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
3368 a C_ID_CLASSNAME. */
3369 c_parser_consume_token (parser);
3370 seen_type = true;
3371 attrs_ok = true;
3372 if (kind == C_ID_ID)
3374 auto_diagnostic_group d;
3375 name_hint hint = lookup_name_fuzzy (value, FUZZY_LOOKUP_TYPENAME,
3376 loc);
3377 if (const char *suggestion = hint.suggestion ())
3379 gcc_rich_location richloc (loc);
3380 richloc.add_fixit_replace (suggestion);
3381 error_at (&richloc,
3382 "unknown type name %qE; did you mean %qs?",
3383 value, suggestion);
3385 else
3386 error_at (loc, "unknown type name %qE", value);
3387 t.kind = ctsk_typedef;
3388 t.spec = error_mark_node;
3390 else if (kind == C_ID_TYPENAME
3391 && (!c_dialect_objc ()
3392 || c_parser_next_token_is_not (parser, CPP_LESS)))
3394 t.kind = ctsk_typedef;
3395 /* For a typedef name, record the meaning, not the name.
3396 In case of 'foo foo, bar;'. */
3397 t.spec = lookup_name (value);
3399 else
3401 tree proto = NULL_TREE;
3402 gcc_assert (c_dialect_objc ());
3403 t.kind = ctsk_objc;
3404 if (c_parser_next_token_is (parser, CPP_LESS))
3405 proto = c_parser_objc_protocol_refs (parser);
3406 t.spec = objc_get_protocol_qualified_type (value, proto);
3408 t.expr = NULL_TREE;
3409 t.expr_const_operands = true;
3410 t.has_enum_type_specifier = false;
3411 declspecs_add_type (name_token->location, specs, t);
3412 continue;
3414 if (c_parser_next_token_is (parser, CPP_LESS))
3416 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3417 nisse@lysator.liu.se. */
3418 tree proto;
3419 gcc_assert (c_dialect_objc ());
3420 if (!typespec_ok || seen_type)
3421 break;
3422 proto = c_parser_objc_protocol_refs (parser);
3423 t.kind = ctsk_objc;
3424 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
3425 t.expr = NULL_TREE;
3426 t.expr_const_operands = true;
3427 t.has_enum_type_specifier = false;
3428 declspecs_add_type (loc, specs, t);
3429 continue;
3431 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
3432 switch (c_parser_peek_token (parser)->keyword)
3434 case RID_STATIC:
3435 case RID_EXTERN:
3436 case RID_REGISTER:
3437 case RID_TYPEDEF:
3438 case RID_INLINE:
3439 case RID_NORETURN:
3440 case RID_AUTO:
3441 case RID_THREAD:
3442 case RID_CONSTEXPR:
3443 if (!scspec_ok)
3444 goto out;
3445 attrs_ok = true;
3446 /* TODO: Distinguish between function specifiers (inline, noreturn)
3447 and storage class specifiers, either here or in
3448 declspecs_add_scspec. */
3449 declspecs_add_scspec (loc, specs,
3450 c_parser_peek_token (parser)->value);
3451 c_parser_consume_token (parser);
3452 break;
3453 case RID_AUTO_TYPE:
3454 if (!auto_type_ok)
3455 goto out;
3456 /* Fall through. */
3457 case RID_UNSIGNED:
3458 case RID_LONG:
3459 case RID_SHORT:
3460 case RID_SIGNED:
3461 case RID_COMPLEX:
3462 case RID_INT:
3463 case RID_CHAR:
3464 case RID_FLOAT:
3465 case RID_DOUBLE:
3466 case RID_VOID:
3467 case RID_DFLOAT32:
3468 case RID_DFLOAT64:
3469 case RID_DFLOAT128:
3470 CASE_RID_FLOATN_NX:
3471 case RID_BOOL:
3472 case RID_FRACT:
3473 case RID_ACCUM:
3474 case RID_SAT:
3475 case RID_INT_N_0:
3476 case RID_INT_N_1:
3477 case RID_INT_N_2:
3478 case RID_INT_N_3:
3479 if (!typespec_ok)
3480 goto out;
3481 attrs_ok = true;
3482 seen_type = true;
3483 if (c_dialect_objc ())
3484 parser->objc_need_raw_identifier = true;
3485 t.kind = ctsk_resword;
3486 t.spec = c_parser_peek_token (parser)->value;
3487 t.expr = NULL_TREE;
3488 t.expr_const_operands = true;
3489 t.has_enum_type_specifier = false;
3490 declspecs_add_type (loc, specs, t);
3491 c_parser_consume_token (parser);
3492 break;
3493 case RID_ENUM:
3494 if (!typespec_ok)
3495 goto out;
3496 attrs_ok = true;
3497 seen_type = true;
3498 t = c_parser_enum_specifier (parser);
3499 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3500 declspecs_add_type (loc, specs, t);
3501 break;
3502 case RID_STRUCT:
3503 case RID_UNION:
3504 if (!typespec_ok)
3505 goto out;
3506 attrs_ok = true;
3507 seen_type = true;
3508 t = c_parser_struct_or_union_specifier (parser);
3509 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3510 declspecs_add_type (loc, specs, t);
3511 break;
3512 case RID_TYPEOF:
3513 case RID_TYPEOF_UNQUAL:
3514 /* ??? The old parser rejected typeof after other type
3515 specifiers, but is a syntax error the best way of
3516 handling this? */
3517 if (!typespec_ok || seen_type)
3518 goto out;
3519 attrs_ok = true;
3520 seen_type = true;
3521 t = c_parser_typeof_specifier (parser);
3522 declspecs_add_type (loc, specs, t);
3523 break;
3524 case RID_BITINT:
3525 if (!typespec_ok)
3526 goto out;
3527 else
3529 attrs_ok = true;
3530 seen_type = true;
3531 t.kind = ctsk_resword;
3532 t.spec = c_parser_peek_token (parser)->value;
3533 t.expr = error_mark_node;
3534 t.expr_const_operands = true;
3535 t.has_enum_type_specifier = false;
3536 c_parser_consume_token (parser);
3537 matching_parens parens;
3538 if (parens.require_open (parser))
3540 c_expr expr = c_parser_expr_no_commas (parser, NULL);
3541 t.expr = convert_lvalue_to_rvalue (loc, expr, true,
3542 true).value;
3543 parens.skip_until_found_close (parser);
3545 declspecs_add_type (loc, specs, t);
3547 break;
3548 case RID_ATOMIC:
3549 /* C parser handling of Objective-C constructs needs
3550 checking for correct lvalue-to-rvalue conversions, and
3551 the code in build_modify_expr handling various
3552 Objective-C cases, and that in build_unary_op handling
3553 Objective-C cases for increment / decrement, also needs
3554 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3555 and objc_types_are_equivalent may also need updates. */
3556 if (c_dialect_objc ())
3557 sorry ("%<_Atomic%> in Objective-C");
3558 if (flag_isoc99)
3559 pedwarn_c99 (loc, OPT_Wpedantic,
3560 "ISO C99 does not support the %<_Atomic%> qualifier");
3561 else
3562 pedwarn_c99 (loc, OPT_Wpedantic,
3563 "ISO C90 does not support the %<_Atomic%> qualifier");
3564 attrs_ok = true;
3565 tree value;
3566 value = c_parser_peek_token (parser)->value;
3567 c_parser_consume_token (parser);
3568 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3570 /* _Atomic ( type-name ). */
3571 seen_type = true;
3572 c_parser_consume_token (parser);
3573 struct c_type_name *type = c_parser_type_name (parser);
3574 t.kind = ctsk_typeof;
3575 t.spec = error_mark_node;
3576 t.expr = NULL_TREE;
3577 t.expr_const_operands = true;
3578 t.has_enum_type_specifier = false;
3579 if (type != NULL)
3580 t.spec = groktypename (type, &t.expr,
3581 &t.expr_const_operands);
3582 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3583 "expected %<)%>");
3584 if (t.spec != error_mark_node)
3586 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3587 error_at (loc, "%<_Atomic%>-qualified array type");
3588 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3589 error_at (loc, "%<_Atomic%>-qualified function type");
3590 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3591 error_at (loc, "%<_Atomic%> applied to a qualified type");
3592 else
3593 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3595 declspecs_add_type (loc, specs, t);
3597 else
3598 declspecs_add_qual (loc, specs, value);
3599 break;
3600 case RID_CONST:
3601 case RID_VOLATILE:
3602 case RID_RESTRICT:
3603 attrs_ok = true;
3604 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3605 c_parser_consume_token (parser);
3606 break;
3607 case RID_ATTRIBUTE:
3608 if (!attrs_ok)
3609 goto out;
3610 attrs = c_parser_gnu_attributes (parser);
3611 declspecs_add_attrs (loc, specs, attrs);
3612 break;
3613 case RID_ALIGNAS:
3614 if (!alignspec_ok)
3615 goto out;
3616 align = c_parser_alignas_specifier (parser);
3617 declspecs_add_alignas (loc, specs, align);
3618 break;
3619 case RID_GIMPLE:
3620 if (! flag_gimple)
3621 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3622 c_parser_consume_token (parser);
3623 specs->declspec_il = cdil_gimple;
3624 specs->locations[cdw_gimple] = loc;
3625 c_parser_gimple_or_rtl_pass_list (parser, specs);
3626 break;
3627 case RID_RTL:
3628 c_parser_consume_token (parser);
3629 specs->declspec_il = cdil_rtl;
3630 specs->locations[cdw_rtl] = loc;
3631 c_parser_gimple_or_rtl_pass_list (parser, specs);
3632 break;
3633 default:
3634 goto out;
3637 out:
3638 if (end_std_attr_ok
3639 && c_parser_nth_token_starts_std_attributes (parser, 1))
3640 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3643 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3645 enum-specifier:
3646 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3647 { enumerator-list } gnu-attributes[opt]
3648 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3649 { enumerator-list , } gnu-attributes[opt] enum-type-specifier[opt]
3650 enum gnu-attributes[opt] identifier
3652 The form with trailing comma is new in C99; enum-type-specifiers
3653 are new in C23. The forms with gnu-attributes are GNU extensions.
3654 In GNU C, we accept any expression without commas in the syntax
3655 (assignment expressions, not just conditional expressions);
3656 assignment expressions will be diagnosed as non-constant.
3658 enum-type-specifier:
3659 : specifier-qualifier-list
3661 enumerator-list:
3662 enumerator
3663 enumerator-list , enumerator
3665 enumerator:
3666 enumeration-constant attribute-specifier-sequence[opt]
3667 enumeration-constant attribute-specifier-sequence[opt]
3668 = constant-expression
3670 GNU Extensions:
3672 enumerator:
3673 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3674 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3675 = constant-expression
3679 static struct c_typespec
3680 c_parser_enum_specifier (c_parser *parser)
3682 struct c_typespec ret;
3683 bool have_std_attrs;
3684 bool potential_nesting_p = false;
3685 tree std_attrs = NULL_TREE;
3686 tree attrs;
3687 tree ident = NULL_TREE;
3688 tree fixed_underlying_type = NULL_TREE;
3689 location_t enum_loc;
3690 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3691 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3692 c_parser_consume_token (parser);
3693 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3694 if (have_std_attrs)
3695 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3696 attrs = c_parser_gnu_attributes (parser);
3697 enum_loc = c_parser_peek_token (parser)->location;
3698 /* Set the location in case we create a decl now. */
3699 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3700 if (c_parser_next_token_is (parser, CPP_NAME))
3702 ident = c_parser_peek_token (parser)->value;
3703 ident_loc = c_parser_peek_token (parser)->location;
3704 enum_loc = ident_loc;
3705 c_parser_consume_token (parser);
3707 if (c_parser_next_token_is (parser, CPP_COLON)
3708 /* Distinguish an enum-type-specifier from a bit-field
3709 declaration of the form "enum e : constant-expression;". */
3710 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
3712 pedwarn_c11 (enum_loc, OPT_Wpedantic,
3713 "ISO C does not support specifying %<enum%> underlying "
3714 "types before C23");
3715 if (ident)
3717 /* The tag is in scope during the enum-type-specifier (which
3718 may refer to the tag inside typeof). */
3719 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident,
3720 have_std_attrs, std_attrs, true);
3721 if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec))
3722 error_at (enum_loc, "%<enum%> declared both with and without "
3723 "fixed underlying type");
3724 potential_nesting_p = NULL_TREE == TYPE_VALUES (ret.spec);
3726 else
3728 /* There must be an enum definition, so this initialization
3729 (to avoid possible warnings about uninitialized data)
3730 will be replaced later (either with the results of that
3731 definition, or with the results of error handling for the
3732 case of no tag and no definition). */
3733 ret.spec = NULL_TREE;
3734 ret.kind = ctsk_tagdef;
3735 ret.expr = NULL_TREE;
3736 ret.expr_const_operands = true;
3737 ret.has_enum_type_specifier = true;
3739 c_parser_consume_token (parser);
3740 struct c_declspecs *specs = build_null_declspecs ();
3741 c_parser_declspecs (parser, specs, false, true, false, false, false,
3742 false, true, cla_prefer_id);
3743 finish_declspecs (specs);
3744 if (specs->default_int_p)
3745 error_at (enum_loc, "no %<enum%> underlying type specified");
3746 else if (TREE_CODE (specs->type) != INTEGER_TYPE
3747 && TREE_CODE (specs->type) != BOOLEAN_TYPE)
3749 error_at (enum_loc, "invalid %<enum%> underlying type");
3750 specs->type = integer_type_node;
3752 else if (specs->restrict_p)
3753 error_at (enum_loc, "invalid use of %<restrict%>");
3754 fixed_underlying_type = TYPE_MAIN_VARIANT (specs->type);
3755 if (ident)
3757 /* The type specified must be consistent with any previously
3758 specified underlying type. If this is a newly declared
3759 type, it is now a complete type. */
3760 if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
3761 && ENUM_UNDERLYING_TYPE (ret.spec) == NULL_TREE)
3763 TYPE_MIN_VALUE (ret.spec) =
3764 TYPE_MIN_VALUE (fixed_underlying_type);
3765 TYPE_MAX_VALUE (ret.spec) =
3766 TYPE_MAX_VALUE (fixed_underlying_type);
3767 TYPE_UNSIGNED (ret.spec) = TYPE_UNSIGNED (fixed_underlying_type);
3768 SET_TYPE_ALIGN (ret.spec, TYPE_ALIGN (fixed_underlying_type));
3769 TYPE_SIZE (ret.spec) = NULL_TREE;
3770 TYPE_PRECISION (ret.spec) =
3771 TYPE_PRECISION (fixed_underlying_type);
3772 ENUM_UNDERLYING_TYPE (ret.spec) = fixed_underlying_type;
3773 layout_type (ret.spec);
3775 else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
3776 && !comptypes (fixed_underlying_type,
3777 ENUM_UNDERLYING_TYPE (ret.spec)))
3779 error_at (enum_loc, "%<enum%> underlying type incompatible with "
3780 "previous declaration");
3781 fixed_underlying_type = ENUM_UNDERLYING_TYPE (ret.spec);
3785 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3787 /* Parse an enum definition. */
3788 struct c_enum_contents the_enum;
3789 tree type;
3790 tree postfix_attrs;
3791 /* We chain the enumerators in reverse order, then put them in
3792 forward order at the end. */
3793 tree values;
3794 timevar_push (TV_PARSE_ENUM);
3795 type = start_enum (enum_loc, &the_enum, ident, fixed_underlying_type,
3796 potential_nesting_p);
3797 values = NULL_TREE;
3798 c_parser_consume_token (parser);
3799 while (true)
3801 tree enum_id;
3802 tree enum_value;
3803 tree enum_decl;
3804 bool seen_comma;
3805 c_token *token;
3806 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3807 location_t decl_loc, value_loc;
3808 if (c_parser_next_token_is_not (parser, CPP_NAME))
3810 /* Give a nicer error for "enum {}". */
3811 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3812 && !parser->error)
3814 error_at (c_parser_peek_token (parser)->location,
3815 "empty enum is invalid");
3816 parser->error = true;
3818 else
3819 c_parser_error (parser, "expected identifier");
3820 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3821 values = error_mark_node;
3822 break;
3824 token = c_parser_peek_token (parser);
3825 enum_id = token->value;
3826 /* Set the location in case we create a decl now. */
3827 c_parser_set_source_position_from_token (token);
3828 decl_loc = value_loc = token->location;
3829 c_parser_consume_token (parser);
3830 /* Parse any specified attributes. */
3831 tree std_attrs = NULL_TREE;
3832 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3833 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3834 tree enum_attrs = chainon (std_attrs,
3835 c_parser_gnu_attributes (parser));
3836 if (c_parser_next_token_is (parser, CPP_EQ))
3838 c_parser_consume_token (parser);
3839 value_loc = c_parser_peek_token (parser)->location;
3840 enum_value = convert_lvalue_to_rvalue (value_loc,
3841 (c_parser_expr_no_commas
3842 (parser, NULL)),
3843 true, true).value;
3845 else
3846 enum_value = NULL_TREE;
3847 enum_decl = build_enumerator (decl_loc, value_loc,
3848 &the_enum, enum_id, enum_value);
3849 if (enum_attrs)
3850 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3851 TREE_CHAIN (enum_decl) = values;
3852 values = enum_decl;
3853 seen_comma = false;
3854 if (c_parser_next_token_is (parser, CPP_COMMA))
3856 comma_loc = c_parser_peek_token (parser)->location;
3857 seen_comma = true;
3858 c_parser_consume_token (parser);
3860 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3862 if (seen_comma)
3863 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3864 "comma at end of enumerator list");
3865 c_parser_consume_token (parser);
3866 break;
3868 if (!seen_comma)
3870 c_parser_error (parser, "expected %<,%> or %<}%>");
3871 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3872 values = error_mark_node;
3873 break;
3876 postfix_attrs = c_parser_gnu_attributes (parser);
3877 ret.spec = finish_enum (type, nreverse (values),
3878 chainon (std_attrs,
3879 chainon (attrs, postfix_attrs)));
3880 ret.kind = ctsk_tagdef;
3881 ret.expr = NULL_TREE;
3882 ret.expr_const_operands = true;
3883 ret.has_enum_type_specifier = fixed_underlying_type != NULL_TREE;
3884 timevar_pop (TV_PARSE_ENUM);
3885 return ret;
3887 else if (!ident)
3889 c_parser_error (parser, "expected %<{%>");
3890 ret.spec = error_mark_node;
3891 ret.kind = ctsk_tagref;
3892 ret.expr = NULL_TREE;
3893 ret.expr_const_operands = true;
3894 ret.has_enum_type_specifier = false;
3895 return ret;
3897 /* Attributes may only appear when the members are defined or in
3898 certain forward declarations (treat enum forward declarations in
3899 GNU C analogously to struct and union forward declarations in
3900 standard C). */
3901 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3902 c_parser_error (parser, "expected %<;%>");
3903 if (fixed_underlying_type == NULL_TREE)
3905 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3906 std_attrs, false);
3907 /* In ISO C, enumerated types without a fixed underlying type
3908 can be referred to only if already defined. */
3909 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3911 gcc_assert (ident);
3912 pedwarn (enum_loc, OPT_Wpedantic,
3913 "ISO C forbids forward references to %<enum%> types");
3916 return ret;
3919 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3921 struct-or-union-specifier:
3922 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3923 identifier[opt] { struct-contents } gnu-attributes[opt]
3924 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3925 identifier
3927 struct-contents:
3928 struct-declaration-list
3930 struct-declaration-list:
3931 struct-declaration ;
3932 struct-declaration-list struct-declaration ;
3934 GNU extensions:
3936 struct-contents:
3937 empty
3938 struct-declaration
3939 struct-declaration-list struct-declaration
3941 struct-declaration-list:
3942 struct-declaration-list ;
3945 (Note that in the syntax here, unlike that in ISO C, the semicolons
3946 are included here rather than in struct-declaration, in order to
3947 describe the syntax with extra semicolons and missing semicolon at
3948 end.)
3950 Objective-C:
3952 struct-declaration-list:
3953 @defs ( class-name )
3955 (Note this does not include a trailing semicolon, but can be
3956 followed by further declarations, and gets a pedwarn-if-pedantic
3957 when followed by a semicolon.) */
3959 static struct c_typespec
3960 c_parser_struct_or_union_specifier (c_parser *parser)
3962 struct c_typespec ret;
3963 bool have_std_attrs;
3964 tree std_attrs = NULL_TREE;
3965 tree attrs;
3966 tree ident = NULL_TREE;
3967 location_t struct_loc;
3968 location_t ident_loc = UNKNOWN_LOCATION;
3969 enum tree_code code;
3970 switch (c_parser_peek_token (parser)->keyword)
3972 case RID_STRUCT:
3973 code = RECORD_TYPE;
3974 break;
3975 case RID_UNION:
3976 code = UNION_TYPE;
3977 break;
3978 default:
3979 gcc_unreachable ();
3981 struct_loc = c_parser_peek_token (parser)->location;
3982 c_parser_consume_token (parser);
3983 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3984 if (have_std_attrs)
3985 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3986 attrs = c_parser_gnu_attributes (parser);
3988 /* Set the location in case we create a decl now. */
3989 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3991 if (c_parser_next_token_is (parser, CPP_NAME))
3993 ident = c_parser_peek_token (parser)->value;
3994 ident_loc = c_parser_peek_token (parser)->location;
3995 struct_loc = ident_loc;
3996 c_parser_consume_token (parser);
3998 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
4000 /* Parse a struct or union definition. Start the scope of the
4001 tag before parsing components. */
4002 class c_struct_parse_info *struct_info;
4003 tree type = start_struct (struct_loc, code, ident, &struct_info);
4004 tree postfix_attrs;
4005 /* We chain the components in reverse order, then put them in
4006 forward order at the end. Each struct-declaration may
4007 declare multiple components (comma-separated), so we must use
4008 chainon to join them, although when parsing each
4009 struct-declaration we can use TREE_CHAIN directly.
4011 The theory behind all this is that there will be more
4012 semicolon separated fields than comma separated fields, and
4013 so we'll be minimizing the number of node traversals required
4014 by chainon. */
4015 tree contents;
4016 tree expr = NULL;
4017 timevar_push (TV_PARSE_STRUCT);
4018 contents = NULL_TREE;
4019 c_parser_consume_token (parser);
4020 /* Handle the Objective-C @defs construct,
4021 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
4022 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
4024 tree name;
4025 gcc_assert (c_dialect_objc ());
4026 c_parser_consume_token (parser);
4027 matching_parens parens;
4028 if (!parens.require_open (parser))
4029 goto end_at_defs;
4030 if (c_parser_next_token_is (parser, CPP_NAME)
4031 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
4033 name = c_parser_peek_token (parser)->value;
4034 c_parser_consume_token (parser);
4036 else
4038 c_parser_error (parser, "expected class name");
4039 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4040 goto end_at_defs;
4042 parens.skip_until_found_close (parser);
4043 contents = nreverse (objc_get_class_ivars (name));
4045 end_at_defs:
4046 /* Parse the struct-declarations and semicolons. Problems with
4047 semicolons are diagnosed here; empty structures are diagnosed
4048 elsewhere. */
4049 while (true)
4051 tree decls;
4052 /* Parse any stray semicolon. */
4053 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4055 location_t semicolon_loc
4056 = c_parser_peek_token (parser)->location;
4057 gcc_rich_location richloc (semicolon_loc);
4058 richloc.add_fixit_remove ();
4059 pedwarn (&richloc, OPT_Wpedantic,
4060 "extra semicolon in struct or union specified");
4061 c_parser_consume_token (parser);
4062 continue;
4064 /* Stop if at the end of the struct or union contents. */
4065 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4067 c_parser_consume_token (parser);
4068 break;
4070 /* Accept #pragmas at struct scope. */
4071 if (c_parser_next_token_is (parser, CPP_PRAGMA))
4073 c_parser_pragma (parser, pragma_struct, NULL);
4074 continue;
4076 /* Parse some comma-separated declarations, but not the
4077 trailing semicolon if any. */
4078 decls = c_parser_struct_declaration (parser, &expr);
4079 contents = chainon (decls, contents);
4080 /* If no semicolon follows, either we have a parse error or
4081 are at the end of the struct or union and should
4082 pedwarn. */
4083 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4084 c_parser_consume_token (parser);
4085 else
4087 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4088 pedwarn (c_parser_peek_token (parser)->location, 0,
4089 "no semicolon at end of struct or union");
4090 else if (parser->error
4091 || !c_parser_next_token_starts_declspecs (parser))
4093 c_parser_error (parser, "expected %<;%>");
4094 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
4095 break;
4098 /* If we come here, we have already emitted an error
4099 for an expected `;', identifier or `(', and we also
4100 recovered already. Go on with the next field. */
4103 postfix_attrs = c_parser_gnu_attributes (parser);
4104 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
4105 chainon (std_attrs,
4106 chainon (attrs, postfix_attrs)),
4107 struct_info, &expr);
4108 ret.kind = ctsk_tagdef;
4109 ret.expr = expr;
4110 ret.expr_const_operands = true;
4111 ret.has_enum_type_specifier = false;
4112 timevar_pop (TV_PARSE_STRUCT);
4113 return ret;
4115 else if (!ident)
4117 c_parser_error (parser, "expected %<{%>");
4118 ret.spec = error_mark_node;
4119 ret.kind = ctsk_tagref;
4120 ret.expr = NULL_TREE;
4121 ret.expr_const_operands = true;
4122 ret.has_enum_type_specifier = false;
4123 return ret;
4125 /* Attributes may only appear when the members are defined or in
4126 certain forward declarations. */
4127 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
4128 c_parser_error (parser, "expected %<;%>");
4129 /* ??? Existing practice is that GNU attributes are ignored after
4130 the struct or union keyword when not defining the members. */
4131 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs,
4132 false);
4133 return ret;
4136 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
4137 *without* the trailing semicolon.
4139 struct-declaration:
4140 attribute-specifier-sequence[opt] specifier-qualifier-list
4141 attribute-specifier-sequence[opt] struct-declarator-list
4142 static_assert-declaration-no-semi
4144 specifier-qualifier-list:
4145 type-specifier specifier-qualifier-list[opt]
4146 type-qualifier specifier-qualifier-list[opt]
4147 alignment-specifier specifier-qualifier-list[opt]
4148 gnu-attributes specifier-qualifier-list[opt]
4150 struct-declarator-list:
4151 struct-declarator
4152 struct-declarator-list , gnu-attributes[opt] struct-declarator
4154 struct-declarator:
4155 declarator gnu-attributes[opt]
4156 declarator[opt] : constant-expression gnu-attributes[opt]
4158 GNU extensions:
4160 struct-declaration:
4161 __extension__ struct-declaration
4162 specifier-qualifier-list
4164 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
4165 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
4166 any expression without commas in the syntax (assignment
4167 expressions, not just conditional expressions); assignment
4168 expressions will be diagnosed as non-constant. */
4170 static tree
4171 c_parser_struct_declaration (c_parser *parser, tree *expr)
4173 struct c_declspecs *specs;
4174 tree prefix_attrs;
4175 tree all_prefix_attrs;
4176 tree decls;
4177 location_t decl_loc;
4178 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
4180 int ext;
4181 tree decl;
4182 ext = disable_extension_diagnostics ();
4183 c_parser_consume_token (parser);
4184 decl = c_parser_struct_declaration (parser, expr);
4185 restore_extension_diagnostics (ext);
4186 return decl;
4188 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
4190 c_parser_static_assert_declaration_no_semi (parser);
4191 return NULL_TREE;
4193 specs = build_null_declspecs ();
4194 decl_loc = c_parser_peek_token (parser)->location;
4195 /* Strictly by the standard, we shouldn't allow _Alignas here,
4196 but it appears to have been intended to allow it there, so
4197 we're keeping it as it is until WG14 reaches a conclusion
4198 of N1731.
4199 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
4200 c_parser_declspecs (parser, specs, false, true, true,
4201 true, false, true, true, cla_nonabstract_decl);
4202 if (parser->error)
4203 return NULL_TREE;
4204 if (!specs->declspecs_seen_p)
4206 c_parser_error (parser, "expected specifier-qualifier-list");
4207 return NULL_TREE;
4209 finish_declspecs (specs);
4210 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
4211 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4213 tree ret;
4214 if (specs->typespec_kind == ctsk_none)
4216 pedwarn (decl_loc, OPT_Wpedantic,
4217 "ISO C forbids member declarations with no members");
4218 shadow_tag_warned (specs, pedantic);
4219 ret = NULL_TREE;
4221 else
4223 /* Support for unnamed structs or unions as members of
4224 structs or unions (which is [a] useful and [b] supports
4225 MS P-SDK). */
4226 tree attrs = NULL;
4228 ret = grokfield (c_parser_peek_token (parser)->location,
4229 build_id_declarator (NULL_TREE), specs,
4230 NULL_TREE, &attrs, expr);
4231 if (ret)
4232 decl_attributes (&ret, attrs, 0);
4234 return ret;
4237 /* Provide better error recovery. Note that a type name here is valid,
4238 and will be treated as a field name. */
4239 if (specs->typespec_kind == ctsk_tagdef
4240 && TREE_CODE (specs->type) != ENUMERAL_TYPE
4241 && c_parser_next_token_starts_declspecs (parser)
4242 && !c_parser_next_token_is (parser, CPP_NAME))
4244 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
4245 parser->error = false;
4246 return NULL_TREE;
4249 pending_xref_error ();
4250 prefix_attrs = specs->attrs;
4251 all_prefix_attrs = prefix_attrs;
4252 specs->attrs = NULL_TREE;
4253 decls = NULL_TREE;
4254 while (true)
4256 /* Declaring one or more declarators or un-named bit-fields. */
4257 struct c_declarator *declarator;
4258 bool dummy = false;
4259 if (c_parser_next_token_is (parser, CPP_COLON))
4260 declarator = build_id_declarator (NULL_TREE);
4261 else
4262 declarator = c_parser_declarator (parser,
4263 specs->typespec_kind != ctsk_none,
4264 C_DTR_NORMAL, &dummy);
4265 if (declarator == NULL)
4267 c_parser_skip_to_end_of_block_or_statement (parser);
4268 break;
4270 if (c_parser_next_token_is (parser, CPP_COLON)
4271 || c_parser_next_token_is (parser, CPP_COMMA)
4272 || c_parser_next_token_is (parser, CPP_SEMICOLON)
4273 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
4274 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4276 tree postfix_attrs = NULL_TREE;
4277 tree width = NULL_TREE;
4278 tree d;
4279 if (c_parser_next_token_is (parser, CPP_COLON))
4281 c_parser_consume_token (parser);
4282 location_t loc = c_parser_peek_token (parser)->location;
4283 width = convert_lvalue_to_rvalue (loc,
4284 (c_parser_expr_no_commas
4285 (parser, NULL)),
4286 true, true).value;
4288 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4289 postfix_attrs = c_parser_gnu_attributes (parser);
4290 d = grokfield (c_parser_peek_token (parser)->location,
4291 declarator, specs, width, &all_prefix_attrs, expr);
4292 decl_attributes (&d, chainon (postfix_attrs,
4293 all_prefix_attrs), 0);
4294 DECL_CHAIN (d) = decls;
4295 decls = d;
4296 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4297 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
4298 prefix_attrs);
4299 else
4300 all_prefix_attrs = prefix_attrs;
4301 if (c_parser_next_token_is (parser, CPP_COMMA))
4302 c_parser_consume_token (parser);
4303 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
4304 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4306 /* Semicolon consumed in caller. */
4307 break;
4309 else
4311 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
4312 break;
4315 else
4317 c_parser_error (parser,
4318 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
4319 "%<__attribute__%>");
4320 break;
4323 return decls;
4326 /* Parse a typeof specifier (a GNU extension adopted in C23).
4328 typeof-specifier:
4329 typeof ( expression )
4330 typeof ( type-name )
4331 typeof_unqual ( expression )
4332 typeof_unqual ( type-name )
4335 static struct c_typespec
4336 c_parser_typeof_specifier (c_parser *parser)
4338 bool is_unqual;
4339 bool is_std;
4340 struct c_typespec ret;
4341 ret.kind = ctsk_typeof;
4342 ret.spec = error_mark_node;
4343 ret.expr = NULL_TREE;
4344 ret.expr_const_operands = true;
4345 ret.has_enum_type_specifier = false;
4346 if (c_parser_next_token_is_keyword (parser, RID_TYPEOF))
4348 is_unqual = false;
4349 tree spelling = c_parser_peek_token (parser)->value;
4350 is_std = (flag_isoc23
4351 && strcmp (IDENTIFIER_POINTER (spelling), "typeof") == 0);
4353 else
4355 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF_UNQUAL));
4356 is_unqual = true;
4357 tree spelling = c_parser_peek_token (parser)->value;
4358 is_std = strcmp (IDENTIFIER_POINTER (spelling), "typeof_unqual") == 0;
4360 c_parser_consume_token (parser);
4361 c_inhibit_evaluation_warnings++;
4362 in_typeof++;
4363 matching_parens parens;
4364 if (!parens.require_open (parser))
4366 c_inhibit_evaluation_warnings--;
4367 in_typeof--;
4368 return ret;
4370 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
4372 struct c_type_name *type = c_parser_type_name (parser);
4373 c_inhibit_evaluation_warnings--;
4374 in_typeof--;
4375 if (type != NULL)
4377 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
4378 pop_maybe_used (c_type_variably_modified_p (ret.spec));
4381 else
4383 bool was_vm;
4384 location_t here = c_parser_peek_token (parser)->location;
4385 struct c_expr expr = c_parser_expression (parser);
4386 c_inhibit_evaluation_warnings--;
4387 in_typeof--;
4388 if (TREE_CODE (expr.value) == COMPONENT_REF
4389 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
4390 error_at (here, "%<typeof%> applied to a bit-field");
4391 mark_exp_read (expr.value);
4392 ret.spec = TREE_TYPE (expr.value);
4393 was_vm = c_type_variably_modified_p (ret.spec);
4394 /* This is returned with the type so that when the type is
4395 evaluated, this can be evaluated. */
4396 if (was_vm)
4397 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
4398 pop_maybe_used (was_vm);
4400 parens.skip_until_found_close (parser);
4401 if (ret.spec != error_mark_node)
4403 if (is_unqual && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
4404 ret.spec = TYPE_MAIN_VARIANT (ret.spec);
4405 if (is_std)
4407 /* In ISO C terms, _Noreturn is not part of the type of
4408 expressions such as &abort, but in GCC it is represented
4409 internally as a type qualifier. */
4410 if (TREE_CODE (ret.spec) == FUNCTION_TYPE
4411 && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
4412 ret.spec = TYPE_MAIN_VARIANT (ret.spec);
4413 else if (FUNCTION_POINTER_TYPE_P (ret.spec)
4414 && TYPE_QUALS (TREE_TYPE (ret.spec)) != TYPE_UNQUALIFIED)
4415 ret.spec
4416 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret.spec)));
4419 return ret;
4422 /* Parse an alignment-specifier.
4424 C11 6.7.5:
4426 alignment-specifier:
4427 _Alignas ( type-name )
4428 _Alignas ( constant-expression )
4431 static tree
4432 c_parser_alignas_specifier (c_parser * parser)
4434 tree ret = error_mark_node;
4435 location_t loc = c_parser_peek_token (parser)->location;
4436 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
4437 tree spelling = c_parser_peek_token (parser)->value;
4438 c_parser_consume_token (parser);
4439 if (flag_isoc99)
4440 pedwarn_c99 (loc, OPT_Wpedantic,
4441 "ISO C99 does not support %qE", spelling);
4442 else
4443 pedwarn_c99 (loc, OPT_Wpedantic,
4444 "ISO C90 does not support %qE", spelling);
4445 matching_parens parens;
4446 if (!parens.require_open (parser))
4447 return ret;
4448 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
4450 struct c_type_name *type = c_parser_type_name (parser);
4451 if (type != NULL)
4452 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
4453 false, true, 1);
4455 else
4456 ret = convert_lvalue_to_rvalue (loc,
4457 c_parser_expr_no_commas (parser, NULL),
4458 true, true).value;
4459 parens.skip_until_found_close (parser);
4460 return ret;
4463 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
4464 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
4465 a typedef name may be redeclared; otherwise it may not. KIND
4466 indicates which kind of declarator is wanted. Returns a valid
4467 declarator except in the case of a syntax error in which case NULL is
4468 returned. *SEEN_ID is set to true if an identifier being declared is
4469 seen; this is used to diagnose bad forms of abstract array declarators
4470 and to determine whether an identifier list is syntactically permitted.
4472 declarator:
4473 pointer[opt] direct-declarator
4475 direct-declarator:
4476 identifier
4477 ( gnu-attributes[opt] declarator )
4478 direct-declarator array-declarator
4479 direct-declarator ( parameter-type-list )
4480 direct-declarator ( identifier-list[opt] )
4482 pointer:
4483 * type-qualifier-list[opt]
4484 * type-qualifier-list[opt] pointer
4486 type-qualifier-list:
4487 type-qualifier
4488 gnu-attributes
4489 type-qualifier-list type-qualifier
4490 type-qualifier-list gnu-attributes
4492 array-declarator:
4493 [ type-qualifier-list[opt] assignment-expression[opt] ]
4494 [ static type-qualifier-list[opt] assignment-expression ]
4495 [ type-qualifier-list static assignment-expression ]
4496 [ type-qualifier-list[opt] * ]
4498 parameter-type-list:
4499 parameter-list
4500 parameter-list , ...
4502 parameter-list:
4503 parameter-declaration
4504 parameter-list , parameter-declaration
4506 parameter-declaration:
4507 declaration-specifiers declarator gnu-attributes[opt]
4508 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
4510 identifier-list:
4511 identifier
4512 identifier-list , identifier
4514 abstract-declarator:
4515 pointer
4516 pointer[opt] direct-abstract-declarator
4518 direct-abstract-declarator:
4519 ( gnu-attributes[opt] abstract-declarator )
4520 direct-abstract-declarator[opt] array-declarator
4521 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
4523 GNU extensions:
4525 direct-declarator:
4526 direct-declarator ( parameter-forward-declarations
4527 parameter-type-list[opt] )
4529 direct-abstract-declarator:
4530 direct-abstract-declarator[opt] ( parameter-forward-declarations
4531 parameter-type-list[opt] )
4533 parameter-forward-declarations:
4534 parameter-list ;
4535 parameter-forward-declarations parameter-list ;
4537 The uses of gnu-attributes shown above are GNU extensions.
4539 Some forms of array declarator are not included in C99 in the
4540 syntax for abstract declarators; these are disallowed elsewhere.
4541 This may be a defect (DR#289).
4543 This function also accepts an omitted abstract declarator as being
4544 an abstract declarator, although not part of the formal syntax. */
4546 struct c_declarator *
4547 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4548 bool *seen_id)
4550 /* Parse any initial pointer part. */
4551 if (c_parser_next_token_is (parser, CPP_MULT))
4553 struct c_declspecs *quals_attrs = build_null_declspecs ();
4554 struct c_declarator *inner;
4555 c_parser_consume_token (parser);
4556 c_parser_declspecs (parser, quals_attrs, false, false, true,
4557 false, false, true, false, cla_prefer_id);
4558 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4559 if (inner == NULL)
4560 return NULL;
4561 else
4562 return make_pointer_declarator (quals_attrs, inner);
4564 /* Now we have a direct declarator, direct abstract declarator or
4565 nothing (which counts as a direct abstract declarator here). */
4566 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
4569 /* Parse a direct declarator or direct abstract declarator; arguments
4570 as c_parser_declarator. */
4572 static struct c_declarator *
4573 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4574 bool *seen_id)
4576 /* The direct declarator must start with an identifier (possibly
4577 omitted) or a parenthesized declarator (possibly abstract). In
4578 an ordinary declarator, initial parentheses must start a
4579 parenthesized declarator. In an abstract declarator or parameter
4580 declarator, they could start a parenthesized declarator or a
4581 parameter list. To tell which, the open parenthesis and any
4582 following gnu-attributes must be read. If a declaration
4583 specifier or standard attributes follow, then it is a parameter
4584 list; if the specifier is a typedef name, there might be an
4585 ambiguity about redeclaring it, which is resolved in the
4586 direction of treating it as a typedef name. If a close
4587 parenthesis follows, it is also an empty parameter list, as the
4588 syntax does not permit empty abstract declarators. Otherwise, it
4589 is a parenthesized declarator (in which case the analysis may be
4590 repeated inside it, recursively).
4592 ??? There is an ambiguity in a parameter declaration "int
4593 (__attribute__((foo)) x)", where x is not a typedef name: it
4594 could be an abstract declarator for a function, or declare x with
4595 parentheses. The proper resolution of this ambiguity needs
4596 documenting. At present we follow an accident of the old
4597 parser's implementation, whereby the first parameter must have
4598 some declaration specifiers other than just gnu-attributes. Thus as
4599 a parameter declaration it is treated as a parenthesized
4600 parameter named x, and as an abstract declarator it is
4601 rejected.
4603 ??? Also following the old parser, gnu-attributes inside an empty
4604 parameter list are ignored, making it a list not yielding a
4605 prototype, rather than giving an error or making it have one
4606 parameter with implicit type int.
4608 ??? Also following the old parser, typedef names may be
4609 redeclared in declarators, but not Objective-C class names. */
4611 if (kind != C_DTR_ABSTRACT
4612 && c_parser_next_token_is (parser, CPP_NAME)
4613 && ((type_seen_p
4614 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
4615 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
4616 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
4618 struct c_declarator *inner
4619 = build_id_declarator (c_parser_peek_token (parser)->value);
4620 *seen_id = true;
4621 inner->id_loc = c_parser_peek_token (parser)->location;
4622 c_parser_consume_token (parser);
4623 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4624 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
4625 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4628 if (kind != C_DTR_NORMAL
4629 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4630 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4632 struct c_declarator *inner = build_id_declarator (NULL_TREE);
4633 inner->id_loc = c_parser_peek_token (parser)->location;
4634 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4637 /* Either we are at the end of an abstract declarator, or we have
4638 parentheses. */
4640 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4642 tree attrs;
4643 struct c_declarator *inner;
4644 c_parser_consume_token (parser);
4645 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4646 RID_ATTRIBUTE);
4647 attrs = c_parser_gnu_attributes (parser);
4648 if (kind != C_DTR_NORMAL
4649 && (c_parser_next_token_starts_declspecs (parser)
4650 || (!have_gnu_attrs
4651 && (c_parser_nth_token_starts_std_attributes (parser, 1)
4652 || c_parser_next_token_is (parser, CPP_ELLIPSIS)))
4653 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
4655 struct c_arg_info *args
4656 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
4657 attrs, have_gnu_attrs);
4658 if (args == NULL)
4659 return NULL;
4660 else
4662 inner = build_id_declarator (NULL_TREE);
4663 if (!(args->types
4664 && args->types != error_mark_node
4665 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4666 && c_parser_nth_token_starts_std_attributes (parser, 1))
4668 tree std_attrs
4669 = c_parser_std_attribute_specifier_sequence (parser);
4670 if (std_attrs)
4671 inner = build_attrs_declarator (std_attrs, inner);
4673 inner = build_function_declarator (args, inner);
4674 return c_parser_direct_declarator_inner (parser, *seen_id,
4675 inner);
4678 /* A parenthesized declarator. */
4679 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4680 if (inner != NULL && attrs != NULL)
4681 inner = build_attrs_declarator (attrs, inner);
4682 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4684 c_parser_consume_token (parser);
4685 if (inner == NULL)
4686 return NULL;
4687 else
4688 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4690 else
4692 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4693 "expected %<)%>");
4694 return NULL;
4697 else
4699 if (kind == C_DTR_NORMAL)
4701 c_parser_error (parser, "expected identifier or %<(%>");
4702 return NULL;
4704 else
4705 return build_id_declarator (NULL_TREE);
4709 /* Parse part of a direct declarator or direct abstract declarator,
4710 given that some (in INNER) has already been parsed; ID_PRESENT is
4711 true if an identifier is present, false for an abstract
4712 declarator. */
4714 static struct c_declarator *
4715 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4716 struct c_declarator *inner)
4718 /* Parse a sequence of array declarators and parameter lists. */
4719 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4720 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4722 location_t brace_loc = c_parser_peek_token (parser)->location;
4723 struct c_declarator *declarator;
4724 struct c_declspecs *quals_attrs = build_null_declspecs ();
4725 struct c_expr dimen;
4726 dimen.value = NULL_TREE;
4727 dimen.original_code = ERROR_MARK;
4728 dimen.original_type = NULL_TREE;
4729 c_parser_consume_token (parser);
4730 c_parser_declspecs (parser, quals_attrs, false, false, true,
4731 false, false, false, false, cla_prefer_id);
4733 location_t static_loc = UNKNOWN_LOCATION;
4734 if (c_parser_next_token_is_keyword (parser, RID_STATIC))
4736 static_loc = c_parser_peek_token (parser)->location;
4737 c_parser_consume_token (parser);
4738 if (!quals_attrs->declspecs_seen_p)
4739 c_parser_declspecs (parser, quals_attrs, false, false, true,
4740 false, false, false, false, cla_prefer_id);
4742 if (!quals_attrs->declspecs_seen_p)
4743 quals_attrs = NULL;
4744 /* If "static" is present, there must be an array dimension.
4745 Otherwise, there may be a dimension, "*", or no
4746 dimension. */
4747 const bool static_seen = (static_loc != UNKNOWN_LOCATION);
4748 bool star_seen = false;
4749 if (c_parser_next_token_is (parser, CPP_MULT)
4750 && c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4752 star_seen = true;
4753 c_parser_consume_token (parser);
4755 else if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4756 dimen = c_parser_expr_no_commas (parser, NULL);
4758 if (static_seen)
4760 if (star_seen)
4762 error_at (static_loc,
4763 "%<static%> may not be used with an unspecified "
4764 "variable length array size");
4765 /* Prevent further errors. */
4766 star_seen = false;
4767 dimen.value = error_mark_node;
4769 else if (!dimen.value)
4770 error_at (static_loc,
4771 "%<static%> may not be used without an array size");
4774 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4775 c_parser_consume_token (parser);
4776 else
4778 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4779 "expected %<]%>");
4780 return NULL;
4782 if (dimen.value)
4783 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4784 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4785 static_seen, star_seen);
4786 if (declarator == NULL)
4787 return NULL;
4788 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4790 tree std_attrs
4791 = c_parser_std_attribute_specifier_sequence (parser);
4792 if (std_attrs)
4793 inner = build_attrs_declarator (std_attrs, inner);
4795 inner = set_array_declarator_inner (declarator, inner);
4796 return c_parser_direct_declarator_inner (parser, id_present, inner);
4798 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4800 tree attrs;
4801 struct c_arg_info *args;
4802 c_parser_consume_token (parser);
4803 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4804 RID_ATTRIBUTE);
4805 attrs = c_parser_gnu_attributes (parser);
4806 args = c_parser_parms_declarator (parser, id_present, attrs,
4807 have_gnu_attrs);
4808 if (args == NULL)
4809 return NULL;
4810 else
4812 if (!(args->types
4813 && args->types != error_mark_node
4814 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4815 && c_parser_nth_token_starts_std_attributes (parser, 1))
4817 tree std_attrs
4818 = c_parser_std_attribute_specifier_sequence (parser);
4819 if (std_attrs)
4820 inner = build_attrs_declarator (std_attrs, inner);
4822 inner = build_function_declarator (args, inner);
4823 return c_parser_direct_declarator_inner (parser, id_present, inner);
4826 return inner;
4829 /* Parse a parameter list or identifier list, including the closing
4830 parenthesis but not the opening one. ATTRS are the gnu-attributes
4831 at the start of the list. ID_LIST_OK is true if an identifier list
4832 is acceptable; such a list must not have attributes at the start.
4833 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4834 attributes) were present (in which case standard attributes cannot
4835 occur). */
4837 static struct c_arg_info *
4838 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4839 bool have_gnu_attrs)
4841 push_scope ();
4842 declare_parm_level ();
4843 /* If the list starts with an identifier, it is an identifier list.
4844 Otherwise, it is either a prototype list or an empty list. */
4845 if (id_list_ok
4846 && !attrs
4847 && c_parser_next_token_is (parser, CPP_NAME)
4848 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4850 /* Look ahead to detect typos in type names. */
4851 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4852 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4853 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4854 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4855 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4857 tree list = NULL_TREE, *nextp = &list;
4858 while (c_parser_next_token_is (parser, CPP_NAME)
4859 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4861 *nextp = build_tree_list (NULL_TREE,
4862 c_parser_peek_token (parser)->value);
4863 nextp = & TREE_CHAIN (*nextp);
4864 c_parser_consume_token (parser);
4865 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4866 break;
4867 c_parser_consume_token (parser);
4868 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4870 c_parser_error (parser, "expected identifier");
4871 break;
4874 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4876 struct c_arg_info *ret = build_arg_info ();
4877 ret->types = list;
4878 c_parser_consume_token (parser);
4879 pop_scope ();
4880 return ret;
4882 else
4884 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4885 "expected %<)%>");
4886 pop_scope ();
4887 return NULL;
4890 else
4892 struct c_arg_info *ret
4893 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4894 pop_scope ();
4895 return ret;
4899 /* Parse a parameter list (possibly empty), including the closing
4900 parenthesis but not the opening one. ATTRS are the gnu-attributes
4901 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4902 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4903 which means standard attributes cannot start the list. EXPR is
4904 NULL or an expression that needs to be evaluated for the side
4905 effects of array size expressions in the parameters. */
4907 static struct c_arg_info *
4908 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4909 bool have_gnu_attrs)
4911 bool bad_parm = false;
4913 /* ??? Following the old parser, forward parameter declarations may
4914 use abstract declarators, and if no real parameter declarations
4915 follow the forward declarations then this is not diagnosed. Also
4916 note as above that gnu-attributes are ignored as the only contents of
4917 the parentheses, or as the only contents after forward
4918 declarations. */
4919 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4921 struct c_arg_info *ret = build_arg_info ();
4922 c_parser_consume_token (parser);
4923 return ret;
4925 if (c_parser_next_token_is (parser, CPP_ELLIPSIS) && !have_gnu_attrs)
4927 struct c_arg_info *ret = build_arg_info ();
4929 ret->types = NULL_TREE;
4930 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
4931 "ISO C requires a named argument before %<...%> "
4932 "before C23");
4933 c_parser_consume_token (parser);
4934 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4936 ret->no_named_args_stdarg_p = true;
4937 c_parser_consume_token (parser);
4938 return ret;
4940 else
4942 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4943 "expected %<)%>");
4944 return NULL;
4947 /* Nonempty list of parameters, either terminated with semicolon
4948 (forward declarations; recurse) or with close parenthesis (normal
4949 function) or with ", ... )" (variadic function). */
4950 while (true)
4952 /* Parse a parameter. */
4953 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4954 have_gnu_attrs);
4955 attrs = NULL_TREE;
4956 have_gnu_attrs = false;
4957 if (parm == NULL)
4958 bad_parm = true;
4959 else
4960 push_parm_decl (parm, &expr);
4961 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4963 tree new_attrs;
4964 c_parser_consume_token (parser);
4965 mark_forward_parm_decls ();
4966 bool new_have_gnu_attrs
4967 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4968 new_attrs = c_parser_gnu_attributes (parser);
4969 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4970 new_have_gnu_attrs);
4972 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4974 c_parser_consume_token (parser);
4975 if (bad_parm)
4976 return NULL;
4977 else
4978 return get_parm_info (false, expr);
4980 if (!c_parser_require (parser, CPP_COMMA,
4981 "expected %<;%>, %<,%> or %<)%>",
4982 UNKNOWN_LOCATION, false))
4984 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4985 return NULL;
4987 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4989 c_parser_consume_token (parser);
4990 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4992 c_parser_consume_token (parser);
4993 if (bad_parm)
4994 return NULL;
4995 else
4996 return get_parm_info (true, expr);
4998 else
5000 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5001 "expected %<)%>");
5002 return NULL;
5008 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
5009 start of the declaration if it is the first parameter;
5010 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
5011 empty) there. */
5013 static struct c_parm *
5014 c_parser_parameter_declaration (c_parser *parser, tree attrs,
5015 bool have_gnu_attrs)
5017 struct c_declspecs *specs;
5018 struct c_declarator *declarator;
5019 tree prefix_attrs;
5020 tree postfix_attrs = NULL_TREE;
5021 bool dummy = false;
5023 /* Accept #pragmas between parameter declarations. */
5024 while (c_parser_next_token_is (parser, CPP_PRAGMA))
5025 c_parser_pragma (parser, pragma_param, NULL);
5027 if (!c_parser_next_token_starts_declspecs (parser)
5028 && !c_parser_nth_token_starts_std_attributes (parser, 1))
5030 c_token *token = c_parser_peek_token (parser);
5031 if (parser->error)
5032 return NULL;
5033 c_parser_set_source_position_from_token (token);
5034 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
5036 auto_diagnostic_group d;
5037 name_hint hint = lookup_name_fuzzy (token->value,
5038 FUZZY_LOOKUP_TYPENAME,
5039 token->location);
5040 if (const char *suggestion = hint.suggestion ())
5042 gcc_rich_location richloc (token->location);
5043 richloc.add_fixit_replace (suggestion);
5044 error_at (&richloc,
5045 "unknown type name %qE; did you mean %qs?",
5046 token->value, suggestion);
5048 else
5049 error_at (token->location, "unknown type name %qE", token->value);
5050 parser->error = true;
5052 /* ??? In some Objective-C cases '...' isn't applicable so there
5053 should be a different message. */
5054 else
5055 c_parser_error (parser,
5056 "expected declaration specifiers or %<...%>");
5057 c_parser_skip_to_end_of_parameter (parser);
5058 return NULL;
5061 location_t start_loc = c_parser_peek_token (parser)->location;
5063 specs = build_null_declspecs ();
5064 if (attrs)
5066 declspecs_add_attrs (input_location, specs, attrs);
5067 attrs = NULL_TREE;
5069 c_parser_declspecs (parser, specs, true, true, true, true, false,
5070 !have_gnu_attrs, true, cla_nonabstract_decl);
5071 finish_declspecs (specs);
5072 pending_xref_error ();
5073 prefix_attrs = specs->attrs;
5074 specs->attrs = NULL_TREE;
5075 declarator = c_parser_declarator (parser,
5076 specs->typespec_kind != ctsk_none,
5077 C_DTR_PARM, &dummy);
5078 if (declarator == NULL)
5080 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5081 return NULL;
5083 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5084 postfix_attrs = c_parser_gnu_attributes (parser);
5086 /* Generate a location for the parameter, ranging from the start of the
5087 initial token to the end of the final token.
5089 If we have a identifier, then use it for the caret location, e.g.
5091 extern int callee (int one, int (*two)(int, int), float three);
5092 ~~~~~~^~~~~~~~~~~~~~
5094 otherwise, reuse the start location for the caret location e.g.:
5096 extern int callee (int one, int (*)(int, int), float three);
5097 ^~~~~~~~~~~~~~~~~
5099 location_t end_loc = parser->last_token_location;
5101 /* Find any cdk_id declarator; determine if we have an identifier. */
5102 c_declarator *id_declarator = declarator;
5103 while (id_declarator && id_declarator->kind != cdk_id)
5104 id_declarator = id_declarator->declarator;
5105 location_t caret_loc = (id_declarator->u.id.id
5106 ? id_declarator->id_loc
5107 : start_loc);
5108 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
5110 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
5111 declarator, param_loc);
5114 /* Parse a string literal in an asm expression. It should not be
5115 translated, and wide string literals are an error although
5116 permitted by the syntax. This is a GNU extension.
5118 asm-string-literal:
5119 string-literal
5122 static tree
5123 c_parser_asm_string_literal (c_parser *parser)
5125 tree str;
5126 int save_flag = warn_overlength_strings;
5127 warn_overlength_strings = 0;
5128 str = c_parser_string_literal (parser, false, false).value;
5129 warn_overlength_strings = save_flag;
5130 return str;
5133 /* Parse a simple asm expression. This is used in restricted
5134 contexts, where a full expression with inputs and outputs does not
5135 make sense. This is a GNU extension.
5137 simple-asm-expr:
5138 asm ( asm-string-literal )
5141 static tree
5142 c_parser_simple_asm_expr (c_parser *parser)
5144 tree str;
5145 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
5146 c_parser_consume_token (parser);
5147 matching_parens parens;
5148 if (!parens.require_open (parser))
5149 return NULL_TREE;
5150 str = c_parser_asm_string_literal (parser);
5151 if (!parens.require_close (parser))
5153 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5154 return NULL_TREE;
5156 return str;
5159 static tree
5160 c_parser_gnu_attribute_any_word (c_parser *parser)
5162 tree attr_name = NULL_TREE;
5164 if (c_parser_next_token_is (parser, CPP_KEYWORD))
5166 /* ??? See comment above about what keywords are accepted here. */
5167 bool ok;
5168 switch (c_parser_peek_token (parser)->keyword)
5170 case RID_STATIC:
5171 case RID_UNSIGNED:
5172 case RID_LONG:
5173 case RID_CONST:
5174 case RID_EXTERN:
5175 case RID_REGISTER:
5176 case RID_TYPEDEF:
5177 case RID_SHORT:
5178 case RID_INLINE:
5179 case RID_NORETURN:
5180 case RID_VOLATILE:
5181 case RID_SIGNED:
5182 case RID_AUTO:
5183 case RID_RESTRICT:
5184 case RID_COMPLEX:
5185 case RID_THREAD:
5186 case RID_INT:
5187 case RID_CHAR:
5188 case RID_FLOAT:
5189 case RID_DOUBLE:
5190 case RID_VOID:
5191 case RID_DFLOAT32:
5192 case RID_DFLOAT64:
5193 case RID_DFLOAT128:
5194 CASE_RID_FLOATN_NX:
5195 case RID_BOOL:
5196 case RID_BITINT:
5197 case RID_FRACT:
5198 case RID_ACCUM:
5199 case RID_SAT:
5200 case RID_TRANSACTION_ATOMIC:
5201 case RID_TRANSACTION_CANCEL:
5202 case RID_ATOMIC:
5203 case RID_AUTO_TYPE:
5204 case RID_CONSTEXPR:
5205 case RID_INT_N_0:
5206 case RID_INT_N_1:
5207 case RID_INT_N_2:
5208 case RID_INT_N_3:
5209 ok = true;
5210 break;
5211 default:
5212 ok = false;
5213 break;
5215 if (!ok)
5216 return NULL_TREE;
5218 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
5219 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
5221 else if (c_parser_next_token_is (parser, CPP_NAME))
5222 attr_name = c_parser_peek_token (parser)->value;
5224 return attr_name;
5227 /* Parse attribute arguments. This is a common form of syntax
5228 covering all currently valid GNU and standard attributes.
5230 gnu-attribute-arguments:
5231 identifier
5232 identifier , nonempty-expr-list
5233 expr-list
5235 where the "identifier" must not be declared as a type. ??? Why not
5236 allow identifiers declared as types to start the arguments? */
5238 static tree
5239 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
5240 bool require_string, bool assume_attr,
5241 bool allow_empty_args)
5243 vec<tree, va_gc> *expr_list;
5244 tree attr_args;
5245 /* Parse the attribute contents. If they start with an
5246 identifier which is followed by a comma or close
5247 parenthesis, then the arguments start with that
5248 identifier; otherwise they are an expression list.
5249 In objective-c the identifier may be a classname. */
5250 if (c_parser_next_token_is (parser, CPP_NAME)
5251 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
5252 || (c_dialect_objc ()
5253 && c_parser_peek_token (parser)->id_kind
5254 == C_ID_CLASSNAME))
5255 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
5256 || (c_parser_peek_2nd_token (parser)->type
5257 == CPP_CLOSE_PAREN))
5258 && (takes_identifier
5259 || (c_dialect_objc ()
5260 && !assume_attr
5261 && c_parser_peek_token (parser)->id_kind
5262 == C_ID_CLASSNAME)))
5264 tree arg1 = c_parser_peek_token (parser)->value;
5265 c_parser_consume_token (parser);
5266 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5267 attr_args = build_tree_list (NULL_TREE, arg1);
5268 else
5270 tree tree_list;
5271 c_parser_consume_token (parser);
5272 expr_list = c_parser_expr_list (parser, false, true,
5273 NULL, NULL, NULL, NULL);
5274 tree_list = build_tree_list_vec (expr_list);
5275 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
5276 release_tree_vector (expr_list);
5279 else
5281 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5283 if (!allow_empty_args)
5284 error_at (c_parser_peek_token (parser)->location,
5285 "parentheses must be omitted if "
5286 "attribute argument list is empty");
5287 attr_args = NULL_TREE;
5289 else if (require_string)
5291 /* The only valid argument for this attribute is a string
5292 literal. Handle this specially here to avoid accepting
5293 string literals with excess parentheses. */
5294 tree string = c_parser_string_literal (parser, false, true).value;
5295 attr_args = build_tree_list (NULL_TREE, string);
5297 else if (assume_attr)
5299 tree cond
5300 = c_parser_conditional_expression (parser, NULL, NULL_TREE).value;
5301 if (!c_parser_next_token_is (parser, CPP_COMMA))
5302 attr_args = build_tree_list (NULL_TREE, cond);
5303 else
5305 tree tree_list;
5306 c_parser_consume_token (parser);
5307 expr_list = c_parser_expr_list (parser, false, true,
5308 NULL, NULL, NULL, NULL);
5309 tree_list = build_tree_list_vec (expr_list);
5310 attr_args = tree_cons (NULL_TREE, cond, tree_list);
5311 release_tree_vector (expr_list);
5314 else
5316 expr_list = c_parser_expr_list (parser, false, true,
5317 NULL, NULL, NULL, NULL);
5318 attr_args = build_tree_list_vec (expr_list);
5319 release_tree_vector (expr_list);
5322 return attr_args;
5325 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
5327 gnu-attributes:
5328 empty
5329 gnu-attributes gnu-attribute
5331 gnu-attribute:
5332 __attribute__ ( ( gnu-attribute-list ) )
5334 gnu-attribute-list:
5335 gnu-attrib
5336 gnu-attribute_list , gnu-attrib
5338 gnu-attrib:
5339 empty
5340 any-word
5341 any-word ( gnu-attribute-arguments )
5343 where "any-word" may be any identifier (including one declared as a
5344 type), a reserved word storage class specifier, type specifier or
5345 type qualifier. ??? This still leaves out most reserved keywords
5346 (following the old parser), shouldn't we include them?
5347 When EXPECT_COMMA is true, expect the attribute to be preceded
5348 by a comma and fail if it isn't.
5349 When EMPTY_OK is true, allow and consume any number of consecutive
5350 commas with no attributes in between. */
5352 static tree
5353 c_parser_gnu_attribute (c_parser *parser, tree attrs,
5354 bool expect_comma = false, bool empty_ok = true)
5356 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
5357 if (!comma_first
5358 && !c_parser_next_token_is (parser, CPP_NAME)
5359 && !c_parser_next_token_is (parser, CPP_KEYWORD))
5360 return NULL_TREE;
5362 while (c_parser_next_token_is (parser, CPP_COMMA))
5364 c_parser_consume_token (parser);
5365 if (!empty_ok)
5366 return attrs;
5369 tree attr_name = c_parser_gnu_attribute_any_word (parser);
5370 if (attr_name == NULL_TREE)
5371 return NULL_TREE;
5373 attr_name = canonicalize_attr_name (attr_name);
5374 c_parser_consume_token (parser);
5376 tree attr;
5377 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5379 if (expect_comma && !comma_first)
5381 /* A comma is missing between the last attribute on the chain
5382 and this one. */
5383 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5384 "expected %<)%>");
5385 return error_mark_node;
5387 attr = build_tree_list (attr_name, NULL_TREE);
5388 /* Add this attribute to the list. */
5389 attrs = chainon (attrs, attr);
5390 return attrs;
5392 c_parser_consume_token (parser);
5394 tree attr_args
5395 = c_parser_attribute_arguments (parser,
5396 attribute_takes_identifier_p (attr_name),
5397 false,
5398 is_attribute_p ("assume", attr_name),
5399 true);
5401 attr = build_tree_list (attr_name, attr_args);
5402 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5403 c_parser_consume_token (parser);
5404 else
5406 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5407 "expected %<)%>");
5408 return error_mark_node;
5411 if (expect_comma && !comma_first)
5413 /* A comma is missing between the last attribute on the chain
5414 and this one. */
5415 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5416 "expected %<)%>");
5417 return error_mark_node;
5420 /* Add this attribute to the list. */
5421 attrs = chainon (attrs, attr);
5422 return attrs;
5425 static tree
5426 c_parser_gnu_attributes (c_parser *parser)
5428 tree attrs = NULL_TREE;
5429 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5431 bool save_translate_strings_p = parser->translate_strings_p;
5432 parser->translate_strings_p = false;
5433 /* Consume the `__attribute__' keyword. */
5434 c_parser_consume_token (parser);
5435 /* Look for the two `(' tokens. */
5436 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5438 parser->translate_strings_p = save_translate_strings_p;
5439 return attrs;
5441 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5443 parser->translate_strings_p = save_translate_strings_p;
5444 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5445 return attrs;
5447 /* Parse the attribute list. Require a comma between successive
5448 (possibly empty) attributes. */
5449 for (bool expect_comma = false; ; expect_comma = true)
5451 /* Parse a single attribute. */
5452 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
5453 if (attr == error_mark_node)
5454 return attrs;
5455 if (!attr)
5456 break;
5457 attrs = attr;
5460 /* Look for the two `)' tokens. */
5461 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5462 c_parser_consume_token (parser);
5463 else
5465 parser->translate_strings_p = save_translate_strings_p;
5466 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5467 "expected %<)%>");
5468 return attrs;
5470 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5471 c_parser_consume_token (parser);
5472 else
5474 parser->translate_strings_p = save_translate_strings_p;
5475 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5476 "expected %<)%>");
5477 return attrs;
5479 parser->translate_strings_p = save_translate_strings_p;
5482 return attrs;
5485 /* Parse an optional balanced token sequence.
5487 balanced-token-sequence:
5488 balanced-token
5489 balanced-token-sequence balanced-token
5491 balanced-token:
5492 ( balanced-token-sequence[opt] )
5493 [ balanced-token-sequence[opt] ]
5494 { balanced-token-sequence[opt] }
5495 any token other than ()[]{}
5498 static void
5499 c_parser_balanced_token_sequence (c_parser *parser)
5501 while (true)
5503 c_token *token = c_parser_peek_token (parser);
5504 switch (token->type)
5506 case CPP_OPEN_BRACE:
5508 matching_braces braces;
5509 braces.consume_open (parser);
5510 c_parser_balanced_token_sequence (parser);
5511 braces.require_close (parser);
5512 break;
5515 case CPP_OPEN_PAREN:
5517 matching_parens parens;
5518 parens.consume_open (parser);
5519 c_parser_balanced_token_sequence (parser);
5520 parens.require_close (parser);
5521 break;
5524 case CPP_OPEN_SQUARE:
5525 c_parser_consume_token (parser);
5526 c_parser_balanced_token_sequence (parser);
5527 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5528 break;
5530 case CPP_CLOSE_BRACE:
5531 case CPP_CLOSE_PAREN:
5532 case CPP_CLOSE_SQUARE:
5533 case CPP_EOF:
5534 return;
5536 case CPP_PRAGMA:
5537 c_parser_consume_pragma (parser);
5538 c_parser_skip_to_pragma_eol (parser, false);
5539 break;
5541 default:
5542 c_parser_consume_token (parser);
5543 break;
5548 static bool c_parser_check_balanced_raw_token_sequence (c_parser *,
5549 unsigned int *);
5551 /* Parse arguments of omp::directive or omp::decl attribute.
5553 directive-name ,[opt] clause-list[opt]
5555 For directive just remember the tokens in a vector for subsequent
5556 parsing. */
5558 static void
5559 c_parser_omp_directive_args (c_parser *parser, tree attribute, bool decl_p)
5561 unsigned int n = 1;
5562 c_token *first = c_parser_peek_token (parser);
5563 if (!c_parser_check_balanced_raw_token_sequence (parser, &n)
5564 || (c_parser_peek_nth_token_raw (parser, n)->type
5565 != CPP_CLOSE_PAREN))
5567 c_parser_balanced_token_sequence (parser);
5568 TREE_VALUE (attribute) = NULL_TREE;
5569 return;
5571 if (n == 1)
5573 error_at (first->location, "expected OpenMP directive name");
5574 TREE_VALUE (attribute) = NULL_TREE;
5575 return;
5577 vec<c_token, va_gc> *v;
5578 vec_alloc (v, n - 1);
5579 for (--n; n; --n)
5581 c_token *tok = c_parser_peek_token (parser);
5582 v->quick_push (*tok);
5583 c_parser_consume_token (parser);
5585 tree arg = make_node (C_TOKEN_VEC);
5586 C_TOKEN_VEC_TOKENS (arg) = v;
5587 if (decl_p)
5588 TREE_PUBLIC (arg) = 1;
5589 TREE_VALUE (attribute) = tree_cons (NULL_TREE, arg, TREE_VALUE (attribute));
5592 /* Parse arguments of omp::sequence attribute.
5594 omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... */
5596 static void
5597 c_parser_omp_sequence_args (c_parser *parser, tree attribute)
5601 c_token *token = c_parser_peek_token (parser);
5602 if (token->type == CPP_NAME
5603 && strcmp (IDENTIFIER_POINTER (token->value), "omp") == 0
5604 && c_parser_peek_2nd_token (parser)->type == CPP_SCOPE)
5606 c_parser_consume_token (parser);
5607 c_parser_consume_token (parser);
5608 token = c_parser_peek_token (parser);
5610 bool directive = false;
5611 const char *p;
5612 if (token->type != CPP_NAME)
5613 p = "";
5614 else
5615 p = IDENTIFIER_POINTER (token->value);
5616 if (strcmp (p, "directive") == 0)
5617 directive = true;
5618 else if (strcmp (p, "sequence") != 0)
5620 error_at (token->location, "expected %<directive%> or %<sequence%>");
5621 unsigned nesting_depth = 0;
5623 while (true)
5625 /* Peek at the next token. */
5626 token = c_parser_peek_token (parser);
5627 /* If we've reached the token we want, consume it and stop. */
5628 if ((token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
5629 && !nesting_depth)
5630 break;
5631 /* If we've run out of tokens, stop. */
5632 if (token->type == CPP_EOF)
5633 break;
5634 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
5635 break;
5636 if (token->type == CPP_OPEN_BRACE
5637 || token->type == CPP_OPEN_PAREN
5638 || token->type == CPP_OPEN_SQUARE)
5639 ++nesting_depth;
5640 else if (token->type == CPP_CLOSE_BRACE
5641 || token->type == CPP_CLOSE_PAREN
5642 || token->type == CPP_CLOSE_SQUARE)
5644 if (nesting_depth-- == 0)
5645 break;
5647 /* Consume this token. */
5648 c_parser_consume_token (parser);
5650 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5651 break;
5652 c_parser_consume_token (parser);
5653 continue;
5655 c_parser_consume_token (parser);
5656 matching_parens parens;
5657 if (parens.require_open (parser))
5659 if (directive)
5660 c_parser_omp_directive_args (parser, attribute, false);
5661 else
5662 c_parser_omp_sequence_args (parser, attribute);
5663 parens.skip_until_found_close (parser);
5664 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5665 break;
5666 c_parser_consume_token (parser);
5668 else if (c_parser_next_token_is_not (parser, CPP_COMMA))
5669 break;
5670 else
5671 c_parser_consume_token (parser);
5673 while (1);
5676 /* Parse standard (C23) attributes (including GNU attributes in the
5677 gnu:: namespace).
5679 attribute-specifier-sequence:
5680 attribute-specifier-sequence[opt] attribute-specifier
5682 attribute-specifier:
5683 [ [ attribute-list ] ]
5685 attribute-list:
5686 attribute[opt]
5687 attribute-list, attribute[opt]
5689 attribute:
5690 attribute-token attribute-argument-clause[opt]
5692 attribute-token:
5693 standard-attribute
5694 attribute-prefixed-token
5696 standard-attribute:
5697 identifier
5699 attribute-prefixed-token:
5700 attribute-prefix :: identifier
5702 attribute-prefix:
5703 identifier
5705 attribute-argument-clause:
5706 ( balanced-token-sequence[opt] )
5708 Keywords are accepted as identifiers for this purpose.
5710 As an extension, we permit an attribute-specifier to be:
5712 [ [ __extension__ attribute-list ] ]
5714 Two colons are then accepted as a synonym for ::. No attempt is made
5715 to check whether the colons are immediately adjacent. LOOSE_SCOPE_P
5716 indicates whether this relaxation is in effect. */
5718 static tree
5719 c_parser_std_attribute (c_parser *parser, bool for_tm)
5721 c_token *token = c_parser_peek_token (parser);
5722 tree ns, name, attribute;
5724 /* Parse the attribute-token. */
5725 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5727 c_parser_error (parser, "expected identifier");
5728 return error_mark_node;
5730 name = canonicalize_attr_name (token->value);
5731 c_parser_consume_token (parser);
5732 if (c_parser_next_token_is (parser, CPP_SCOPE)
5733 || (c_parser_next_token_is (parser, CPP_COLON)
5734 && (c_parser_peek_token (parser)->flags & COLON_SCOPE) != 0
5735 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5737 ns = name;
5738 if (c_parser_next_token_is (parser, CPP_COLON))
5739 c_parser_consume_token (parser);
5740 c_parser_consume_token (parser);
5741 token = c_parser_peek_token (parser);
5742 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5744 c_parser_error (parser, "expected identifier");
5745 return error_mark_node;
5747 name = canonicalize_attr_name (token->value);
5748 c_parser_consume_token (parser);
5750 else
5751 ns = NULL_TREE;
5752 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
5754 /* Parse the arguments, if any. */
5755 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
5756 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5758 if ((flag_openmp || flag_openmp_simd)
5759 && ns
5760 && is_attribute_p ("omp", ns)
5761 && (is_attribute_p ("directive", name)
5762 || is_attribute_p ("sequence", name)
5763 || is_attribute_p ("decl", name)))
5765 error ("%<omp::%E%> attribute requires argument", name);
5766 return error_mark_node;
5768 goto out;
5771 location_t open_loc = c_parser_peek_token (parser)->location;
5772 matching_parens parens;
5773 parens.consume_open (parser);
5774 if ((as && as->max_length == 0)
5775 /* Special-case the transactional-memory attribute "outer",
5776 which is specially handled but not registered as an
5777 attribute, to avoid allowing arbitrary balanced token
5778 sequences as arguments. */
5779 || is_attribute_p ("outer", name))
5781 error_at (open_loc, "%qE attribute does not take any arguments", name);
5782 parens.skip_until_found_close (parser);
5783 return error_mark_node;
5785 /* If this is a fake attribute created to handle -Wno-attributes,
5786 we must skip parsing the arguments. */
5787 if (as && !attribute_ignored_p (as))
5789 bool takes_identifier
5790 = (ns != NULL_TREE
5791 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5792 && attribute_takes_identifier_p (name));
5793 bool require_string
5794 = (ns == NULL_TREE
5795 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
5796 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
5797 bool assume_attr
5798 = (ns != NULL_TREE
5799 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5800 && strcmp (IDENTIFIER_POINTER (name), "assume") == 0);
5801 TREE_VALUE (attribute)
5802 = c_parser_attribute_arguments (parser, takes_identifier,
5803 require_string, assume_attr, false);
5805 else
5807 if ((flag_openmp || flag_openmp_simd)
5808 && ns
5809 && is_attribute_p ("omp", ns))
5811 if (is_attribute_p ("directive", name))
5813 c_parser_omp_directive_args (parser, attribute, false);
5814 parens.skip_until_found_close (parser);
5815 return attribute;
5817 else if (is_attribute_p ("decl", name))
5819 TREE_VALUE (TREE_PURPOSE (attribute))
5820 = get_identifier ("directive");
5821 c_parser_omp_directive_args (parser, attribute, true);
5822 parens.skip_until_found_close (parser);
5823 return attribute;
5825 else if (is_attribute_p ("sequence", name))
5827 TREE_VALUE (TREE_PURPOSE (attribute))
5828 = get_identifier ("directive");
5829 c_parser_omp_sequence_args (parser, attribute);
5830 parens.skip_until_found_close (parser);
5831 TREE_VALUE (attribute) = nreverse (TREE_VALUE (attribute));
5832 return attribute;
5835 c_parser_balanced_token_sequence (parser);
5837 parens.require_close (parser);
5839 out:
5840 if (ns == NULL_TREE && !for_tm && !as)
5842 /* An attribute with standard syntax and no namespace specified
5843 is a constraint violation if it is not one of the known
5844 standard attributes. Diagnose it here with a pedwarn and
5845 then discard it to prevent a duplicate warning later. */
5846 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
5847 name);
5848 return error_mark_node;
5850 return attribute;
5853 static tree
5854 c_parser_std_attribute_list (c_parser *parser, bool for_tm)
5856 tree attributes = NULL_TREE;
5857 while (true)
5859 c_token *token = c_parser_peek_token (parser);
5860 if (token->type == CPP_CLOSE_SQUARE)
5861 break;
5862 if (token->type == CPP_COMMA)
5864 c_parser_consume_token (parser);
5865 continue;
5867 tree attribute = c_parser_std_attribute (parser, for_tm);
5868 if (attribute != error_mark_node)
5870 TREE_CHAIN (attribute) = attributes;
5871 attributes = attribute;
5873 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5874 break;
5876 return attributes;
5879 static tree
5880 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
5882 location_t loc = c_parser_peek_token (parser)->location;
5883 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5884 return NULL_TREE;
5885 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5887 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5888 return NULL_TREE;
5890 tree attributes;
5891 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5893 auto ext = disable_extension_diagnostics ();
5894 c_parser_consume_token (parser);
5895 attributes = c_parser_std_attribute_list (parser, for_tm);
5896 restore_extension_diagnostics (ext);
5898 else
5900 if (!for_tm)
5901 pedwarn_c11 (loc, OPT_Wpedantic,
5902 "ISO C does not support %<[[]]%> attributes before C23");
5903 attributes = c_parser_std_attribute_list (parser, for_tm);
5905 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5906 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5907 return nreverse (attributes);
5910 /* Look past an optional balanced token sequence of raw look-ahead
5911 tokens starting with the *Nth token. *N is updated to point to the
5912 following token. Return true if such a sequence was found, false
5913 if the tokens parsed were not balanced. */
5915 static bool
5916 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5918 while (true)
5920 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5921 switch (token->type)
5923 case CPP_OPEN_BRACE:
5925 ++*n;
5926 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5928 token = c_parser_peek_nth_token_raw (parser, *n);
5929 if (token->type == CPP_CLOSE_BRACE)
5930 ++*n;
5931 else
5932 return false;
5934 else
5935 return false;
5936 break;
5939 case CPP_OPEN_PAREN:
5941 ++*n;
5942 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5944 token = c_parser_peek_nth_token_raw (parser, *n);
5945 if (token->type == CPP_CLOSE_PAREN)
5946 ++*n;
5947 else
5948 return false;
5950 else
5951 return false;
5952 break;
5955 case CPP_OPEN_SQUARE:
5957 ++*n;
5958 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5960 token = c_parser_peek_nth_token_raw (parser, *n);
5961 if (token->type == CPP_CLOSE_SQUARE)
5962 ++*n;
5963 else
5964 return false;
5966 else
5967 return false;
5968 break;
5971 case CPP_CLOSE_BRACE:
5972 case CPP_CLOSE_PAREN:
5973 case CPP_CLOSE_SQUARE:
5974 case CPP_EOF:
5975 return true;
5977 default:
5978 ++*n;
5979 break;
5984 /* Return whether standard attributes start with the Nth token. */
5986 static bool
5987 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5989 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5990 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5991 return false;
5992 /* In C, '[[' must start attributes. In Objective-C, we need to
5993 check whether '[[' is matched by ']]'. */
5994 if (!c_dialect_objc ())
5995 return true;
5996 n += 2;
5997 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5998 return false;
5999 c_token *token = c_parser_peek_nth_token_raw (parser, n);
6000 if (token->type != CPP_CLOSE_SQUARE)
6001 return false;
6002 token = c_parser_peek_nth_token_raw (parser, n + 1);
6003 return token->type == CPP_CLOSE_SQUARE;
6006 /* Skip standard attribute tokens starting at Nth token (with 1 as the
6007 next token), return index of the first token after the standard
6008 attribute tokens, or N on failure. */
6010 static size_t
6011 c_parser_skip_std_attribute_spec_seq (c_parser *parser, size_t n)
6013 size_t orig_n = n;
6014 while (true)
6016 if (c_parser_peek_nth_token_raw (parser, n)->type == CPP_OPEN_SQUARE
6017 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
6018 == CPP_OPEN_SQUARE))
6020 unsigned int m = n + 2;
6021 if (!c_parser_check_balanced_raw_token_sequence (parser, &m))
6022 return orig_n;
6023 c_token *token = c_parser_peek_nth_token_raw (parser, m);
6024 if (token->type != CPP_CLOSE_SQUARE)
6025 return orig_n;
6026 token = c_parser_peek_nth_token_raw (parser, m + 1);
6027 if (token->type != CPP_CLOSE_SQUARE)
6028 return orig_n;
6029 n = m + 2;
6031 else
6032 break;
6034 return n;
6037 static tree
6038 c_parser_std_attribute_specifier_sequence (c_parser *parser)
6040 tree attributes = NULL_TREE;
6043 tree attrs = c_parser_std_attribute_specifier (parser, false);
6044 attributes = chainon (attributes, attrs);
6046 while (c_parser_nth_token_starts_std_attributes (parser, 1));
6047 return attributes;
6050 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
6051 says whether alignment specifiers are OK (only in cases that might
6052 be the type name of a compound literal).
6054 type-name:
6055 specifier-qualifier-list abstract-declarator[opt]
6058 struct c_type_name *
6059 c_parser_type_name (c_parser *parser, bool alignas_ok)
6061 struct c_declspecs *specs = build_null_declspecs ();
6062 struct c_declarator *declarator;
6063 struct c_type_name *ret;
6064 bool dummy = false;
6065 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
6066 false, true, cla_prefer_type);
6067 if (!specs->declspecs_seen_p)
6069 c_parser_error (parser, "expected specifier-qualifier-list");
6070 return NULL;
6072 if (specs->type != error_mark_node)
6074 pending_xref_error ();
6075 finish_declspecs (specs);
6077 declarator = c_parser_declarator (parser,
6078 specs->typespec_kind != ctsk_none,
6079 C_DTR_ABSTRACT, &dummy);
6080 if (declarator == NULL)
6081 return NULL;
6082 ret = XOBNEW (&parser_obstack, struct c_type_name);
6083 ret->specs = specs;
6084 ret->declarator = declarator;
6085 return ret;
6088 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
6090 initializer:
6091 assignment-expression
6092 { initializer-list }
6093 { initializer-list , }
6095 initializer-list:
6096 designation[opt] initializer
6097 initializer-list , designation[opt] initializer
6099 designation:
6100 designator-list =
6102 designator-list:
6103 designator
6104 designator-list designator
6106 designator:
6107 array-designator
6108 . identifier
6110 array-designator:
6111 [ constant-expression ]
6113 GNU extensions:
6115 initializer:
6118 designation:
6119 array-designator
6120 identifier :
6122 array-designator:
6123 [ constant-expression ... constant-expression ]
6125 Any expression without commas is accepted in the syntax for the
6126 constant-expressions, with non-constant expressions rejected later.
6128 DECL is the declaration we're parsing this initializer for.
6130 This function is only used for top-level initializers; for nested
6131 ones, see c_parser_initval. */
6133 static struct c_expr
6134 c_parser_initializer (c_parser *parser, tree decl)
6136 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6137 return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
6138 else
6140 struct c_expr ret;
6141 location_t loc = c_parser_peek_token (parser)->location;
6142 ret = c_parser_expr_no_commas (parser, NULL);
6143 if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
6145 error_at (loc,
6146 "variable-sized object may not be initialized except "
6147 "with an empty initializer");
6148 ret.set_error ();
6150 /* This is handled mostly by gimplify.cc, but we have to deal with
6151 not warning about int x = x; as it is a GCC extension to turn off
6152 this warning but only if warn_init_self is zero. */
6153 if (VAR_P (decl)
6154 && !DECL_EXTERNAL (decl)
6155 && !TREE_STATIC (decl)
6156 && ret.value == decl
6157 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl), OPT_Winit_self))
6158 suppress_warning (decl, OPT_Winit_self);
6159 if (TREE_CODE (ret.value) != STRING_CST
6160 && (TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR
6161 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6162 (ret.value))))
6163 ret = convert_lvalue_to_rvalue (loc, ret, true, true, true);
6164 return ret;
6168 /* The location of the last comma within the current initializer list,
6169 or UNKNOWN_LOCATION if not within one. */
6171 location_t last_init_list_comma;
6173 /* Parse a braced initializer list. TYPE is the type specified for a
6174 compound literal, and NULL_TREE for other initializers and for
6175 nested braced lists. NESTED_P is true for nested braced lists,
6176 false for the list of a compound literal or the list that is the
6177 top-level initializer in a declaration. DECL is the declaration for
6178 the top-level initializer for a declaration, otherwise NULL_TREE. */
6180 static struct c_expr
6181 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
6182 struct obstack *outer_obstack, tree decl)
6184 struct c_expr ret;
6185 struct obstack braced_init_obstack;
6186 location_t brace_loc = c_parser_peek_token (parser)->location;
6187 gcc_obstack_init (&braced_init_obstack);
6188 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
6189 bool save_c_omp_array_section_p = c_omp_array_section_p;
6190 c_omp_array_section_p = false;
6191 matching_braces braces;
6192 braces.consume_open (parser);
6193 if (nested_p)
6195 finish_implicit_inits (brace_loc, outer_obstack);
6196 push_init_level (brace_loc, 0, &braced_init_obstack);
6198 else
6199 really_start_incremental_init (type);
6200 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6202 pedwarn_c11 (brace_loc, OPT_Wpedantic,
6203 "ISO C forbids empty initializer braces before C23");
6205 else
6207 if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
6208 error_at (brace_loc,
6209 "variable-sized object may not be initialized except "
6210 "with an empty initializer");
6211 /* Parse a non-empty initializer list, possibly with a trailing
6212 comma. */
6213 while (true)
6215 c_parser_initelt (parser, &braced_init_obstack);
6216 if (parser->error)
6217 break;
6218 if (c_parser_next_token_is (parser, CPP_COMMA))
6220 last_init_list_comma = c_parser_peek_token (parser)->location;
6221 c_parser_consume_token (parser);
6223 else
6224 break;
6225 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6226 break;
6229 c_omp_array_section_p = save_c_omp_array_section_p;
6230 c_token *next_tok = c_parser_peek_token (parser);
6231 if (next_tok->type != CPP_CLOSE_BRACE)
6233 ret.set_error ();
6234 ret.original_code = ERROR_MARK;
6235 ret.original_type = NULL;
6236 braces.skip_until_found_close (parser);
6237 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
6238 obstack_free (&braced_init_obstack, NULL);
6239 return ret;
6241 location_t close_loc = next_tok->location;
6242 c_parser_consume_token (parser);
6243 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
6244 obstack_free (&braced_init_obstack, NULL);
6245 set_c_expr_source_range (&ret, brace_loc, close_loc);
6246 return ret;
6249 /* Parse a nested initializer, including designators. */
6251 static void
6252 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
6254 /* Parse any designator or designator list. A single array
6255 designator may have the subsequent "=" omitted in GNU C, but a
6256 longer list or a structure member designator may not. */
6257 if (c_parser_next_token_is (parser, CPP_NAME)
6258 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
6260 /* Old-style structure member designator. */
6261 set_init_label (c_parser_peek_token (parser)->location,
6262 c_parser_peek_token (parser)->value,
6263 c_parser_peek_token (parser)->location,
6264 braced_init_obstack);
6265 /* Use the colon as the error location. */
6266 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
6267 "obsolete use of designated initializer with %<:%>");
6268 c_parser_consume_token (parser);
6269 c_parser_consume_token (parser);
6271 else
6273 /* des_seen is 0 if there have been no designators, 1 if there
6274 has been a single array designator and 2 otherwise. */
6275 int des_seen = 0;
6276 /* Location of a designator. */
6277 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6278 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
6279 || c_parser_next_token_is (parser, CPP_DOT))
6281 int des_prev = des_seen;
6282 if (!des_seen)
6283 des_loc = c_parser_peek_token (parser)->location;
6284 if (des_seen < 2)
6285 des_seen++;
6286 if (c_parser_next_token_is (parser, CPP_DOT))
6288 des_seen = 2;
6289 c_parser_consume_token (parser);
6290 if (c_parser_next_token_is (parser, CPP_NAME))
6292 set_init_label (des_loc, c_parser_peek_token (parser)->value,
6293 c_parser_peek_token (parser)->location,
6294 braced_init_obstack);
6295 c_parser_consume_token (parser);
6297 else
6299 struct c_expr init;
6300 init.set_error ();
6301 init.original_code = ERROR_MARK;
6302 init.original_type = NULL;
6303 c_parser_error (parser, "expected identifier");
6304 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
6305 process_init_element (input_location, init, false,
6306 braced_init_obstack);
6307 return;
6310 else
6312 struct c_expr first_expr;
6313 tree first, second;
6314 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6315 location_t array_index_loc = UNKNOWN_LOCATION;
6316 /* ??? Following the old parser, [ objc-receiver
6317 objc-message-args ] is accepted as an initializer,
6318 being distinguished from a designator by what follows
6319 the first assignment expression inside the square
6320 brackets, but after a first array designator a
6321 subsequent square bracket is for Objective-C taken to
6322 start an expression, using the obsolete form of
6323 designated initializer without '=', rather than
6324 possibly being a second level of designation: in LALR
6325 terms, the '[' is shifted rather than reducing
6326 designator to designator-list. */
6327 if (des_prev == 1 && c_dialect_objc ())
6329 des_seen = des_prev;
6330 break;
6332 if (des_prev == 0 && c_dialect_objc ())
6334 /* This might be an array designator or an
6335 Objective-C message expression. If the former,
6336 continue parsing here; if the latter, parse the
6337 remainder of the initializer given the starting
6338 primary-expression. ??? It might make sense to
6339 distinguish when des_prev == 1 as well; see
6340 previous comment. */
6341 tree rec, args;
6342 struct c_expr mexpr;
6343 c_parser_consume_token (parser);
6344 if (c_parser_peek_token (parser)->type == CPP_NAME
6345 && ((c_parser_peek_token (parser)->id_kind
6346 == C_ID_TYPENAME)
6347 || (c_parser_peek_token (parser)->id_kind
6348 == C_ID_CLASSNAME)))
6350 /* Type name receiver. */
6351 tree id = c_parser_peek_token (parser)->value;
6352 c_parser_consume_token (parser);
6353 rec = objc_get_class_reference (id);
6354 goto parse_message_args;
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 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
6360 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
6361 goto array_desig_after_first;
6362 first = first_expr.value;
6363 /* Expression receiver. So far only one part
6364 without commas has been parsed; there might be
6365 more of the expression. */
6366 rec = first;
6367 while (c_parser_next_token_is (parser, CPP_COMMA))
6369 struct c_expr next;
6370 location_t comma_loc, exp_loc;
6371 comma_loc = c_parser_peek_token (parser)->location;
6372 c_parser_consume_token (parser);
6373 exp_loc = c_parser_peek_token (parser)->location;
6374 next = c_parser_expr_no_commas (parser, NULL);
6375 next = convert_lvalue_to_rvalue (exp_loc, next,
6376 true, true);
6377 rec = build_compound_expr (comma_loc, rec, next.value);
6379 parse_message_args:
6380 /* Now parse the objc-message-args. */
6381 args = c_parser_objc_message_args (parser);
6382 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6383 "expected %<]%>");
6384 mexpr.value
6385 = objc_build_message_expr (rec, args);
6386 mexpr.original_code = ERROR_MARK;
6387 mexpr.original_type = NULL;
6388 mexpr.m_decimal = 0;
6389 /* Now parse and process the remainder of the
6390 initializer, starting with this message
6391 expression as a primary-expression. */
6392 c_parser_initval (parser, &mexpr, braced_init_obstack);
6393 return;
6395 c_parser_consume_token (parser);
6396 array_index_loc = c_parser_peek_token (parser)->location;
6397 first_expr = c_parser_expr_no_commas (parser, NULL);
6398 mark_exp_read (first_expr.value);
6399 array_desig_after_first:
6400 first_expr = convert_lvalue_to_rvalue (array_index_loc,
6401 first_expr,
6402 true, true);
6403 first = first_expr.value;
6404 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
6406 ellipsis_loc = c_parser_peek_token (parser)->location;
6407 c_parser_consume_token (parser);
6408 second = convert_lvalue_to_rvalue (ellipsis_loc,
6409 (c_parser_expr_no_commas
6410 (parser, NULL)),
6411 true, true).value;
6412 mark_exp_read (second);
6414 else
6415 second = NULL_TREE;
6416 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
6418 c_parser_consume_token (parser);
6419 set_init_index (array_index_loc, first, second,
6420 braced_init_obstack);
6421 if (second)
6422 pedwarn (ellipsis_loc, OPT_Wpedantic,
6423 "ISO C forbids specifying range of elements to initialize");
6425 else
6426 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6427 "expected %<]%>");
6430 if (des_seen >= 1)
6432 if (c_parser_next_token_is (parser, CPP_EQ))
6434 pedwarn_c90 (des_loc, OPT_Wpedantic,
6435 "ISO C90 forbids specifying subobject "
6436 "to initialize");
6437 c_parser_consume_token (parser);
6439 else
6441 if (des_seen == 1)
6442 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
6443 "obsolete use of designated initializer without %<=%>");
6444 else
6446 struct c_expr init;
6447 init.set_error ();
6448 init.original_code = ERROR_MARK;
6449 init.original_type = NULL;
6450 c_parser_error (parser, "expected %<=%>");
6451 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
6452 process_init_element (input_location, init, false,
6453 braced_init_obstack);
6454 return;
6459 c_parser_initval (parser, NULL, braced_init_obstack);
6462 /* Parse a nested initializer; as c_parser_initializer but parses
6463 initializers within braced lists, after any designators have been
6464 applied. If AFTER is not NULL then it is an Objective-C message
6465 expression which is the primary-expression starting the
6466 initializer. */
6468 static void
6469 c_parser_initval (c_parser *parser, struct c_expr *after,
6470 struct obstack * braced_init_obstack)
6472 struct c_expr init;
6473 gcc_assert (!after || c_dialect_objc ());
6474 location_t loc = c_parser_peek_token (parser)->location;
6476 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
6477 init = c_parser_braced_init (parser, NULL_TREE, true,
6478 braced_init_obstack, NULL_TREE);
6479 else
6481 init = c_parser_expr_no_commas (parser, after);
6482 if (init.value != NULL_TREE
6483 && TREE_CODE (init.value) != STRING_CST
6484 && (TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR
6485 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6486 (init.value))))
6487 init = convert_lvalue_to_rvalue (loc, init, true, true, true);
6489 process_init_element (loc, init, false, braced_init_obstack);
6492 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6493 C99 6.8.2, C11 6.8.2, C23 6.8.2).
6495 compound-statement:
6496 { block-item-list[opt] }
6497 { label-declarations block-item-list }
6499 block-item-list:
6500 block-item
6501 block-item-list block-item
6503 block-item:
6504 label
6505 nested-declaration
6506 statement
6508 nested-declaration:
6509 declaration
6511 GNU extensions:
6513 compound-statement:
6514 { label-declarations block-item-list }
6516 nested-declaration:
6517 __extension__ nested-declaration
6518 nested-function-definition
6520 label-declarations:
6521 label-declaration
6522 label-declarations label-declaration
6524 label-declaration:
6525 __label__ identifier-list ;
6527 Allowing the mixing of declarations and code is new in C99. The
6528 GNU syntax also permits (not shown above) labels at the end of
6529 compound statements, which yield an error. We don't allow labels
6530 on declarations; this might seem like a natural extension, but
6531 there would be a conflict between gnu-attributes on the label and
6532 prefix gnu-attributes on the declaration. ??? The syntax follows the
6533 old parser in requiring something after label declarations.
6534 Although they are erroneous if the labels declared aren't defined,
6535 is it useful for the syntax to be this way?
6537 OpenACC:
6539 block-item:
6540 openacc-directive
6542 openacc-directive:
6543 update-directive
6545 OpenMP:
6547 block-item:
6548 openmp-directive
6550 openmp-directive:
6551 barrier-directive
6552 flush-directive
6553 taskwait-directive
6554 taskyield-directive
6555 cancel-directive
6556 cancellation-point-directive */
6558 static tree
6559 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
6561 tree stmt;
6562 location_t brace_loc;
6563 brace_loc = c_parser_peek_token (parser)->location;
6564 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
6566 /* Ensure a scope is entered and left anyway to avoid confusion
6567 if we have just prepared to enter a function body. */
6568 stmt = c_begin_compound_stmt (true);
6569 c_end_compound_stmt (brace_loc, stmt, true);
6570 return error_mark_node;
6572 stmt = c_begin_compound_stmt (true);
6573 location_t end_loc = c_parser_compound_statement_nostart (parser);
6574 if (endlocp)
6575 *endlocp = end_loc;
6577 return c_end_compound_stmt (brace_loc, stmt, true);
6580 /* Diagnose errors related to imperfectly nested loops in an OMP
6581 loop construct. This function is called when such code is seen.
6582 Only issue one such diagnostic no matter how much invalid
6583 intervening code there is in the loop.
6584 FIXME: maybe the location associated with the diagnostic should
6585 be the current parser token instead of the location of the outer loop
6586 nest. */
6588 static void
6589 check_omp_intervening_code (c_parser *parser)
6591 struct omp_for_parse_data *omp_for_parse_state = parser->omp_for_parse_state;
6592 gcc_assert (omp_for_parse_state);
6594 if (!omp_for_parse_state->in_intervening_code)
6595 return;
6596 omp_for_parse_state->saw_intervening_code = true;
6598 /* Only diagnose errors related to perfect nesting once. */
6599 if (!omp_for_parse_state->perfect_nesting_fail)
6602 /* OpenACC does not (yet) permit intervening code, in
6603 addition to situations forbidden by the OpenMP spec. */
6604 if (omp_for_parse_state->code == OACC_LOOP)
6606 error_at (omp_for_parse_state->for_loc,
6607 "inner loops must be perfectly nested in "
6608 "%<#pragma acc loop%>");
6609 omp_for_parse_state->perfect_nesting_fail = true;
6611 else if (omp_for_parse_state->ordered)
6613 error_at (omp_for_parse_state->for_loc,
6614 "inner loops must be perfectly nested with "
6615 "%<ordered%> clause");
6616 omp_for_parse_state->perfect_nesting_fail = true;
6618 else if (omp_for_parse_state->inscan)
6620 error_at (omp_for_parse_state->for_loc,
6621 "inner loops must be perfectly nested with "
6622 "%<reduction%> %<inscan%> clause");
6623 omp_for_parse_state->perfect_nesting_fail = true;
6625 else if (omp_for_parse_state->code == OMP_TILE)
6627 error_at (omp_for_parse_state->for_loc,
6628 "inner loops must be perfectly nested in "
6629 "%<pragma omp tile%>");
6630 omp_for_parse_state->perfect_nesting_fail = true;
6632 if (omp_for_parse_state->perfect_nesting_fail)
6633 omp_for_parse_state->fail = true;
6637 /* Helper function for below: wrap an OMP_STRUCTURED_BLOCK around SL
6638 and add the statement to the current list. If SL is an empty statement
6639 list, do nothing. */
6640 static void
6641 add_structured_block_stmt (tree sl)
6643 if (TREE_CODE (sl) != STATEMENT_LIST
6644 || !tsi_end_p (tsi_start (sl)))
6645 add_stmt (build1 (OMP_STRUCTURED_BLOCK, void_type_node, sl));
6648 struct c_omp_attribute_data
6650 vec<c_token, va_gc> *tokens;
6651 const c_omp_directive *dir;
6652 c_omp_directive_kind kind;
6655 /* Handle omp::directive and omp::sequence attributes in ATTRS
6656 (if any) at the start of a statement or in attribute-declaration. */
6658 static bool
6659 c_parser_handle_statement_omp_attributes (c_parser *parser, tree &attrs,
6660 bool *have_std_attrs)
6662 if (!flag_openmp && !flag_openmp_simd)
6663 return false;
6665 auto_vec<c_omp_attribute_data, 16> vd;
6666 int cnt = 0;
6667 int tokens = 0;
6668 bool bad = false;
6669 for (tree *pa = &attrs; *pa; )
6670 if (is_attribute_namespace_p ("omp", *pa)
6671 && is_attribute_p ("directive", get_attribute_name (*pa)))
6673 cnt++;
6674 for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
6676 tree d = TREE_VALUE (a);
6677 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
6678 vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
6679 c_token *first = toks->address ();
6680 c_token *last = first + toks->length ();
6681 if (parser->omp_attrs_forbidden_p)
6683 error_at (first->location,
6684 "mixing OpenMP directives with attribute and pragma "
6685 "syntax on the same statement");
6686 parser->omp_attrs_forbidden_p = false;
6687 bad = true;
6689 else if (TREE_PUBLIC (d))
6691 error_at (first->location,
6692 "OpenMP %<omp::decl%> attribute on a statement");
6693 bad = true;
6695 const char *directive[3] = {};
6696 for (int i = 0; i < 3; i++)
6698 tree id = NULL_TREE;
6699 if (first + i == last)
6700 break;
6701 if (first[i].type == CPP_NAME)
6702 id = first[i].value;
6703 else if (first[i].type == CPP_KEYWORD)
6704 id = ridpointers[(int) first[i].keyword];
6705 else
6706 break;
6707 directive[i] = IDENTIFIER_POINTER (id);
6709 const c_omp_directive *dir = NULL;
6710 if (directive[0])
6711 dir = c_omp_categorize_directive (directive[0], directive[1],
6712 directive[2]);
6713 if (dir == NULL)
6715 error_at (first->location,
6716 "unknown OpenMP directive name in %qs attribute "
6717 "argument",
6718 TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
6719 continue;
6721 c_omp_directive_kind kind = dir->kind;
6722 if (dir->id == PRAGMA_OMP_ORDERED)
6724 /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
6725 depend/doacross clause. */
6726 if (directive[1]
6727 && (strcmp (directive[1], "depend") == 0
6728 || strcmp (directive[1], "doacross") == 0))
6729 kind = C_OMP_DIR_STANDALONE;
6730 else if (first + 2 < last
6731 && first[1].type == CPP_COMMA
6732 && first[2].type == CPP_NAME
6733 && (strcmp (IDENTIFIER_POINTER (first[2].value),
6734 "depend") == 0
6735 || strcmp (IDENTIFIER_POINTER (first[2].value),
6736 "doacross") == 0))
6737 kind = C_OMP_DIR_STANDALONE;
6739 else if (dir->id == PRAGMA_OMP_ERROR)
6741 /* error with at(execution) clause is C_OMP_DIR_STANDALONE. */
6742 int paren_depth = 0;
6743 for (int i = 1; first + i < last; i++)
6744 if (first[i].type == CPP_OPEN_PAREN)
6745 paren_depth++;
6746 else if (first[i].type == CPP_CLOSE_PAREN)
6747 paren_depth--;
6748 else if (paren_depth == 0
6749 && first + i + 2 < last
6750 && first[i].type == CPP_NAME
6751 && first[i + 1].type == CPP_OPEN_PAREN
6752 && first[i + 2].type == CPP_NAME
6753 && !strcmp (IDENTIFIER_POINTER (first[i].value),
6754 "at")
6755 && !strcmp (IDENTIFIER_POINTER (first[i
6756 + 2].value),
6757 "execution"))
6759 kind = C_OMP_DIR_STANDALONE;
6760 break;
6763 c_omp_attribute_data v = { toks, dir, kind };
6764 vd.safe_push (v);
6765 if (flag_openmp || dir->simd)
6766 tokens += (last - first) + 1;
6768 c_omp_attribute_data v = {};
6769 vd.safe_push (v);
6770 *pa = TREE_CHAIN (*pa);
6772 else
6773 pa = &TREE_CHAIN (*pa);
6775 if (bad)
6777 fail:
6778 if (have_std_attrs && attrs == NULL)
6779 *have_std_attrs = false;
6780 return false;
6783 unsigned int i;
6784 c_omp_attribute_data *v;
6785 c_omp_attribute_data *construct_seen = nullptr;
6786 c_omp_attribute_data *standalone_seen = nullptr;
6787 c_omp_attribute_data *prev_standalone_seen = nullptr;
6788 FOR_EACH_VEC_ELT (vd, i, v)
6789 if (v->tokens)
6791 if (v->kind == C_OMP_DIR_CONSTRUCT && !construct_seen)
6792 construct_seen = v;
6793 else if (v->kind == C_OMP_DIR_STANDALONE && !standalone_seen)
6794 standalone_seen = v;
6796 else
6798 if (standalone_seen && !prev_standalone_seen)
6800 prev_standalone_seen = standalone_seen;
6801 standalone_seen = nullptr;
6805 if (cnt > 1 && construct_seen)
6807 error_at ((*construct_seen->tokens)[0].location,
6808 "OpenMP construct among %<omp::directive%> attributes"
6809 " requires all %<omp::directive%> attributes on the"
6810 " same statement to be in the same %<omp::sequence%>");
6811 goto fail;
6813 if (cnt > 1 && standalone_seen && prev_standalone_seen)
6815 error_at ((*standalone_seen->tokens)[0].location,
6816 "multiple OpenMP standalone directives among"
6817 " %<omp::directive%> attributes must be all within the"
6818 " same %<omp::sequence%>");
6819 goto fail;
6822 if (prev_standalone_seen)
6823 standalone_seen = prev_standalone_seen;
6824 if (standalone_seen
6825 && !c_parser_next_token_is (parser, CPP_SEMICOLON))
6827 error_at (standalone_seen->tokens->address ()->location,
6828 "standalone OpenMP directives in %<omp::directive%> attribute"
6829 " can only appear on an empty statement");
6830 goto fail;
6832 if (cnt && c_parser_next_token_is (parser, CPP_PRAGMA))
6834 c_token *token = c_parser_peek_token (parser);
6835 enum pragma_kind kind = token->pragma_kind;
6836 if (kind >= PRAGMA_OMP__START_ && kind <= PRAGMA_OMP__LAST_)
6838 error_at (token->location,
6839 "mixing OpenMP directives with attribute and pragma "
6840 "syntax on the same statement");
6841 goto fail;
6845 if (!tokens)
6846 return false;
6848 unsigned int tokens_avail = parser->tokens_avail;
6849 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
6851 tokens++;
6852 vec<c_token, va_gc> *toks = NULL;
6853 vec_safe_reserve (toks, tokens, true);
6854 FOR_EACH_VEC_ELT (vd, i, v)
6856 if (!v->tokens)
6857 continue;
6858 if (!flag_openmp && !v->dir->simd)
6859 continue;
6860 c_token *first = v->tokens->address ();
6861 c_token *last = first + v->tokens->length ();
6862 c_token tok = {};
6863 tok.type = CPP_PRAGMA;
6864 tok.keyword = RID_MAX;
6865 tok.pragma_kind = pragma_kind (v->dir->id);
6866 tok.location = first->location;
6867 toks->quick_push (tok);
6868 while (++first < last)
6869 toks->quick_push (*first);
6870 tok = {};
6871 tok.type = CPP_PRAGMA_EOL;
6872 tok.keyword = RID_MAX;
6873 tok.location = last[-1].location;
6874 toks->quick_push (tok);
6877 c_token tok = {};
6878 tok.type = CPP_EOF;
6879 tok.keyword = RID_MAX;
6880 tok.location = toks->last ().location;
6881 tok.flags = tokens_avail;
6882 toks->quick_push (tok);
6884 parser->tokens = toks->address ();
6885 parser->tokens_avail = tokens;
6886 parser->in_omp_attribute_pragma = toks;
6887 return true;
6890 /* Handle omp::directive and omp::sequence attributes in ATTRS
6891 (if any) at the start or after declaration-id of a declaration. */
6893 static void
6894 c_parser_handle_directive_omp_attributes (tree &attrs,
6895 vec<c_token> *&pragma_clauses,
6896 vec<c_token> *attr_clauses)
6898 if (!flag_openmp && !flag_openmp_simd)
6899 return;
6901 for (tree *pa = &attrs; *pa; )
6902 if (is_attribute_namespace_p ("omp", *pa)
6903 && is_attribute_p ("directive", get_attribute_name (*pa)))
6905 int cnt = 0;
6906 for (tree *pa2 = &TREE_VALUE (*pa); *pa2; )
6908 tree a = *pa2;
6909 tree d = TREE_VALUE (a);
6910 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
6911 vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
6912 c_token *first = toks->address ();
6913 c_token *last = first + toks->length ();
6914 const char *directive[3] = {};
6915 for (int i = 0; i < 3; i++)
6917 tree id = NULL_TREE;
6918 if (first + i == last)
6919 break;
6920 if (first[i].type == CPP_NAME)
6921 id = first[i].value;
6922 else if (first[i].type == CPP_KEYWORD)
6923 id = ridpointers[(int) first[i].keyword];
6924 else
6925 break;
6926 directive[i] = IDENTIFIER_POINTER (id);
6928 const c_omp_directive *dir = NULL;
6929 if (directive[0])
6930 dir = c_omp_categorize_directive (directive[0], directive[1],
6931 directive[2]);
6932 if (dir == NULL)
6934 error_at (first->location,
6935 "unknown OpenMP directive name in "
6936 "%qs attribute argument",
6937 TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
6938 *pa2 = TREE_CHAIN (a);
6940 else if (dir->id == PRAGMA_OMP_DECLARE
6941 && (strcmp (directive[1], "simd") == 0
6942 || strcmp (directive[1], "variant") == 0))
6944 if (pragma_clauses)
6946 error_at (first->location,
6947 "mixing OpenMP directives with attribute and "
6948 "pragma syntax on the same declaration");
6949 for (pa = &attrs; *pa; )
6950 if (is_attribute_namespace_p ("omp", *pa)
6951 && is_attribute_p ("directive",
6952 get_attribute_name (*pa)))
6953 *pa = TREE_CHAIN (*pa);
6954 else
6955 pa = &TREE_CHAIN (*pa);
6956 return;
6958 ++cnt;
6959 attr_clauses->reserve (attr_clauses->length ()
6960 + toks->length () + 2);
6961 for (++first; first < last; ++first)
6962 attr_clauses->quick_push (*first);
6963 c_token tok = {};
6964 tok.type = CPP_PRAGMA_EOL;
6965 tok.keyword = RID_MAX;
6966 tok.location = last[-1].location;
6967 attr_clauses->quick_push (tok);
6968 *pa2 = TREE_CHAIN (a);
6970 else
6971 pa2 = &TREE_CHAIN (a);
6973 if (cnt && TREE_VALUE (*pa) == NULL_TREE)
6974 *pa = TREE_CHAIN (*pa);
6975 else
6976 pa = &TREE_CHAIN (*pa);
6978 else
6979 pa = &TREE_CHAIN (*pa);
6980 if (attr_clauses->length ())
6982 c_token tok = {};
6983 tok.type = CPP_EOF;
6984 tok.keyword = RID_MAX;
6985 tok.location = attr_clauses->last ().location;
6986 attr_clauses->quick_push (tok);
6987 attr_clauses->quick_push (tok);
6988 pragma_clauses = attr_clauses;
6992 /* Check if STD_ATTR contains a musttail attribute and remove if it
6993 precedes a return. PARSER is the parser and ATTR is the output
6994 attr_state. */
6996 static tree
6997 c_parser_handle_musttail (c_parser *parser, tree std_attrs, attr_state &attr)
6999 if (c_parser_next_token_is_keyword (parser, RID_RETURN))
7001 if (lookup_attribute ("gnu", "musttail", std_attrs))
7003 std_attrs = remove_attribute ("gnu", "musttail", std_attrs);
7004 attr.musttail_p = true;
7006 if (lookup_attribute ("clang", "musttail", std_attrs))
7008 std_attrs = remove_attribute ("clang", "musttail", std_attrs);
7009 attr.musttail_p = true;
7012 return std_attrs;
7015 /* Parse a compound statement except for the opening brace. This is
7016 used for parsing both compound statements and statement expressions
7017 (which follow different paths to handling the opening). */
7019 static location_t
7020 c_parser_compound_statement_nostart (c_parser *parser)
7022 bool last_stmt = false;
7023 bool last_label = false;
7024 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
7025 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7026 struct omp_for_parse_data *omp_for_parse_state
7027 = parser->omp_for_parse_state;
7028 bool in_omp_loop_block
7029 = omp_for_parse_state ? omp_for_parse_state->want_nested_loop : false;
7030 tree sl = NULL_TREE;
7031 attr_state a = {};
7033 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
7035 location_t endloc = c_parser_peek_token (parser)->location;
7036 add_debug_begin_stmt (endloc);
7037 c_parser_consume_token (parser);
7038 return endloc;
7041 /* If we're parsing a {} sequence in an OMP_FOR body, start a
7042 statement list for intervening code. */
7043 if (in_omp_loop_block)
7044 sl = push_stmt_list ();
7046 mark_valid_location_for_stdc_pragma (true);
7047 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
7049 /* Read zero or more forward-declarations for labels that nested
7050 functions can jump to. */
7051 mark_valid_location_for_stdc_pragma (false);
7052 if (in_omp_loop_block)
7053 check_omp_intervening_code (parser);
7054 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
7056 label_loc = c_parser_peek_token (parser)->location;
7057 c_parser_consume_token (parser);
7058 /* Any identifiers, including those declared as type names,
7059 are OK here. */
7060 while (true)
7062 tree label;
7063 if (c_parser_next_token_is_not (parser, CPP_NAME))
7065 c_parser_error (parser, "expected identifier");
7066 break;
7068 label
7069 = declare_label (c_parser_peek_token (parser)->value);
7070 C_DECLARED_LABEL_FLAG (label) = 1;
7071 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
7072 c_parser_consume_token (parser);
7073 if (c_parser_next_token_is (parser, CPP_COMMA))
7074 c_parser_consume_token (parser);
7075 else
7076 break;
7078 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7080 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
7082 /* We must now have at least one statement, label or declaration. */
7083 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
7085 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7086 c_parser_error (parser, "expected declaration or statement");
7087 location_t endloc = c_parser_peek_token (parser)->location;
7088 c_parser_consume_token (parser);
7089 return endloc;
7091 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
7093 location_t loc = c_parser_peek_token (parser)->location;
7094 loc = expansion_point_location_if_in_system_header (loc);
7096 bool want_nested_loop = (omp_for_parse_state
7097 ? omp_for_parse_state->want_nested_loop
7098 : false);
7100 /* First take care of special cases for OpenMP "canonical loop
7101 nest form", that do not allow standard attributes, labels, or
7102 __extension__ before the nested statement. */
7103 if (in_omp_loop_block && !last_label)
7105 tree_code code = omp_for_parse_state->code;
7106 if (want_nested_loop
7107 && c_parser_omp_next_tokens_can_be_canon_loop (parser, code,
7108 false))
7110 /* Found the next nested loop. If there were intervening
7111 code statements collected before now, wrap them in an
7112 OMP_STRUCTURED_BLOCK node, and start a new structured
7113 block to hold statements that may come after the FOR. */
7114 gcc_assert (sl);
7115 add_structured_block_stmt (pop_stmt_list (sl));
7116 omp_for_parse_state->depth++;
7117 add_stmt (c_parser_omp_loop_nest (parser, NULL));
7118 omp_for_parse_state->depth--;
7119 sl = push_stmt_list ();
7120 parser->error = false;
7121 continue;
7123 else if (want_nested_loop
7124 && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7126 /* If this nested compound statement contains the nested loop,
7127 we need to separate the other statements in the current
7128 statement into separate blocks of intervening code. If
7129 there's no nested loop, it's all part of the same
7130 chunk of intervening code. */
7131 tree pre_sl = pop_stmt_list (sl);
7132 tree nested_sl = push_stmt_list ();
7133 mark_valid_location_for_stdc_pragma (false);
7134 c_parser_statement_after_labels (parser, NULL);
7135 nested_sl = pop_stmt_list (nested_sl);
7136 if (omp_for_parse_state->want_nested_loop)
7138 /* This block didn't contain a loop-nest, so it's
7139 all part of the same chunk of intervening code. */
7140 check_omp_intervening_code (parser);
7141 sl = push_stmt_list ();
7142 add_stmt (pre_sl);
7143 add_stmt (nested_sl);
7145 else
7147 /* It contains the nested loop. */
7148 add_structured_block_stmt (pre_sl);
7149 add_stmt (nested_sl);
7150 sl = push_stmt_list ();
7152 parser->error = false;
7153 continue;
7155 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7157 /* Prior to implementing the OpenMP 5.1 syntax for canonical
7158 loop form, GCC used to accept an empty statements that
7159 would now be flagged as intervening code. Continue to
7160 do that, as an extension. */
7161 /* FIXME: Maybe issue a warning or something here? */
7162 c_parser_consume_token (parser);
7163 continue;
7167 /* Standard attributes may start a label, statement or declaration. */
7168 bool have_std_attrs
7169 = c_parser_nth_token_starts_std_attributes (parser, 1);
7170 tree std_attrs = NULL_TREE;
7171 if (have_std_attrs)
7173 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7174 std_attrs = c_parser_handle_musttail (parser, std_attrs, a);
7176 if (c_parser_next_token_is_keyword (parser, RID_CASE)
7177 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
7178 || (c_parser_next_token_is (parser, CPP_NAME)
7179 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
7181 if (c_parser_next_token_is_keyword (parser, RID_CASE))
7182 label_loc = c_parser_peek_2nd_token (parser)->location;
7183 else
7184 label_loc = c_parser_peek_token (parser)->location;
7185 last_label = true;
7186 last_stmt = false;
7187 mark_valid_location_for_stdc_pragma (false);
7188 if (in_omp_loop_block)
7189 check_omp_intervening_code (parser);
7190 c_parser_label (parser, std_attrs);
7192 else if (c_parser_next_tokens_start_declaration (parser)
7193 || (have_std_attrs
7194 && !c_parser_handle_statement_omp_attributes
7195 (parser, std_attrs, &have_std_attrs)
7196 && c_parser_next_token_is (parser, CPP_SEMICOLON)
7197 && (have_std_attrs = true)))
7199 if (last_label)
7200 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
7201 "a label can only be part of a statement and "
7202 "a declaration is not a statement");
7203 /* It's unlikely we'll see a nested loop in a declaration in
7204 intervening code in an OMP loop, but disallow it anyway. */
7205 if (in_omp_loop_block)
7207 check_omp_intervening_code (parser);
7208 omp_for_parse_state->want_nested_loop = false;
7210 mark_valid_location_for_stdc_pragma (false);
7211 bool fallthru_attr_p = false;
7212 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
7213 true, true, true, NULL,
7214 NULL, have_std_attrs, std_attrs,
7215 NULL, &fallthru_attr_p);
7217 if (in_omp_loop_block)
7218 omp_for_parse_state->want_nested_loop = want_nested_loop;
7219 if (last_stmt && !fallthru_attr_p)
7220 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
7221 "ISO C90 forbids mixed declarations and code");
7222 last_stmt = fallthru_attr_p;
7223 last_label = false;
7225 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
7227 /* __extension__ can start a declaration, but is also an
7228 unary operator that can start an expression. Consume all
7229 but the last of a possible series of __extension__ to
7230 determine which. If standard attributes have already
7231 been seen, it must start a statement, not a declaration,
7232 but standard attributes starting a declaration may appear
7233 after __extension__. */
7234 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
7235 && (c_parser_peek_2nd_token (parser)->keyword
7236 == RID_EXTENSION))
7237 c_parser_consume_token (parser);
7238 if (!have_std_attrs
7239 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
7240 || c_parser_nth_token_starts_std_attributes (parser, 2)))
7242 int ext;
7243 ext = disable_extension_diagnostics ();
7244 c_parser_consume_token (parser);
7245 last_label = false;
7246 /* It's unlikely we'll see a nested loop in a declaration in
7247 intervening code in an OMP loop, but disallow it anyway. */
7248 if (in_omp_loop_block)
7250 check_omp_intervening_code (parser);
7251 omp_for_parse_state->want_nested_loop = false;
7253 mark_valid_location_for_stdc_pragma (false);
7254 c_parser_declaration_or_fndef (parser, true, true, true, true,
7255 true);
7256 if (in_omp_loop_block)
7257 omp_for_parse_state->want_nested_loop = want_nested_loop;
7258 /* Following the old parser, __extension__ does not
7259 disable this diagnostic. */
7260 restore_extension_diagnostics (ext);
7261 if (last_stmt)
7262 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
7263 "ISO C90 forbids mixed declarations and code");
7264 last_stmt = false;
7266 else
7267 goto statement;
7269 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
7271 if (have_std_attrs && !parser->in_omp_attribute_pragma)
7272 c_parser_error (parser, "expected declaration or statement");
7273 else if (std_attrs)
7274 c_warn_unused_attributes (std_attrs);
7275 /* External pragmas, and some omp pragmas, are not associated
7276 with regular c code, and so are not to be considered statements
7277 syntactically. This ensures that the user doesn't put them
7278 places that would turn into syntax errors if the directive
7279 were ignored. */
7280 if (omp_for_parse_state)
7281 omp_for_parse_state->want_nested_loop = false;
7282 if (c_parser_pragma (parser,
7283 last_label ? pragma_stmt : pragma_compound,
7284 NULL))
7286 last_label = false;
7287 last_stmt = true;
7288 if (omp_for_parse_state)
7289 check_omp_intervening_code (parser);
7291 if (omp_for_parse_state)
7292 omp_for_parse_state->want_nested_loop = want_nested_loop;
7294 else if (c_parser_next_token_is (parser, CPP_EOF))
7296 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7297 c_parser_error (parser, "expected declaration or statement");
7298 return c_parser_peek_token (parser)->location;
7300 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
7302 if (parser->in_if_block)
7304 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7305 error_at (loc, "expected %<}%> before %<else%>");
7306 return c_parser_peek_token (parser)->location;
7308 else
7310 error_at (loc, "%<else%> without a previous %<if%>");
7311 c_parser_consume_token (parser);
7312 continue;
7315 else
7317 statement:
7318 c_warn_unused_attributes (std_attrs);
7319 last_label = false;
7320 last_stmt = true;
7321 mark_valid_location_for_stdc_pragma (false);
7322 if (!omp_for_parse_state)
7323 c_parser_statement_after_labels (parser, NULL, NULL, a);
7324 else
7326 /* In canonical loop nest form, nested loops can only appear
7327 directly, or in a directly nested compound statement. We
7328 already took care of those cases above, so now we have
7329 something else. This statement and everything inside
7330 it must be intervening code. */
7331 omp_for_parse_state->want_nested_loop = false;
7332 check_omp_intervening_code (parser);
7333 c_parser_statement_after_labels (parser, NULL);
7334 omp_for_parse_state->want_nested_loop = want_nested_loop;
7338 parser->error = false;
7340 if (last_label)
7341 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
7342 location_t endloc = c_parser_peek_token (parser)->location;
7343 c_parser_consume_token (parser);
7345 /* Restore the value we started with. */
7346 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
7348 /* Package leftover intervening code, or the whole contents of the
7349 compound statement if we were looking for a nested loop in an OMP_FOR
7350 construct and didn't find one. */
7351 if (sl)
7353 sl = pop_stmt_list (sl);
7354 if (omp_for_parse_state->want_nested_loop)
7355 add_stmt (sl);
7356 else
7357 add_structured_block_stmt (sl);
7359 return endloc;
7362 /* Parse all consecutive labels, possibly preceded by standard
7363 attributes. In this context, a statement is required, not a
7364 declaration, so attributes must be followed by a statement that is
7365 not just a semicolon. Returns an attr_state. */
7367 static attr_state
7368 c_parser_all_labels (c_parser *parser)
7370 attr_state attr = {};
7371 bool have_std_attrs;
7372 tree std_attrs = NULL;
7373 if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1)))
7375 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7376 std_attrs = c_parser_handle_musttail (parser, std_attrs, attr);
7379 while (c_parser_next_token_is_keyword (parser, RID_CASE)
7380 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
7381 || (c_parser_next_token_is (parser, CPP_NAME)
7382 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
7384 c_parser_label (parser, std_attrs);
7385 std_attrs = NULL;
7386 if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser,
7387 1)))
7389 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
7390 std_attrs = c_parser_handle_musttail (parser, std_attrs, attr);
7393 if (std_attrs
7394 && (!c_parser_handle_statement_omp_attributes (parser, std_attrs, &have_std_attrs)
7395 || std_attrs))
7397 if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
7398 c_parser_error (parser, "expected statement");
7399 c_warn_unused_attributes (std_attrs);
7401 else if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
7402 c_parser_error (parser, "expected statement");
7403 return attr;
7406 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
7408 label:
7409 identifier : gnu-attributes[opt]
7410 case constant-expression :
7411 default :
7413 GNU extensions:
7415 label:
7416 case constant-expression ... constant-expression :
7418 The use of gnu-attributes on labels is a GNU extension. The syntax in
7419 GNU C accepts any expressions without commas, non-constant
7420 expressions being rejected later. Any standard
7421 attribute-specifier-sequence before the first label has been parsed
7422 in the caller, to distinguish statements from declarations. Any
7423 attribute-specifier-sequence after the label is parsed in this
7424 function. */
7425 static void
7426 c_parser_label (c_parser *parser, tree std_attrs)
7428 location_t loc1 = c_parser_peek_token (parser)->location;
7429 tree label = NULL_TREE;
7431 /* Remember whether this case or a user-defined label is allowed to fall
7432 through to. */
7433 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
7435 if (c_parser_next_token_is_keyword (parser, RID_CASE))
7437 tree exp1, exp2;
7438 c_parser_consume_token (parser);
7439 exp1 = convert_lvalue_to_rvalue (loc1,
7440 c_parser_expr_no_commas (parser, NULL),
7441 true, true).value;
7442 if (c_parser_next_token_is (parser, CPP_COLON))
7444 c_parser_consume_token (parser);
7445 label = do_case (loc1, exp1, NULL_TREE, std_attrs);
7447 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
7449 c_parser_consume_token (parser);
7450 exp2 = convert_lvalue_to_rvalue (loc1,
7451 c_parser_expr_no_commas (parser,
7452 NULL),
7453 true, true).value;
7454 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7455 label = do_case (loc1, exp1, exp2, std_attrs);
7457 else
7458 c_parser_error (parser, "expected %<:%> or %<...%>");
7460 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
7462 c_parser_consume_token (parser);
7463 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7464 label = do_case (loc1, NULL_TREE, NULL_TREE, std_attrs);
7466 else
7468 tree name = c_parser_peek_token (parser)->value;
7469 tree tlab;
7470 tree attrs;
7471 location_t loc2 = c_parser_peek_token (parser)->location;
7472 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
7473 c_parser_consume_token (parser);
7474 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
7475 c_parser_consume_token (parser);
7476 attrs = c_parser_gnu_attributes (parser);
7477 tlab = define_label (loc2, name);
7478 if (tlab)
7480 decl_attributes (&tlab, attrs, 0);
7481 decl_attributes (&tlab, std_attrs, 0);
7482 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
7484 if (attrs
7485 && c_parser_next_tokens_start_declaration (parser))
7486 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
7487 " label and declaration appertains to the label");
7489 if (label)
7491 if (TREE_CODE (label) == LABEL_EXPR)
7492 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
7493 else
7494 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
7498 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
7500 statement:
7501 labeled-statement
7502 attribute-specifier-sequence[opt] compound-statement
7503 expression-statement
7504 attribute-specifier-sequence[opt] selection-statement
7505 attribute-specifier-sequence[opt] iteration-statement
7506 attribute-specifier-sequence[opt] jump-statement
7508 labeled-statement:
7509 attribute-specifier-sequence[opt] label statement
7511 expression-statement:
7512 expression[opt] ;
7513 attribute-specifier-sequence expression ;
7515 selection-statement:
7516 if-statement
7517 switch-statement
7519 iteration-statement:
7520 while-statement
7521 do-statement
7522 for-statement
7524 jump-statement:
7525 goto identifier ;
7526 continue ;
7527 break ;
7528 return expression[opt] ;
7530 GNU extensions:
7532 statement:
7533 attribute-specifier-sequence[opt] asm-statement
7535 jump-statement:
7536 goto * expression ;
7538 expression-statement:
7539 gnu-attributes ;
7541 Objective-C:
7543 statement:
7544 attribute-specifier-sequence[opt] objc-throw-statement
7545 attribute-specifier-sequence[opt] objc-try-catch-statement
7546 attribute-specifier-sequence[opt] objc-synchronized-statement
7548 objc-throw-statement:
7549 @throw expression ;
7550 @throw ;
7552 OpenACC:
7554 statement:
7555 attribute-specifier-sequence[opt] openacc-construct
7557 openacc-construct:
7558 parallel-construct
7559 kernels-construct
7560 data-construct
7561 loop-construct
7563 parallel-construct:
7564 parallel-directive structured-block
7566 kernels-construct:
7567 kernels-directive structured-block
7569 data-construct:
7570 data-directive structured-block
7572 loop-construct:
7573 loop-directive structured-block
7575 OpenMP:
7577 statement:
7578 attribute-specifier-sequence[opt] openmp-construct
7580 openmp-construct:
7581 parallel-construct
7582 for-construct
7583 simd-construct
7584 for-simd-construct
7585 sections-construct
7586 single-construct
7587 parallel-for-construct
7588 parallel-for-simd-construct
7589 parallel-sections-construct
7590 master-construct
7591 critical-construct
7592 atomic-construct
7593 ordered-construct
7595 parallel-construct:
7596 parallel-directive structured-block
7598 for-construct:
7599 for-directive iteration-statement
7601 simd-construct:
7602 simd-directive iteration-statements
7604 for-simd-construct:
7605 for-simd-directive iteration-statements
7607 sections-construct:
7608 sections-directive section-scope
7610 single-construct:
7611 single-directive structured-block
7613 parallel-for-construct:
7614 parallel-for-directive iteration-statement
7616 parallel-for-simd-construct:
7617 parallel-for-simd-directive iteration-statement
7619 parallel-sections-construct:
7620 parallel-sections-directive section-scope
7622 master-construct:
7623 master-directive structured-block
7625 critical-construct:
7626 critical-directive structured-block
7628 atomic-construct:
7629 atomic-directive expression-statement
7631 ordered-construct:
7632 ordered-directive structured-block
7634 Transactional Memory:
7636 statement:
7637 attribute-specifier-sequence[opt] transaction-statement
7638 attribute-specifier-sequence[opt] transaction-cancel-statement
7640 IF_P is used to track whether there's a (possibly labeled) if statement
7641 which is not enclosed in braces and has an else clause. This is used to
7642 implement -Wparentheses. */
7644 static void
7645 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
7647 attr_state a = c_parser_all_labels (parser);
7648 if (loc_after_labels)
7649 *loc_after_labels = c_parser_peek_token (parser)->location;
7650 parser->omp_attrs_forbidden_p = false;
7651 c_parser_statement_after_labels (parser, if_p, NULL, a);
7654 /* Parse a statement, other than a labeled statement. CHAIN is a vector
7655 of if-else-if conditions. All labels and standard attributes have
7656 been parsed in the caller.
7658 IF_P is used to track whether there's a (possibly labeled) if statement
7659 which is not enclosed in braces and has an else clause. This is used to
7660 implement -Wparentheses. ASTATE is an earlier parsed attribute state. */
7662 static void
7663 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
7664 vec<tree> *chain, attr_state astate)
7666 location_t loc = c_parser_peek_token (parser)->location;
7667 tree stmt = NULL_TREE;
7668 bool in_if_block = parser->in_if_block;
7669 parser->in_if_block = false;
7670 if (if_p != NULL)
7671 *if_p = false;
7673 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
7674 add_debug_begin_stmt (loc);
7676 restart:
7677 switch (c_parser_peek_token (parser)->type)
7679 case CPP_OPEN_BRACE:
7680 add_stmt (c_parser_compound_statement (parser));
7681 break;
7682 case CPP_KEYWORD:
7683 switch (c_parser_peek_token (parser)->keyword)
7685 case RID_IF:
7686 c_parser_if_statement (parser, if_p, chain);
7687 break;
7688 case RID_SWITCH:
7689 c_parser_switch_statement (parser, if_p);
7690 break;
7691 case RID_WHILE:
7692 c_parser_while_statement (parser, false, 0, false, if_p);
7693 break;
7694 case RID_DO:
7695 c_parser_do_statement (parser, false, 0, false);
7696 break;
7697 case RID_FOR:
7698 c_parser_for_statement (parser, false, 0, false, if_p);
7699 break;
7700 case RID_GOTO:
7701 c_parser_consume_token (parser);
7702 if (c_parser_next_token_is (parser, CPP_NAME))
7704 stmt = c_finish_goto_label (loc,
7705 c_parser_peek_token (parser)->value);
7706 c_parser_consume_token (parser);
7708 else if (c_parser_next_token_is (parser, CPP_MULT))
7710 struct c_expr val;
7712 c_parser_consume_token (parser);
7713 val = c_parser_expression (parser);
7714 val = convert_lvalue_to_rvalue (loc, val, false, true);
7715 stmt = c_finish_goto_ptr (loc, val);
7717 else
7718 c_parser_error (parser, "expected identifier or %<*%>");
7719 goto expect_semicolon;
7720 case RID_CONTINUE:
7721 c_parser_consume_token (parser);
7722 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
7723 goto expect_semicolon;
7724 case RID_BREAK:
7725 c_parser_consume_token (parser);
7726 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
7727 goto expect_semicolon;
7728 case RID_RETURN:
7729 c_parser_consume_token (parser);
7730 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7732 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE,
7733 astate.musttail_p);
7734 c_parser_consume_token (parser);
7736 else
7738 location_t xloc = c_parser_peek_token (parser)->location;
7739 struct c_expr expr = c_parser_expression_conv (parser);
7740 mark_exp_read (expr.value);
7741 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
7742 expr.value, expr.original_type,
7743 astate.musttail_p);
7744 goto expect_semicolon;
7746 break;
7747 case RID_ASM:
7748 stmt = c_parser_asm_statement (parser);
7749 break;
7750 case RID_TRANSACTION_ATOMIC:
7751 case RID_TRANSACTION_RELAXED:
7752 stmt = c_parser_transaction (parser,
7753 c_parser_peek_token (parser)->keyword);
7754 break;
7755 case RID_TRANSACTION_CANCEL:
7756 stmt = c_parser_transaction_cancel (parser);
7757 goto expect_semicolon;
7758 case RID_AT_THROW:
7759 gcc_assert (c_dialect_objc ());
7760 c_parser_consume_token (parser);
7761 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7763 stmt = objc_build_throw_stmt (loc, NULL_TREE);
7764 c_parser_consume_token (parser);
7766 else
7768 struct c_expr expr = c_parser_expression (parser);
7769 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
7770 expr.value = c_fully_fold (expr.value, false, NULL);
7771 stmt = objc_build_throw_stmt (loc, expr.value);
7772 goto expect_semicolon;
7774 break;
7775 case RID_AT_TRY:
7776 gcc_assert (c_dialect_objc ());
7777 c_parser_objc_try_catch_finally_statement (parser);
7778 break;
7779 case RID_AT_SYNCHRONIZED:
7780 gcc_assert (c_dialect_objc ());
7781 c_parser_objc_synchronized_statement (parser);
7782 break;
7783 case RID_ATTRIBUTE:
7785 /* Allow '__attribute__((fallthrough));' or
7786 '__attribute__((assume(cond)));'. */
7787 tree attrs = c_parser_gnu_attributes (parser);
7788 bool has_assume = lookup_attribute ("assume", attrs);
7789 if (has_assume)
7791 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7792 attrs = handle_assume_attribute (loc, attrs, true);
7793 else
7795 warning_at (loc, OPT_Wattributes,
7796 "%<assume%> attribute not followed by %<;%>");
7797 has_assume = false;
7800 if (attribute_fallthrough_p (attrs))
7802 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7804 tree fn = build_call_expr_internal_loc (loc,
7805 IFN_FALLTHROUGH,
7806 void_type_node, 0);
7807 add_stmt (fn);
7808 /* Eat the ';'. */
7809 c_parser_consume_token (parser);
7811 else
7812 warning_at (loc, OPT_Wattributes,
7813 "%<fallthrough%> attribute not followed "
7814 "by %<;%>");
7816 else if (has_assume)
7817 /* Eat the ';'. */
7818 c_parser_consume_token (parser);
7819 else if (attrs != NULL_TREE)
7820 warning_at (loc, OPT_Wattributes,
7821 "only attribute %<fallthrough%> or %<assume%> can "
7822 "be applied to a null statement");
7823 break;
7825 default:
7826 goto expr_stmt;
7828 break;
7829 case CPP_SEMICOLON:
7830 c_parser_consume_token (parser);
7831 break;
7832 case CPP_CLOSE_PAREN:
7833 case CPP_CLOSE_SQUARE:
7834 /* Avoid infinite loop in error recovery:
7835 c_parser_skip_until_found stops at a closing nesting
7836 delimiter without consuming it, but here we need to consume
7837 it to proceed further. */
7838 c_parser_error (parser, "expected statement");
7839 c_parser_consume_token (parser);
7840 break;
7841 case CPP_PRAGMA:
7842 if (!c_parser_pragma (parser, pragma_stmt, if_p))
7843 goto restart;
7844 break;
7845 default:
7846 expr_stmt:
7847 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
7848 expect_semicolon:
7849 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7850 break;
7852 /* Two cases cannot and do not have line numbers associated: If stmt
7853 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
7854 cannot hold line numbers. But that's OK because the statement
7855 will either be changed to a MODIFY_EXPR during gimplification of
7856 the statement expr, or discarded. If stmt was compound, but
7857 without new variables, we will have skipped the creation of a
7858 BIND and will have a bare STATEMENT_LIST. But that's OK because
7859 (recursively) all of the component statements should already have
7860 line numbers assigned. ??? Can we discard no-op statements
7861 earlier? */
7862 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
7863 protected_set_expr_location (stmt, loc);
7865 parser->in_if_block = in_if_block;
7868 /* Parse the condition from an if, do, while or for statements. */
7870 static tree
7871 c_parser_condition (c_parser *parser)
7873 location_t loc = c_parser_peek_token (parser)->location;
7874 tree cond;
7875 cond = c_parser_expression_conv (parser).value;
7876 cond = c_objc_common_truthvalue_conversion (loc, cond);
7877 cond = c_fully_fold (cond, false, NULL);
7878 if (warn_sequence_point)
7879 verify_sequence_points (cond);
7880 return cond;
7883 /* Parse a parenthesized condition from an if, do or while statement.
7885 condition:
7886 ( expression )
7888 static tree
7889 c_parser_paren_condition (c_parser *parser)
7891 tree cond;
7892 matching_parens parens;
7893 if (!parens.require_open (parser))
7894 return error_mark_node;
7895 cond = c_parser_condition (parser);
7896 parens.skip_until_found_close (parser);
7897 return cond;
7900 /* Parse a statement which is a block in C99.
7902 IF_P is used to track whether there's a (possibly labeled) if statement
7903 which is not enclosed in braces and has an else clause. This is used to
7904 implement -Wparentheses. */
7906 static tree
7907 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
7908 location_t *loc_after_labels)
7910 tree block = c_begin_compound_stmt (flag_isoc99);
7911 location_t loc = c_parser_peek_token (parser)->location;
7912 c_parser_statement (parser, if_p, loc_after_labels);
7913 return c_end_compound_stmt (loc, block, flag_isoc99);
7916 /* Parse the body of an if statement. This is just parsing a
7917 statement but (a) it is a block in C99, (b) we track whether the
7918 body is an if statement for the sake of -Wparentheses warnings, (c)
7919 we handle an empty body specially for the sake of -Wempty-body
7920 warnings, and (d) we call parser_compound_statement directly
7921 because c_parser_statement_after_labels resets
7922 parser->in_if_block.
7924 IF_P is used to track whether there's a (possibly labeled) if statement
7925 which is not enclosed in braces and has an else clause. This is used to
7926 implement -Wparentheses. */
7928 static tree
7929 c_parser_if_body (c_parser *parser, bool *if_p,
7930 const token_indent_info &if_tinfo)
7932 tree block = c_begin_compound_stmt (flag_isoc99);
7933 location_t body_loc = c_parser_peek_token (parser)->location;
7934 location_t body_loc_after_labels = UNKNOWN_LOCATION;
7935 token_indent_info body_tinfo
7936 = get_token_indent_info (c_parser_peek_token (parser));
7938 c_parser_all_labels (parser);
7939 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7941 location_t loc = c_parser_peek_token (parser)->location;
7942 add_stmt (build_empty_stmt (loc));
7943 c_parser_consume_token (parser);
7944 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
7945 warning_at (loc, OPT_Wempty_body,
7946 "suggest braces around empty body in an %<if%> statement");
7948 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7949 add_stmt (c_parser_compound_statement (parser));
7950 else
7952 body_loc_after_labels = c_parser_peek_token (parser)->location;
7953 c_parser_statement_after_labels (parser, if_p);
7956 token_indent_info next_tinfo
7957 = get_token_indent_info (c_parser_peek_token (parser));
7958 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
7959 if (body_loc_after_labels != UNKNOWN_LOCATION
7960 && next_tinfo.type != CPP_SEMICOLON)
7961 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
7962 if_tinfo.location, RID_IF);
7964 return c_end_compound_stmt (body_loc, block, flag_isoc99);
7967 /* Parse the else body of an if statement. This is just parsing a
7968 statement but (a) it is a block in C99, (b) we handle an empty body
7969 specially for the sake of -Wempty-body warnings. CHAIN is a vector
7970 of if-else-if conditions. */
7972 static tree
7973 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
7974 vec<tree> *chain)
7976 location_t body_loc = c_parser_peek_token (parser)->location;
7977 tree block = c_begin_compound_stmt (flag_isoc99);
7978 token_indent_info body_tinfo
7979 = get_token_indent_info (c_parser_peek_token (parser));
7980 location_t body_loc_after_labels = UNKNOWN_LOCATION;
7982 c_parser_all_labels (parser);
7983 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7985 location_t loc = c_parser_peek_token (parser)->location;
7986 warning_at (loc,
7987 OPT_Wempty_body,
7988 "suggest braces around empty body in an %<else%> statement");
7989 add_stmt (build_empty_stmt (loc));
7990 c_parser_consume_token (parser);
7992 else
7994 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7995 body_loc_after_labels = c_parser_peek_token (parser)->location;
7996 c_parser_statement_after_labels (parser, NULL, chain);
7999 token_indent_info next_tinfo
8000 = get_token_indent_info (c_parser_peek_token (parser));
8001 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
8002 if (body_loc_after_labels != UNKNOWN_LOCATION
8003 && next_tinfo.type != CPP_SEMICOLON)
8004 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
8005 else_tinfo.location, RID_ELSE);
8007 return c_end_compound_stmt (body_loc, block, flag_isoc99);
8010 /* We might need to reclassify any previously-lexed identifier, e.g.
8011 when we've left a for loop with an if-statement without else in the
8012 body - we might have used a wrong scope for the token. See PR67784. */
8014 static void
8015 c_parser_maybe_reclassify_token (c_parser *parser)
8017 if (c_parser_next_token_is (parser, CPP_NAME))
8019 c_token *token = c_parser_peek_token (parser);
8021 if (token->id_kind != C_ID_CLASSNAME)
8023 tree decl = lookup_name (token->value);
8025 token->id_kind = C_ID_ID;
8026 if (decl)
8028 if (TREE_CODE (decl) == TYPE_DECL)
8029 token->id_kind = C_ID_TYPENAME;
8031 else if (c_dialect_objc ())
8033 tree objc_interface_decl = objc_is_class_name (token->value);
8034 /* Objective-C class names are in the same namespace as
8035 variables and typedefs, and hence are shadowed by local
8036 declarations. */
8037 if (objc_interface_decl)
8039 token->value = objc_interface_decl;
8040 token->id_kind = C_ID_CLASSNAME;
8047 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8049 if-statement:
8050 if ( expression ) statement
8051 if ( expression ) statement else statement
8053 CHAIN is a vector of if-else-if conditions.
8054 IF_P is used to track whether there's a (possibly labeled) if statement
8055 which is not enclosed in braces and has an else clause. This is used to
8056 implement -Wparentheses. */
8058 static void
8059 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
8061 tree block;
8062 location_t loc;
8063 tree cond;
8064 bool nested_if = false;
8065 tree first_body, second_body;
8066 bool in_if_block;
8068 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
8069 token_indent_info if_tinfo
8070 = get_token_indent_info (c_parser_peek_token (parser));
8071 c_parser_consume_token (parser);
8072 block = c_begin_compound_stmt (flag_isoc99);
8073 loc = c_parser_peek_token (parser)->location;
8074 cond = c_parser_paren_condition (parser);
8075 in_if_block = parser->in_if_block;
8076 parser->in_if_block = true;
8077 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
8078 parser->in_if_block = in_if_block;
8080 if (warn_duplicated_cond)
8081 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
8083 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
8085 token_indent_info else_tinfo
8086 = get_token_indent_info (c_parser_peek_token (parser));
8087 c_parser_consume_token (parser);
8088 if (warn_duplicated_cond)
8090 if (c_parser_next_token_is_keyword (parser, RID_IF)
8091 && chain == NULL)
8093 /* We've got "if (COND) else if (COND2)". Start the
8094 condition chain and add COND as the first element. */
8095 chain = new vec<tree> ();
8096 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
8097 chain->safe_push (cond);
8099 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
8100 /* This is if-else without subsequent if. Zap the condition
8101 chain; we would have already warned at this point. */
8102 vec_free (chain);
8104 second_body = c_parser_else_body (parser, else_tinfo, chain);
8105 /* Set IF_P to true to indicate that this if statement has an
8106 else clause. This may trigger the Wparentheses warning
8107 below when we get back up to the parent if statement. */
8108 if (if_p != NULL)
8109 *if_p = true;
8111 else
8113 second_body = NULL_TREE;
8115 /* Diagnose an ambiguous else if if-then-else is nested inside
8116 if-then. */
8117 if (nested_if)
8118 warning_at (loc, OPT_Wdangling_else,
8119 "suggest explicit braces to avoid ambiguous %<else%>");
8121 if (warn_duplicated_cond)
8122 /* This if statement does not have an else clause. We don't
8123 need the condition chain anymore. */
8124 vec_free (chain);
8126 c_finish_if_stmt (loc, cond, first_body, second_body);
8127 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8129 c_parser_maybe_reclassify_token (parser);
8132 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8134 switch-statement:
8135 switch (expression) statement
8138 static void
8139 c_parser_switch_statement (c_parser *parser, bool *if_p)
8141 struct c_expr ce;
8142 tree block, expr, body;
8143 unsigned char save_in_statement;
8144 location_t switch_loc = c_parser_peek_token (parser)->location;
8145 location_t switch_cond_loc;
8146 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
8147 c_parser_consume_token (parser);
8148 block = c_begin_compound_stmt (flag_isoc99);
8149 bool explicit_cast_p = false;
8150 matching_parens parens;
8151 if (parens.require_open (parser))
8153 switch_cond_loc = c_parser_peek_token (parser)->location;
8154 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8155 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8156 explicit_cast_p = true;
8157 ce = c_parser_expression (parser);
8158 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
8159 expr = ce.value;
8160 /* ??? expr has no valid location? */
8161 parens.skip_until_found_close (parser);
8163 else
8165 switch_cond_loc = UNKNOWN_LOCATION;
8166 expr = error_mark_node;
8167 ce.original_type = error_mark_node;
8169 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
8170 save_in_statement = in_statement;
8171 in_statement |= IN_SWITCH_STMT;
8172 location_t loc_after_labels;
8173 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
8174 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8175 location_t next_loc = c_parser_peek_token (parser)->location;
8176 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
8177 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
8178 RID_SWITCH);
8179 c_finish_switch (body, ce.original_type);
8180 in_statement = save_in_statement;
8181 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
8182 c_parser_maybe_reclassify_token (parser);
8185 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8187 while-statement:
8188 while (expression) statement
8190 IF_P is used to track whether there's a (possibly labeled) if statement
8191 which is not enclosed in braces and has an else clause. This is used to
8192 implement -Wparentheses. */
8194 static void
8195 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8196 bool novector, bool *if_p)
8198 tree block, cond, body;
8199 unsigned char save_in_statement;
8200 location_t loc;
8201 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
8202 token_indent_info while_tinfo
8203 = get_token_indent_info (c_parser_peek_token (parser));
8205 if (parser->omp_for_parse_state)
8207 error_at (c_parser_peek_token (parser)->location,
8208 "loop not permitted in intervening code in OpenMP loop body");
8209 parser->omp_for_parse_state->fail = true;
8212 c_parser_consume_token (parser);
8213 block = c_begin_compound_stmt (flag_isoc99);
8214 loc = c_parser_peek_token (parser)->location;
8215 cond = c_parser_paren_condition (parser);
8216 if (ivdep && cond != error_mark_node)
8217 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8218 build_int_cst (integer_type_node,
8219 annot_expr_ivdep_kind),
8220 integer_zero_node);
8221 if (unroll && cond != error_mark_node)
8222 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8223 build_int_cst (integer_type_node,
8224 annot_expr_unroll_kind),
8225 build_int_cst (integer_type_node, unroll));
8226 if (novector && cond != error_mark_node)
8227 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8228 build_int_cst (integer_type_node,
8229 annot_expr_no_vector_kind),
8230 integer_zero_node);
8231 save_in_statement = in_statement;
8232 in_statement = IN_ITERATION_STMT;
8234 token_indent_info body_tinfo
8235 = get_token_indent_info (c_parser_peek_token (parser));
8237 location_t loc_after_labels;
8238 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
8239 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8240 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
8241 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8242 c_parser_maybe_reclassify_token (parser);
8244 token_indent_info next_tinfo
8245 = get_token_indent_info (c_parser_peek_token (parser));
8246 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
8248 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
8249 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
8250 while_tinfo.location, RID_WHILE);
8252 in_statement = save_in_statement;
8255 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8257 do-statement:
8258 do statement while ( expression ) ;
8261 static void
8262 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8263 bool novector)
8265 tree block, cond, body;
8266 unsigned char save_in_statement;
8267 location_t loc;
8268 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
8270 if (parser->omp_for_parse_state)
8272 error_at (c_parser_peek_token (parser)->location,
8273 "loop not permitted in intervening code in OpenMP loop body");
8274 parser->omp_for_parse_state->fail = true;
8277 c_parser_consume_token (parser);
8278 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8279 warning_at (c_parser_peek_token (parser)->location,
8280 OPT_Wempty_body,
8281 "suggest braces around empty body in %<do%> statement");
8282 block = c_begin_compound_stmt (flag_isoc99);
8283 loc = c_parser_peek_token (parser)->location;
8284 save_in_statement = in_statement;
8285 in_statement = IN_ITERATION_STMT;
8286 body = c_parser_c99_block_statement (parser, NULL);
8287 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
8288 in_statement = save_in_statement;
8289 cond = c_parser_paren_condition (parser);
8290 if (ivdep && cond != error_mark_node)
8291 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8292 build_int_cst (integer_type_node,
8293 annot_expr_ivdep_kind),
8294 integer_zero_node);
8295 if (unroll && cond != error_mark_node)
8296 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8297 build_int_cst (integer_type_node,
8298 annot_expr_unroll_kind),
8299 build_int_cst (integer_type_node, unroll));
8300 if (novector && cond != error_mark_node)
8301 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8302 build_int_cst (integer_type_node,
8303 annot_expr_no_vector_kind),
8304 integer_zero_node);
8305 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
8306 c_parser_skip_to_end_of_block_or_statement (parser);
8308 add_stmt (build_stmt (loc, DO_STMT, cond, body));
8309 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
8312 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8314 for-statement:
8315 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
8316 for ( nested-declaration expression[opt] ; expression[opt] ) statement
8318 The form with a declaration is new in C99.
8320 ??? In accordance with the old parser, the declaration may be a
8321 nested function, which is then rejected in check_for_loop_decls,
8322 but does it make any sense for this to be included in the grammar?
8323 Note in particular that the nested function does not include a
8324 trailing ';', whereas the "declaration" production includes one.
8325 Also, can we reject bad declarations earlier and cheaper than
8326 check_for_loop_decls?
8328 In Objective-C, there are two additional variants:
8330 foreach-statement:
8331 for ( expression in expresssion ) statement
8332 for ( declaration in expression ) statement
8334 This is inconsistent with C, because the second variant is allowed
8335 even if c99 is not enabled.
8337 The rest of the comment documents these Objective-C foreach-statement.
8339 Here is the canonical example of the first variant:
8340 for (object in array) { do something with object }
8341 we call the first expression ("object") the "object_expression" and
8342 the second expression ("array") the "collection_expression".
8343 object_expression must be an lvalue of type "id" (a generic Objective-C
8344 object) because the loop works by assigning to object_expression the
8345 various objects from the collection_expression. collection_expression
8346 must evaluate to something of type "id" which responds to the method
8347 countByEnumeratingWithState:objects:count:.
8349 The canonical example of the second variant is:
8350 for (id object in array) { do something with object }
8351 which is completely equivalent to
8353 id object;
8354 for (object in array) { do something with object }
8356 Note that initizializing 'object' in some way (eg, "for ((object =
8357 xxx) in array) { do something with object }") is possibly
8358 technically valid, but completely pointless as 'object' will be
8359 assigned to something else as soon as the loop starts. We should
8360 most likely reject it (TODO).
8362 The beginning of the Objective-C foreach-statement looks exactly
8363 like the beginning of the for-statement, and we can tell it is a
8364 foreach-statement only because the initial declaration or
8365 expression is terminated by 'in' instead of ';'.
8367 IF_P is used to track whether there's a (possibly labeled) if statement
8368 which is not enclosed in braces and has an else clause. This is used to
8369 implement -Wparentheses. */
8371 static void
8372 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
8373 bool novector, bool *if_p)
8375 tree block, cond, incr, body;
8376 unsigned char save_in_statement;
8377 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
8378 /* The following are only used when parsing an ObjC foreach statement. */
8379 tree object_expression;
8380 /* Silence the bogus uninitialized warning. */
8381 tree collection_expression = NULL;
8382 location_t loc = c_parser_peek_token (parser)->location;
8383 location_t for_loc = loc;
8384 bool is_foreach_statement = false;
8385 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
8386 token_indent_info for_tinfo
8387 = get_token_indent_info (c_parser_peek_token (parser));
8389 if (parser->omp_for_parse_state)
8391 error_at (for_loc,
8392 "loop not permitted in intervening code in OpenMP loop body");
8393 parser->omp_for_parse_state->fail = true;
8396 c_parser_consume_token (parser);
8397 /* Open a compound statement in Objective-C as well, just in case this is
8398 as foreach expression. */
8399 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
8400 cond = error_mark_node;
8401 incr = error_mark_node;
8402 matching_parens parens;
8403 if (parens.require_open (parser))
8405 /* Parse the initialization declaration or expression. */
8406 object_expression = error_mark_node;
8407 parser->objc_could_be_foreach_context = c_dialect_objc ();
8408 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8410 parser->objc_could_be_foreach_context = false;
8411 c_parser_consume_token (parser);
8412 c_finish_expr_stmt (loc, NULL_TREE);
8414 else if (c_parser_next_tokens_start_declaration (parser)
8415 || c_parser_nth_token_starts_std_attributes (parser, 1))
8417 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
8418 &object_expression);
8419 parser->objc_could_be_foreach_context = false;
8421 if (c_parser_next_token_is_keyword (parser, RID_IN))
8423 c_parser_consume_token (parser);
8424 is_foreach_statement = true;
8425 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
8426 c_parser_error (parser, "multiple iterating variables in "
8427 "fast enumeration");
8429 else
8430 check_for_loop_decls (for_loc, flag_isoc99);
8432 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
8434 /* __extension__ can start a declaration, but is also an
8435 unary operator that can start an expression. Consume all
8436 but the last of a possible series of __extension__ to
8437 determine which. */
8438 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
8439 && (c_parser_peek_2nd_token (parser)->keyword
8440 == RID_EXTENSION))
8441 c_parser_consume_token (parser);
8442 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
8443 || c_parser_nth_token_starts_std_attributes (parser, 2))
8445 int ext;
8446 ext = disable_extension_diagnostics ();
8447 c_parser_consume_token (parser);
8448 c_parser_declaration_or_fndef (parser, true, true, true, true,
8449 true, &object_expression);
8450 parser->objc_could_be_foreach_context = false;
8452 restore_extension_diagnostics (ext);
8453 if (c_parser_next_token_is_keyword (parser, RID_IN))
8455 c_parser_consume_token (parser);
8456 is_foreach_statement = true;
8457 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
8458 c_parser_error (parser, "multiple iterating variables in "
8459 "fast enumeration");
8461 else
8462 check_for_loop_decls (for_loc, flag_isoc99);
8464 else
8465 goto init_expr;
8467 else
8469 init_expr:
8471 struct c_expr ce;
8472 tree init_expression;
8473 ce = c_parser_expression (parser);
8474 init_expression = ce.value;
8475 parser->objc_could_be_foreach_context = false;
8476 if (c_parser_next_token_is_keyword (parser, RID_IN))
8478 c_parser_consume_token (parser);
8479 is_foreach_statement = true;
8480 if (! lvalue_p (init_expression))
8481 c_parser_error (parser, "invalid iterating variable in "
8482 "fast enumeration");
8483 object_expression
8484 = c_fully_fold (init_expression, false, NULL);
8486 else
8488 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
8489 init_expression = ce.value;
8490 c_finish_expr_stmt (loc, init_expression);
8491 c_parser_skip_until_found (parser, CPP_SEMICOLON,
8492 "expected %<;%>");
8496 /* Parse the loop condition. In the case of a foreach
8497 statement, there is no loop condition. */
8498 gcc_assert (!parser->objc_could_be_foreach_context);
8499 if (!is_foreach_statement)
8501 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
8503 if (ivdep)
8505 c_parser_error (parser, "missing loop condition in loop "
8506 "with %<GCC ivdep%> pragma");
8507 cond = error_mark_node;
8509 else if (unroll)
8511 c_parser_error (parser, "missing loop condition in loop "
8512 "with %<GCC unroll%> pragma");
8513 cond = error_mark_node;
8515 else
8517 c_parser_consume_token (parser);
8518 cond = NULL_TREE;
8521 else
8523 cond = c_parser_condition (parser);
8524 c_parser_skip_until_found (parser, CPP_SEMICOLON,
8525 "expected %<;%>");
8527 if (ivdep && cond != error_mark_node)
8528 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8529 build_int_cst (integer_type_node,
8530 annot_expr_ivdep_kind),
8531 integer_zero_node);
8532 if (unroll && cond != error_mark_node)
8533 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8534 build_int_cst (integer_type_node,
8535 annot_expr_unroll_kind),
8536 build_int_cst (integer_type_node, unroll));
8537 if (novector && cond && cond != error_mark_node)
8538 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
8539 build_int_cst (integer_type_node,
8540 annot_expr_no_vector_kind),
8541 integer_zero_node);
8543 /* Parse the increment expression (the third expression in a
8544 for-statement). In the case of a foreach-statement, this is
8545 the expression that follows the 'in'. */
8546 loc = c_parser_peek_token (parser)->location;
8547 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8549 if (is_foreach_statement)
8551 c_parser_error (parser,
8552 "missing collection in fast enumeration");
8553 collection_expression = error_mark_node;
8555 else
8556 incr = c_process_expr_stmt (loc, NULL_TREE);
8558 else
8560 if (is_foreach_statement)
8561 collection_expression
8562 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
8563 else
8565 struct c_expr ce = c_parser_expression (parser);
8566 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
8567 incr = c_process_expr_stmt (loc, ce.value);
8570 parens.skip_until_found_close (parser);
8572 save_in_statement = in_statement;
8573 if (is_foreach_statement)
8575 in_statement = IN_OBJC_FOREACH;
8576 save_objc_foreach_break_label = objc_foreach_break_label;
8577 save_objc_foreach_continue_label = objc_foreach_continue_label;
8578 objc_foreach_break_label = create_artificial_label (loc);
8579 objc_foreach_continue_label = create_artificial_label (loc);
8581 else
8582 in_statement = IN_ITERATION_STMT;
8584 token_indent_info body_tinfo
8585 = get_token_indent_info (c_parser_peek_token (parser));
8587 location_t loc_after_labels;
8588 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
8589 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
8591 if (is_foreach_statement)
8592 objc_finish_foreach_loop (for_loc, object_expression,
8593 collection_expression, body,
8594 objc_foreach_break_label,
8595 objc_foreach_continue_label);
8596 else
8597 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
8598 body, NULL_TREE));
8599 add_stmt (c_end_compound_stmt (for_loc, block,
8600 flag_isoc99 || c_dialect_objc ()));
8601 c_parser_maybe_reclassify_token (parser);
8603 token_indent_info next_tinfo
8604 = get_token_indent_info (c_parser_peek_token (parser));
8605 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
8607 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
8608 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
8609 for_tinfo.location, RID_FOR);
8611 in_statement = save_in_statement;
8612 if (is_foreach_statement)
8614 objc_foreach_break_label = save_objc_foreach_break_label;
8615 objc_foreach_continue_label = save_objc_foreach_continue_label;
8619 /* Parse an asm statement, a GNU extension. This is a full-blown asm
8620 statement with inputs, outputs, clobbers, and volatile, inline, and goto
8621 tags allowed.
8623 asm-qualifier:
8624 volatile
8625 inline
8626 goto
8628 asm-qualifier-list:
8629 asm-qualifier-list asm-qualifier
8630 asm-qualifier
8632 asm-statement:
8633 asm asm-qualifier-list[opt] ( asm-argument ) ;
8635 asm-argument:
8636 asm-string-literal
8637 asm-string-literal : asm-operands[opt]
8638 asm-string-literal : asm-operands[opt] : asm-operands[opt]
8639 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
8640 : asm-clobbers[opt]
8641 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
8642 : asm-goto-operands
8644 The form with asm-goto-operands is valid if and only if the
8645 asm-qualifier-list contains goto, and is the only allowed form in that case.
8646 Duplicate asm-qualifiers are not allowed.
8648 The :: token is considered equivalent to two consecutive : tokens. */
8650 static tree
8651 c_parser_asm_statement (c_parser *parser)
8653 tree str, outputs, inputs, clobbers, labels, ret;
8654 bool simple;
8655 location_t asm_loc = c_parser_peek_token (parser)->location;
8656 int section, nsections;
8658 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
8659 c_parser_consume_token (parser);
8661 /* Handle the asm-qualifier-list. */
8662 location_t volatile_loc = UNKNOWN_LOCATION;
8663 location_t inline_loc = UNKNOWN_LOCATION;
8664 location_t goto_loc = UNKNOWN_LOCATION;
8665 for (;;)
8667 c_token *token = c_parser_peek_token (parser);
8668 location_t loc = token->location;
8669 switch (token->keyword)
8671 case RID_VOLATILE:
8672 if (volatile_loc)
8674 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8675 inform (volatile_loc, "first seen here");
8677 else
8678 volatile_loc = loc;
8679 c_parser_consume_token (parser);
8680 continue;
8682 case RID_INLINE:
8683 if (inline_loc)
8685 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8686 inform (inline_loc, "first seen here");
8688 else
8689 inline_loc = loc;
8690 c_parser_consume_token (parser);
8691 continue;
8693 case RID_GOTO:
8694 if (goto_loc)
8696 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
8697 inform (goto_loc, "first seen here");
8699 else
8700 goto_loc = loc;
8701 c_parser_consume_token (parser);
8702 continue;
8704 case RID_CONST:
8705 case RID_RESTRICT:
8706 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
8707 c_parser_consume_token (parser);
8708 continue;
8710 default:
8711 break;
8713 break;
8716 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
8717 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
8718 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
8720 ret = NULL;
8722 matching_parens parens;
8723 if (!parens.require_open (parser))
8724 goto error;
8726 str = c_parser_asm_string_literal (parser);
8727 if (str == NULL_TREE)
8728 goto error_close_paren;
8730 simple = true;
8731 outputs = NULL_TREE;
8732 inputs = NULL_TREE;
8733 clobbers = NULL_TREE;
8734 labels = NULL_TREE;
8736 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
8737 goto done_asm;
8739 /* Parse each colon-delimited section of operands. */
8740 nsections = 3 + is_goto;
8741 for (section = 0; section < nsections; ++section)
8743 if (c_parser_next_token_is (parser, CPP_SCOPE))
8745 ++section;
8746 if (section == nsections)
8748 c_parser_error (parser, "expected %<)%>");
8749 goto error_close_paren;
8751 c_parser_consume_token (parser);
8753 else if (!c_parser_require (parser, CPP_COLON,
8754 is_goto
8755 ? G_("expected %<:%>")
8756 : G_("expected %<:%> or %<)%>"),
8757 UNKNOWN_LOCATION, is_goto))
8758 goto error_close_paren;
8760 /* Once past any colon, we're no longer a simple asm. */
8761 simple = false;
8763 if ((!c_parser_next_token_is (parser, CPP_COLON)
8764 && !c_parser_next_token_is (parser, CPP_SCOPE)
8765 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8766 || section == 3)
8767 switch (section)
8769 case 0:
8770 outputs = c_parser_asm_operands (parser);
8771 break;
8772 case 1:
8773 inputs = c_parser_asm_operands (parser);
8774 break;
8775 case 2:
8776 clobbers = c_parser_asm_clobbers (parser);
8777 break;
8778 case 3:
8779 labels = c_parser_asm_goto_operands (parser);
8780 break;
8781 default:
8782 gcc_unreachable ();
8785 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
8786 goto done_asm;
8789 done_asm:
8790 if (!parens.require_close (parser))
8792 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8793 goto error;
8796 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
8797 c_parser_skip_to_end_of_block_or_statement (parser);
8799 ret = build_asm_stmt (is_volatile,
8800 build_asm_expr (asm_loc, str, outputs, inputs,
8801 clobbers, labels, simple, is_inline));
8803 error:
8804 return ret;
8806 error_close_paren:
8807 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8808 goto error;
8811 /* Parse asm operands, a GNU extension.
8813 asm-operands:
8814 asm-operand
8815 asm-operands , asm-operand
8817 asm-operand:
8818 asm-string-literal ( expression )
8819 [ identifier ] asm-string-literal ( expression )
8822 static tree
8823 c_parser_asm_operands (c_parser *parser)
8825 tree list = NULL_TREE;
8826 while (true)
8828 tree name, str;
8829 struct c_expr expr;
8830 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
8832 c_parser_consume_token (parser);
8833 if (c_parser_next_token_is (parser, CPP_NAME))
8835 tree id = c_parser_peek_token (parser)->value;
8836 c_parser_consume_token (parser);
8837 name = build_string (IDENTIFIER_LENGTH (id),
8838 IDENTIFIER_POINTER (id));
8840 else
8842 c_parser_error (parser, "expected identifier");
8843 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
8844 return NULL_TREE;
8846 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
8847 "expected %<]%>");
8849 else
8850 name = NULL_TREE;
8851 str = c_parser_asm_string_literal (parser);
8852 if (str == NULL_TREE)
8853 return NULL_TREE;
8854 matching_parens parens;
8855 if (!parens.require_open (parser))
8856 return NULL_TREE;
8857 expr = c_parser_expression (parser);
8858 mark_exp_read (expr.value);
8859 if (!parens.require_close (parser))
8861 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8862 return NULL_TREE;
8864 list = chainon (list, build_tree_list (build_tree_list (name, str),
8865 expr.value));
8866 if (c_parser_next_token_is (parser, CPP_COMMA))
8867 c_parser_consume_token (parser);
8868 else
8869 break;
8871 return list;
8874 /* Parse asm clobbers, a GNU extension.
8876 asm-clobbers:
8877 asm-string-literal
8878 asm-clobbers , asm-string-literal
8881 static tree
8882 c_parser_asm_clobbers (c_parser *parser)
8884 tree list = NULL_TREE;
8885 while (true)
8887 tree str = c_parser_asm_string_literal (parser);
8888 if (str)
8889 list = tree_cons (NULL_TREE, str, list);
8890 else
8891 return NULL_TREE;
8892 if (c_parser_next_token_is (parser, CPP_COMMA))
8893 c_parser_consume_token (parser);
8894 else
8895 break;
8897 return list;
8900 /* Parse asm goto labels, a GNU extension.
8902 asm-goto-operands:
8903 identifier
8904 asm-goto-operands , identifier
8907 static tree
8908 c_parser_asm_goto_operands (c_parser *parser)
8910 tree list = NULL_TREE;
8911 while (true)
8913 tree name, label;
8915 if (c_parser_next_token_is (parser, CPP_NAME))
8917 c_token *tok = c_parser_peek_token (parser);
8918 name = tok->value;
8919 label = lookup_label_for_goto (tok->location, name);
8920 c_parser_consume_token (parser);
8921 TREE_USED (label) = 1;
8923 else
8925 c_parser_error (parser, "expected identifier");
8926 return NULL_TREE;
8929 name = build_string (IDENTIFIER_LENGTH (name),
8930 IDENTIFIER_POINTER (name));
8931 list = tree_cons (name, label, list);
8932 if (c_parser_next_token_is (parser, CPP_COMMA))
8933 c_parser_consume_token (parser);
8934 else
8935 return nreverse (list);
8939 /* Parse a possibly concatenated sequence of string literals.
8940 TRANSLATE says whether to translate them to the execution character
8941 set; WIDE_OK says whether any kind of prefixed string literal is
8942 permitted in this context. This code is based on that in
8943 lex_string. */
8945 struct c_expr
8946 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
8948 struct c_expr ret;
8949 size_t count;
8950 struct obstack str_ob;
8951 struct obstack loc_ob;
8952 cpp_string str, istr, *strs;
8953 c_token *tok;
8954 location_t loc, last_tok_loc;
8955 enum cpp_ttype type;
8956 tree value, string_tree;
8958 tok = c_parser_peek_token (parser);
8959 loc = tok->location;
8960 last_tok_loc = linemap_resolve_location (line_table, loc,
8961 LRK_MACRO_DEFINITION_LOCATION,
8962 NULL);
8963 type = tok->type;
8964 switch (type)
8966 case CPP_STRING:
8967 case CPP_WSTRING:
8968 case CPP_STRING16:
8969 case CPP_STRING32:
8970 case CPP_UTF8STRING:
8971 string_tree = tok->value;
8972 break;
8974 default:
8975 c_parser_error (parser, "expected string literal");
8976 ret.set_error ();
8977 ret.value = NULL_TREE;
8978 ret.original_code = ERROR_MARK;
8979 ret.original_type = NULL_TREE;
8980 return ret;
8983 /* Try to avoid the overhead of creating and destroying an obstack
8984 for the common case of just one string. */
8985 switch (c_parser_peek_2nd_token (parser)->type)
8987 default:
8988 c_parser_consume_token (parser);
8989 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
8990 str.len = TREE_STRING_LENGTH (string_tree);
8991 count = 1;
8992 strs = &str;
8993 break;
8995 case CPP_STRING:
8996 case CPP_WSTRING:
8997 case CPP_STRING16:
8998 case CPP_STRING32:
8999 case CPP_UTF8STRING:
9000 gcc_obstack_init (&str_ob);
9001 gcc_obstack_init (&loc_ob);
9002 count = 0;
9005 c_parser_consume_token (parser);
9006 count++;
9007 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
9008 str.len = TREE_STRING_LENGTH (string_tree);
9009 if (type != tok->type)
9011 if (type == CPP_STRING)
9012 type = tok->type;
9013 else if (tok->type != CPP_STRING)
9014 error ("unsupported non-standard concatenation "
9015 "of string literals");
9017 obstack_grow (&str_ob, &str, sizeof (cpp_string));
9018 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
9019 tok = c_parser_peek_token (parser);
9020 string_tree = tok->value;
9021 last_tok_loc
9022 = linemap_resolve_location (line_table, tok->location,
9023 LRK_MACRO_DEFINITION_LOCATION, NULL);
9025 while (tok->type == CPP_STRING
9026 || tok->type == CPP_WSTRING
9027 || tok->type == CPP_STRING16
9028 || tok->type == CPP_STRING32
9029 || tok->type == CPP_UTF8STRING);
9030 strs = (cpp_string *) obstack_finish (&str_ob);
9033 if (count > 1 && !in_system_header_at (input_location))
9034 warning (OPT_Wtraditional,
9035 "traditional C rejects string constant concatenation");
9037 if ((type == CPP_STRING || wide_ok)
9038 && ((translate
9039 ? cpp_interpret_string : cpp_interpret_string_notranslate)
9040 (parse_in, strs, count, &istr, type)))
9042 value = build_string (istr.len, (const char *) istr.text);
9043 free (CONST_CAST (unsigned char *, istr.text));
9044 if (count > 1)
9046 location_t *locs = (location_t *) obstack_finish (&loc_ob);
9047 gcc_assert (g_string_concat_db);
9048 g_string_concat_db->record_string_concatenation (count, locs);
9051 else
9053 if (type != CPP_STRING && !wide_ok)
9055 error_at (loc, "a wide string is invalid in this context");
9056 type = CPP_STRING;
9058 /* Callers cannot generally handle error_mark_node in this
9059 context, so return the empty string instead. An error has
9060 been issued, either above or from cpp_interpret_string. */
9061 switch (type)
9063 default:
9064 case CPP_STRING:
9065 case CPP_UTF8STRING:
9066 if (type == CPP_UTF8STRING && flag_char8_t)
9068 value = build_string (TYPE_PRECISION (char8_type_node)
9069 / TYPE_PRECISION (char_type_node),
9070 ""); /* char8_t is 8 bits */
9072 else
9073 value = build_string (1, "");
9074 break;
9075 case CPP_STRING16:
9076 value = build_string (TYPE_PRECISION (char16_type_node)
9077 / TYPE_PRECISION (char_type_node),
9078 "\0"); /* char16_t is 16 bits */
9079 break;
9080 case CPP_STRING32:
9081 value = build_string (TYPE_PRECISION (char32_type_node)
9082 / TYPE_PRECISION (char_type_node),
9083 "\0\0\0"); /* char32_t is 32 bits */
9084 break;
9085 case CPP_WSTRING:
9086 value = build_string (TYPE_PRECISION (wchar_type_node)
9087 / TYPE_PRECISION (char_type_node),
9088 "\0\0\0"); /* widest supported wchar_t
9089 is 32 bits */
9090 break;
9094 switch (type)
9096 default:
9097 case CPP_STRING:
9098 TREE_TYPE (value) = char_array_type_node;
9099 break;
9100 case CPP_UTF8STRING:
9101 if (flag_char8_t)
9102 TREE_TYPE (value) = char8_array_type_node;
9103 else
9104 TREE_TYPE (value) = char_array_type_node;
9105 break;
9106 case CPP_STRING16:
9107 TREE_TYPE (value) = char16_array_type_node;
9108 break;
9109 case CPP_STRING32:
9110 TREE_TYPE (value) = char32_array_type_node;
9111 break;
9112 case CPP_WSTRING:
9113 TREE_TYPE (value) = wchar_array_type_node;
9115 value = fix_string_type (value);
9117 if (count > 1)
9119 obstack_free (&str_ob, 0);
9120 obstack_free (&loc_ob, 0);
9123 ret.value = value;
9124 ret.original_code = STRING_CST;
9125 ret.original_type = NULL_TREE;
9126 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
9127 ret.m_decimal = 0;
9128 parser->seen_string_literal = true;
9129 return ret;
9132 /* Parse an expression other than a compound expression; that is, an
9133 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
9134 AFTER is not NULL then it is an Objective-C message expression which
9135 is the primary-expression starting the expression as an initializer.
9137 assignment-expression:
9138 conditional-expression
9139 unary-expression assignment-operator assignment-expression
9141 assignment-operator: one of
9142 = *= /= %= += -= <<= >>= &= ^= |=
9144 In GNU C we accept any conditional expression on the LHS and
9145 diagnose the invalid lvalue rather than producing a syntax
9146 error. */
9148 static struct c_expr
9149 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
9150 tree omp_atomic_lhs)
9152 struct c_expr lhs, rhs, ret;
9153 enum tree_code code;
9154 location_t op_location, exp_location;
9155 bool save_in_omp_for = c_in_omp_for;
9156 c_in_omp_for = false;
9157 gcc_assert (!after || c_dialect_objc ());
9158 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
9159 op_location = c_parser_peek_token (parser)->location;
9160 switch (c_parser_peek_token (parser)->type)
9162 case CPP_EQ:
9163 code = NOP_EXPR;
9164 break;
9165 case CPP_MULT_EQ:
9166 code = MULT_EXPR;
9167 break;
9168 case CPP_DIV_EQ:
9169 code = TRUNC_DIV_EXPR;
9170 break;
9171 case CPP_MOD_EQ:
9172 code = TRUNC_MOD_EXPR;
9173 break;
9174 case CPP_PLUS_EQ:
9175 code = PLUS_EXPR;
9176 break;
9177 case CPP_MINUS_EQ:
9178 code = MINUS_EXPR;
9179 break;
9180 case CPP_LSHIFT_EQ:
9181 code = LSHIFT_EXPR;
9182 break;
9183 case CPP_RSHIFT_EQ:
9184 code = RSHIFT_EXPR;
9185 break;
9186 case CPP_AND_EQ:
9187 code = BIT_AND_EXPR;
9188 break;
9189 case CPP_XOR_EQ:
9190 code = BIT_XOR_EXPR;
9191 break;
9192 case CPP_OR_EQ:
9193 code = BIT_IOR_EXPR;
9194 break;
9195 default:
9196 c_in_omp_for = save_in_omp_for;
9197 return lhs;
9199 c_parser_consume_token (parser);
9200 exp_location = c_parser_peek_token (parser)->location;
9201 rhs = c_parser_expr_no_commas (parser, NULL);
9202 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
9204 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
9205 code, exp_location, rhs.value,
9206 rhs.original_type);
9207 ret.m_decimal = 0;
9208 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
9209 if (code == NOP_EXPR)
9210 ret.original_code = MODIFY_EXPR;
9211 else
9213 suppress_warning (ret.value, OPT_Wparentheses);
9214 ret.original_code = ERROR_MARK;
9216 ret.original_type = NULL;
9217 c_in_omp_for = save_in_omp_for;
9218 return ret;
9221 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
9222 AFTER is not NULL then it is an Objective-C message expression which is
9223 the primary-expression starting the expression as an initializer.
9225 conditional-expression:
9226 logical-OR-expression
9227 logical-OR-expression ? expression : conditional-expression
9229 GNU extensions:
9231 conditional-expression:
9232 logical-OR-expression ? : conditional-expression
9235 static struct c_expr
9236 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
9237 tree omp_atomic_lhs)
9239 struct c_expr cond, exp1, exp2, ret;
9240 location_t start, cond_loc, colon_loc;
9241 bool save_c_omp_array_section_p = c_omp_array_section_p;
9243 gcc_assert (!after || c_dialect_objc ());
9245 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
9247 if (c_parser_next_token_is_not (parser, CPP_QUERY))
9248 return cond;
9249 c_omp_array_section_p = false;
9250 if (cond.value != error_mark_node)
9251 start = cond.get_start ();
9252 else
9253 start = UNKNOWN_LOCATION;
9254 cond_loc = c_parser_peek_token (parser)->location;
9255 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
9256 c_parser_consume_token (parser);
9257 if (c_parser_next_token_is (parser, CPP_COLON))
9259 tree eptype = NULL_TREE;
9261 location_t middle_loc = c_parser_peek_token (parser)->location;
9262 pedwarn (middle_loc, OPT_Wpedantic,
9263 "ISO C forbids omitting the middle term of a %<?:%> expression");
9264 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
9266 eptype = TREE_TYPE (cond.value);
9267 cond.value = TREE_OPERAND (cond.value, 0);
9269 tree e = cond.value;
9270 while (TREE_CODE (e) == COMPOUND_EXPR)
9271 e = TREE_OPERAND (e, 1);
9272 warn_for_omitted_condop (middle_loc, e);
9273 /* Make sure first operand is calculated only once. */
9274 exp1.value = save_expr (default_conversion (cond.value));
9275 if (eptype)
9276 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
9277 exp1.original_type = NULL;
9278 exp1.src_range = cond.src_range;
9279 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
9280 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
9282 else
9284 cond.value
9285 = c_objc_common_truthvalue_conversion
9286 (cond_loc, default_conversion (cond.value));
9287 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
9288 exp1 = c_parser_expression_conv (parser);
9289 mark_exp_read (exp1.value);
9290 c_inhibit_evaluation_warnings +=
9291 ((cond.value == truthvalue_true_node)
9292 - (cond.value == truthvalue_false_node));
9295 colon_loc = c_parser_peek_token (parser)->location;
9296 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
9298 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
9299 ret.set_error ();
9300 ret.original_code = ERROR_MARK;
9301 ret.original_type = NULL;
9302 c_omp_array_section_p = save_c_omp_array_section_p;
9303 return ret;
9306 location_t exp2_loc = c_parser_peek_token (parser)->location;
9307 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
9308 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
9310 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
9311 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
9312 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
9313 if (UNLIKELY (omp_atomic_lhs != NULL)
9314 && (TREE_CODE (cond.value) == GT_EXPR
9315 || TREE_CODE (cond.value) == LT_EXPR
9316 || TREE_CODE (cond.value) == EQ_EXPR)
9317 && c_tree_equal (exp2.value, omp_atomic_lhs)
9318 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
9319 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
9320 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
9321 cond.value, exp1.value, exp2.value);
9322 else
9323 ret.value
9324 = build_conditional_expr (colon_loc, cond.value,
9325 cond.original_code == C_MAYBE_CONST_EXPR,
9326 exp1.value, exp1.original_type, loc1,
9327 exp2.value, exp2.original_type, loc2);
9328 ret.original_code = ERROR_MARK;
9329 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
9330 ret.original_type = NULL;
9331 else
9333 tree t1, t2;
9335 /* If both sides are enum type, the default conversion will have
9336 made the type of the result be an integer type. We want to
9337 remember the enum types we started with. */
9338 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
9339 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
9340 ret.original_type = ((t1 != error_mark_node
9341 && t2 != error_mark_node
9342 && (TYPE_MAIN_VARIANT (t1)
9343 == TYPE_MAIN_VARIANT (t2)))
9344 ? t1
9345 : NULL);
9347 set_c_expr_source_range (&ret, start, exp2.get_finish ());
9348 ret.m_decimal = 0;
9349 c_omp_array_section_p = save_c_omp_array_section_p;
9350 return ret;
9353 /* Parse a binary expression; that is, a logical-OR-expression (C90
9354 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
9355 NULL then it is an Objective-C message expression which is the
9356 primary-expression starting the expression as an initializer.
9358 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
9359 when it should be the unfolded lhs. In a valid OpenMP source,
9360 one of the operands of the toplevel binary expression must be equal
9361 to it. In that case, just return a build2 created binary operation
9362 rather than result of parser_build_binary_op.
9364 multiplicative-expression:
9365 cast-expression
9366 multiplicative-expression * cast-expression
9367 multiplicative-expression / cast-expression
9368 multiplicative-expression % cast-expression
9370 additive-expression:
9371 multiplicative-expression
9372 additive-expression + multiplicative-expression
9373 additive-expression - multiplicative-expression
9375 shift-expression:
9376 additive-expression
9377 shift-expression << additive-expression
9378 shift-expression >> additive-expression
9380 relational-expression:
9381 shift-expression
9382 relational-expression < shift-expression
9383 relational-expression > shift-expression
9384 relational-expression <= shift-expression
9385 relational-expression >= shift-expression
9387 equality-expression:
9388 relational-expression
9389 equality-expression == relational-expression
9390 equality-expression != relational-expression
9392 AND-expression:
9393 equality-expression
9394 AND-expression & equality-expression
9396 exclusive-OR-expression:
9397 AND-expression
9398 exclusive-OR-expression ^ AND-expression
9400 inclusive-OR-expression:
9401 exclusive-OR-expression
9402 inclusive-OR-expression | exclusive-OR-expression
9404 logical-AND-expression:
9405 inclusive-OR-expression
9406 logical-AND-expression && inclusive-OR-expression
9408 logical-OR-expression:
9409 logical-AND-expression
9410 logical-OR-expression || logical-AND-expression
9413 static struct c_expr
9414 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
9415 tree omp_atomic_lhs)
9417 /* A binary expression is parsed using operator-precedence parsing,
9418 with the operands being cast expressions. All the binary
9419 operators are left-associative. Thus a binary expression is of
9420 form:
9422 E0 op1 E1 op2 E2 ...
9424 which we represent on a stack. On the stack, the precedence
9425 levels are strictly increasing. When a new operator is
9426 encountered of higher precedence than that at the top of the
9427 stack, it is pushed; its LHS is the top expression, and its RHS
9428 is everything parsed until it is popped. When a new operator is
9429 encountered with precedence less than or equal to that at the top
9430 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
9431 by the result of the operation until the operator at the top of
9432 the stack has lower precedence than the new operator or there is
9433 only one element on the stack; then the top expression is the LHS
9434 of the new operator. In the case of logical AND and OR
9435 expressions, we also need to adjust c_inhibit_evaluation_warnings
9436 as appropriate when the operators are pushed and popped. */
9438 struct {
9439 /* The expression at this stack level. */
9440 struct c_expr expr;
9441 /* The precedence of the operator on its left, PREC_NONE at the
9442 bottom of the stack. */
9443 enum c_parser_prec prec;
9444 /* The operation on its left. */
9445 enum tree_code op;
9446 /* The source location of this operation. */
9447 location_t loc;
9448 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
9449 tree sizeof_arg;
9450 } stack[NUM_PRECS];
9451 int sp;
9452 /* Location of the binary operator. */
9453 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
9454 #define POP \
9455 do { \
9456 switch (stack[sp].op) \
9458 case TRUTH_ANDIF_EXPR: \
9459 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9460 == truthvalue_false_node); \
9461 break; \
9462 case TRUTH_ORIF_EXPR: \
9463 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9464 == truthvalue_true_node); \
9465 break; \
9466 case TRUNC_DIV_EXPR: \
9467 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
9468 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
9469 && (stack[sp].expr.original_code == SIZEOF_EXPR \
9470 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
9472 tree type0 = stack[sp - 1].sizeof_arg; \
9473 tree type1 = stack[sp].sizeof_arg; \
9474 tree first_arg = type0; \
9475 if (!TYPE_P (type0)) \
9476 type0 = TREE_TYPE (type0); \
9477 if (!TYPE_P (type1)) \
9478 type1 = TREE_TYPE (type1); \
9479 if (POINTER_TYPE_P (type0) \
9480 && comptypes (TREE_TYPE (type0), type1) \
9481 && !(TREE_CODE (first_arg) == PARM_DECL \
9482 && C_ARRAY_PARAMETER (first_arg) \
9483 && warn_sizeof_array_argument)) \
9485 auto_diagnostic_group d; \
9486 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
9487 "division %<sizeof (%T) / sizeof (%T)%> " \
9488 "does not compute the number of array " \
9489 "elements", \
9490 type0, type1)) \
9491 if (DECL_P (first_arg)) \
9492 inform (DECL_SOURCE_LOCATION (first_arg), \
9493 "first %<sizeof%> operand was declared here"); \
9495 else if (TREE_CODE (type0) == ARRAY_TYPE \
9496 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
9497 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
9498 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
9499 stack[sp].sizeof_arg, type1); \
9501 break; \
9502 default: \
9503 break; \
9505 stack[sp - 1].expr \
9506 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
9507 stack[sp - 1].expr, true, true); \
9508 stack[sp].expr \
9509 = convert_lvalue_to_rvalue (stack[sp].loc, \
9510 stack[sp].expr, true, true); \
9511 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
9512 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
9513 && ((1 << stack[sp].prec) \
9514 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
9515 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
9516 | (1 << PREC_ADD) | (1 << PREC_MULT) \
9517 | (1 << PREC_EQ)))) \
9518 || ((c_parser_next_token_is (parser, CPP_QUERY) \
9519 || (omp_atomic_lhs == void_list_node \
9520 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
9521 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
9522 && stack[sp].op != TRUNC_MOD_EXPR \
9523 && stack[sp].op != GE_EXPR \
9524 && stack[sp].op != LE_EXPR \
9525 && stack[sp].op != NE_EXPR \
9526 && stack[0].expr.value != error_mark_node \
9527 && stack[1].expr.value != error_mark_node \
9528 && (omp_atomic_lhs == void_list_node \
9529 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
9530 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
9531 || (stack[sp].op == EQ_EXPR \
9532 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
9534 tree t = make_node (stack[1].op); \
9535 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
9536 TREE_OPERAND (t, 0) = stack[0].expr.value; \
9537 TREE_OPERAND (t, 1) = stack[1].expr.value; \
9538 stack[0].expr.value = t; \
9539 stack[0].expr.m_decimal = 0; \
9541 else \
9542 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
9543 stack[sp].op, \
9544 stack[sp - 1].expr, \
9545 stack[sp].expr); \
9546 sp--; \
9547 } while (0)
9548 gcc_assert (!after || c_dialect_objc ());
9549 stack[0].loc = c_parser_peek_token (parser)->location;
9550 stack[0].expr = c_parser_cast_expression (parser, after);
9551 stack[0].prec = PREC_NONE;
9552 stack[0].sizeof_arg = c_last_sizeof_arg;
9553 sp = 0;
9554 while (true)
9556 enum c_parser_prec oprec;
9557 enum tree_code ocode;
9558 source_range src_range;
9559 if (parser->error)
9560 goto out;
9561 switch (c_parser_peek_token (parser)->type)
9563 case CPP_MULT:
9564 oprec = PREC_MULT;
9565 ocode = MULT_EXPR;
9566 break;
9567 case CPP_DIV:
9568 oprec = PREC_MULT;
9569 ocode = TRUNC_DIV_EXPR;
9570 break;
9571 case CPP_MOD:
9572 oprec = PREC_MULT;
9573 ocode = TRUNC_MOD_EXPR;
9574 break;
9575 case CPP_PLUS:
9576 oprec = PREC_ADD;
9577 ocode = PLUS_EXPR;
9578 break;
9579 case CPP_MINUS:
9580 oprec = PREC_ADD;
9581 ocode = MINUS_EXPR;
9582 break;
9583 case CPP_LSHIFT:
9584 oprec = PREC_SHIFT;
9585 ocode = LSHIFT_EXPR;
9586 break;
9587 case CPP_RSHIFT:
9588 oprec = PREC_SHIFT;
9589 ocode = RSHIFT_EXPR;
9590 break;
9591 case CPP_LESS:
9592 oprec = PREC_REL;
9593 ocode = LT_EXPR;
9594 break;
9595 case CPP_GREATER:
9596 oprec = PREC_REL;
9597 ocode = GT_EXPR;
9598 break;
9599 case CPP_LESS_EQ:
9600 oprec = PREC_REL;
9601 ocode = LE_EXPR;
9602 break;
9603 case CPP_GREATER_EQ:
9604 oprec = PREC_REL;
9605 ocode = GE_EXPR;
9606 break;
9607 case CPP_EQ_EQ:
9608 oprec = PREC_EQ;
9609 ocode = EQ_EXPR;
9610 break;
9611 case CPP_NOT_EQ:
9612 oprec = PREC_EQ;
9613 ocode = NE_EXPR;
9614 break;
9615 case CPP_AND:
9616 oprec = PREC_BITAND;
9617 ocode = BIT_AND_EXPR;
9618 break;
9619 case CPP_XOR:
9620 oprec = PREC_BITXOR;
9621 ocode = BIT_XOR_EXPR;
9622 break;
9623 case CPP_OR:
9624 oprec = PREC_BITOR;
9625 ocode = BIT_IOR_EXPR;
9626 break;
9627 case CPP_AND_AND:
9628 oprec = PREC_LOGAND;
9629 ocode = TRUTH_ANDIF_EXPR;
9630 break;
9631 case CPP_OR_OR:
9632 oprec = PREC_LOGOR;
9633 ocode = TRUTH_ORIF_EXPR;
9634 break;
9635 default:
9636 /* Not a binary operator, so end of the binary
9637 expression. */
9638 goto out;
9640 binary_loc = c_parser_peek_token (parser)->location;
9641 while (oprec <= stack[sp].prec)
9642 POP;
9643 c_parser_consume_token (parser);
9644 switch (ocode)
9646 case TRUTH_ANDIF_EXPR:
9647 src_range = stack[sp].expr.src_range;
9648 stack[sp].expr
9649 = convert_lvalue_to_rvalue (stack[sp].loc,
9650 stack[sp].expr, true, true);
9651 stack[sp].expr.value = c_objc_common_truthvalue_conversion
9652 (stack[sp].loc, default_conversion (stack[sp].expr.value));
9653 c_inhibit_evaluation_warnings += (stack[sp].expr.value
9654 == truthvalue_false_node);
9655 set_c_expr_source_range (&stack[sp].expr, src_range);
9656 break;
9657 case TRUTH_ORIF_EXPR:
9658 src_range = stack[sp].expr.src_range;
9659 stack[sp].expr
9660 = convert_lvalue_to_rvalue (stack[sp].loc,
9661 stack[sp].expr, true, true);
9662 stack[sp].expr.value = c_objc_common_truthvalue_conversion
9663 (stack[sp].loc, default_conversion (stack[sp].expr.value));
9664 c_inhibit_evaluation_warnings += (stack[sp].expr.value
9665 == truthvalue_true_node);
9666 set_c_expr_source_range (&stack[sp].expr, src_range);
9667 break;
9668 default:
9669 break;
9671 sp++;
9672 stack[sp].loc = binary_loc;
9673 stack[sp].expr = c_parser_cast_expression (parser, NULL);
9674 stack[sp].prec = oprec;
9675 stack[sp].op = ocode;
9676 stack[sp].sizeof_arg = c_last_sizeof_arg;
9678 out:
9679 while (sp > 0)
9680 POP;
9681 return stack[0].expr;
9682 #undef POP
9685 /* Parse any storage class specifiers after an open parenthesis in a
9686 context where a compound literal is permitted. */
9688 static struct c_declspecs *
9689 c_parser_compound_literal_scspecs (c_parser *parser)
9691 bool seen_scspec = false;
9692 struct c_declspecs *specs = build_null_declspecs ();
9693 while (c_parser_next_token_is (parser, CPP_KEYWORD))
9695 switch (c_parser_peek_token (parser)->keyword)
9697 case RID_CONSTEXPR:
9698 case RID_REGISTER:
9699 case RID_STATIC:
9700 case RID_THREAD:
9701 seen_scspec = true;
9702 declspecs_add_scspec (c_parser_peek_token (parser)->location,
9703 specs, c_parser_peek_token (parser)->value);
9704 c_parser_consume_token (parser);
9705 break;
9706 default:
9707 goto out;
9710 out:
9711 return seen_scspec ? specs : NULL;
9714 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
9715 is not NULL then it is an Objective-C message expression which is the
9716 primary-expression starting the expression as an initializer.
9718 cast-expression:
9719 unary-expression
9720 ( type-name ) unary-expression
9723 static struct c_expr
9724 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
9726 location_t cast_loc = c_parser_peek_token (parser)->location;
9727 gcc_assert (!after || c_dialect_objc ());
9728 if (after)
9729 return c_parser_postfix_expression_after_primary (parser,
9730 cast_loc, *after);
9731 /* If the expression begins with a parenthesized type name, it may
9732 be either a cast or a compound literal; we need to see whether
9733 the next character is '{' to tell the difference. If not, it is
9734 an unary expression. Full detection of unknown typenames here
9735 would require a 3-token lookahead. */
9736 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9737 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9739 struct c_declspecs *scspecs;
9740 struct c_type_name *type_name;
9741 struct c_expr ret;
9742 struct c_expr expr;
9743 matching_parens parens;
9744 parens.consume_open (parser);
9745 scspecs = c_parser_compound_literal_scspecs (parser);
9746 type_name = c_parser_type_name (parser, true);
9747 parens.skip_until_found_close (parser);
9748 if (type_name == NULL)
9750 ret.set_error ();
9751 ret.original_code = ERROR_MARK;
9752 ret.original_type = NULL;
9753 return ret;
9756 /* Save casted types in the function's used types hash table. */
9757 used_types_insert (type_name->specs->type);
9759 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9760 return c_parser_postfix_expression_after_paren_type (parser, scspecs,
9761 type_name,
9762 cast_loc);
9763 if (scspecs)
9764 error_at (cast_loc, "storage class specifier in cast");
9765 if (type_name->specs->alignas_p)
9766 error_at (type_name->specs->locations[cdw_alignas],
9767 "alignment specified for type name in cast");
9769 location_t expr_loc = c_parser_peek_token (parser)->location;
9770 expr = c_parser_cast_expression (parser, NULL);
9771 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
9773 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
9774 if (ret.value && expr.value)
9775 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
9776 ret.original_code = ERROR_MARK;
9777 ret.original_type = NULL;
9778 ret.m_decimal = 0;
9779 return ret;
9781 else
9782 return c_parser_unary_expression (parser);
9785 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
9787 unary-expression:
9788 postfix-expression
9789 ++ unary-expression
9790 -- unary-expression
9791 unary-operator cast-expression
9792 sizeof unary-expression
9793 sizeof ( type-name )
9795 unary-operator: one of
9796 & * + - ~ !
9798 GNU extensions:
9800 unary-expression:
9801 __alignof__ unary-expression
9802 __alignof__ ( type-name )
9803 && identifier
9805 (C11 permits _Alignof with type names only.)
9807 unary-operator: one of
9808 __extension__ __real__ __imag__
9810 Transactional Memory:
9812 unary-expression:
9813 transaction-expression
9815 In addition, the GNU syntax treats ++ and -- as unary operators, so
9816 they may be applied to cast expressions with errors for non-lvalues
9817 given later. */
9819 static struct c_expr
9820 c_parser_unary_expression (c_parser *parser)
9822 int ext;
9823 struct c_expr ret, op;
9824 location_t op_loc = c_parser_peek_token (parser)->location;
9825 location_t exp_loc;
9826 location_t finish;
9827 ret.original_code = ERROR_MARK;
9828 ret.original_type = NULL;
9829 switch (c_parser_peek_token (parser)->type)
9831 case CPP_PLUS_PLUS:
9832 c_parser_consume_token (parser);
9833 exp_loc = c_parser_peek_token (parser)->location;
9834 op = c_parser_cast_expression (parser, NULL);
9836 op = default_function_array_read_conversion (exp_loc, op);
9837 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
9838 case CPP_MINUS_MINUS:
9839 c_parser_consume_token (parser);
9840 exp_loc = c_parser_peek_token (parser)->location;
9841 op = c_parser_cast_expression (parser, NULL);
9843 op = default_function_array_read_conversion (exp_loc, op);
9844 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
9845 case CPP_AND:
9846 c_parser_consume_token (parser);
9847 op = c_parser_cast_expression (parser, NULL);
9848 mark_exp_read (op.value);
9849 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
9850 case CPP_MULT:
9852 c_parser_consume_token (parser);
9853 exp_loc = c_parser_peek_token (parser)->location;
9854 op = c_parser_cast_expression (parser, NULL);
9855 finish = op.get_finish ();
9856 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9857 location_t combined_loc = make_location (op_loc, op_loc, finish);
9858 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
9859 ret.src_range.m_start = op_loc;
9860 ret.src_range.m_finish = finish;
9861 ret.m_decimal = 0;
9862 return ret;
9864 case CPP_PLUS:
9865 if (!c_dialect_objc () && !in_system_header_at (input_location))
9866 warning_at (op_loc,
9867 OPT_Wtraditional,
9868 "traditional C rejects the unary plus operator");
9869 c_parser_consume_token (parser);
9870 exp_loc = c_parser_peek_token (parser)->location;
9871 op = c_parser_cast_expression (parser, NULL);
9872 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9873 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
9874 case CPP_MINUS:
9875 c_parser_consume_token (parser);
9876 exp_loc = c_parser_peek_token (parser)->location;
9877 op = c_parser_cast_expression (parser, NULL);
9878 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9879 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
9880 case CPP_COMPL:
9881 c_parser_consume_token (parser);
9882 exp_loc = c_parser_peek_token (parser)->location;
9883 op = c_parser_cast_expression (parser, NULL);
9884 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9885 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
9886 case CPP_NOT:
9887 c_parser_consume_token (parser);
9888 exp_loc = c_parser_peek_token (parser)->location;
9889 op = c_parser_cast_expression (parser, NULL);
9890 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
9891 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
9892 case CPP_AND_AND:
9893 /* Refer to the address of a label as a pointer. */
9894 c_parser_consume_token (parser);
9895 if (c_parser_next_token_is (parser, CPP_NAME))
9897 ret.value = finish_label_address_expr
9898 (c_parser_peek_token (parser)->value, op_loc);
9899 set_c_expr_source_range (&ret, op_loc,
9900 c_parser_peek_token (parser)->get_finish ());
9901 c_parser_consume_token (parser);
9903 else
9905 c_parser_error (parser, "expected identifier");
9906 ret.set_error ();
9908 return ret;
9909 case CPP_KEYWORD:
9910 switch (c_parser_peek_token (parser)->keyword)
9912 case RID_SIZEOF:
9913 return c_parser_sizeof_expression (parser);
9914 case RID_ALIGNOF:
9915 return c_parser_alignof_expression (parser);
9916 case RID_BUILTIN_HAS_ATTRIBUTE:
9917 return c_parser_has_attribute_expression (parser);
9918 case RID_EXTENSION:
9919 c_parser_consume_token (parser);
9920 ext = disable_extension_diagnostics ();
9921 ret = c_parser_cast_expression (parser, NULL);
9922 restore_extension_diagnostics (ext);
9923 return ret;
9924 case RID_REALPART:
9925 c_parser_consume_token (parser);
9926 exp_loc = c_parser_peek_token (parser)->location;
9927 op = c_parser_cast_expression (parser, NULL);
9928 op = default_function_array_conversion (exp_loc, op);
9929 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
9930 case RID_IMAGPART:
9931 c_parser_consume_token (parser);
9932 exp_loc = c_parser_peek_token (parser)->location;
9933 op = c_parser_cast_expression (parser, NULL);
9934 op = default_function_array_conversion (exp_loc, op);
9935 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
9936 case RID_TRANSACTION_ATOMIC:
9937 case RID_TRANSACTION_RELAXED:
9938 return c_parser_transaction_expression (parser,
9939 c_parser_peek_token (parser)->keyword);
9940 default:
9941 return c_parser_postfix_expression (parser);
9943 default:
9944 return c_parser_postfix_expression (parser);
9948 /* Parse a sizeof expression. */
9950 static struct c_expr
9951 c_parser_sizeof_expression (c_parser *parser)
9953 struct c_expr expr;
9954 struct c_expr result;
9955 location_t expr_loc;
9956 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
9958 location_t start;
9959 location_t finish = UNKNOWN_LOCATION;
9961 start = c_parser_peek_token (parser)->location;
9963 c_parser_consume_token (parser);
9964 c_inhibit_evaluation_warnings++;
9965 in_sizeof++;
9966 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
9967 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
9969 /* Either sizeof ( type-name ) or sizeof unary-expression
9970 starting with a compound literal. */
9971 struct c_declspecs *scspecs;
9972 struct c_type_name *type_name;
9973 matching_parens parens;
9974 parens.consume_open (parser);
9975 expr_loc = c_parser_peek_token (parser)->location;
9976 scspecs = c_parser_compound_literal_scspecs (parser);
9977 type_name = c_parser_type_name (parser, true);
9978 parens.skip_until_found_close (parser);
9979 finish = parser->tokens_buf[0].location;
9980 if (type_name == NULL)
9982 struct c_expr ret;
9983 c_inhibit_evaluation_warnings--;
9984 in_sizeof--;
9985 ret.set_error ();
9986 ret.original_code = ERROR_MARK;
9987 ret.original_type = NULL;
9988 return ret;
9990 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9992 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
9993 type_name,
9994 expr_loc);
9995 finish = expr.get_finish ();
9996 goto sizeof_expr;
9998 /* sizeof ( type-name ). */
9999 if (scspecs)
10000 error_at (expr_loc, "storage class specifier in %<sizeof%>");
10001 if (type_name->specs->alignas_p)
10002 error_at (type_name->specs->locations[cdw_alignas],
10003 "alignment specified for type name in %<sizeof%>");
10004 c_inhibit_evaluation_warnings--;
10005 in_sizeof--;
10006 result = c_expr_sizeof_type (expr_loc, type_name);
10008 else
10010 expr_loc = c_parser_peek_token (parser)->location;
10011 expr = c_parser_unary_expression (parser);
10012 finish = expr.get_finish ();
10013 sizeof_expr:
10014 c_inhibit_evaluation_warnings--;
10015 in_sizeof--;
10016 mark_exp_read (expr.value);
10017 if (TREE_CODE (expr.value) == COMPONENT_REF
10018 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
10019 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
10020 result = c_expr_sizeof_expr (expr_loc, expr);
10022 if (finish == UNKNOWN_LOCATION)
10023 finish = start;
10024 set_c_expr_source_range (&result, start, finish);
10025 return result;
10028 /* Parse an alignof expression. */
10030 static struct c_expr
10031 c_parser_alignof_expression (c_parser *parser)
10033 struct c_expr expr;
10034 location_t start_loc = c_parser_peek_token (parser)->location;
10035 location_t end_loc;
10036 tree alignof_spelling = c_parser_peek_token (parser)->value;
10037 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
10038 bool is_c11_alignof = (strcmp (IDENTIFIER_POINTER (alignof_spelling),
10039 "_Alignof") == 0
10040 || strcmp (IDENTIFIER_POINTER (alignof_spelling),
10041 "alignof") == 0);
10042 /* A diagnostic is not required for the use of this identifier in
10043 the implementation namespace; only diagnose it for the C11 or C23
10044 spelling because of existing code using the other spellings. */
10045 if (is_c11_alignof)
10047 if (flag_isoc99)
10048 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
10049 alignof_spelling);
10050 else
10051 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
10052 alignof_spelling);
10054 c_parser_consume_token (parser);
10055 c_inhibit_evaluation_warnings++;
10056 in_alignof++;
10057 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
10058 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
10060 /* Either __alignof__ ( type-name ) or __alignof__
10061 unary-expression starting with a compound literal. */
10062 location_t loc;
10063 struct c_declspecs *scspecs;
10064 struct c_type_name *type_name;
10065 struct c_expr ret;
10066 matching_parens parens;
10067 parens.consume_open (parser);
10068 loc = c_parser_peek_token (parser)->location;
10069 scspecs = c_parser_compound_literal_scspecs (parser);
10070 type_name = c_parser_type_name (parser, true);
10071 end_loc = c_parser_peek_token (parser)->location;
10072 parens.skip_until_found_close (parser);
10073 if (type_name == NULL)
10075 struct c_expr ret;
10076 c_inhibit_evaluation_warnings--;
10077 in_alignof--;
10078 ret.set_error ();
10079 ret.original_code = ERROR_MARK;
10080 ret.original_type = NULL;
10081 return ret;
10083 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10085 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
10086 type_name,
10087 loc);
10088 goto alignof_expr;
10090 /* alignof ( type-name ). */
10091 if (scspecs)
10092 error_at (loc, "storage class specifier in %qE", alignof_spelling);
10093 if (type_name->specs->alignas_p)
10094 error_at (type_name->specs->locations[cdw_alignas],
10095 "alignment specified for type name in %qE",
10096 alignof_spelling);
10097 c_inhibit_evaluation_warnings--;
10098 in_alignof--;
10099 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
10100 NULL, NULL),
10101 false, is_c11_alignof, 1);
10102 ret.original_code = ERROR_MARK;
10103 ret.original_type = NULL;
10104 set_c_expr_source_range (&ret, start_loc, end_loc);
10105 ret.m_decimal = 0;
10106 return ret;
10108 else
10110 struct c_expr ret;
10111 expr = c_parser_unary_expression (parser);
10112 end_loc = expr.src_range.m_finish;
10113 alignof_expr:
10114 mark_exp_read (expr.value);
10115 c_inhibit_evaluation_warnings--;
10116 in_alignof--;
10117 if (is_c11_alignof)
10118 pedwarn (start_loc,
10119 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
10120 alignof_spelling);
10121 ret.value = c_alignof_expr (start_loc, expr.value);
10122 ret.original_code = ERROR_MARK;
10123 ret.original_type = NULL;
10124 set_c_expr_source_range (&ret, start_loc, end_loc);
10125 ret.m_decimal = 0;
10126 return ret;
10130 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
10131 expression. */
10133 static struct c_expr
10134 c_parser_has_attribute_expression (c_parser *parser)
10136 gcc_assert (c_parser_next_token_is_keyword (parser,
10137 RID_BUILTIN_HAS_ATTRIBUTE));
10138 location_t start = c_parser_peek_token (parser)->location;
10139 c_parser_consume_token (parser);
10141 c_inhibit_evaluation_warnings++;
10143 matching_parens parens;
10144 if (!parens.require_open (parser))
10146 c_inhibit_evaluation_warnings--;
10147 in_typeof--;
10149 struct c_expr result;
10150 result.set_error ();
10151 result.original_code = ERROR_MARK;
10152 result.original_type = NULL;
10153 return result;
10156 /* Treat the type argument the same way as in typeof for the purposes
10157 of warnings. FIXME: Generalize this so the warning refers to
10158 __builtin_has_attribute rather than typeof. */
10159 in_typeof++;
10161 /* The first operand: one of DECL, EXPR, or TYPE. */
10162 tree oper = NULL_TREE;
10163 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
10165 struct c_type_name *tname = c_parser_type_name (parser);
10166 in_typeof--;
10167 if (tname)
10169 oper = groktypename (tname, NULL, NULL);
10170 pop_maybe_used (c_type_variably_modified_p (oper));
10173 else
10175 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
10176 c_inhibit_evaluation_warnings--;
10177 in_typeof--;
10178 if (cexpr.value != error_mark_node)
10180 mark_exp_read (cexpr.value);
10181 oper = cexpr.value;
10182 tree etype = TREE_TYPE (oper);
10183 bool was_vm = c_type_variably_modified_p (etype);
10184 /* This is returned with the type so that when the type is
10185 evaluated, this can be evaluated. */
10186 if (was_vm)
10187 oper = c_fully_fold (oper, false, NULL);
10188 pop_maybe_used (was_vm);
10192 struct c_expr result;
10193 result.original_code = ERROR_MARK;
10194 result.original_type = NULL;
10196 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10198 /* Consume the closing parenthesis if that's the next token
10199 in the likely case the built-in was invoked with fewer
10200 than two arguments. */
10201 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10202 c_parser_consume_token (parser);
10203 c_inhibit_evaluation_warnings--;
10204 result.set_error ();
10205 return result;
10208 bool save_translate_strings_p = parser->translate_strings_p;
10210 location_t atloc = c_parser_peek_token (parser)->location;
10211 /* Parse a single attribute. Require no leading comma and do not
10212 allow empty attributes. */
10213 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
10215 parser->translate_strings_p = save_translate_strings_p;
10217 location_t finish = c_parser_peek_token (parser)->location;
10218 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10219 c_parser_consume_token (parser);
10220 else
10222 c_parser_error (parser, "expected identifier");
10223 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10225 result.set_error ();
10226 return result;
10229 if (!attr)
10231 error_at (atloc, "expected identifier");
10232 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10233 "expected %<)%>");
10234 result.set_error ();
10235 return result;
10238 result.original_code = INTEGER_CST;
10239 result.original_type = boolean_type_node;
10241 if (has_attribute (atloc, oper, attr, default_conversion))
10242 result.value = boolean_true_node;
10243 else
10244 result.value = boolean_false_node;
10246 set_c_expr_source_range (&result, start, finish);
10247 result.m_decimal = 0;
10248 return result;
10251 /* Helper function to read arguments of builtins which are interfaces
10252 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
10253 others. The name of the builtin is passed using BNAME parameter.
10254 Function returns true if there were no errors while parsing and
10255 stores the arguments in CEXPR_LIST. If it returns true,
10256 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
10257 parenthesis. */
10258 static bool
10259 c_parser_get_builtin_args (c_parser *parser, const char *bname,
10260 vec<c_expr_t, va_gc> **ret_cexpr_list,
10261 bool choose_expr_p,
10262 location_t *out_close_paren_loc)
10264 location_t loc = c_parser_peek_token (parser)->location;
10265 vec<c_expr_t, va_gc> *cexpr_list;
10266 c_expr_t expr;
10267 bool saved_force_folding_builtin_constant_p;
10269 *ret_cexpr_list = NULL;
10270 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
10272 error_at (loc, "cannot take address of %qs", bname);
10273 return false;
10276 c_parser_consume_token (parser);
10278 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10280 *out_close_paren_loc = c_parser_peek_token (parser)->location;
10281 c_parser_consume_token (parser);
10282 return true;
10285 saved_force_folding_builtin_constant_p
10286 = force_folding_builtin_constant_p;
10287 force_folding_builtin_constant_p |= choose_expr_p;
10288 expr = c_parser_expr_no_commas (parser, NULL);
10289 force_folding_builtin_constant_p
10290 = saved_force_folding_builtin_constant_p;
10291 vec_alloc (cexpr_list, 1);
10292 vec_safe_push (cexpr_list, expr);
10293 while (c_parser_next_token_is (parser, CPP_COMMA))
10295 c_parser_consume_token (parser);
10296 expr = c_parser_expr_no_commas (parser, NULL);
10297 vec_safe_push (cexpr_list, expr);
10300 *out_close_paren_loc = c_parser_peek_token (parser)->location;
10301 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
10302 return false;
10304 *ret_cexpr_list = cexpr_list;
10305 return true;
10308 /* This represents a single generic-association. */
10310 struct c_generic_association
10312 /* The location of the starting token of the type. */
10313 location_t type_location;
10314 /* The association's type, or NULL_TREE for 'default'. */
10315 tree type;
10316 /* The association's expression. */
10317 struct c_expr expression;
10320 /* Parse a generic-selection. (C11 6.5.1.1).
10322 generic-selection:
10323 _Generic ( generic-controlling-operand , generic-assoc-list )
10325 generic-controlling-operand:
10326 assignment-expression
10327 type-name
10329 (The use of a type-name is new in C2Y.)
10331 generic-assoc-list:
10332 generic-association
10333 generic-assoc-list , generic-association
10335 generic-association:
10336 type-name : assignment-expression
10337 default : assignment-expression
10340 static struct c_expr
10341 c_parser_generic_selection (c_parser *parser)
10343 struct c_expr selector, error_expr;
10344 tree selector_type;
10345 struct c_generic_association matched_assoc;
10346 int match_found = -1;
10347 location_t generic_loc, selector_loc;
10349 error_expr.original_code = ERROR_MARK;
10350 error_expr.original_type = NULL;
10351 error_expr.set_error ();
10352 matched_assoc.type_location = UNKNOWN_LOCATION;
10353 matched_assoc.type = NULL_TREE;
10354 matched_assoc.expression = error_expr;
10356 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
10357 generic_loc = c_parser_peek_token (parser)->location;
10358 c_parser_consume_token (parser);
10359 if (flag_isoc99)
10360 pedwarn_c99 (generic_loc, OPT_Wpedantic,
10361 "ISO C99 does not support %<_Generic%>");
10362 else
10363 pedwarn_c99 (generic_loc, OPT_Wpedantic,
10364 "ISO C90 does not support %<_Generic%>");
10366 matching_parens parens;
10367 if (!parens.require_open (parser))
10368 return error_expr;
10370 selector_loc = c_parser_peek_token (parser)->location;
10371 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
10373 c_inhibit_evaluation_warnings++;
10374 pedwarn_c23 (selector_loc, OPT_Wpedantic,
10375 "ISO C does not support use of type name as %<_Generic%> "
10376 "controlling operand before C2Y");
10377 struct c_type_name *type = c_parser_type_name (parser);
10378 selector_type = groktypename (type, NULL, NULL);
10379 c_inhibit_evaluation_warnings--;
10381 else
10383 c_inhibit_evaluation_warnings++;
10384 selector = c_parser_expr_no_commas (parser, NULL);
10385 selector = default_function_array_conversion (selector_loc, selector);
10386 c_inhibit_evaluation_warnings--;
10388 if (selector.value == error_mark_node)
10390 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10391 return selector;
10393 mark_exp_read (selector.value);
10394 selector_type = TREE_TYPE (selector.value);
10395 /* In ISO C terms, rvalues (including the controlling expression
10396 of _Generic) do not have qualified types. */
10397 if (TREE_CODE (selector_type) != ARRAY_TYPE)
10398 selector_type = TYPE_MAIN_VARIANT (selector_type);
10399 /* In ISO C terms, _Noreturn is not part of the type of expressions
10400 such as &abort, but in GCC it is represented internally as a type
10401 qualifier. */
10402 if (FUNCTION_POINTER_TYPE_P (selector_type)
10403 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
10404 selector_type
10405 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
10408 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10410 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10411 return error_expr;
10414 auto_vec<c_generic_association> associations;
10415 while (1)
10417 struct c_generic_association assoc, *iter;
10418 unsigned int ix;
10419 c_token *token = c_parser_peek_token (parser);
10421 assoc.type_location = token->location;
10422 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
10424 c_parser_consume_token (parser);
10425 assoc.type = NULL_TREE;
10427 else
10429 struct c_type_name *type_name;
10431 type_name = c_parser_type_name (parser);
10432 if (type_name == NULL)
10434 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10435 return error_expr;
10437 assoc.type = groktypename (type_name, NULL, NULL);
10438 if (assoc.type == error_mark_node)
10440 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10441 return error_expr;
10444 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
10445 pedwarn_c23 (assoc.type_location, OPT_Wpedantic,
10446 "ISO C does not support %<_Generic%> association with "
10447 "function type before C2Y");
10448 else if (!COMPLETE_TYPE_P (assoc.type))
10449 pedwarn_c23 (assoc.type_location, OPT_Wpedantic,
10450 "ISO C does not support %<_Generic%> association with "
10451 "incomplete type before C2Y");
10453 if (c_type_variably_modified_p (assoc.type))
10454 error_at (assoc.type_location,
10455 "%<_Generic%> association has "
10456 "variable length type");
10459 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
10461 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10462 return error_expr;
10465 bool match = assoc.type == NULL_TREE
10466 || comptypes (assoc.type, selector_type);
10468 if (!match)
10469 c_inhibit_evaluation_warnings++;
10471 assoc.expression = c_parser_expr_no_commas (parser, NULL);
10473 if (!match)
10474 c_inhibit_evaluation_warnings--;
10476 if (assoc.expression.value == error_mark_node)
10478 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10479 return error_expr;
10482 for (ix = 0; associations.iterate (ix, &iter); ++ix)
10484 if (assoc.type == NULL_TREE)
10486 if (iter->type == NULL_TREE)
10488 error_at (assoc.type_location,
10489 "duplicate %<default%> case in %<_Generic%>");
10490 inform (iter->type_location, "original %<default%> is here");
10493 else if (iter->type != NULL_TREE)
10495 if (comptypes (assoc.type, iter->type))
10497 error_at (assoc.type_location,
10498 "%<_Generic%> specifies two compatible types");
10499 inform (iter->type_location, "compatible type is here");
10504 if (assoc.type == NULL_TREE)
10506 if (match_found < 0)
10508 matched_assoc = assoc;
10509 match_found = associations.length ();
10512 else if (match)
10514 if (match_found < 0 || matched_assoc.type == NULL_TREE)
10516 matched_assoc = assoc;
10517 match_found = associations.length ();
10519 else
10521 error_at (assoc.type_location,
10522 "%<_Generic%> selector matches multiple associations");
10523 inform (matched_assoc.type_location,
10524 "other match is here");
10528 associations.safe_push (assoc);
10530 if (c_parser_peek_token (parser)->type != CPP_COMMA)
10531 break;
10532 c_parser_consume_token (parser);
10535 unsigned int ix;
10536 struct c_generic_association *iter;
10537 FOR_EACH_VEC_ELT (associations, ix, iter)
10538 if (ix != (unsigned) match_found)
10539 mark_exp_read (iter->expression.value);
10541 if (!parens.require_close (parser))
10543 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10544 return error_expr;
10547 if (match_found < 0)
10549 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
10550 "compatible with any association",
10551 selector_type);
10552 return error_expr;
10555 return matched_assoc.expression;
10558 /* Check the validity of a function pointer argument *EXPR (argument
10559 position POS) to __builtin_tgmath. Return the number of function
10560 arguments if possibly valid; return 0 having reported an error if
10561 not valid. */
10563 static unsigned int
10564 check_tgmath_function (c_expr *expr, unsigned int pos)
10566 tree type = TREE_TYPE (expr->value);
10567 if (!FUNCTION_POINTER_TYPE_P (type))
10569 error_at (expr->get_location (),
10570 "argument %u of %<__builtin_tgmath%> is not a function pointer",
10571 pos);
10572 return 0;
10574 type = TREE_TYPE (type);
10575 if (!prototype_p (type))
10577 error_at (expr->get_location (),
10578 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
10579 return 0;
10581 if (stdarg_p (type))
10583 error_at (expr->get_location (),
10584 "argument %u of %<__builtin_tgmath%> has variable arguments",
10585 pos);
10586 return 0;
10588 unsigned int nargs = 0;
10589 function_args_iterator iter;
10590 tree t;
10591 FOREACH_FUNCTION_ARGS (type, t, iter)
10593 if (t == void_type_node)
10594 break;
10595 nargs++;
10597 if (nargs == 0)
10599 error_at (expr->get_location (),
10600 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
10601 return 0;
10603 return nargs;
10606 /* Ways in which a parameter or return value of a type-generic macro
10607 may vary between the different functions the macro may call. */
10608 enum tgmath_parm_kind
10610 tgmath_fixed, tgmath_real, tgmath_complex
10613 /* Helper function for c_parser_postfix_expression. Parse predefined
10614 identifiers. */
10616 static struct c_expr
10617 c_parser_predefined_identifier (c_parser *parser)
10619 location_t loc = c_parser_peek_token (parser)->location;
10620 switch (c_parser_peek_token (parser)->keyword)
10622 case RID_FUNCTION_NAME:
10623 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
10624 "identifier", "__FUNCTION__");
10625 break;
10626 case RID_PRETTY_FUNCTION_NAME:
10627 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
10628 "identifier", "__PRETTY_FUNCTION__");
10629 break;
10630 case RID_C99_FUNCTION_NAME:
10631 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
10632 "%<__func__%> predefined identifier");
10633 break;
10634 default:
10635 gcc_unreachable ();
10638 struct c_expr expr;
10639 expr.original_code = ERROR_MARK;
10640 expr.original_type = NULL;
10641 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
10642 c_parser_peek_token (parser)->value);
10643 set_c_expr_source_range (&expr, loc, loc);
10644 expr.m_decimal = 0;
10645 c_parser_consume_token (parser);
10646 return expr;
10649 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
10650 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
10651 call c_parser_postfix_expression_after_paren_type on encountering them.
10653 postfix-expression:
10654 primary-expression
10655 postfix-expression [ expression ]
10656 postfix-expression ( argument-expression-list[opt] )
10657 postfix-expression . identifier
10658 postfix-expression -> identifier
10659 postfix-expression ++
10660 postfix-expression --
10661 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
10662 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
10664 argument-expression-list:
10665 argument-expression
10666 argument-expression-list , argument-expression
10668 primary-expression:
10669 identifier
10670 constant
10671 string-literal
10672 ( expression )
10673 generic-selection
10675 GNU extensions:
10677 primary-expression:
10678 __func__
10679 (treated as a keyword in GNU C)
10680 __FUNCTION__
10681 __PRETTY_FUNCTION__
10682 ( compound-statement )
10683 __builtin_va_arg ( assignment-expression , type-name )
10684 __builtin_offsetof ( type-name , offsetof-member-designator )
10685 __builtin_choose_expr ( assignment-expression ,
10686 assignment-expression ,
10687 assignment-expression )
10688 __builtin_types_compatible_p ( type-name , type-name )
10689 __builtin_tgmath ( expr-list )
10690 __builtin_complex ( assignment-expression , assignment-expression )
10691 __builtin_shuffle ( assignment-expression , assignment-expression )
10692 __builtin_shuffle ( assignment-expression ,
10693 assignment-expression ,
10694 assignment-expression, )
10695 __builtin_convertvector ( assignment-expression , type-name )
10696 __builtin_assoc_barrier ( assignment-expression )
10698 offsetof-member-designator:
10699 identifier
10700 offsetof-member-designator . identifier
10701 offsetof-member-designator [ expression ]
10703 Objective-C:
10705 primary-expression:
10706 [ objc-receiver objc-message-args ]
10707 @selector ( objc-selector-arg )
10708 @protocol ( identifier )
10709 @encode ( type-name )
10710 objc-string-literal
10711 Classname . identifier
10714 static struct c_expr
10715 c_parser_postfix_expression (c_parser *parser)
10717 struct c_expr expr, e1;
10718 struct c_type_name *t1, *t2;
10719 location_t loc = c_parser_peek_token (parser)->location;
10720 source_range tok_range = c_parser_peek_token (parser)->get_range ();
10721 expr.original_code = ERROR_MARK;
10722 expr.original_type = NULL;
10723 expr.m_decimal = 0;
10724 switch (c_parser_peek_token (parser)->type)
10726 case CPP_NUMBER:
10727 expr.value = c_parser_peek_token (parser)->value;
10728 set_c_expr_source_range (&expr, tok_range);
10729 loc = c_parser_peek_token (parser)->location;
10730 expr.m_decimal = c_parser_peek_token (parser)->flags & DECIMAL_INT;
10731 c_parser_consume_token (parser);
10732 if (TREE_CODE (expr.value) == FIXED_CST
10733 && !targetm.fixed_point_supported_p ())
10735 error_at (loc, "fixed-point types not supported for this target");
10736 expr.set_error ();
10738 break;
10739 case CPP_CHAR:
10740 case CPP_CHAR16:
10741 case CPP_CHAR32:
10742 case CPP_UTF8CHAR:
10743 case CPP_WCHAR:
10744 expr.value = c_parser_peek_token (parser)->value;
10745 /* For the purpose of warning when a pointer is compared with
10746 a zero character constant. */
10747 expr.original_type = char_type_node;
10748 set_c_expr_source_range (&expr, tok_range);
10749 c_parser_consume_token (parser);
10750 break;
10751 case CPP_STRING:
10752 case CPP_STRING16:
10753 case CPP_STRING32:
10754 case CPP_WSTRING:
10755 case CPP_UTF8STRING:
10756 expr = c_parser_string_literal (parser, parser->translate_strings_p,
10757 true);
10758 break;
10759 case CPP_OBJC_STRING:
10760 gcc_assert (c_dialect_objc ());
10761 expr.value
10762 = objc_build_string_object (c_parser_peek_token (parser)->value);
10763 set_c_expr_source_range (&expr, tok_range);
10764 c_parser_consume_token (parser);
10765 break;
10766 case CPP_NAME:
10767 switch (c_parser_peek_token (parser)->id_kind)
10769 case C_ID_ID:
10771 tree id = c_parser_peek_token (parser)->value;
10772 c_parser_consume_token (parser);
10773 expr.value = build_external_ref (loc, id,
10774 (c_parser_peek_token (parser)->type
10775 == CPP_OPEN_PAREN),
10776 &expr.original_type);
10777 set_c_expr_source_range (&expr, tok_range);
10778 break;
10780 case C_ID_CLASSNAME:
10782 /* Here we parse the Objective-C 2.0 Class.name dot
10783 syntax. */
10784 tree class_name = c_parser_peek_token (parser)->value;
10785 tree component;
10786 c_parser_consume_token (parser);
10787 gcc_assert (c_dialect_objc ());
10788 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
10790 expr.set_error ();
10791 break;
10793 if (c_parser_next_token_is_not (parser, CPP_NAME))
10795 c_parser_error (parser, "expected identifier");
10796 expr.set_error ();
10797 break;
10799 c_token *component_tok = c_parser_peek_token (parser);
10800 component = component_tok->value;
10801 location_t end_loc = component_tok->get_finish ();
10802 c_parser_consume_token (parser);
10803 expr.value = objc_build_class_component_ref (class_name,
10804 component);
10805 set_c_expr_source_range (&expr, loc, end_loc);
10806 break;
10808 default:
10809 c_parser_error (parser, "expected expression");
10810 expr.set_error ();
10811 break;
10813 break;
10814 case CPP_OPEN_PAREN:
10815 /* A parenthesized expression, statement expression or compound
10816 literal. */
10817 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
10819 /* A statement expression. */
10820 tree stmt;
10821 location_t brace_loc;
10822 bool save_c_omp_array_section_p = c_omp_array_section_p;
10823 c_parser_consume_token (parser);
10824 brace_loc = c_parser_peek_token (parser)->location;
10825 c_parser_consume_token (parser);
10826 /* If we've not yet started the current function's statement list,
10827 or we're in the parameter scope of an old-style function
10828 declaration, statement expressions are not allowed. */
10829 if (!building_stmt_list_p () || old_style_parameter_scope ())
10831 error_at (loc, "braced-group within expression allowed "
10832 "only inside a function");
10833 parser->error = true;
10834 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
10835 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10836 expr.set_error ();
10837 break;
10839 c_omp_array_section_p = false;
10840 stmt = c_begin_stmt_expr ();
10841 c_parser_compound_statement_nostart (parser);
10842 location_t close_loc = c_parser_peek_token (parser)->location;
10843 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10844 "expected %<)%>");
10845 pedwarn (loc, OPT_Wpedantic,
10846 "ISO C forbids braced-groups within expressions");
10847 expr.value = c_finish_stmt_expr (brace_loc, stmt);
10848 set_c_expr_source_range (&expr, loc, close_loc);
10849 mark_exp_read (expr.value);
10850 c_omp_array_section_p = save_c_omp_array_section_p;
10852 else
10854 /* A parenthesized expression. */
10855 location_t loc_open_paren = c_parser_peek_token (parser)->location;
10856 c_parser_consume_token (parser);
10857 expr = c_parser_expression (parser);
10858 if (TREE_CODE (expr.value) == MODIFY_EXPR)
10859 suppress_warning (expr.value, OPT_Wparentheses);
10860 if (expr.original_code != C_MAYBE_CONST_EXPR
10861 && expr.original_code != SIZEOF_EXPR)
10862 expr.original_code = ERROR_MARK;
10863 /* Remember that we saw ( ) around the sizeof. */
10864 if (expr.original_code == SIZEOF_EXPR)
10865 expr.original_code = PAREN_SIZEOF_EXPR;
10866 /* Don't change EXPR.ORIGINAL_TYPE. */
10867 location_t loc_close_paren = c_parser_peek_token (parser)->location;
10868 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
10869 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10870 "expected %<)%>", loc_open_paren);
10872 break;
10873 case CPP_KEYWORD:
10874 switch (c_parser_peek_token (parser)->keyword)
10876 case RID_FUNCTION_NAME:
10877 case RID_PRETTY_FUNCTION_NAME:
10878 case RID_C99_FUNCTION_NAME:
10879 expr = c_parser_predefined_identifier (parser);
10880 break;
10881 case RID_VA_ARG:
10883 location_t start_loc = loc;
10884 c_parser_consume_token (parser);
10885 matching_parens parens;
10886 if (!parens.require_open (parser))
10888 expr.set_error ();
10889 break;
10891 e1 = c_parser_expr_no_commas (parser, NULL);
10892 mark_exp_read (e1.value);
10893 e1.value = c_fully_fold (e1.value, false, NULL);
10894 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10896 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10897 expr.set_error ();
10898 break;
10900 loc = c_parser_peek_token (parser)->location;
10901 t1 = c_parser_type_name (parser);
10902 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10903 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10904 "expected %<)%>");
10905 if (t1 == NULL)
10907 expr.set_error ();
10909 else
10911 tree type_expr = NULL_TREE;
10912 expr.value = c_build_va_arg (start_loc, e1.value, loc,
10913 groktypename (t1, &type_expr, NULL));
10914 if (type_expr)
10916 expr.value = build2 (C_MAYBE_CONST_EXPR,
10917 TREE_TYPE (expr.value), type_expr,
10918 expr.value);
10919 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
10921 set_c_expr_source_range (&expr, start_loc, end_loc);
10924 break;
10925 case RID_OFFSETOF:
10927 c_parser_consume_token (parser);
10928 matching_parens parens;
10929 if (!parens.require_open (parser))
10931 expr.set_error ();
10932 break;
10934 t1 = c_parser_type_name (parser);
10935 if (t1 == NULL)
10936 parser->error = true;
10937 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10938 gcc_assert (parser->error);
10939 if (parser->error)
10941 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10942 expr.set_error ();
10943 break;
10945 tree type = groktypename (t1, NULL, NULL);
10946 tree offsetof_ref;
10947 if (type == error_mark_node)
10948 offsetof_ref = error_mark_node;
10949 else
10951 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
10952 SET_EXPR_LOCATION (offsetof_ref, loc);
10954 /* Parse the second argument to __builtin_offsetof. We
10955 must have one identifier, and beyond that we want to
10956 accept sub structure and sub array references. */
10957 if (c_parser_next_token_is (parser, CPP_NAME))
10959 c_token *comp_tok = c_parser_peek_token (parser);
10960 /* Ignore the counted_by attribute for reference inside
10961 offsetof since the information is not useful at all. */
10962 offsetof_ref
10963 = build_component_ref (loc, offsetof_ref, comp_tok->value,
10964 comp_tok->location, UNKNOWN_LOCATION,
10965 false);
10966 c_parser_consume_token (parser);
10967 while (c_parser_next_token_is (parser, CPP_DOT)
10968 || c_parser_next_token_is (parser,
10969 CPP_OPEN_SQUARE)
10970 || c_parser_next_token_is (parser,
10971 CPP_DEREF))
10973 if (c_parser_next_token_is (parser, CPP_DEREF))
10975 loc = c_parser_peek_token (parser)->location;
10976 offsetof_ref = build_array_ref (loc,
10977 offsetof_ref,
10978 integer_zero_node);
10979 goto do_dot;
10981 else if (c_parser_next_token_is (parser, CPP_DOT))
10983 do_dot:
10984 c_parser_consume_token (parser);
10985 if (c_parser_next_token_is_not (parser,
10986 CPP_NAME))
10988 c_parser_error (parser, "expected identifier");
10989 break;
10991 c_token *comp_tok = c_parser_peek_token (parser);
10992 /* Ignore the counted_by attribute for reference inside
10993 offsetof since the information is not useful. */
10994 offsetof_ref
10995 = build_component_ref (loc, offsetof_ref,
10996 comp_tok->value,
10997 comp_tok->location,
10998 UNKNOWN_LOCATION,
10999 false);
11000 c_parser_consume_token (parser);
11002 else
11004 struct c_expr ce;
11005 tree idx;
11006 loc = c_parser_peek_token (parser)->location;
11007 c_parser_consume_token (parser);
11008 ce = c_parser_expression (parser);
11009 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11010 idx = ce.value;
11011 idx = c_fully_fold (idx, false, NULL);
11012 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
11013 "expected %<]%>");
11014 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
11018 else
11019 c_parser_error (parser, "expected identifier");
11020 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
11021 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11022 "expected %<)%>");
11023 expr.value = fold_offsetof (offsetof_ref);
11024 set_c_expr_source_range (&expr, loc, end_loc);
11026 break;
11027 case RID_CHOOSE_EXPR:
11029 vec<c_expr_t, va_gc> *cexpr_list;
11030 c_expr_t *e1_p, *e2_p, *e3_p;
11031 tree c;
11032 location_t close_paren_loc;
11034 c_parser_consume_token (parser);
11035 if (!c_parser_get_builtin_args (parser,
11036 "__builtin_choose_expr",
11037 &cexpr_list, true,
11038 &close_paren_loc))
11040 expr.set_error ();
11041 break;
11044 if (vec_safe_length (cexpr_list) != 3)
11046 error_at (loc, "wrong number of arguments to "
11047 "%<__builtin_choose_expr%>");
11048 expr.set_error ();
11049 break;
11052 e1_p = &(*cexpr_list)[0];
11053 e2_p = &(*cexpr_list)[1];
11054 e3_p = &(*cexpr_list)[2];
11056 c = e1_p->value;
11057 mark_exp_read (e2_p->value);
11058 mark_exp_read (e3_p->value);
11059 if (TREE_CODE (c) != INTEGER_CST
11060 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
11061 error_at (loc,
11062 "first argument to %<__builtin_choose_expr%> not"
11063 " a constant");
11064 constant_expression_warning (c);
11065 expr = integer_zerop (c) ? *e3_p : *e2_p;
11066 set_c_expr_source_range (&expr, loc, close_paren_loc);
11067 break;
11069 case RID_TYPES_COMPATIBLE_P:
11071 c_parser_consume_token (parser);
11072 matching_parens parens;
11073 if (!parens.require_open (parser))
11075 expr.set_error ();
11076 break;
11078 t1 = c_parser_type_name (parser);
11079 if (t1 == NULL)
11081 expr.set_error ();
11082 break;
11084 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
11086 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
11087 expr.set_error ();
11088 break;
11090 t2 = c_parser_type_name (parser);
11091 if (t2 == NULL)
11093 expr.set_error ();
11094 break;
11096 location_t close_paren_loc = c_parser_peek_token (parser)->location;
11097 parens.skip_until_found_close (parser);
11098 tree e1, e2;
11099 e1 = groktypename (t1, NULL, NULL);
11100 e2 = groktypename (t2, NULL, NULL);
11101 if (e1 == error_mark_node || e2 == error_mark_node)
11103 expr.set_error ();
11104 break;
11107 e1 = TYPE_MAIN_VARIANT (e1);
11108 e2 = TYPE_MAIN_VARIANT (e2);
11110 expr.value
11111 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
11112 set_c_expr_source_range (&expr, loc, close_paren_loc);
11114 break;
11115 case RID_BUILTIN_TGMATH:
11117 vec<c_expr_t, va_gc> *cexpr_list;
11118 location_t close_paren_loc;
11120 c_parser_consume_token (parser);
11121 if (!c_parser_get_builtin_args (parser,
11122 "__builtin_tgmath",
11123 &cexpr_list, false,
11124 &close_paren_loc))
11126 expr.set_error ();
11127 break;
11130 if (vec_safe_length (cexpr_list) < 3)
11132 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11133 expr.set_error ();
11134 break;
11137 unsigned int i;
11138 c_expr_t *p;
11139 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
11140 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11141 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
11142 if (nargs == 0)
11144 expr.set_error ();
11145 break;
11147 if (vec_safe_length (cexpr_list) < nargs)
11149 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11150 expr.set_error ();
11151 break;
11153 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
11154 if (num_functions < 2)
11156 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
11157 expr.set_error ();
11158 break;
11161 /* The first NUM_FUNCTIONS expressions are the function
11162 pointers. The remaining NARGS expressions are the
11163 arguments that are to be passed to one of those
11164 functions, chosen following <tgmath.h> rules. */
11165 for (unsigned int j = 1; j < num_functions; j++)
11167 unsigned int this_nargs
11168 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
11169 if (this_nargs == 0)
11171 expr.set_error ();
11172 goto out;
11174 if (this_nargs != nargs)
11176 error_at ((*cexpr_list)[j].get_location (),
11177 "argument %u of %<__builtin_tgmath%> has "
11178 "wrong number of arguments", j + 1);
11179 expr.set_error ();
11180 goto out;
11184 /* The functions all have the same number of arguments.
11185 Determine whether arguments and return types vary in
11186 ways permitted for <tgmath.h> functions. */
11187 /* The first entry in each of these vectors is for the
11188 return type, subsequent entries for parameter
11189 types. */
11190 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
11191 auto_vec<tree> parm_first (nargs + 1);
11192 auto_vec<bool> parm_complex (nargs + 1);
11193 auto_vec<bool> parm_varies (nargs + 1);
11194 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
11195 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
11196 parm_first.quick_push (first_ret);
11197 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
11198 parm_varies.quick_push (false);
11199 function_args_iterator iter;
11200 tree t;
11201 unsigned int argpos;
11202 FOREACH_FUNCTION_ARGS (first_type, t, iter)
11204 if (t == void_type_node)
11205 break;
11206 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
11207 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
11208 parm_varies.quick_push (false);
11210 for (unsigned int j = 1; j < num_functions; j++)
11212 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11213 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
11214 if (ret != parm_first[0])
11216 parm_varies[0] = true;
11217 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
11218 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
11220 error_at ((*cexpr_list)[0].get_location (),
11221 "invalid type-generic return type for "
11222 "argument %u of %<__builtin_tgmath%>",
11224 expr.set_error ();
11225 goto out;
11227 if (!SCALAR_FLOAT_TYPE_P (ret)
11228 && !COMPLEX_FLOAT_TYPE_P (ret))
11230 error_at ((*cexpr_list)[j].get_location (),
11231 "invalid type-generic return type for "
11232 "argument %u of %<__builtin_tgmath%>",
11233 j + 1);
11234 expr.set_error ();
11235 goto out;
11238 if (TREE_CODE (ret) == COMPLEX_TYPE)
11239 parm_complex[0] = true;
11240 argpos = 1;
11241 FOREACH_FUNCTION_ARGS (type, t, iter)
11243 if (t == void_type_node)
11244 break;
11245 t = TYPE_MAIN_VARIANT (t);
11246 if (t != parm_first[argpos])
11248 parm_varies[argpos] = true;
11249 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
11250 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
11252 error_at ((*cexpr_list)[0].get_location (),
11253 "invalid type-generic type for "
11254 "argument %u of argument %u of "
11255 "%<__builtin_tgmath%>", argpos, 1);
11256 expr.set_error ();
11257 goto out;
11259 if (!SCALAR_FLOAT_TYPE_P (t)
11260 && !COMPLEX_FLOAT_TYPE_P (t))
11262 error_at ((*cexpr_list)[j].get_location (),
11263 "invalid type-generic type for "
11264 "argument %u of argument %u of "
11265 "%<__builtin_tgmath%>", argpos, j + 1);
11266 expr.set_error ();
11267 goto out;
11270 if (TREE_CODE (t) == COMPLEX_TYPE)
11271 parm_complex[argpos] = true;
11272 argpos++;
11275 enum tgmath_parm_kind max_variation = tgmath_fixed;
11276 for (unsigned int j = 0; j <= nargs; j++)
11278 enum tgmath_parm_kind this_kind;
11279 if (parm_varies[j])
11281 if (parm_complex[j])
11282 max_variation = this_kind = tgmath_complex;
11283 else
11285 this_kind = tgmath_real;
11286 if (max_variation != tgmath_complex)
11287 max_variation = tgmath_real;
11290 else
11291 this_kind = tgmath_fixed;
11292 parm_kind.quick_push (this_kind);
11294 if (max_variation == tgmath_fixed)
11296 error_at (loc, "function arguments of %<__builtin_tgmath%> "
11297 "all have the same type");
11298 expr.set_error ();
11299 break;
11302 /* Identify a parameter (not the return type) that varies,
11303 including with complex types if any variation includes
11304 complex types; there must be at least one such
11305 parameter. */
11306 unsigned int tgarg = 0;
11307 for (unsigned int j = 1; j <= nargs; j++)
11308 if (parm_kind[j] == max_variation)
11310 tgarg = j;
11311 break;
11313 if (tgarg == 0)
11315 error_at (loc, "function arguments of %<__builtin_tgmath%> "
11316 "lack type-generic parameter");
11317 expr.set_error ();
11318 break;
11321 /* Determine the type of the relevant parameter for each
11322 function. */
11323 auto_vec<tree> tg_type (num_functions);
11324 for (unsigned int j = 0; j < num_functions; j++)
11326 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11327 argpos = 1;
11328 FOREACH_FUNCTION_ARGS (type, t, iter)
11330 if (argpos == tgarg)
11332 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
11333 break;
11335 argpos++;
11339 /* Verify that the corresponding types are different for
11340 all the listed functions. Also determine whether all
11341 the types are complex, whether all the types are
11342 standard or binary, and whether all the types are
11343 decimal. */
11344 bool all_complex = true;
11345 bool all_binary = true;
11346 bool all_decimal = true;
11347 hash_set<tree> tg_types;
11348 FOR_EACH_VEC_ELT (tg_type, i, t)
11350 if (TREE_CODE (t) == COMPLEX_TYPE)
11351 all_decimal = false;
11352 else
11354 all_complex = false;
11355 if (DECIMAL_FLOAT_TYPE_P (t))
11356 all_binary = false;
11357 else
11358 all_decimal = false;
11360 if (tg_types.add (t))
11362 error_at ((*cexpr_list)[i].get_location (),
11363 "duplicate type-generic parameter type for "
11364 "function argument %u of %<__builtin_tgmath%>",
11365 i + 1);
11366 expr.set_error ();
11367 goto out;
11371 /* Verify that other parameters and the return type whose
11372 types vary have their types varying in the correct
11373 way. */
11374 for (unsigned int j = 0; j < num_functions; j++)
11376 tree exp_type = tg_type[j];
11377 tree exp_real_type = exp_type;
11378 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
11379 exp_real_type = TREE_TYPE (exp_type);
11380 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
11381 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
11382 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
11383 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
11385 error_at ((*cexpr_list)[j].get_location (),
11386 "bad return type for function argument %u "
11387 "of %<__builtin_tgmath%>", j + 1);
11388 expr.set_error ();
11389 goto out;
11391 argpos = 1;
11392 FOREACH_FUNCTION_ARGS (type, t, iter)
11394 if (t == void_type_node)
11395 break;
11396 t = TYPE_MAIN_VARIANT (t);
11397 if ((parm_kind[argpos] == tgmath_complex
11398 && t != exp_type)
11399 || (parm_kind[argpos] == tgmath_real
11400 && t != exp_real_type))
11402 error_at ((*cexpr_list)[j].get_location (),
11403 "bad type for argument %u of "
11404 "function argument %u of "
11405 "%<__builtin_tgmath%>", argpos, j + 1);
11406 expr.set_error ();
11407 goto out;
11409 argpos++;
11413 /* The functions listed are a valid set of functions for a
11414 <tgmath.h> macro to select between. Identify the
11415 matching function, if any. First, the argument types
11416 must be combined following <tgmath.h> rules. Integer
11417 types are treated as _Decimal64 if any type-generic
11418 argument is decimal, or if the only alternatives for
11419 type-generic arguments are of decimal types, and are
11420 otherwise treated as _Float32x (or _Complex _Float32x
11421 for complex integer types) if any type-generic argument
11422 has _FloatNx type, otherwise as double (or _Complex
11423 double for complex integer types). After that
11424 adjustment, types are combined following the usual
11425 arithmetic conversions. If the function only accepts
11426 complex arguments, a complex type is produced. */
11427 bool arg_complex = all_complex;
11428 bool arg_binary = all_binary;
11429 bool arg_int_decimal = all_decimal;
11430 bool arg_int_floatnx = false;
11431 for (unsigned int j = 1; j <= nargs; j++)
11433 if (parm_kind[j] == tgmath_fixed)
11434 continue;
11435 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
11436 tree type = TREE_TYPE (ce->value);
11437 if (!INTEGRAL_TYPE_P (type)
11438 && !SCALAR_FLOAT_TYPE_P (type)
11439 && TREE_CODE (type) != COMPLEX_TYPE)
11441 error_at (ce->get_location (),
11442 "invalid type of argument %u of type-generic "
11443 "function", j);
11444 expr.set_error ();
11445 goto out;
11447 if (DECIMAL_FLOAT_TYPE_P (type))
11449 arg_int_decimal = true;
11450 if (all_complex)
11452 error_at (ce->get_location (),
11453 "decimal floating-point argument %u to "
11454 "complex-only type-generic function", j);
11455 expr.set_error ();
11456 goto out;
11458 else if (all_binary)
11460 error_at (ce->get_location (),
11461 "decimal floating-point argument %u to "
11462 "binary-only type-generic function", j);
11463 expr.set_error ();
11464 goto out;
11466 else if (arg_complex)
11468 error_at (ce->get_location (),
11469 "both complex and decimal floating-point "
11470 "arguments to type-generic function");
11471 expr.set_error ();
11472 goto out;
11474 else if (arg_binary)
11476 error_at (ce->get_location (),
11477 "both binary and decimal floating-point "
11478 "arguments to type-generic function");
11479 expr.set_error ();
11480 goto out;
11483 else if (TREE_CODE (type) == COMPLEX_TYPE)
11485 arg_complex = true;
11486 if (COMPLEX_FLOAT_TYPE_P (type))
11487 arg_binary = true;
11488 if (all_decimal)
11490 error_at (ce->get_location (),
11491 "complex argument %u to "
11492 "decimal-only type-generic function", j);
11493 expr.set_error ();
11494 goto out;
11496 else if (arg_int_decimal)
11498 error_at (ce->get_location (),
11499 "both complex and decimal floating-point "
11500 "arguments to type-generic function");
11501 expr.set_error ();
11502 goto out;
11505 else if (SCALAR_FLOAT_TYPE_P (type))
11507 arg_binary = true;
11508 if (all_decimal)
11510 error_at (ce->get_location (),
11511 "binary argument %u to "
11512 "decimal-only type-generic function", j);
11513 expr.set_error ();
11514 goto out;
11516 else if (arg_int_decimal)
11518 error_at (ce->get_location (),
11519 "both binary and decimal floating-point "
11520 "arguments to type-generic function");
11521 expr.set_error ();
11522 goto out;
11525 tree rtype = TYPE_MAIN_VARIANT (type);
11526 if (TREE_CODE (rtype) == COMPLEX_TYPE)
11527 rtype = TREE_TYPE (rtype);
11528 if (SCALAR_FLOAT_TYPE_P (rtype))
11529 for (unsigned int j = 0; j < NUM_FLOATNX_TYPES; j++)
11530 if (rtype == FLOATNX_TYPE_NODE (j))
11532 arg_int_floatnx = true;
11533 break;
11536 tree arg_real = NULL_TREE;
11537 for (unsigned int j = 1; j <= nargs; j++)
11539 if (parm_kind[j] == tgmath_fixed)
11540 continue;
11541 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
11542 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
11543 if (TREE_CODE (type) == COMPLEX_TYPE)
11544 type = TREE_TYPE (type);
11545 if (INTEGRAL_TYPE_P (type))
11546 type = (arg_int_decimal
11547 ? dfloat64_type_node
11548 : arg_int_floatnx
11549 ? float32x_type_node
11550 : double_type_node);
11551 if (arg_real == NULL_TREE)
11552 arg_real = type;
11553 else
11554 arg_real = common_type (arg_real, type);
11555 if (arg_real == error_mark_node)
11557 expr.set_error ();
11558 goto out;
11561 tree arg_type = (arg_complex
11562 ? build_complex_type (arg_real)
11563 : arg_real);
11565 /* Look for a function to call with type-generic parameter
11566 type ARG_TYPE. */
11567 c_expr_t *fn = NULL;
11568 for (unsigned int j = 0; j < num_functions; j++)
11570 if (tg_type[j] == arg_type)
11572 fn = &(*cexpr_list)[j];
11573 break;
11576 if (fn == NULL
11577 && parm_kind[0] == tgmath_fixed
11578 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
11580 /* Presume this is a macro that rounds its result to a
11581 narrower type, and look for the first function with
11582 at least the range and precision of the argument
11583 type. */
11584 for (unsigned int j = 0; j < num_functions; j++)
11586 if (arg_complex
11587 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
11588 continue;
11589 tree real_tg_type = (arg_complex
11590 ? TREE_TYPE (tg_type[j])
11591 : tg_type[j]);
11592 if (DECIMAL_FLOAT_TYPE_P (arg_real)
11593 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
11594 continue;
11595 scalar_float_mode arg_mode
11596 = SCALAR_FLOAT_TYPE_MODE (arg_real);
11597 scalar_float_mode tg_mode
11598 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
11599 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
11600 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
11601 if (arg_fmt->b == tg_fmt->b
11602 && arg_fmt->p <= tg_fmt->p
11603 && arg_fmt->emax <= tg_fmt->emax
11604 && (arg_fmt->emin - arg_fmt->p
11605 >= tg_fmt->emin - tg_fmt->p))
11607 fn = &(*cexpr_list)[j];
11608 break;
11612 if (fn == NULL)
11614 error_at (loc, "no matching function for type-generic call");
11615 expr.set_error ();
11616 break;
11619 /* Construct a call to FN. */
11620 vec<tree, va_gc> *args;
11621 vec_alloc (args, nargs);
11622 vec<tree, va_gc> *origtypes;
11623 vec_alloc (origtypes, nargs);
11624 auto_vec<location_t> arg_loc (nargs);
11625 for (unsigned int j = 0; j < nargs; j++)
11627 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
11628 args->quick_push (ce->value);
11629 arg_loc.quick_push (ce->get_location ());
11630 origtypes->quick_push (ce->original_type);
11632 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
11633 args, origtypes);
11634 set_c_expr_source_range (&expr, loc, close_paren_loc);
11635 break;
11637 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
11639 vec<c_expr_t, va_gc> *cexpr_list;
11640 c_expr_t *e2_p;
11641 tree chain_value;
11642 location_t close_paren_loc;
11644 c_parser_consume_token (parser);
11645 if (!c_parser_get_builtin_args (parser,
11646 "__builtin_call_with_static_chain",
11647 &cexpr_list, false,
11648 &close_paren_loc))
11650 expr.set_error ();
11651 break;
11653 if (vec_safe_length (cexpr_list) != 2)
11655 error_at (loc, "wrong number of arguments to "
11656 "%<__builtin_call_with_static_chain%>");
11657 expr.set_error ();
11658 break;
11661 expr = (*cexpr_list)[0];
11662 e2_p = &(*cexpr_list)[1];
11663 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
11664 chain_value = e2_p->value;
11665 mark_exp_read (chain_value);
11667 if (TREE_CODE (expr.value) != CALL_EXPR)
11668 error_at (loc, "first argument to "
11669 "%<__builtin_call_with_static_chain%> "
11670 "must be a call expression");
11671 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
11672 error_at (loc, "second argument to "
11673 "%<__builtin_call_with_static_chain%> "
11674 "must be a pointer type");
11675 else
11676 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
11677 set_c_expr_source_range (&expr, loc, close_paren_loc);
11678 break;
11680 case RID_BUILTIN_COMPLEX:
11682 vec<c_expr_t, va_gc> *cexpr_list;
11683 c_expr_t *e1_p, *e2_p;
11684 location_t close_paren_loc;
11686 c_parser_consume_token (parser);
11687 if (!c_parser_get_builtin_args (parser,
11688 "__builtin_complex",
11689 &cexpr_list, false,
11690 &close_paren_loc))
11692 expr.set_error ();
11693 break;
11696 if (vec_safe_length (cexpr_list) != 2)
11698 error_at (loc, "wrong number of arguments to "
11699 "%<__builtin_complex%>");
11700 expr.set_error ();
11701 break;
11704 e1_p = &(*cexpr_list)[0];
11705 e2_p = &(*cexpr_list)[1];
11707 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
11708 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
11709 e1_p->value = convert (TREE_TYPE (e1_p->value),
11710 TREE_OPERAND (e1_p->value, 0));
11711 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
11712 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
11713 e2_p->value = convert (TREE_TYPE (e2_p->value),
11714 TREE_OPERAND (e2_p->value, 0));
11715 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
11716 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
11717 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
11718 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
11720 error_at (loc, "%<__builtin_complex%> operand "
11721 "not of real binary floating-point type");
11722 expr.set_error ();
11723 break;
11725 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
11726 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
11728 error_at (loc,
11729 "%<__builtin_complex%> operands of different types");
11730 expr.set_error ();
11731 break;
11733 pedwarn_c90 (loc, OPT_Wpedantic,
11734 "ISO C90 does not support complex types");
11735 expr.value = build2_loc (loc, COMPLEX_EXPR,
11736 build_complex_type
11737 (TYPE_MAIN_VARIANT
11738 (TREE_TYPE (e1_p->value))),
11739 e1_p->value, e2_p->value);
11740 set_c_expr_source_range (&expr, loc, close_paren_loc);
11741 break;
11743 case RID_BUILTIN_SHUFFLE:
11745 vec<c_expr_t, va_gc> *cexpr_list;
11746 unsigned int i;
11747 c_expr_t *p;
11748 location_t close_paren_loc;
11750 c_parser_consume_token (parser);
11751 if (!c_parser_get_builtin_args (parser,
11752 "__builtin_shuffle",
11753 &cexpr_list, false,
11754 &close_paren_loc))
11756 expr.set_error ();
11757 break;
11760 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
11761 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11763 if (vec_safe_length (cexpr_list) == 2)
11764 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
11765 NULL_TREE,
11766 (*cexpr_list)[1].value);
11768 else if (vec_safe_length (cexpr_list) == 3)
11769 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
11770 (*cexpr_list)[1].value,
11771 (*cexpr_list)[2].value);
11772 else
11774 error_at (loc, "wrong number of arguments to "
11775 "%<__builtin_shuffle%>");
11776 expr.set_error ();
11778 set_c_expr_source_range (&expr, loc, close_paren_loc);
11779 break;
11781 case RID_BUILTIN_SHUFFLEVECTOR:
11783 vec<c_expr_t, va_gc> *cexpr_list;
11784 unsigned int i;
11785 c_expr_t *p;
11786 location_t close_paren_loc;
11788 c_parser_consume_token (parser);
11789 if (!c_parser_get_builtin_args (parser,
11790 "__builtin_shufflevector",
11791 &cexpr_list, false,
11792 &close_paren_loc))
11794 expr.set_error ();
11795 break;
11798 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
11799 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
11801 if (vec_safe_length (cexpr_list) < 3)
11803 error_at (loc, "wrong number of arguments to "
11804 "%<__builtin_shuffle%>");
11805 expr.set_error ();
11807 else
11809 auto_vec<tree, 16> mask;
11810 for (i = 2; i < cexpr_list->length (); ++i)
11811 mask.safe_push ((*cexpr_list)[i].value);
11812 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
11813 (*cexpr_list)[1].value,
11814 mask);
11816 set_c_expr_source_range (&expr, loc, close_paren_loc);
11817 break;
11819 case RID_BUILTIN_CONVERTVECTOR:
11821 location_t start_loc = loc;
11822 c_parser_consume_token (parser);
11823 matching_parens parens;
11824 if (!parens.require_open (parser))
11826 expr.set_error ();
11827 break;
11829 e1 = c_parser_expr_no_commas (parser, NULL);
11830 mark_exp_read (e1.value);
11831 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
11833 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
11834 expr.set_error ();
11835 break;
11837 loc = c_parser_peek_token (parser)->location;
11838 t1 = c_parser_type_name (parser);
11839 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
11840 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11841 "expected %<)%>");
11842 if (t1 == NULL)
11843 expr.set_error ();
11844 else
11846 tree type_expr = NULL_TREE;
11847 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
11848 groktypename (t1, &type_expr,
11849 NULL));
11850 set_c_expr_source_range (&expr, start_loc, end_loc);
11853 break;
11854 case RID_BUILTIN_ASSOC_BARRIER:
11856 location_t start_loc = loc;
11857 c_parser_consume_token (parser);
11858 matching_parens parens;
11859 if (!parens.require_open (parser))
11861 expr.set_error ();
11862 break;
11864 e1 = c_parser_expr_no_commas (parser, NULL);
11865 mark_exp_read (e1.value);
11866 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
11867 parens.skip_until_found_close (parser);
11868 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
11869 set_c_expr_source_range (&expr, start_loc, end_loc);
11871 break;
11872 case RID_BUILTIN_STDC:
11874 vec<c_expr_t, va_gc> *cexpr_list;
11875 c_expr_t *arg_p;
11876 location_t close_paren_loc;
11877 enum c_builtin_stdc {
11878 C_BUILTIN_STDC_BIT_CEIL,
11879 C_BUILTIN_STDC_BIT_FLOOR,
11880 C_BUILTIN_STDC_BIT_WIDTH,
11881 C_BUILTIN_STDC_COUNT_ONES,
11882 C_BUILTIN_STDC_COUNT_ZEROS,
11883 C_BUILTIN_STDC_FIRST_LEADING_ONE,
11884 C_BUILTIN_STDC_FIRST_LEADING_ZERO,
11885 C_BUILTIN_STDC_FIRST_TRAILING_ONE,
11886 C_BUILTIN_STDC_FIRST_TRAILING_ZERO,
11887 C_BUILTIN_STDC_HAS_SINGLE_BIT,
11888 C_BUILTIN_STDC_LEADING_ONES,
11889 C_BUILTIN_STDC_LEADING_ZEROS,
11890 C_BUILTIN_STDC_TRAILING_ONES,
11891 C_BUILTIN_STDC_TRAILING_ZEROS,
11892 C_BUILTIN_STDC_MAX
11893 } stdc_rid = C_BUILTIN_STDC_MAX;
11894 const char *name
11895 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
11896 switch (name[sizeof ("__builtin_stdc_") - 1])
11898 case 'b':
11899 switch (name[sizeof ("__builtin_stdc_bit_") - 1])
11901 case 'c':
11902 stdc_rid = C_BUILTIN_STDC_BIT_CEIL;
11903 break;
11904 case 'f':
11905 stdc_rid = C_BUILTIN_STDC_BIT_FLOOR;
11906 break;
11907 default:
11908 stdc_rid = C_BUILTIN_STDC_BIT_WIDTH;
11909 break;
11911 break;
11912 case 'c':
11913 if (name[sizeof ("__builtin_stdc_count_") - 1] == 'o')
11914 stdc_rid = C_BUILTIN_STDC_COUNT_ONES;
11915 else
11916 stdc_rid = C_BUILTIN_STDC_COUNT_ZEROS;
11917 break;
11918 case 'f':
11919 switch (name[sizeof ("__builtin_stdc_first_trailing_") - 1])
11921 case 'n':
11922 stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ONE;
11923 break;
11924 case 'e':
11925 stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ZERO;
11926 break;
11927 case 'o':
11928 stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ONE;
11929 break;
11930 default:
11931 stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ZERO;
11932 break;
11934 break;
11935 case 'h':
11936 stdc_rid = C_BUILTIN_STDC_HAS_SINGLE_BIT;
11937 break;
11938 case 'l':
11939 if (name[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
11940 stdc_rid = C_BUILTIN_STDC_LEADING_ONES;
11941 else
11942 stdc_rid = C_BUILTIN_STDC_LEADING_ZEROS;
11943 break;
11944 case 't':
11945 if (name[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
11946 stdc_rid = C_BUILTIN_STDC_TRAILING_ONES;
11947 else
11948 stdc_rid = C_BUILTIN_STDC_TRAILING_ZEROS;
11949 break;
11951 gcc_checking_assert (stdc_rid != C_BUILTIN_STDC_MAX);
11953 c_parser_consume_token (parser);
11954 if (!c_parser_get_builtin_args (parser, name,
11955 &cexpr_list, false,
11956 &close_paren_loc))
11958 expr.set_error ();
11959 break;
11962 if (vec_safe_length (cexpr_list) != 1)
11964 error_at (loc, "wrong number of arguments to %qs", name);
11965 expr.set_error ();
11966 break;
11969 arg_p = &(*cexpr_list)[0];
11970 *arg_p = convert_lvalue_to_rvalue (loc, *arg_p, true, true);
11971 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p->value)))
11973 error_at (loc, "%qs operand not an integral type", name);
11974 expr.set_error ();
11975 break;
11977 if (TREE_CODE (TREE_TYPE (arg_p->value)) == ENUMERAL_TYPE)
11979 error_at (loc, "argument %u in call to function "
11980 "%qs has enumerated type", 1, name);
11981 expr.set_error ();
11982 break;
11984 if (TREE_CODE (TREE_TYPE (arg_p->value)) == BOOLEAN_TYPE)
11986 error_at (loc, "argument %u in call to function "
11987 "%qs has boolean type", 1, name);
11988 expr.set_error ();
11989 break;
11991 if (!TYPE_UNSIGNED (TREE_TYPE (arg_p->value)))
11993 error_at (loc, "argument 1 in call to function "
11994 "%qs has signed type", name);
11995 expr.set_error ();
11996 break;
11998 tree arg = arg_p->value;
11999 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
12000 /* Expand:
12001 __builtin_stdc_leading_zeros (arg) as
12002 (unsigned int) __builtin_clzg (arg, prec)
12003 __builtin_stdc_leading_ones (arg) as
12004 (unsigned int) __builtin_clzg ((type) ~arg, prec)
12005 __builtin_stdc_trailing_zeros (arg) as
12006 (unsigned int) __builtin_ctzg (arg, prec)
12007 __builtin_stdc_trailing_ones (arg) as
12008 (unsigned int) __builtin_ctzg ((type) ~arg, prec)
12009 __builtin_stdc_first_leading_zero (arg) as
12010 __builtin_clzg ((type) ~arg, -1) + 1U
12011 __builtin_stdc_first_leading_one (arg) as
12012 __builtin_clzg (arg, -1) + 1U
12013 __builtin_stdc_first_trailing_zero (arg) as
12014 __builtin_ctzg ((type) ~arg, -1) + 1U
12015 __builtin_stdc_first_trailing_one (arg) as
12016 __builtin_ctzg (arg, -1) + 1U
12017 __builtin_stdc_count_zeros (arg) as
12018 (unsigned int) __builtin_popcountg ((type) ~arg)
12019 __builtin_stdc_count_ones (arg) as
12020 (unsigned int) __builtin_popcountg (arg)
12021 __builtin_stdc_has_single_bit (arg) as
12022 (_Bool) (__builtin_popcountg (arg) == 1)
12023 __builtin_stdc_bit_width (arg) as
12024 (unsigned int) (prec - __builtin_clzg (arg, prec))
12025 __builtin_stdc_bit_floor (arg) as
12026 arg == 0 ? (type) 0
12027 : (type) 1 << (prec - 1 - __builtin_clzg (arg))
12028 __builtin_stdc_bit_ceil (arg) as
12029 arg <= 1 ? (type) 1
12030 : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
12031 without evaluating arg multiple times, type being
12032 __typeof (arg) and prec __builtin_popcountg ((type) ~0)). */
12033 int prec = TYPE_PRECISION (type);
12034 tree barg1 = arg;
12035 switch (stdc_rid)
12037 case C_BUILTIN_STDC_BIT_CEIL:
12038 arg = save_expr (arg);
12039 barg1 = build2_loc (loc, PLUS_EXPR, type, arg,
12040 build_int_cst (type, -1));
12041 break;
12042 case C_BUILTIN_STDC_BIT_FLOOR:
12043 barg1 = arg = save_expr (arg);
12044 break;
12045 case C_BUILTIN_STDC_COUNT_ZEROS:
12046 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
12047 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
12048 case C_BUILTIN_STDC_LEADING_ONES:
12049 case C_BUILTIN_STDC_TRAILING_ONES:
12050 barg1 = build1_loc (loc, BIT_NOT_EXPR, type, arg);
12051 break;
12052 default:
12053 break;
12055 tree barg2 = NULL_TREE;
12056 switch (stdc_rid)
12058 case C_BUILTIN_STDC_BIT_WIDTH:
12059 case C_BUILTIN_STDC_LEADING_ONES:
12060 case C_BUILTIN_STDC_LEADING_ZEROS:
12061 case C_BUILTIN_STDC_TRAILING_ONES:
12062 case C_BUILTIN_STDC_TRAILING_ZEROS:
12063 barg2 = build_int_cst (integer_type_node, prec);
12064 break;
12065 case C_BUILTIN_STDC_FIRST_LEADING_ONE:
12066 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
12067 case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
12068 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
12069 barg2 = integer_minus_one_node;
12070 break;
12071 default:
12072 break;
12074 tree fndecl = NULL_TREE;
12075 switch (stdc_rid)
12077 case C_BUILTIN_STDC_BIT_CEIL:
12078 case C_BUILTIN_STDC_BIT_FLOOR:
12079 case C_BUILTIN_STDC_BIT_WIDTH:
12080 case C_BUILTIN_STDC_FIRST_LEADING_ONE:
12081 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
12082 case C_BUILTIN_STDC_LEADING_ONES:
12083 case C_BUILTIN_STDC_LEADING_ZEROS:
12084 fndecl = builtin_decl_explicit (BUILT_IN_CLZG);
12085 break;
12086 case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
12087 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
12088 case C_BUILTIN_STDC_TRAILING_ONES:
12089 case C_BUILTIN_STDC_TRAILING_ZEROS:
12090 fndecl = builtin_decl_explicit (BUILT_IN_CTZG);
12091 break;
12092 case C_BUILTIN_STDC_COUNT_ONES:
12093 case C_BUILTIN_STDC_COUNT_ZEROS:
12094 case C_BUILTIN_STDC_HAS_SINGLE_BIT:
12095 fndecl = builtin_decl_explicit (BUILT_IN_POPCOUNTG);
12096 break;
12097 default:
12098 gcc_unreachable ();
12100 /* Construct a call to __builtin_{clz,ctz,popcount}g. */
12101 int nargs = barg2 != NULL_TREE ? 2 : 1;
12102 vec<tree, va_gc> *args;
12103 vec_alloc (args, nargs);
12104 vec<tree, va_gc> *origtypes;
12105 vec_alloc (origtypes, nargs);
12106 auto_vec<location_t> arg_loc (nargs);
12107 args->quick_push (barg1);
12108 arg_loc.quick_push (arg_p->get_location ());
12109 origtypes->quick_push (arg_p->original_type);
12110 if (nargs == 2)
12112 args->quick_push (barg2);
12113 arg_loc.quick_push (loc);
12114 origtypes->quick_push (integer_type_node);
12116 expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
12117 args, origtypes);
12118 set_c_expr_source_range (&expr, loc, close_paren_loc);
12119 if (expr.value == error_mark_node)
12120 break;
12121 switch (stdc_rid)
12123 case C_BUILTIN_STDC_BIT_CEIL:
12124 case C_BUILTIN_STDC_BIT_FLOOR:
12125 --prec;
12126 /* FALLTHRU */
12127 case C_BUILTIN_STDC_BIT_WIDTH:
12128 expr.value = build2_loc (loc, MINUS_EXPR, integer_type_node,
12129 build_int_cst (integer_type_node,
12130 prec), expr.value);
12131 break;
12132 case C_BUILTIN_STDC_FIRST_LEADING_ONE:
12133 case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
12134 case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
12135 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
12136 expr.value = build2_loc (loc, PLUS_EXPR, integer_type_node,
12137 expr.value, integer_one_node);
12138 break;
12139 case C_BUILTIN_STDC_HAS_SINGLE_BIT:
12140 expr.value = build2_loc (loc, EQ_EXPR, boolean_type_node,
12141 expr.value, integer_one_node);
12142 break;
12143 default:
12144 break;
12147 if (stdc_rid != C_BUILTIN_STDC_BIT_CEIL
12148 && stdc_rid != C_BUILTIN_STDC_BIT_FLOOR)
12150 if (stdc_rid != C_BUILTIN_STDC_HAS_SINGLE_BIT)
12151 expr.value = fold_convert_loc (loc, unsigned_type_node,
12152 expr.value);
12153 break;
12155 /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
12156 or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
12157 warnings. The LSHIFT_EXPR is in dead code in that case. */
12158 if (integer_zerop (arg)
12159 || (stdc_rid == C_BUILTIN_STDC_BIT_CEIL && integer_onep (arg)))
12160 expr.value = build_int_cst (type, 0);
12161 else
12162 expr.value
12163 = build2_loc (loc, LSHIFT_EXPR, type,
12164 build_int_cst (type,
12165 (stdc_rid
12166 == C_BUILTIN_STDC_BIT_CEIL
12167 ? 2 : 1)), expr.value);
12168 if (stdc_rid == C_BUILTIN_STDC_BIT_CEIL)
12169 expr.value = build3_loc (loc, COND_EXPR, type,
12170 build2_loc (loc, LE_EXPR,
12171 boolean_type_node, arg,
12172 build_int_cst (type, 1)),
12173 build_int_cst (type, 1),
12174 expr.value);
12175 else
12176 expr.value = build3_loc (loc, COND_EXPR, type,
12177 build2_loc (loc, EQ_EXPR,
12178 boolean_type_node, arg,
12179 build_int_cst (type, 0)),
12180 build_int_cst (type, 0),
12181 expr.value);
12182 break;
12184 case RID_AT_SELECTOR:
12186 gcc_assert (c_dialect_objc ());
12187 c_parser_consume_token (parser);
12188 matching_parens parens;
12189 if (!parens.require_open (parser))
12191 expr.set_error ();
12192 break;
12194 tree sel = c_parser_objc_selector_arg (parser);
12195 location_t close_loc = c_parser_peek_token (parser)->location;
12196 parens.skip_until_found_close (parser);
12197 expr.value = objc_build_selector_expr (loc, sel);
12198 set_c_expr_source_range (&expr, loc, close_loc);
12200 break;
12201 case RID_AT_PROTOCOL:
12203 gcc_assert (c_dialect_objc ());
12204 c_parser_consume_token (parser);
12205 matching_parens parens;
12206 if (!parens.require_open (parser))
12208 expr.set_error ();
12209 break;
12211 if (c_parser_next_token_is_not (parser, CPP_NAME))
12213 c_parser_error (parser, "expected identifier");
12214 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
12215 expr.set_error ();
12216 break;
12218 tree id = c_parser_peek_token (parser)->value;
12219 c_parser_consume_token (parser);
12220 location_t close_loc = c_parser_peek_token (parser)->location;
12221 parens.skip_until_found_close (parser);
12222 expr.value = objc_build_protocol_expr (id);
12223 set_c_expr_source_range (&expr, loc, close_loc);
12225 break;
12226 case RID_AT_ENCODE:
12228 /* Extension to support C-structures in the archiver. */
12229 gcc_assert (c_dialect_objc ());
12230 c_parser_consume_token (parser);
12231 matching_parens parens;
12232 if (!parens.require_open (parser))
12234 expr.set_error ();
12235 break;
12237 t1 = c_parser_type_name (parser);
12238 if (t1 == NULL)
12240 expr.set_error ();
12241 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
12242 break;
12244 location_t close_loc = c_parser_peek_token (parser)->location;
12245 parens.skip_until_found_close (parser);
12246 tree type = groktypename (t1, NULL, NULL);
12247 expr.value = objc_build_encode_expr (type);
12248 set_c_expr_source_range (&expr, loc, close_loc);
12250 break;
12251 case RID_GENERIC:
12252 expr = c_parser_generic_selection (parser);
12253 break;
12254 case RID_OMP_ALL_MEMORY:
12255 gcc_assert (flag_openmp);
12256 c_parser_consume_token (parser);
12257 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
12258 "%<depend%> clause");
12259 expr.set_error ();
12260 break;
12261 /* C23 'nullptr' literal. */
12262 case RID_NULLPTR:
12263 c_parser_consume_token (parser);
12264 expr.value = nullptr_node;
12265 set_c_expr_source_range (&expr, tok_range);
12266 pedwarn_c11 (loc, OPT_Wpedantic,
12267 "ISO C does not support %qs before C23", "nullptr");
12268 break;
12269 case RID_TRUE:
12270 c_parser_consume_token (parser);
12271 expr.value = boolean_true_node;
12272 set_c_expr_source_range (&expr, tok_range);
12273 break;
12274 case RID_FALSE:
12275 c_parser_consume_token (parser);
12276 expr.value = boolean_false_node;
12277 set_c_expr_source_range (&expr, tok_range);
12278 break;
12279 default:
12280 c_parser_error (parser, "expected expression");
12281 expr.set_error ();
12282 break;
12284 break;
12285 case CPP_OPEN_SQUARE:
12286 if (c_dialect_objc ())
12288 tree receiver, args;
12289 c_parser_consume_token (parser);
12290 receiver = c_parser_objc_receiver (parser);
12291 args = c_parser_objc_message_args (parser);
12292 location_t close_loc = c_parser_peek_token (parser)->location;
12293 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
12294 "expected %<]%>");
12295 expr.value = objc_build_message_expr (receiver, args);
12296 set_c_expr_source_range (&expr, loc, close_loc);
12297 break;
12299 /* Else fall through to report error. */
12300 /* FALLTHRU */
12301 default:
12302 c_parser_error (parser, "expected expression");
12303 expr.set_error ();
12304 break;
12306 out:
12307 return c_parser_postfix_expression_after_primary
12308 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
12311 /* Parse a postfix expression after a parenthesized type name: the
12312 brace-enclosed initializer of a compound literal, possibly followed
12313 by some postfix operators. This is separate because it is not
12314 possible to tell until after the type name whether a cast
12315 expression has a cast or a compound literal, or whether the operand
12316 of sizeof is a parenthesized type name or starts with a compound
12317 literal. TYPE_LOC is the location where TYPE_NAME starts--the
12318 location of the first token after the parentheses around the type
12319 name. */
12321 static struct c_expr
12322 c_parser_postfix_expression_after_paren_type (c_parser *parser,
12323 struct c_declspecs *scspecs,
12324 struct c_type_name *type_name,
12325 location_t type_loc)
12327 tree type;
12328 struct c_expr init;
12329 bool non_const;
12330 struct c_expr expr;
12331 location_t start_loc;
12332 tree type_expr = NULL_TREE;
12333 bool type_expr_const = true;
12334 bool constexpr_p = scspecs ? scspecs->constexpr_p : false;
12335 unsigned int underspec_state = 0;
12336 check_compound_literal_type (type_loc, type_name);
12337 rich_location richloc (line_table, type_loc);
12338 start_loc = c_parser_peek_token (parser)->location;
12339 if (constexpr_p)
12341 underspec_state = start_underspecified_init (start_loc, NULL_TREE);
12342 /* A constexpr compound literal is subject to the constraints on
12343 underspecified declarations, which may not declare tags or
12344 members or structures or unions; it is undefined behavior to
12345 declare the members of an enumeration. Where the structure,
12346 union or enumeration type is declared within the compound
12347 literal initializer, this is diagnosed elsewhere as a result
12348 of the above call to start_underspecified_init. Diagnose
12349 here the case of declaring such a type in the type specifiers
12350 of the compound literal. */
12351 switch (type_name->specs->typespec_kind)
12353 case ctsk_tagfirstref:
12354 case ctsk_tagfirstref_attrs:
12355 error_at (type_loc, "%qT declared in %<constexpr%> compound literal",
12356 type_name->specs->type);
12357 break;
12359 case ctsk_tagdef:
12360 error_at (type_loc, "%qT defined in %<constexpr%> compound literal",
12361 type_name->specs->type);
12362 break;
12364 default:
12365 break;
12368 start_init (NULL_TREE, NULL,
12369 (global_bindings_p ()
12370 || (scspecs && scspecs->storage_class == csc_static)
12371 || constexpr_p), constexpr_p, &richloc);
12372 type = groktypename (type_name, &type_expr, &type_expr_const);
12373 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
12375 error_at (type_loc, "compound literal has variable size");
12376 type = error_mark_node;
12378 else if (TREE_CODE (type) == FUNCTION_TYPE)
12380 error_at (type_loc, "compound literal has function type");
12381 type = error_mark_node;
12383 if (constexpr_p && type != error_mark_node)
12385 tree type_no_array = strip_array_types (type);
12386 /* The type of a constexpr object must not be variably modified
12387 (which applies to all compound literals), volatile, atomic or
12388 restrict qualified or have a member with such a qualifier.
12389 const qualification is implicitly added. */
12390 if (TYPE_QUALS (type_no_array)
12391 & (TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC))
12392 error_at (type_loc, "invalid qualifiers for %<constexpr%> object");
12393 else if (RECORD_OR_UNION_TYPE_P (type_no_array)
12394 && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array))
12395 error_at (type_loc, "invalid qualifiers for field of "
12396 "%<constexpr%> object");
12397 type = c_build_qualified_type (type,
12398 (TYPE_QUALS (type_no_array)
12399 | TYPE_QUAL_CONST));
12401 init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
12402 if (constexpr_p)
12403 finish_underspecified_init (NULL_TREE, underspec_state);
12404 finish_init ();
12405 maybe_warn_string_init (type_loc, type, init);
12407 if (type != error_mark_node
12408 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
12409 && current_function_decl)
12411 error ("compound literal qualified by address-space qualifier");
12412 type = error_mark_node;
12415 if (!pedwarn_c90 (start_loc, OPT_Wpedantic,
12416 "ISO C90 forbids compound literals") && scspecs)
12417 pedwarn_c11 (start_loc, OPT_Wpedantic,
12418 "ISO C forbids storage class specifiers in compound literals "
12419 "before C23");
12420 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
12421 ? CONSTRUCTOR_NON_CONST (init.value)
12422 : init.original_code == C_MAYBE_CONST_EXPR);
12423 non_const |= !type_expr_const;
12424 unsigned int alignas_align = 0;
12425 if (type != error_mark_node
12426 && type_name->specs->align_log != -1)
12428 alignas_align = 1U << type_name->specs->align_log;
12429 if (alignas_align < min_align_of_type (type))
12431 error_at (type_name->specs->locations[cdw_alignas],
12432 "%<_Alignas%> specifiers cannot reduce "
12433 "alignment of compound literal");
12434 alignas_align = 0;
12437 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
12438 alignas_align, scspecs);
12439 set_c_expr_source_range (&expr, init.src_range);
12440 expr.m_decimal = 0;
12441 expr.original_code = ERROR_MARK;
12442 expr.original_type = NULL;
12443 if (type != error_mark_node
12444 && expr.value != error_mark_node
12445 && type_expr)
12447 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
12449 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
12450 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
12452 else
12454 gcc_assert (!non_const);
12455 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
12456 type_expr, expr.value);
12459 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
12462 /* Callback function for sizeof_pointer_memaccess_warning to compare
12463 types. */
12465 static bool
12466 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
12468 return comptypes (type1, type2) == 1;
12471 /* Warn for patterns where abs-like function appears to be used incorrectly,
12472 gracefully ignore any non-abs-like function. The warning location should
12473 be LOC. FNDECL is the declaration of called function, it must be a
12474 BUILT_IN_NORMAL function. ARG is the first and only argument of the
12475 call. */
12477 static void
12478 warn_for_abs (location_t loc, tree fndecl, tree arg)
12480 /* Avoid warning in unreachable subexpressions. */
12481 if (c_inhibit_evaluation_warnings)
12482 return;
12484 tree atype = TREE_TYPE (arg);
12486 /* Casts from pointers (and thus arrays and fndecls) will generate
12487 -Wint-conversion warnings. Most other wrong types hopefully lead to type
12488 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
12489 types and possibly other exotic types. */
12490 if (!INTEGRAL_TYPE_P (atype)
12491 && !SCALAR_FLOAT_TYPE_P (atype)
12492 && TREE_CODE (atype) != COMPLEX_TYPE)
12493 return;
12495 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
12497 switch (fcode)
12499 case BUILT_IN_ABS:
12500 case BUILT_IN_LABS:
12501 case BUILT_IN_LLABS:
12502 case BUILT_IN_IMAXABS:
12503 if (!INTEGRAL_TYPE_P (atype))
12505 if (SCALAR_FLOAT_TYPE_P (atype))
12506 warning_at (loc, OPT_Wabsolute_value,
12507 "using integer absolute value function %qD when "
12508 "argument is of floating-point type %qT",
12509 fndecl, atype);
12510 else if (TREE_CODE (atype) == COMPLEX_TYPE)
12511 warning_at (loc, OPT_Wabsolute_value,
12512 "using integer absolute value function %qD when "
12513 "argument is of complex type %qT", fndecl, atype);
12514 else
12515 gcc_unreachable ();
12516 return;
12518 if (TYPE_UNSIGNED (atype))
12519 warning_at (loc, OPT_Wabsolute_value,
12520 "taking the absolute value of unsigned type %qT "
12521 "has no effect", atype);
12522 break;
12524 CASE_FLT_FN (BUILT_IN_FABS):
12525 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
12526 if (!SCALAR_FLOAT_TYPE_P (atype)
12527 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
12529 if (INTEGRAL_TYPE_P (atype))
12530 warning_at (loc, OPT_Wabsolute_value,
12531 "using floating-point absolute value function %qD "
12532 "when argument is of integer type %qT", fndecl, atype);
12533 else if (DECIMAL_FLOAT_TYPE_P (atype))
12534 warning_at (loc, OPT_Wabsolute_value,
12535 "using floating-point absolute value function %qD "
12536 "when argument is of decimal floating-point type %qT",
12537 fndecl, atype);
12538 else if (TREE_CODE (atype) == COMPLEX_TYPE)
12539 warning_at (loc, OPT_Wabsolute_value,
12540 "using floating-point absolute value function %qD when "
12541 "argument is of complex type %qT", fndecl, atype);
12542 else
12543 gcc_unreachable ();
12544 return;
12546 break;
12548 CASE_FLT_FN (BUILT_IN_CABS):
12549 if (TREE_CODE (atype) != COMPLEX_TYPE)
12551 if (INTEGRAL_TYPE_P (atype))
12552 warning_at (loc, OPT_Wabsolute_value,
12553 "using complex absolute value function %qD when "
12554 "argument is of integer type %qT", fndecl, atype);
12555 else if (SCALAR_FLOAT_TYPE_P (atype))
12556 warning_at (loc, OPT_Wabsolute_value,
12557 "using complex absolute value function %qD when "
12558 "argument is of floating-point type %qT",
12559 fndecl, atype);
12560 else
12561 gcc_unreachable ();
12563 return;
12565 break;
12567 case BUILT_IN_FABSD32:
12568 case BUILT_IN_FABSD64:
12569 case BUILT_IN_FABSD128:
12570 if (!DECIMAL_FLOAT_TYPE_P (atype))
12572 if (INTEGRAL_TYPE_P (atype))
12573 warning_at (loc, OPT_Wabsolute_value,
12574 "using decimal floating-point absolute value "
12575 "function %qD when argument is of integer type %qT",
12576 fndecl, atype);
12577 else if (SCALAR_FLOAT_TYPE_P (atype))
12578 warning_at (loc, OPT_Wabsolute_value,
12579 "using decimal floating-point absolute value "
12580 "function %qD when argument is of floating-point "
12581 "type %qT", fndecl, atype);
12582 else if (TREE_CODE (atype) == COMPLEX_TYPE)
12583 warning_at (loc, OPT_Wabsolute_value,
12584 "using decimal floating-point absolute value "
12585 "function %qD when argument is of complex type %qT",
12586 fndecl, atype);
12587 else
12588 gcc_unreachable ();
12589 return;
12591 break;
12593 default:
12594 return;
12597 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
12598 return;
12600 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
12601 if (TREE_CODE (atype) == COMPLEX_TYPE)
12603 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
12604 atype = TREE_TYPE (atype);
12605 ftype = TREE_TYPE (ftype);
12608 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
12609 warning_at (loc, OPT_Wabsolute_value,
12610 "absolute value function %qD given an argument of type %qT "
12611 "but has parameter of type %qT which may cause truncation "
12612 "of value", fndecl, atype, ftype);
12616 /* Parse a postfix expression after the initial primary or compound
12617 literal; that is, parse a series of postfix operators.
12619 EXPR_LOC is the location of the primary expression. */
12621 static struct c_expr
12622 c_parser_postfix_expression_after_primary (c_parser *parser,
12623 location_t expr_loc,
12624 struct c_expr expr)
12626 struct c_expr orig_expr;
12627 tree ident, idx, len;
12628 location_t sizeof_arg_loc[6], comp_loc;
12629 tree sizeof_arg[6];
12630 unsigned int literal_zero_mask;
12631 unsigned int i;
12632 vec<tree, va_gc> *exprlist;
12633 vec<tree, va_gc> *origtypes = NULL;
12634 vec<location_t> arg_loc = vNULL;
12635 location_t start;
12636 location_t finish;
12638 while (true)
12640 location_t op_loc = c_parser_peek_token (parser)->location;
12641 switch (c_parser_peek_token (parser)->type)
12643 case CPP_OPEN_SQUARE:
12644 /* Array reference. */
12645 c_parser_consume_token (parser);
12646 idx = len = NULL_TREE;
12647 if (!c_omp_array_section_p
12648 || c_parser_next_token_is_not (parser, CPP_COLON))
12649 idx = c_parser_expression (parser).value;
12651 if (c_omp_array_section_p
12652 && c_parser_next_token_is (parser, CPP_COLON))
12654 c_parser_consume_token (parser);
12655 if (c_parser_next_token_is_not (parser, CPP_CLOSE_SQUARE))
12656 len = c_parser_expression (parser).value;
12658 expr.value = build_omp_array_section (op_loc, expr.value, idx,
12659 len);
12661 else
12662 expr.value = build_array_ref (op_loc, expr.value, idx);
12664 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
12665 "expected %<]%>");
12667 start = expr.get_start ();
12668 finish = parser->tokens_buf[0].location;
12669 set_c_expr_source_range (&expr, start, finish);
12670 expr.original_code = ERROR_MARK;
12671 expr.original_type = NULL;
12672 expr.m_decimal = 0;
12673 break;
12674 case CPP_OPEN_PAREN:
12675 /* Function call. */
12677 matching_parens parens;
12678 parens.consume_open (parser);
12679 for (i = 0; i < 6; i++)
12681 sizeof_arg[i] = NULL_TREE;
12682 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
12684 literal_zero_mask = 0;
12685 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12686 exprlist = NULL;
12687 else if (TREE_CODE (expr.value) == FUNCTION_DECL
12688 && fndecl_built_in_p (expr.value, BUILT_IN_CLASSIFY_TYPE)
12689 && c_parser_next_tokens_start_typename (parser,
12690 cla_prefer_id))
12692 /* __builtin_classify_type (type) */
12693 c_inhibit_evaluation_warnings++;
12694 in_alignof++;
12695 struct c_type_name *type = c_parser_type_name (parser);
12696 c_inhibit_evaluation_warnings--;
12697 in_alignof--;
12698 struct c_typespec ret;
12699 ret.expr = NULL_TREE;
12700 ret.spec = error_mark_node;
12701 ret.expr_const_operands = false;
12702 if (type != NULL)
12703 ret.spec = groktypename (type, &ret.expr,
12704 &ret.expr_const_operands);
12705 parens.skip_until_found_close (parser);
12706 expr.value = build_int_cst (integer_type_node,
12707 type_to_class (ret.spec));
12708 break;
12710 else
12711 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
12712 sizeof_arg_loc, sizeof_arg,
12713 &arg_loc, &literal_zero_mask);
12714 parens.skip_until_found_close (parser);
12716 orig_expr = expr;
12717 mark_exp_read (expr.value);
12718 if (warn_sizeof_pointer_memaccess)
12719 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
12720 expr.value, exprlist,
12721 sizeof_arg,
12722 sizeof_ptr_memacc_comptypes);
12723 if (TREE_CODE (expr.value) == FUNCTION_DECL)
12725 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
12726 && vec_safe_length (exprlist) == 3)
12728 tree arg0 = (*exprlist)[0];
12729 tree arg2 = (*exprlist)[2];
12730 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
12732 if (warn_absolute_value
12733 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
12734 && vec_safe_length (exprlist) == 1)
12735 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
12736 if (parser->omp_for_parse_state
12737 && parser->omp_for_parse_state->in_intervening_code
12738 && omp_runtime_api_call (expr.value))
12740 error_at (expr_loc, "calls to the OpenMP runtime API are "
12741 "not permitted in intervening code");
12742 parser->omp_for_parse_state->fail = true;
12744 if (warn_calloc_transposed_args)
12745 if (tree attr = lookup_attribute ("alloc_size",
12746 TYPE_ATTRIBUTES
12747 (TREE_TYPE (expr.value))))
12748 if (TREE_VALUE (attr) && TREE_CHAIN (TREE_VALUE (attr)))
12749 warn_for_calloc (sizeof_arg_loc, expr.value, exprlist,
12750 sizeof_arg, attr);
12753 start = expr.get_start ();
12754 finish = parser->tokens_buf[0].get_finish ();
12755 expr.value
12756 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
12757 exprlist, origtypes);
12758 set_c_expr_source_range (&expr, start, finish);
12759 expr.m_decimal = 0;
12761 expr.original_code = ERROR_MARK;
12762 if (TREE_CODE (expr.value) == INTEGER_CST
12763 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
12764 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
12765 expr.original_code = C_MAYBE_CONST_EXPR;
12766 expr.original_type = NULL;
12767 if (exprlist)
12769 release_tree_vector (exprlist);
12770 release_tree_vector (origtypes);
12772 arg_loc.release ();
12773 break;
12774 case CPP_DOT:
12775 /* Structure element reference. */
12776 c_parser_consume_token (parser);
12777 expr = default_function_array_conversion (expr_loc, expr);
12778 if (c_parser_next_token_is (parser, CPP_NAME))
12780 c_token *comp_tok = c_parser_peek_token (parser);
12781 ident = comp_tok->value;
12782 comp_loc = comp_tok->location;
12784 else
12786 c_parser_error (parser, "expected identifier");
12787 expr.set_error ();
12788 expr.original_code = ERROR_MARK;
12789 expr.original_type = NULL;
12790 return expr;
12792 start = expr.get_start ();
12793 finish = c_parser_peek_token (parser)->get_finish ();
12794 c_parser_consume_token (parser);
12795 expr.value = build_component_ref (op_loc, expr.value, ident,
12796 comp_loc, UNKNOWN_LOCATION);
12797 set_c_expr_source_range (&expr, start, finish);
12798 expr.original_code = ERROR_MARK;
12799 if (TREE_CODE (expr.value) != COMPONENT_REF)
12800 expr.original_type = NULL;
12801 else
12803 /* Remember the original type of a bitfield. */
12804 tree field = TREE_OPERAND (expr.value, 1);
12805 if (TREE_CODE (field) != FIELD_DECL)
12806 expr.original_type = NULL;
12807 else
12808 expr.original_type = DECL_BIT_FIELD_TYPE (field);
12810 expr.m_decimal = 0;
12811 break;
12812 case CPP_DEREF:
12813 /* Structure element reference. */
12814 c_parser_consume_token (parser);
12815 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
12816 if (c_parser_next_token_is (parser, CPP_NAME))
12818 c_token *comp_tok = c_parser_peek_token (parser);
12819 ident = comp_tok->value;
12820 comp_loc = comp_tok->location;
12822 else
12824 c_parser_error (parser, "expected identifier");
12825 expr.set_error ();
12826 expr.original_code = ERROR_MARK;
12827 expr.original_type = NULL;
12828 return expr;
12830 start = expr.get_start ();
12831 finish = c_parser_peek_token (parser)->get_finish ();
12832 c_parser_consume_token (parser);
12833 expr.value = build_component_ref (op_loc,
12834 build_indirect_ref (op_loc,
12835 expr.value,
12836 RO_ARROW),
12837 ident, comp_loc,
12838 expr.get_location ());
12839 set_c_expr_source_range (&expr, start, finish);
12840 expr.original_code = ERROR_MARK;
12841 if (TREE_CODE (expr.value) != COMPONENT_REF)
12842 expr.original_type = NULL;
12843 else
12845 /* Remember the original type of a bitfield. */
12846 tree field = TREE_OPERAND (expr.value, 1);
12847 if (TREE_CODE (field) != FIELD_DECL)
12848 expr.original_type = NULL;
12849 else
12850 expr.original_type = DECL_BIT_FIELD_TYPE (field);
12852 expr.m_decimal = 0;
12853 break;
12854 case CPP_PLUS_PLUS:
12855 /* Postincrement. */
12856 start = expr.get_start ();
12857 finish = c_parser_peek_token (parser)->get_finish ();
12858 c_parser_consume_token (parser);
12859 expr = default_function_array_read_conversion (expr_loc, expr);
12860 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
12861 expr.value, false);
12862 set_c_expr_source_range (&expr, start, finish);
12863 expr.original_code = ERROR_MARK;
12864 expr.original_type = NULL;
12865 break;
12866 case CPP_MINUS_MINUS:
12867 /* Postdecrement. */
12868 start = expr.get_start ();
12869 finish = c_parser_peek_token (parser)->get_finish ();
12870 c_parser_consume_token (parser);
12871 expr = default_function_array_read_conversion (expr_loc, expr);
12872 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
12873 expr.value, false);
12874 set_c_expr_source_range (&expr, start, finish);
12875 expr.original_code = ERROR_MARK;
12876 expr.original_type = NULL;
12877 break;
12878 default:
12879 return expr;
12884 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
12886 expression:
12887 assignment-expression
12888 expression , assignment-expression
12891 static struct c_expr
12892 c_parser_expression (c_parser *parser)
12894 location_t tloc = c_parser_peek_token (parser)->location;
12895 struct c_expr expr;
12896 expr = c_parser_expr_no_commas (parser, NULL);
12897 if (c_parser_next_token_is (parser, CPP_COMMA))
12898 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
12899 while (c_parser_next_token_is (parser, CPP_COMMA))
12901 struct c_expr next;
12902 tree lhsval;
12903 location_t loc = c_parser_peek_token (parser)->location;
12904 location_t expr_loc;
12905 c_parser_consume_token (parser);
12906 expr_loc = c_parser_peek_token (parser)->location;
12907 lhsval = expr.value;
12908 while (TREE_CODE (lhsval) == COMPOUND_EXPR
12909 || TREE_CODE (lhsval) == NOP_EXPR)
12911 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
12912 lhsval = TREE_OPERAND (lhsval, 1);
12913 else
12914 lhsval = TREE_OPERAND (lhsval, 0);
12916 if (DECL_P (lhsval) || handled_component_p (lhsval))
12917 mark_exp_read (lhsval);
12918 next = c_parser_expr_no_commas (parser, NULL);
12919 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
12920 expr.value = build_compound_expr (loc, expr.value, next.value);
12921 expr.original_code = COMPOUND_EXPR;
12922 expr.original_type = next.original_type;
12923 expr.m_decimal = 0;
12925 return expr;
12928 /* Parse an expression and convert functions or arrays to pointers and
12929 lvalues to rvalues. */
12931 static struct c_expr
12932 c_parser_expression_conv (c_parser *parser)
12934 struct c_expr expr;
12935 location_t loc = c_parser_peek_token (parser)->location;
12936 expr = c_parser_expression (parser);
12937 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
12938 return expr;
12941 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
12942 argument is a literal zero alone and if so, set it in literal_zero_mask. */
12944 static inline void
12945 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
12946 unsigned int idx)
12948 if (idx >= HOST_BITS_PER_INT)
12949 return;
12951 c_token *tok = c_parser_peek_token (parser);
12952 switch (tok->type)
12954 case CPP_NUMBER:
12955 case CPP_CHAR:
12956 case CPP_WCHAR:
12957 case CPP_CHAR16:
12958 case CPP_CHAR32:
12959 case CPP_UTF8CHAR:
12960 /* If a parameter is literal zero alone, remember it
12961 for -Wmemset-transposed-args warning. */
12962 if (integer_zerop (tok->value)
12963 && !TREE_OVERFLOW (tok->value)
12964 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
12965 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
12966 *literal_zero_mask |= 1U << idx;
12967 default:
12968 break;
12972 /* Parse a non-empty list of expressions. If CONVERT_P, convert
12973 functions and arrays to pointers and lvalues to rvalues. If
12974 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
12975 locations of function arguments into this vector.
12977 nonempty-expr-list:
12978 assignment-expression
12979 nonempty-expr-list , assignment-expression
12982 static vec<tree, va_gc> *
12983 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
12984 vec<tree, va_gc> **p_orig_types,
12985 location_t *sizeof_arg_loc, tree *sizeof_arg,
12986 vec<location_t> *locations,
12987 unsigned int *literal_zero_mask)
12989 vec<tree, va_gc> *ret;
12990 vec<tree, va_gc> *orig_types;
12991 struct c_expr expr;
12992 unsigned int idx = 0;
12993 bool save_c_omp_array_section_p = c_omp_array_section_p;
12994 c_omp_array_section_p = false;
12996 ret = make_tree_vector ();
12997 if (p_orig_types == NULL)
12998 orig_types = NULL;
12999 else
13000 orig_types = make_tree_vector ();
13002 if (literal_zero_mask)
13003 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
13004 expr = c_parser_expr_no_commas (parser, NULL);
13005 if (convert_p)
13006 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
13007 if (fold_p)
13008 expr.value = c_fully_fold (expr.value, false, NULL);
13009 ret->quick_push (expr.value);
13010 if (orig_types)
13011 orig_types->quick_push (expr.original_type);
13012 if (locations)
13013 locations->safe_push (expr.get_location ());
13014 if (sizeof_arg != NULL
13015 && (expr.original_code == SIZEOF_EXPR
13016 || expr.original_code == PAREN_SIZEOF_EXPR))
13018 sizeof_arg[0] = c_last_sizeof_arg;
13019 sizeof_arg_loc[0] = c_last_sizeof_loc;
13021 while (c_parser_next_token_is (parser, CPP_COMMA))
13023 c_parser_consume_token (parser);
13024 if (literal_zero_mask)
13025 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
13026 expr = c_parser_expr_no_commas (parser, NULL);
13027 if (convert_p)
13028 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
13029 true);
13030 if (fold_p)
13031 expr.value = c_fully_fold (expr.value, false, NULL);
13032 vec_safe_push (ret, expr.value);
13033 if (orig_types)
13034 vec_safe_push (orig_types, expr.original_type);
13035 if (locations)
13036 locations->safe_push (expr.get_location ());
13037 if (++idx < 6
13038 && sizeof_arg != NULL
13039 && (expr.original_code == SIZEOF_EXPR
13040 || expr.original_code == PAREN_SIZEOF_EXPR))
13042 sizeof_arg[idx] = c_last_sizeof_arg;
13043 sizeof_arg_loc[idx] = c_last_sizeof_loc;
13046 if (orig_types)
13047 *p_orig_types = orig_types;
13048 c_omp_array_section_p = save_c_omp_array_section_p;
13049 return ret;
13052 /* Parse Objective-C-specific constructs. */
13054 /* Parse an objc-class-definition.
13056 objc-class-definition:
13057 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
13058 objc-class-instance-variables[opt] objc-methodprotolist @end
13059 @implementation identifier objc-superclass[opt]
13060 objc-class-instance-variables[opt]
13061 @interface identifier ( identifier ) objc-protocol-refs[opt]
13062 objc-methodprotolist @end
13063 @interface identifier ( ) objc-protocol-refs[opt]
13064 objc-methodprotolist @end
13065 @implementation identifier ( identifier )
13067 objc-superclass:
13068 : identifier
13070 "@interface identifier (" must start "@interface identifier (
13071 identifier ) ...": objc-methodprotolist in the first production may
13072 not start with a parenthesized identifier as a declarator of a data
13073 definition with no declaration specifiers if the objc-superclass,
13074 objc-protocol-refs and objc-class-instance-variables are omitted. */
13076 static void
13077 c_parser_objc_class_definition (c_parser *parser, tree attributes)
13079 bool iface_p;
13080 tree id1;
13081 tree superclass;
13082 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
13083 iface_p = true;
13084 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
13085 iface_p = false;
13086 else
13087 gcc_unreachable ();
13089 c_parser_consume_token (parser);
13090 if (c_parser_next_token_is_not (parser, CPP_NAME))
13092 c_parser_error (parser, "expected identifier");
13093 return;
13095 id1 = c_parser_peek_token (parser)->value;
13096 location_t loc1 = c_parser_peek_token (parser)->location;
13097 c_parser_consume_token (parser);
13098 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13100 /* We have a category or class extension. */
13101 tree id2;
13102 tree proto = NULL_TREE;
13103 matching_parens parens;
13104 parens.consume_open (parser);
13105 if (c_parser_next_token_is_not (parser, CPP_NAME))
13107 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
13109 /* We have a class extension. */
13110 id2 = NULL_TREE;
13112 else
13114 c_parser_error (parser, "expected identifier or %<)%>");
13115 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
13116 return;
13119 else
13121 id2 = c_parser_peek_token (parser)->value;
13122 c_parser_consume_token (parser);
13124 parens.skip_until_found_close (parser);
13125 if (!iface_p)
13127 objc_start_category_implementation (id1, id2);
13128 return;
13130 if (c_parser_next_token_is (parser, CPP_LESS))
13131 proto = c_parser_objc_protocol_refs (parser);
13132 objc_start_category_interface (id1, id2, proto, attributes);
13133 c_parser_objc_methodprotolist (parser);
13134 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13135 objc_finish_interface ();
13136 return;
13138 if (c_parser_next_token_is (parser, CPP_COLON))
13140 c_parser_consume_token (parser);
13141 if (c_parser_next_token_is_not (parser, CPP_NAME))
13143 c_parser_error (parser, "expected identifier");
13144 return;
13146 superclass = c_parser_peek_token (parser)->value;
13147 c_parser_consume_token (parser);
13149 else
13150 superclass = NULL_TREE;
13151 if (iface_p)
13153 tree proto = NULL_TREE;
13154 if (c_parser_next_token_is (parser, CPP_LESS))
13155 proto = c_parser_objc_protocol_refs (parser);
13156 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
13158 else
13159 objc_start_class_implementation (id1, superclass);
13160 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13161 c_parser_objc_class_instance_variables (parser);
13162 if (iface_p)
13164 objc_continue_interface ();
13165 c_parser_objc_methodprotolist (parser);
13166 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13167 objc_finish_interface ();
13169 else
13171 objc_continue_implementation ();
13172 return;
13176 /* Parse objc-class-instance-variables.
13178 objc-class-instance-variables:
13179 { objc-instance-variable-decl-list[opt] }
13181 objc-instance-variable-decl-list:
13182 objc-visibility-spec
13183 objc-instance-variable-decl ;
13185 objc-instance-variable-decl-list objc-visibility-spec
13186 objc-instance-variable-decl-list objc-instance-variable-decl ;
13187 objc-instance-variable-decl-list ;
13189 objc-visibility-spec:
13190 @private
13191 @protected
13192 @public
13194 objc-instance-variable-decl:
13195 struct-declaration
13198 static void
13199 c_parser_objc_class_instance_variables (c_parser *parser)
13201 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
13202 c_parser_consume_token (parser);
13203 while (c_parser_next_token_is_not (parser, CPP_EOF))
13205 tree decls;
13206 /* Parse any stray semicolon. */
13207 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
13209 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13210 "extra semicolon");
13211 c_parser_consume_token (parser);
13212 continue;
13214 /* Stop if at the end of the instance variables. */
13215 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
13217 c_parser_consume_token (parser);
13218 break;
13220 /* Parse any objc-visibility-spec. */
13221 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
13223 c_parser_consume_token (parser);
13224 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
13225 continue;
13227 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
13229 c_parser_consume_token (parser);
13230 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
13231 continue;
13233 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
13235 c_parser_consume_token (parser);
13236 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
13237 continue;
13239 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
13241 c_parser_consume_token (parser);
13242 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
13243 continue;
13245 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
13247 c_parser_pragma (parser, pragma_external, NULL);
13248 continue;
13251 /* Parse some comma-separated declarations. */
13252 decls = c_parser_struct_declaration (parser, NULL);
13253 if (decls == NULL)
13255 /* There is a syntax error. We want to skip the offending
13256 tokens up to the next ';' (included) or '}'
13257 (excluded). */
13259 /* First, skip manually a ')' or ']'. This is because they
13260 reduce the nesting level, so c_parser_skip_until_found()
13261 wouldn't be able to skip past them. */
13262 c_token *token = c_parser_peek_token (parser);
13263 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
13264 c_parser_consume_token (parser);
13266 /* Then, do the standard skipping. */
13267 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13269 /* We hopefully recovered. Start normal parsing again. */
13270 parser->error = false;
13271 continue;
13273 else
13275 /* Comma-separated instance variables are chained together
13276 in reverse order; add them one by one. */
13277 tree ivar = nreverse (decls);
13278 for (; ivar; ivar = DECL_CHAIN (ivar))
13279 objc_add_instance_variable (copy_node (ivar));
13281 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13285 /* Parse an objc-class-declaration.
13287 objc-class-declaration:
13288 @class identifier-list ;
13291 static void
13292 c_parser_objc_class_declaration (c_parser *parser)
13294 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
13295 c_parser_consume_token (parser);
13296 /* Any identifiers, including those declared as type names, are OK
13297 here. */
13298 while (true)
13300 tree id;
13301 if (c_parser_next_token_is_not (parser, CPP_NAME))
13303 c_parser_error (parser, "expected identifier");
13304 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13305 parser->error = false;
13306 return;
13308 id = c_parser_peek_token (parser)->value;
13309 objc_declare_class (id);
13310 c_parser_consume_token (parser);
13311 if (c_parser_next_token_is (parser, CPP_COMMA))
13312 c_parser_consume_token (parser);
13313 else
13314 break;
13316 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13319 /* Parse an objc-alias-declaration.
13321 objc-alias-declaration:
13322 @compatibility_alias identifier identifier ;
13325 static void
13326 c_parser_objc_alias_declaration (c_parser *parser)
13328 tree id1, id2;
13329 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
13330 c_parser_consume_token (parser);
13331 if (c_parser_next_token_is_not (parser, CPP_NAME))
13333 c_parser_error (parser, "expected identifier");
13334 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13335 return;
13337 id1 = c_parser_peek_token (parser)->value;
13338 c_parser_consume_token (parser);
13339 if (c_parser_next_token_is_not (parser, CPP_NAME))
13341 c_parser_error (parser, "expected identifier");
13342 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
13343 return;
13345 id2 = c_parser_peek_token (parser)->value;
13346 c_parser_consume_token (parser);
13347 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13348 objc_declare_alias (id1, id2);
13351 /* Parse an objc-protocol-definition.
13353 objc-protocol-definition:
13354 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
13355 @protocol identifier-list ;
13357 "@protocol identifier ;" should be resolved as "@protocol
13358 identifier-list ;": objc-methodprotolist may not start with a
13359 semicolon in the first alternative if objc-protocol-refs are
13360 omitted. */
13362 static void
13363 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
13365 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
13367 c_parser_consume_token (parser);
13368 if (c_parser_next_token_is_not (parser, CPP_NAME))
13370 c_parser_error (parser, "expected identifier");
13371 return;
13373 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13374 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
13376 /* Any identifiers, including those declared as type names, are
13377 OK here. */
13378 while (true)
13380 tree id;
13381 if (c_parser_next_token_is_not (parser, CPP_NAME))
13383 c_parser_error (parser, "expected identifier");
13384 break;
13386 id = c_parser_peek_token (parser)->value;
13387 objc_declare_protocol (id, attributes);
13388 c_parser_consume_token (parser);
13389 if (c_parser_next_token_is (parser, CPP_COMMA))
13390 c_parser_consume_token (parser);
13391 else
13392 break;
13394 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13396 else
13398 tree id = c_parser_peek_token (parser)->value;
13399 tree proto = NULL_TREE;
13400 c_parser_consume_token (parser);
13401 if (c_parser_next_token_is (parser, CPP_LESS))
13402 proto = c_parser_objc_protocol_refs (parser);
13403 parser->objc_pq_context = true;
13404 objc_start_protocol (id, proto, attributes);
13405 c_parser_objc_methodprotolist (parser);
13406 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
13407 parser->objc_pq_context = false;
13408 objc_finish_interface ();
13412 /* Parse an objc-method-type.
13414 objc-method-type:
13418 Return true if it is a class method (+) and false if it is
13419 an instance method (-).
13421 static inline bool
13422 c_parser_objc_method_type (c_parser *parser)
13424 switch (c_parser_peek_token (parser)->type)
13426 case CPP_PLUS:
13427 c_parser_consume_token (parser);
13428 return true;
13429 case CPP_MINUS:
13430 c_parser_consume_token (parser);
13431 return false;
13432 default:
13433 gcc_unreachable ();
13437 /* Parse an objc-method-definition.
13439 objc-method-definition:
13440 objc-method-type objc-method-decl ;[opt] compound-statement
13443 static void
13444 c_parser_objc_method_definition (c_parser *parser)
13446 bool is_class_method = c_parser_objc_method_type (parser);
13447 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
13448 parser->objc_pq_context = true;
13449 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
13450 &expr);
13451 if (decl == error_mark_node)
13452 return; /* Bail here. */
13454 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
13456 c_parser_consume_token (parser);
13457 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13458 "extra semicolon in method definition specified");
13461 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13463 c_parser_error (parser, "expected %<{%>");
13464 return;
13467 parser->objc_pq_context = false;
13468 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
13470 add_stmt (c_parser_compound_statement (parser));
13471 objc_finish_method_definition (current_function_decl);
13473 else
13475 /* This code is executed when we find a method definition
13476 outside of an @implementation context (or invalid for other
13477 reasons). Parse the method (to keep going) but do not emit
13478 any code.
13480 c_parser_compound_statement (parser);
13484 /* Parse an objc-methodprotolist.
13486 objc-methodprotolist:
13487 empty
13488 objc-methodprotolist objc-methodproto
13489 objc-methodprotolist declaration
13490 objc-methodprotolist ;
13491 @optional
13492 @required
13494 The declaration is a data definition, which may be missing
13495 declaration specifiers under the same rules and diagnostics as
13496 other data definitions outside functions, and the stray semicolon
13497 is diagnosed the same way as a stray semicolon outside a
13498 function. */
13500 static void
13501 c_parser_objc_methodprotolist (c_parser *parser)
13503 while (true)
13505 /* The list is terminated by @end. */
13506 switch (c_parser_peek_token (parser)->type)
13508 case CPP_SEMICOLON:
13509 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
13510 "ISO C does not allow extra %<;%> outside of a function");
13511 c_parser_consume_token (parser);
13512 break;
13513 case CPP_PLUS:
13514 case CPP_MINUS:
13515 c_parser_objc_methodproto (parser);
13516 break;
13517 case CPP_PRAGMA:
13518 c_parser_pragma (parser, pragma_external, NULL);
13519 break;
13520 case CPP_EOF:
13521 return;
13522 default:
13523 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
13524 return;
13525 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
13526 c_parser_objc_at_property_declaration (parser);
13527 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
13529 objc_set_method_opt (true);
13530 c_parser_consume_token (parser);
13532 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
13534 objc_set_method_opt (false);
13535 c_parser_consume_token (parser);
13537 else
13538 c_parser_declaration_or_fndef (parser, false, false, true,
13539 false, true);
13540 break;
13545 /* Parse an objc-methodproto.
13547 objc-methodproto:
13548 objc-method-type objc-method-decl ;
13551 static void
13552 c_parser_objc_methodproto (c_parser *parser)
13554 bool is_class_method = c_parser_objc_method_type (parser);
13555 tree decl, attributes = NULL_TREE;
13557 /* Remember protocol qualifiers in prototypes. */
13558 parser->objc_pq_context = true;
13559 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
13560 NULL);
13561 /* Forget protocol qualifiers now. */
13562 parser->objc_pq_context = false;
13564 /* Do not allow the presence of attributes to hide an erroneous
13565 method implementation in the interface section. */
13566 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
13568 c_parser_error (parser, "expected %<;%>");
13569 return;
13572 if (decl != error_mark_node)
13573 objc_add_method_declaration (is_class_method, decl, attributes);
13575 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13578 /* If we are at a position that method attributes may be present, check that
13579 there are not any parsed already (a syntax error) and then collect any
13580 specified at the current location. Finally, if new attributes were present,
13581 check that the next token is legal ( ';' for decls and '{' for defs). */
13583 static bool
13584 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
13586 bool bad = false;
13587 if (*attributes)
13589 c_parser_error (parser,
13590 "method attributes must be specified at the end only");
13591 *attributes = NULL_TREE;
13592 bad = true;
13595 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
13596 *attributes = c_parser_gnu_attributes (parser);
13598 /* If there were no attributes here, just report any earlier error. */
13599 if (*attributes == NULL_TREE || bad)
13600 return bad;
13602 /* If the attributes are followed by a ; or {, then just report any earlier
13603 error. */
13604 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
13605 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
13606 return bad;
13608 /* We've got attributes, but not at the end. */
13609 c_parser_error (parser,
13610 "expected %<;%> or %<{%> after method attribute definition");
13611 return true;
13614 /* Parse an objc-method-decl.
13616 objc-method-decl:
13617 ( objc-type-name ) objc-selector
13618 objc-selector
13619 ( objc-type-name ) objc-keyword-selector objc-optparmlist
13620 objc-keyword-selector objc-optparmlist
13621 gnu-attributes
13623 objc-keyword-selector:
13624 objc-keyword-decl
13625 objc-keyword-selector objc-keyword-decl
13627 objc-keyword-decl:
13628 objc-selector : ( objc-type-name ) identifier
13629 objc-selector : identifier
13630 : ( objc-type-name ) identifier
13631 : identifier
13633 objc-optparmlist:
13634 objc-optparms objc-optellipsis
13636 objc-optparms:
13637 empty
13638 objc-opt-parms , parameter-declaration
13640 objc-optellipsis:
13641 empty
13642 , ...
13645 static tree
13646 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
13647 tree *attributes, tree *expr)
13649 tree type = NULL_TREE;
13650 tree sel;
13651 tree parms = NULL_TREE;
13652 bool ellipsis = false;
13653 bool attr_err = false;
13655 *attributes = NULL_TREE;
13656 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13658 matching_parens parens;
13659 parens.consume_open (parser);
13660 type = c_parser_objc_type_name (parser);
13661 parens.skip_until_found_close (parser);
13663 sel = c_parser_objc_selector (parser);
13664 /* If there is no selector, or a colon follows, we have an
13665 objc-keyword-selector. If there is a selector, and a colon does
13666 not follow, that selector ends the objc-method-decl. */
13667 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
13669 tree tsel = sel;
13670 tree list = NULL_TREE;
13671 while (true)
13673 tree atype = NULL_TREE, id, keyworddecl;
13674 tree param_attr = NULL_TREE;
13675 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13676 break;
13677 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13679 c_parser_consume_token (parser);
13680 atype = c_parser_objc_type_name (parser);
13681 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
13682 "expected %<)%>");
13684 /* New ObjC allows attributes on method parameters. */
13685 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
13686 param_attr = c_parser_gnu_attributes (parser);
13687 if (c_parser_next_token_is_not (parser, CPP_NAME))
13689 c_parser_error (parser, "expected identifier");
13690 return error_mark_node;
13692 id = c_parser_peek_token (parser)->value;
13693 c_parser_consume_token (parser);
13694 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
13695 list = chainon (list, keyworddecl);
13696 tsel = c_parser_objc_selector (parser);
13697 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
13698 break;
13701 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
13703 /* Parse the optional parameter list. Optional Objective-C
13704 method parameters follow the C syntax, and may include '...'
13705 to denote a variable number of arguments. */
13706 parms = make_node (TREE_LIST);
13707 while (c_parser_next_token_is (parser, CPP_COMMA))
13709 struct c_parm *parm;
13710 c_parser_consume_token (parser);
13711 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
13713 ellipsis = true;
13714 c_parser_consume_token (parser);
13715 attr_err |= c_parser_objc_maybe_method_attributes
13716 (parser, attributes) ;
13717 break;
13719 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
13720 if (parm == NULL)
13721 break;
13722 parms = chainon (parms,
13723 build_tree_list (NULL_TREE, grokparm (parm, expr)));
13725 sel = list;
13727 else
13728 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
13730 if (sel == NULL)
13732 c_parser_error (parser, "objective-c method declaration is expected");
13733 return error_mark_node;
13736 if (attr_err)
13737 return error_mark_node;
13739 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
13742 /* Parse an objc-type-name.
13744 objc-type-name:
13745 objc-type-qualifiers[opt] type-name
13746 objc-type-qualifiers[opt]
13748 objc-type-qualifiers:
13749 objc-type-qualifier
13750 objc-type-qualifiers objc-type-qualifier
13752 objc-type-qualifier: one of
13753 in out inout bycopy byref oneway
13756 static tree
13757 c_parser_objc_type_name (c_parser *parser)
13759 tree quals = NULL_TREE;
13760 struct c_type_name *type_name = NULL;
13761 tree type = NULL_TREE;
13762 while (true)
13764 c_token *token = c_parser_peek_token (parser);
13765 if (token->type == CPP_KEYWORD
13766 && (token->keyword == RID_IN
13767 || token->keyword == RID_OUT
13768 || token->keyword == RID_INOUT
13769 || token->keyword == RID_BYCOPY
13770 || token->keyword == RID_BYREF
13771 || token->keyword == RID_ONEWAY))
13773 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
13774 c_parser_consume_token (parser);
13776 else
13777 break;
13779 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
13780 type_name = c_parser_type_name (parser);
13781 if (type_name)
13782 type = groktypename (type_name, NULL, NULL);
13784 /* If the type is unknown, and error has already been produced and
13785 we need to recover from the error. In that case, use NULL_TREE
13786 for the type, as if no type had been specified; this will use the
13787 default type ('id') which is good for error recovery. */
13788 if (type == error_mark_node)
13789 type = NULL_TREE;
13791 return build_tree_list (quals, type);
13794 /* Parse objc-protocol-refs.
13796 objc-protocol-refs:
13797 < identifier-list >
13800 static tree
13801 c_parser_objc_protocol_refs (c_parser *parser)
13803 tree list = NULL_TREE;
13804 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
13805 c_parser_consume_token (parser);
13806 /* Any identifiers, including those declared as type names, are OK
13807 here. */
13808 while (true)
13810 tree id;
13811 if (c_parser_next_token_is_not (parser, CPP_NAME))
13813 c_parser_error (parser, "expected identifier");
13814 break;
13816 id = c_parser_peek_token (parser)->value;
13817 list = chainon (list, build_tree_list (NULL_TREE, id));
13818 c_parser_consume_token (parser);
13819 if (c_parser_next_token_is (parser, CPP_COMMA))
13820 c_parser_consume_token (parser);
13821 else
13822 break;
13824 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
13825 return list;
13828 /* Parse an objc-try-catch-finally-statement.
13830 objc-try-catch-finally-statement:
13831 @try compound-statement objc-catch-list[opt]
13832 @try compound-statement objc-catch-list[opt] @finally compound-statement
13834 objc-catch-list:
13835 @catch ( objc-catch-parameter-declaration ) compound-statement
13836 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
13838 objc-catch-parameter-declaration:
13839 parameter-declaration
13840 '...'
13842 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
13844 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
13845 for C++. Keep them in sync. */
13847 static void
13848 c_parser_objc_try_catch_finally_statement (c_parser *parser)
13850 location_t location;
13851 tree stmt;
13853 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
13854 c_parser_consume_token (parser);
13855 location = c_parser_peek_token (parser)->location;
13856 objc_maybe_warn_exceptions (location);
13857 stmt = c_parser_compound_statement (parser);
13858 objc_begin_try_stmt (location, stmt);
13860 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
13862 struct c_parm *parm;
13863 tree parameter_declaration = error_mark_node;
13864 bool seen_open_paren = false;
13866 c_parser_consume_token (parser);
13867 matching_parens parens;
13868 if (!parens.require_open (parser))
13869 seen_open_paren = true;
13870 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
13872 /* We have "@catch (...)" (where the '...' are literally
13873 what is in the code). Skip the '...'.
13874 parameter_declaration is set to NULL_TREE, and
13875 objc_being_catch_clauses() knows that that means
13876 '...'. */
13877 c_parser_consume_token (parser);
13878 parameter_declaration = NULL_TREE;
13880 else
13882 /* We have "@catch (NSException *exception)" or something
13883 like that. Parse the parameter declaration. */
13884 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
13885 if (parm == NULL)
13886 parameter_declaration = error_mark_node;
13887 else
13888 parameter_declaration = grokparm (parm, NULL);
13890 if (seen_open_paren)
13891 parens.require_close (parser);
13892 else
13894 /* If there was no open parenthesis, we are recovering from
13895 an error, and we are trying to figure out what mistake
13896 the user has made. */
13898 /* If there is an immediate closing parenthesis, the user
13899 probably forgot the opening one (ie, they typed "@catch
13900 NSException *e)". Parse the closing parenthesis and keep
13901 going. */
13902 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
13903 c_parser_consume_token (parser);
13905 /* If these is no immediate closing parenthesis, the user
13906 probably doesn't know that parenthesis are required at
13907 all (ie, they typed "@catch NSException *e"). So, just
13908 forget about the closing parenthesis and keep going. */
13910 objc_begin_catch_clause (parameter_declaration);
13911 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
13912 c_parser_compound_statement_nostart (parser);
13913 objc_finish_catch_clause ();
13915 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
13917 c_parser_consume_token (parser);
13918 location = c_parser_peek_token (parser)->location;
13919 stmt = c_parser_compound_statement (parser);
13920 objc_build_finally_clause (location, stmt);
13922 objc_finish_try_stmt ();
13925 /* Parse an objc-synchronized-statement.
13927 objc-synchronized-statement:
13928 @synchronized ( expression ) compound-statement
13931 static void
13932 c_parser_objc_synchronized_statement (c_parser *parser)
13934 location_t loc;
13935 tree expr, stmt;
13936 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
13937 c_parser_consume_token (parser);
13938 loc = c_parser_peek_token (parser)->location;
13939 objc_maybe_warn_exceptions (loc);
13940 matching_parens parens;
13941 if (parens.require_open (parser))
13943 struct c_expr ce = c_parser_expression (parser);
13944 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
13945 expr = ce.value;
13946 expr = c_fully_fold (expr, false, NULL);
13947 parens.skip_until_found_close (parser);
13949 else
13950 expr = error_mark_node;
13951 stmt = c_parser_compound_statement (parser);
13952 objc_build_synchronized (loc, expr, stmt);
13955 /* Parse an objc-selector; return NULL_TREE without an error if the
13956 next token is not an objc-selector.
13958 objc-selector:
13959 identifier
13960 one of
13961 enum struct union if else while do for switch case default
13962 break continue return goto asm sizeof typeof typeof_unqual __alignof
13963 unsigned long const short volatile signed restrict _Complex
13964 in out inout bycopy byref oneway int char float double void _Bool
13965 _Atomic
13967 ??? Why this selection of keywords but not, for example, storage
13968 class specifiers? */
13970 static tree
13971 c_parser_objc_selector (c_parser *parser)
13973 c_token *token = c_parser_peek_token (parser);
13974 tree value = token->value;
13975 if (token->type == CPP_NAME)
13977 c_parser_consume_token (parser);
13978 return value;
13980 if (token->type != CPP_KEYWORD)
13981 return NULL_TREE;
13982 switch (token->keyword)
13984 case RID_ENUM:
13985 case RID_STRUCT:
13986 case RID_UNION:
13987 case RID_IF:
13988 case RID_ELSE:
13989 case RID_WHILE:
13990 case RID_DO:
13991 case RID_FOR:
13992 case RID_SWITCH:
13993 case RID_CASE:
13994 case RID_DEFAULT:
13995 case RID_BREAK:
13996 case RID_CONTINUE:
13997 case RID_RETURN:
13998 case RID_GOTO:
13999 case RID_ASM:
14000 case RID_SIZEOF:
14001 case RID_TYPEOF:
14002 case RID_TYPEOF_UNQUAL:
14003 case RID_ALIGNOF:
14004 case RID_UNSIGNED:
14005 case RID_LONG:
14006 case RID_CONST:
14007 case RID_SHORT:
14008 case RID_VOLATILE:
14009 case RID_SIGNED:
14010 case RID_RESTRICT:
14011 case RID_COMPLEX:
14012 case RID_IN:
14013 case RID_OUT:
14014 case RID_INOUT:
14015 case RID_BYCOPY:
14016 case RID_BYREF:
14017 case RID_ONEWAY:
14018 case RID_INT:
14019 case RID_CHAR:
14020 case RID_FLOAT:
14021 case RID_DOUBLE:
14022 CASE_RID_FLOATN_NX:
14023 case RID_VOID:
14024 case RID_BOOL:
14025 case RID_ATOMIC:
14026 case RID_AUTO_TYPE:
14027 case RID_INT_N_0:
14028 case RID_INT_N_1:
14029 case RID_INT_N_2:
14030 case RID_INT_N_3:
14031 c_parser_consume_token (parser);
14032 return value;
14033 default:
14034 return NULL_TREE;
14038 /* Parse an objc-selector-arg.
14040 objc-selector-arg:
14041 objc-selector
14042 objc-keywordname-list
14044 objc-keywordname-list:
14045 objc-keywordname
14046 objc-keywordname-list objc-keywordname
14048 objc-keywordname:
14049 objc-selector :
14053 static tree
14054 c_parser_objc_selector_arg (c_parser *parser)
14056 tree sel = c_parser_objc_selector (parser);
14057 tree list = NULL_TREE;
14058 if (sel
14059 && c_parser_next_token_is_not (parser, CPP_COLON)
14060 && c_parser_next_token_is_not (parser, CPP_SCOPE))
14061 return sel;
14062 while (true)
14064 if (c_parser_next_token_is (parser, CPP_SCOPE))
14066 c_parser_consume_token (parser);
14067 list = chainon (list, build_tree_list (sel, NULL_TREE));
14068 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
14070 else
14072 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14073 return list;
14074 list = chainon (list, build_tree_list (sel, NULL_TREE));
14076 sel = c_parser_objc_selector (parser);
14077 if (!sel
14078 && c_parser_next_token_is_not (parser, CPP_COLON)
14079 && c_parser_next_token_is_not (parser, CPP_SCOPE))
14080 break;
14082 return list;
14085 /* Parse an objc-receiver.
14087 objc-receiver:
14088 expression
14089 class-name
14090 type-name
14093 static tree
14094 c_parser_objc_receiver (c_parser *parser)
14096 location_t loc = c_parser_peek_token (parser)->location;
14098 if (c_parser_peek_token (parser)->type == CPP_NAME
14099 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
14100 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
14102 tree id = c_parser_peek_token (parser)->value;
14103 c_parser_consume_token (parser);
14104 return objc_get_class_reference (id);
14106 struct c_expr ce = c_parser_expression (parser);
14107 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
14108 return c_fully_fold (ce.value, false, NULL);
14111 /* Parse objc-message-args.
14113 objc-message-args:
14114 objc-selector
14115 objc-keywordarg-list
14117 objc-keywordarg-list:
14118 objc-keywordarg
14119 objc-keywordarg-list objc-keywordarg
14121 objc-keywordarg:
14122 objc-selector : objc-keywordexpr
14123 : objc-keywordexpr
14126 static tree
14127 c_parser_objc_message_args (c_parser *parser)
14129 tree sel = c_parser_objc_selector (parser);
14130 tree list = NULL_TREE;
14131 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
14132 return sel;
14133 while (true)
14135 tree keywordexpr;
14136 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14137 return error_mark_node;
14138 keywordexpr = c_parser_objc_keywordexpr (parser);
14139 list = chainon (list, build_tree_list (sel, keywordexpr));
14140 sel = c_parser_objc_selector (parser);
14141 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
14142 break;
14144 return list;
14147 /* Parse an objc-keywordexpr.
14149 objc-keywordexpr:
14150 nonempty-expr-list
14153 static tree
14154 c_parser_objc_keywordexpr (c_parser *parser)
14156 tree ret;
14157 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
14158 NULL, NULL, NULL, NULL);
14159 if (vec_safe_length (expr_list) == 1)
14161 /* Just return the expression, remove a level of
14162 indirection. */
14163 ret = (*expr_list)[0];
14165 else
14167 /* We have a comma expression, we will collapse later. */
14168 ret = build_tree_list_vec (expr_list);
14170 release_tree_vector (expr_list);
14171 return ret;
14174 /* A check, needed in several places, that ObjC interface, implementation or
14175 method definitions are not prefixed by incorrect items. */
14176 static bool
14177 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
14178 struct c_declspecs *specs)
14180 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
14181 || specs->typespec_kind != ctsk_none)
14183 c_parser_error (parser,
14184 "no type or storage class may be specified here,");
14185 c_parser_skip_to_end_of_block_or_statement (parser);
14186 return true;
14188 return false;
14191 /* Parse an Objective-C @property declaration. The syntax is:
14193 objc-property-declaration:
14194 '@property' objc-property-attributes[opt] struct-declaration ;
14196 objc-property-attributes:
14197 '(' objc-property-attribute-list ')'
14199 objc-property-attribute-list:
14200 objc-property-attribute
14201 objc-property-attribute-list, objc-property-attribute
14203 objc-property-attribute
14204 'getter' = identifier
14205 'setter' = identifier
14206 'readonly'
14207 'readwrite'
14208 'assign'
14209 'retain'
14210 'copy'
14211 'nonatomic'
14213 For example:
14214 @property NSString *name;
14215 @property (readonly) id object;
14216 @property (retain, nonatomic, getter=getTheName) id name;
14217 @property int a, b, c;
14219 PS: This function is identical to cp_parser_objc_at_propery_declaration
14220 for C++. Keep them in sync. */
14221 static void
14222 c_parser_objc_at_property_declaration (c_parser *parser)
14224 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
14225 location_t loc = c_parser_peek_token (parser)->location;
14226 c_parser_consume_token (parser); /* Eat '@property'. */
14228 /* Parse the optional attribute list.
14230 A list of parsed, but not verified, attributes. */
14231 vec<property_attribute_info *> prop_attr_list = vNULL;
14233 bool syntax_error = false;
14234 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14236 matching_parens parens;
14238 location_t attr_start = c_parser_peek_token (parser)->location;
14239 /* Eat the '(' */
14240 parens.consume_open (parser);
14242 /* Property attribute keywords are valid now. */
14243 parser->objc_property_attr_context = true;
14245 /* Allow @property (), with a warning. */
14246 location_t attr_end = c_parser_peek_token (parser)->location;
14248 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14250 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
14251 warning_at (attr_comb, OPT_Wattributes,
14252 "empty property attribute list");
14254 else
14255 while (true)
14257 c_token *token = c_parser_peek_token (parser);
14258 attr_start = token->location;
14259 attr_end = get_finish (token->location);
14260 location_t attr_comb = make_location (attr_start, attr_start,
14261 attr_end);
14263 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
14265 warning_at (attr_comb, OPT_Wattributes,
14266 "missing property attribute");
14267 if (token->type == CPP_CLOSE_PAREN)
14268 break;
14269 c_parser_consume_token (parser);
14270 continue;
14273 tree attr_name = NULL_TREE;
14274 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
14275 bool add_at = false;
14276 if (token->type == CPP_KEYWORD)
14278 keyword = token->keyword;
14279 if (OBJC_IS_AT_KEYWORD (keyword))
14281 /* For '@' keywords the token value has the keyword,
14282 prepend the '@' for diagnostics. */
14283 attr_name = token->value;
14284 add_at = true;
14286 else
14287 attr_name = ridpointers[(int)keyword];
14289 else if (token->type == CPP_NAME)
14290 attr_name = token->value;
14291 c_parser_consume_token (parser);
14293 enum objc_property_attribute_kind prop_kind
14294 = objc_prop_attr_kind_for_rid (keyword);
14295 property_attribute_info *prop
14296 = new property_attribute_info (attr_name, attr_comb, prop_kind);
14297 prop_attr_list.safe_push (prop);
14299 tree meth_name;
14300 switch (prop->prop_kind)
14302 default: break;
14303 case OBJC_PROPERTY_ATTR_UNKNOWN:
14304 if (attr_name)
14305 error_at (attr_comb, "unknown property attribute %<%s%s%>",
14306 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
14307 else
14308 error_at (attr_comb, "unknown property attribute");
14309 prop->parse_error = syntax_error = true;
14310 break;
14312 case OBJC_PROPERTY_ATTR_GETTER:
14313 case OBJC_PROPERTY_ATTR_SETTER:
14314 if (c_parser_next_token_is_not (parser, CPP_EQ))
14316 attr_comb = make_location (attr_end, attr_start, attr_end);
14317 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
14318 attr_name);
14319 prop->parse_error = syntax_error = true;
14320 break;
14322 token = c_parser_peek_token (parser);
14323 attr_end = token->location;
14324 c_parser_consume_token (parser); /* eat the = */
14325 if (c_parser_next_token_is_not (parser, CPP_NAME))
14327 attr_comb = make_location (attr_end, attr_start, attr_end);
14328 error_at (attr_comb, "expected %qE selector name",
14329 attr_name);
14330 prop->parse_error = syntax_error = true;
14331 break;
14333 /* Get the end of the method name, and consume the name. */
14334 token = c_parser_peek_token (parser);
14335 attr_end = get_finish (token->location);
14336 meth_name = token->value;
14337 c_parser_consume_token (parser);
14338 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
14340 if (c_parser_next_token_is_not (parser, CPP_COLON))
14342 attr_comb = make_location (attr_end, attr_start,
14343 attr_end);
14344 error_at (attr_comb, "setter method names must"
14345 " terminate with %<:%>");
14346 prop->parse_error = syntax_error = true;
14348 else
14350 attr_end = get_finish (c_parser_peek_token
14351 (parser)->location);
14352 c_parser_consume_token (parser);
14354 attr_comb = make_location (attr_start, attr_start,
14355 attr_end);
14357 else
14358 attr_comb = make_location (attr_start, attr_start,
14359 attr_end);
14360 prop->ident = meth_name;
14361 /* Updated location including all that was successfully
14362 parsed. */
14363 prop->prop_loc = attr_comb;
14364 break;
14367 /* If we see a comma here, then keep going - even if we already
14368 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
14369 this makes a more useful output and avoid spurious warnings about
14370 missing attributes that are, in fact, specified after the one with
14371 the syntax error. */
14372 if (c_parser_next_token_is (parser, CPP_COMMA))
14373 c_parser_consume_token (parser);
14374 else
14375 break;
14377 parser->objc_property_attr_context = false;
14379 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
14380 /* We don't really want to chew the whole of the file looking for a
14381 matching closing parenthesis, so we will try to read the decl and
14382 let the error handling for that close out the statement. */
14384 else
14385 syntax_error = false, parens.skip_until_found_close (parser);
14388 /* 'properties' is the list of properties that we read. Usually a
14389 single one, but maybe more (eg, in "@property int a, b, c;" there
14390 are three). */
14391 tree properties = c_parser_struct_declaration (parser, NULL);
14393 if (properties == error_mark_node)
14394 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14395 else
14397 if (properties == NULL_TREE)
14398 c_parser_error (parser, "expected identifier");
14399 else
14401 /* Comma-separated properties are chained together in reverse order;
14402 add them one by one. */
14403 properties = nreverse (properties);
14404 for (; properties; properties = TREE_CHAIN (properties))
14405 objc_add_property_declaration (loc, copy_node (properties),
14406 prop_attr_list);
14408 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14411 while (!prop_attr_list.is_empty())
14412 delete prop_attr_list.pop ();
14413 prop_attr_list.release ();
14414 parser->error = false;
14417 /* Parse an Objective-C @synthesize declaration. The syntax is:
14419 objc-synthesize-declaration:
14420 @synthesize objc-synthesize-identifier-list ;
14422 objc-synthesize-identifier-list:
14423 objc-synthesize-identifier
14424 objc-synthesize-identifier-list, objc-synthesize-identifier
14426 objc-synthesize-identifier
14427 identifier
14428 identifier = identifier
14430 For example:
14431 @synthesize MyProperty;
14432 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
14434 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
14435 for C++. Keep them in sync.
14437 static void
14438 c_parser_objc_at_synthesize_declaration (c_parser *parser)
14440 tree list = NULL_TREE;
14441 location_t loc;
14442 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
14443 loc = c_parser_peek_token (parser)->location;
14445 c_parser_consume_token (parser);
14446 while (true)
14448 tree property, ivar;
14449 if (c_parser_next_token_is_not (parser, CPP_NAME))
14451 c_parser_error (parser, "expected identifier");
14452 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14453 /* Once we find the semicolon, we can resume normal parsing.
14454 We have to reset parser->error manually because
14455 c_parser_skip_until_found() won't reset it for us if the
14456 next token is precisely a semicolon. */
14457 parser->error = false;
14458 return;
14460 property = c_parser_peek_token (parser)->value;
14461 c_parser_consume_token (parser);
14462 if (c_parser_next_token_is (parser, CPP_EQ))
14464 c_parser_consume_token (parser);
14465 if (c_parser_next_token_is_not (parser, CPP_NAME))
14467 c_parser_error (parser, "expected identifier");
14468 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14469 parser->error = false;
14470 return;
14472 ivar = c_parser_peek_token (parser)->value;
14473 c_parser_consume_token (parser);
14475 else
14476 ivar = NULL_TREE;
14477 list = chainon (list, build_tree_list (ivar, property));
14478 if (c_parser_next_token_is (parser, CPP_COMMA))
14479 c_parser_consume_token (parser);
14480 else
14481 break;
14483 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14484 objc_add_synthesize_declaration (loc, list);
14487 /* Parse an Objective-C @dynamic declaration. The syntax is:
14489 objc-dynamic-declaration:
14490 @dynamic identifier-list ;
14492 For example:
14493 @dynamic MyProperty;
14494 @dynamic MyProperty, AnotherProperty;
14496 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
14497 for C++. Keep them in sync.
14499 static void
14500 c_parser_objc_at_dynamic_declaration (c_parser *parser)
14502 tree list = NULL_TREE;
14503 location_t loc;
14504 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
14505 loc = c_parser_peek_token (parser)->location;
14507 c_parser_consume_token (parser);
14508 while (true)
14510 tree property;
14511 if (c_parser_next_token_is_not (parser, CPP_NAME))
14513 c_parser_error (parser, "expected identifier");
14514 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
14515 parser->error = false;
14516 return;
14518 property = c_parser_peek_token (parser)->value;
14519 list = chainon (list, build_tree_list (NULL_TREE, property));
14520 c_parser_consume_token (parser);
14521 if (c_parser_next_token_is (parser, CPP_COMMA))
14522 c_parser_consume_token (parser);
14523 else
14524 break;
14526 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
14527 objc_add_dynamic_declaration (loc, list);
14531 /* Parse a pragma GCC ivdep. */
14533 static bool
14534 c_parse_pragma_ivdep (c_parser *parser)
14536 c_parser_consume_pragma (parser);
14537 c_parser_skip_to_pragma_eol (parser);
14538 return true;
14541 /* Parse a pragma GCC novector. */
14543 static bool
14544 c_parse_pragma_novector (c_parser *parser)
14546 c_parser_consume_pragma (parser);
14547 c_parser_skip_to_pragma_eol (parser);
14548 return true;
14551 /* Parse a pragma GCC unroll. */
14553 static unsigned short
14554 c_parser_pragma_unroll (c_parser *parser)
14556 unsigned short unroll;
14557 c_parser_consume_pragma (parser);
14558 location_t location = c_parser_peek_token (parser)->location;
14559 tree expr = c_parser_expr_no_commas (parser, NULL).value;
14560 mark_exp_read (expr);
14561 expr = c_fully_fold (expr, false, NULL);
14562 HOST_WIDE_INT lunroll = 0;
14563 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14564 || TREE_CODE (expr) != INTEGER_CST
14565 || (lunroll = tree_to_shwi (expr)) < 0
14566 || lunroll >= USHRT_MAX)
14568 error_at (location, "%<#pragma GCC unroll%> requires an"
14569 " assignment-expression that evaluates to a non-negative"
14570 " integral constant less than %u", USHRT_MAX);
14571 unroll = 0;
14573 else
14575 unroll = (unsigned short)lunroll;
14576 if (unroll == 0)
14577 unroll = 1;
14580 c_parser_skip_to_pragma_eol (parser);
14581 return unroll;
14584 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
14585 should be considered, statements. ALLOW_STMT is true if we're within
14586 the context of a function and such pragmas are to be allowed. Returns
14587 true if we actually parsed such a pragma. */
14589 static bool
14590 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
14592 unsigned int id;
14593 const char *construct = NULL;
14595 input_location = c_parser_peek_token (parser)->location;
14596 id = c_parser_peek_token (parser)->pragma_kind;
14597 gcc_assert (id != PRAGMA_NONE);
14598 if (parser->omp_for_parse_state
14599 && parser->omp_for_parse_state->in_intervening_code
14600 && id >= PRAGMA_OMP__START_
14601 && id <= PRAGMA_OMP__LAST_)
14603 error_at (input_location,
14604 "intervening code must not contain OpenMP directives");
14605 parser->omp_for_parse_state->fail = true;
14606 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14607 return false;
14610 switch (id)
14612 case PRAGMA_OACC_DECLARE:
14613 c_parser_oacc_declare (parser);
14614 return false;
14616 case PRAGMA_OACC_ENTER_DATA:
14617 if (context != pragma_compound)
14619 construct = "acc enter data";
14620 in_compound:
14621 if (context == pragma_stmt)
14623 error_at (c_parser_peek_token (parser)->location,
14624 "%<#pragma %s%> may only be used in compound "
14625 "statements", construct);
14626 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14627 return true;
14629 goto bad_stmt;
14631 c_parser_oacc_enter_exit_data (parser, true);
14632 return false;
14634 case PRAGMA_OACC_EXIT_DATA:
14635 if (context != pragma_compound)
14637 construct = "acc exit data";
14638 goto in_compound;
14640 c_parser_oacc_enter_exit_data (parser, false);
14641 return false;
14643 case PRAGMA_OACC_ROUTINE:
14644 if (context != pragma_external)
14646 error_at (c_parser_peek_token (parser)->location,
14647 "%<#pragma acc routine%> must be at file scope");
14648 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14649 return false;
14651 c_parser_oacc_routine (parser, context);
14652 return false;
14654 case PRAGMA_OACC_UPDATE:
14655 if (context != pragma_compound)
14657 construct = "acc update";
14658 goto in_compound;
14660 c_parser_oacc_update (parser);
14661 return false;
14663 case PRAGMA_OMP_BARRIER:
14664 if (context != pragma_compound)
14666 construct = "omp barrier";
14667 goto in_compound;
14669 c_parser_omp_barrier (parser);
14670 return false;
14672 case PRAGMA_OMP_DEPOBJ:
14673 if (context != pragma_compound)
14675 construct = "omp depobj";
14676 goto in_compound;
14678 c_parser_omp_depobj (parser);
14679 return false;
14681 case PRAGMA_OMP_FLUSH:
14682 if (context != pragma_compound)
14684 construct = "omp flush";
14685 goto in_compound;
14687 c_parser_omp_flush (parser);
14688 return false;
14690 case PRAGMA_OMP_TASKWAIT:
14691 if (context != pragma_compound)
14693 construct = "omp taskwait";
14694 goto in_compound;
14696 c_parser_omp_taskwait (parser);
14697 return false;
14699 case PRAGMA_OMP_TASKYIELD:
14700 if (context != pragma_compound)
14702 construct = "omp taskyield";
14703 goto in_compound;
14705 c_parser_omp_taskyield (parser);
14706 return false;
14708 case PRAGMA_OMP_CANCEL:
14709 if (context != pragma_compound)
14711 construct = "omp cancel";
14712 goto in_compound;
14714 c_parser_omp_cancel (parser);
14715 return false;
14717 case PRAGMA_OMP_CANCELLATION_POINT:
14718 return c_parser_omp_cancellation_point (parser, context);
14720 case PRAGMA_OMP_THREADPRIVATE:
14721 c_parser_omp_threadprivate (parser);
14722 return false;
14724 case PRAGMA_OMP_TARGET:
14725 return c_parser_omp_target (parser, context, if_p);
14727 case PRAGMA_OMP_BEGIN:
14728 c_parser_omp_begin (parser);
14729 return false;
14731 case PRAGMA_OMP_END:
14732 c_parser_omp_end (parser);
14733 return false;
14735 case PRAGMA_OMP_SCAN:
14736 error_at (c_parser_peek_token (parser)->location,
14737 "%<#pragma omp scan%> may only be used in "
14738 "a loop construct with %<inscan%> %<reduction%> clause");
14739 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14740 return false;
14742 case PRAGMA_OMP_SECTION:
14743 error_at (c_parser_peek_token (parser)->location,
14744 "%<#pragma omp section%> may only be used in "
14745 "%<#pragma omp sections%> construct");
14746 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14747 return false;
14749 case PRAGMA_OMP_DECLARE:
14750 return c_parser_omp_declare (parser, context);
14752 case PRAGMA_OMP_REQUIRES:
14753 if (context != pragma_external)
14755 error_at (c_parser_peek_token (parser)->location,
14756 "%<#pragma %s%> may only be used at file scope",
14757 "omp requires");
14758 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14759 return false;
14761 c_parser_omp_requires (parser);
14762 return false;
14764 case PRAGMA_OMP_ALLOCATE:
14765 c_parser_omp_allocate (parser);
14766 return false;
14768 case PRAGMA_OMP_ASSUMES:
14769 if (context != pragma_external)
14771 error_at (c_parser_peek_token (parser)->location,
14772 "%<#pragma %s%> may only be used at file scope",
14773 "omp assumes");
14774 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14775 return false;
14777 c_parser_omp_assumes (parser);
14778 return false;
14780 case PRAGMA_OMP_NOTHING:
14781 c_parser_omp_nothing (parser);
14782 return false;
14784 case PRAGMA_OMP_ERROR:
14785 return c_parser_omp_error (parser, context);
14787 case PRAGMA_OMP_ORDERED:
14788 return c_parser_omp_ordered (parser, context, if_p);
14790 case PRAGMA_NOVECTOR:
14791 case PRAGMA_UNROLL:
14792 case PRAGMA_IVDEP:
14794 bool novector = false;
14795 unsigned short unroll = 0;
14796 bool ivdep = false;
14798 switch (id)
14800 case PRAGMA_NOVECTOR:
14801 novector = c_parse_pragma_novector (parser);
14802 break;
14803 case PRAGMA_UNROLL:
14804 unroll = c_parser_pragma_unroll (parser);
14805 break;
14806 case PRAGMA_IVDEP:
14807 ivdep = c_parse_pragma_ivdep (parser);
14808 break;
14809 default:
14810 gcc_unreachable ();
14813 c_token *tok = c_parser_peek_token (parser);
14814 bool has_more = tok->type == CPP_PRAGMA;
14815 while (has_more)
14817 switch (tok->pragma_kind)
14819 case PRAGMA_IVDEP:
14820 ivdep = c_parse_pragma_ivdep (parser);
14821 break;
14822 case PRAGMA_UNROLL:
14823 unroll = c_parser_pragma_unroll (parser);
14824 break;
14825 case PRAGMA_NOVECTOR:
14826 novector = c_parse_pragma_novector (parser);
14827 break;
14828 default:
14829 has_more = false;
14830 break;
14832 tok = c_parser_peek_token (parser);
14833 has_more = has_more && tok->type == CPP_PRAGMA;
14835 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
14836 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
14837 && !c_parser_next_token_is_keyword (parser, RID_DO))
14839 c_parser_error (parser, "for, while or do statement expected");
14840 return false;
14842 if (c_parser_next_token_is_keyword (parser, RID_FOR))
14843 c_parser_for_statement (parser, ivdep, unroll, novector, if_p);
14844 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
14845 c_parser_while_statement (parser, ivdep, unroll, novector, if_p);
14846 else
14847 c_parser_do_statement (parser, ivdep, unroll, novector);
14849 return true;
14851 case PRAGMA_GCC_PCH_PREPROCESS:
14852 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
14853 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14854 return false;
14856 case PRAGMA_OACC_WAIT:
14857 if (context != pragma_compound)
14859 construct = "acc wait";
14860 goto in_compound;
14862 /* FALL THROUGH. */
14864 default:
14865 if (id < PRAGMA_FIRST_EXTERNAL)
14867 if (context != pragma_stmt && context != pragma_compound)
14869 bad_stmt:
14870 c_parser_error (parser, "expected declaration specifiers");
14871 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
14872 return false;
14874 c_parser_omp_construct (parser, if_p);
14875 return true;
14877 break;
14880 c_parser_consume_pragma (parser);
14881 c_invoke_pragma_handler (id);
14883 /* Skip to EOL, but suppress any error message. Those will have been
14884 generated by the handler routine through calling error, as opposed
14885 to calling c_parser_error. */
14886 parser->error = true;
14887 c_parser_skip_to_pragma_eol (parser);
14889 return false;
14892 /* The interface the pragma parsers have to the lexer. */
14894 enum cpp_ttype
14895 pragma_lex (tree *value, location_t *loc)
14897 c_token *tok = c_parser_peek_token (the_parser);
14898 enum cpp_ttype ret = tok->type;
14900 *value = tok->value;
14901 if (loc)
14902 *loc = tok->location;
14904 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
14905 ret = CPP_EOF;
14906 else if (ret == CPP_STRING)
14907 *value = c_parser_string_literal (the_parser, false, false).value;
14908 else
14910 if (ret == CPP_KEYWORD)
14911 ret = CPP_NAME;
14912 c_parser_consume_token (the_parser);
14915 return ret;
14918 void
14919 pragma_lex_discard_to_eol ()
14921 cpp_ttype type;
14924 type = c_parser_peek_token (the_parser)->type;
14925 gcc_assert (type != CPP_EOF);
14926 c_parser_consume_token (the_parser);
14927 } while (type != CPP_PRAGMA_EOL);
14930 static void
14931 c_parser_pragma_pch_preprocess (c_parser *parser)
14933 tree name = NULL;
14935 parser->lex_joined_string = true;
14936 c_parser_consume_pragma (parser);
14937 if (c_parser_next_token_is (parser, CPP_STRING))
14939 name = c_parser_peek_token (parser)->value;
14940 c_parser_consume_token (parser);
14942 else
14943 c_parser_error (parser, "expected string literal");
14944 c_parser_skip_to_pragma_eol (parser);
14945 parser->lex_joined_string = false;
14947 if (name)
14948 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
14951 /* OpenACC and OpenMP parsing routines. */
14953 /* Returns name of the next clause.
14954 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
14955 the token is not consumed. Otherwise appropriate pragma_omp_clause is
14956 returned and the token is consumed. */
14958 static pragma_omp_clause
14959 c_parser_omp_clause_name (c_parser *parser)
14961 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
14963 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14964 result = PRAGMA_OACC_CLAUSE_AUTO;
14965 else if (c_parser_next_token_is_keyword (parser, RID_IF))
14966 result = PRAGMA_OMP_CLAUSE_IF;
14967 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14968 result = PRAGMA_OMP_CLAUSE_DEFAULT;
14969 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
14970 result = PRAGMA_OMP_CLAUSE_FOR;
14971 else if (c_parser_next_token_is (parser, CPP_NAME))
14973 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14975 switch (p[0])
14977 case 'a':
14978 if (!strcmp ("affinity", p))
14979 result = PRAGMA_OMP_CLAUSE_AFFINITY;
14980 else if (!strcmp ("aligned", p))
14981 result = PRAGMA_OMP_CLAUSE_ALIGNED;
14982 else if (!strcmp ("allocate", p))
14983 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
14984 else if (!strcmp ("async", p))
14985 result = PRAGMA_OACC_CLAUSE_ASYNC;
14986 else if (!strcmp ("attach", p))
14987 result = PRAGMA_OACC_CLAUSE_ATTACH;
14988 break;
14989 case 'b':
14990 if (!strcmp ("bind", p))
14991 result = PRAGMA_OMP_CLAUSE_BIND;
14992 break;
14993 case 'c':
14994 if (!strcmp ("collapse", p))
14995 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
14996 else if (!strcmp ("copy", p))
14997 result = PRAGMA_OACC_CLAUSE_COPY;
14998 else if (!strcmp ("copyin", p))
14999 result = PRAGMA_OMP_CLAUSE_COPYIN;
15000 else if (!strcmp ("copyout", p))
15001 result = PRAGMA_OACC_CLAUSE_COPYOUT;
15002 else if (!strcmp ("copyprivate", p))
15003 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
15004 else if (!strcmp ("create", p))
15005 result = PRAGMA_OACC_CLAUSE_CREATE;
15006 break;
15007 case 'd':
15008 if (!strcmp ("defaultmap", p))
15009 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
15010 else if (!strcmp ("delete", p))
15011 result = PRAGMA_OACC_CLAUSE_DELETE;
15012 else if (!strcmp ("depend", p))
15013 result = PRAGMA_OMP_CLAUSE_DEPEND;
15014 else if (!strcmp ("detach", p))
15015 result = PRAGMA_OACC_CLAUSE_DETACH;
15016 else if (!strcmp ("device", p))
15017 result = PRAGMA_OMP_CLAUSE_DEVICE;
15018 else if (!strcmp ("deviceptr", p))
15019 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
15020 else if (!strcmp ("device_resident", p))
15021 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
15022 else if (!strcmp ("device_type", p))
15023 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
15024 else if (!strcmp ("dist_schedule", p))
15025 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
15026 else if (!strcmp ("doacross", p))
15027 result = PRAGMA_OMP_CLAUSE_DOACROSS;
15028 break;
15029 case 'e':
15030 if (!strcmp ("enter", p))
15031 result = PRAGMA_OMP_CLAUSE_ENTER;
15032 break;
15033 case 'f':
15034 if (!strcmp ("filter", p))
15035 result = PRAGMA_OMP_CLAUSE_FILTER;
15036 else if (!strcmp ("final", p))
15037 result = PRAGMA_OMP_CLAUSE_FINAL;
15038 else if (!strcmp ("finalize", p))
15039 result = PRAGMA_OACC_CLAUSE_FINALIZE;
15040 else if (!strcmp ("firstprivate", p))
15041 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
15042 else if (!strcmp ("from", p))
15043 result = PRAGMA_OMP_CLAUSE_FROM;
15044 else if (!strcmp ("full", p))
15045 result = PRAGMA_OMP_CLAUSE_FULL;
15046 break;
15047 case 'g':
15048 if (!strcmp ("gang", p))
15049 result = PRAGMA_OACC_CLAUSE_GANG;
15050 else if (!strcmp ("grainsize", p))
15051 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
15052 break;
15053 case 'h':
15054 if (!strcmp ("has_device_addr", p))
15055 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
15056 else if (!strcmp ("hint", p))
15057 result = PRAGMA_OMP_CLAUSE_HINT;
15058 else if (!strcmp ("host", p))
15059 result = PRAGMA_OACC_CLAUSE_HOST;
15060 break;
15061 case 'i':
15062 if (!strcmp ("if_present", p))
15063 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
15064 else if (!strcmp ("in_reduction", p))
15065 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
15066 else if (!strcmp ("inbranch", p))
15067 result = PRAGMA_OMP_CLAUSE_INBRANCH;
15068 else if (!strcmp ("independent", p))
15069 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
15070 else if (!strcmp ("indirect", p))
15071 result = PRAGMA_OMP_CLAUSE_INDIRECT;
15072 else if (!strcmp ("is_device_ptr", p))
15073 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
15074 break;
15075 case 'l':
15076 if (!strcmp ("lastprivate", p))
15077 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
15078 else if (!strcmp ("linear", p))
15079 result = PRAGMA_OMP_CLAUSE_LINEAR;
15080 else if (!strcmp ("link", p))
15081 result = PRAGMA_OMP_CLAUSE_LINK;
15082 break;
15083 case 'm':
15084 if (!strcmp ("map", p))
15085 result = PRAGMA_OMP_CLAUSE_MAP;
15086 else if (!strcmp ("mergeable", p))
15087 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
15088 break;
15089 case 'n':
15090 if (!strcmp ("no_create", p))
15091 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
15092 else if (!strcmp ("nogroup", p))
15093 result = PRAGMA_OMP_CLAUSE_NOGROUP;
15094 else if (!strcmp ("nohost", p))
15095 result = PRAGMA_OACC_CLAUSE_NOHOST;
15096 else if (!strcmp ("nontemporal", p))
15097 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
15098 else if (!strcmp ("notinbranch", p))
15099 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
15100 else if (!strcmp ("nowait", p))
15101 result = PRAGMA_OMP_CLAUSE_NOWAIT;
15102 else if (!strcmp ("num_gangs", p))
15103 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
15104 else if (!strcmp ("num_tasks", p))
15105 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
15106 else if (!strcmp ("num_teams", p))
15107 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
15108 else if (!strcmp ("num_threads", p))
15109 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
15110 else if (!strcmp ("num_workers", p))
15111 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
15112 break;
15113 case 'o':
15114 if (!strcmp ("ordered", p))
15115 result = PRAGMA_OMP_CLAUSE_ORDERED;
15116 else if (!strcmp ("order", p))
15117 result = PRAGMA_OMP_CLAUSE_ORDER;
15118 break;
15119 case 'p':
15120 if (!strcmp ("parallel", p))
15121 result = PRAGMA_OMP_CLAUSE_PARALLEL;
15122 else if (!strcmp ("partial", p))
15123 result = PRAGMA_OMP_CLAUSE_PARTIAL;
15124 else if (!strcmp ("present", p))
15125 result = PRAGMA_OACC_CLAUSE_PRESENT;
15126 /* As of OpenACC 2.5, these are now aliases of the non-present_or
15127 clauses. */
15128 else if (!strcmp ("present_or_copy", p)
15129 || !strcmp ("pcopy", p))
15130 result = PRAGMA_OACC_CLAUSE_COPY;
15131 else if (!strcmp ("present_or_copyin", p)
15132 || !strcmp ("pcopyin", p))
15133 result = PRAGMA_OACC_CLAUSE_COPYIN;
15134 else if (!strcmp ("present_or_copyout", p)
15135 || !strcmp ("pcopyout", p))
15136 result = PRAGMA_OACC_CLAUSE_COPYOUT;
15137 else if (!strcmp ("present_or_create", p)
15138 || !strcmp ("pcreate", p))
15139 result = PRAGMA_OACC_CLAUSE_CREATE;
15140 else if (!strcmp ("priority", p))
15141 result = PRAGMA_OMP_CLAUSE_PRIORITY;
15142 else if (!strcmp ("private", p))
15143 result = PRAGMA_OMP_CLAUSE_PRIVATE;
15144 else if (!strcmp ("proc_bind", p))
15145 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
15146 break;
15147 case 'r':
15148 if (!strcmp ("reduction", p))
15149 result = PRAGMA_OMP_CLAUSE_REDUCTION;
15150 break;
15151 case 's':
15152 if (!strcmp ("safelen", p))
15153 result = PRAGMA_OMP_CLAUSE_SAFELEN;
15154 else if (!strcmp ("schedule", p))
15155 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
15156 else if (!strcmp ("sections", p))
15157 result = PRAGMA_OMP_CLAUSE_SECTIONS;
15158 else if (!strcmp ("self", p))
15159 result = PRAGMA_OACC_CLAUSE_SELF;
15160 else if (!strcmp ("seq", p))
15161 result = PRAGMA_OACC_CLAUSE_SEQ;
15162 else if (!strcmp ("shared", p))
15163 result = PRAGMA_OMP_CLAUSE_SHARED;
15164 else if (!strcmp ("simd", p))
15165 result = PRAGMA_OMP_CLAUSE_SIMD;
15166 else if (!strcmp ("simdlen", p))
15167 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
15168 break;
15169 case 't':
15170 if (!strcmp ("task_reduction", p))
15171 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
15172 else if (!strcmp ("taskgroup", p))
15173 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
15174 else if (!strcmp ("thread_limit", p))
15175 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
15176 else if (!strcmp ("threads", p))
15177 result = PRAGMA_OMP_CLAUSE_THREADS;
15178 else if (!strcmp ("tile", p))
15179 result = PRAGMA_OACC_CLAUSE_TILE;
15180 else if (!strcmp ("to", p))
15181 result = PRAGMA_OMP_CLAUSE_TO;
15182 break;
15183 case 'u':
15184 if (!strcmp ("uniform", p))
15185 result = PRAGMA_OMP_CLAUSE_UNIFORM;
15186 else if (!strcmp ("untied", p))
15187 result = PRAGMA_OMP_CLAUSE_UNTIED;
15188 else if (!strcmp ("use_device", p))
15189 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
15190 else if (!strcmp ("use_device_addr", p))
15191 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
15192 else if (!strcmp ("use_device_ptr", p))
15193 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
15194 break;
15195 case 'v':
15196 if (!strcmp ("vector", p))
15197 result = PRAGMA_OACC_CLAUSE_VECTOR;
15198 else if (!strcmp ("vector_length", p))
15199 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
15200 break;
15201 case 'w':
15202 if (!strcmp ("wait", p))
15203 result = PRAGMA_OACC_CLAUSE_WAIT;
15204 else if (!strcmp ("worker", p))
15205 result = PRAGMA_OACC_CLAUSE_WORKER;
15206 break;
15210 if (result != PRAGMA_OMP_CLAUSE_NONE)
15211 c_parser_consume_token (parser);
15213 return result;
15216 /* Validate that a clause of the given type does not already exist. */
15218 static void
15219 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
15220 const char *name)
15222 if (tree c = omp_find_clause (clauses, code))
15223 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
15226 /* OpenACC 2.0
15227 Parse wait clause or wait directive parameters. */
15229 static tree
15230 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
15232 vec<tree, va_gc> *args;
15233 tree t, args_tree;
15235 matching_parens parens;
15236 if (!parens.require_open (parser))
15237 return list;
15239 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
15240 args_tree = build_tree_list_vec (args);
15242 for (t = args_tree; t; t = TREE_CHAIN (t))
15244 tree targ = TREE_VALUE (t);
15246 if (targ != error_mark_node)
15248 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
15250 c_parser_error (parser, "expression must be integral");
15251 targ = error_mark_node;
15253 else
15255 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
15257 OMP_CLAUSE_DECL (c) = targ;
15258 OMP_CLAUSE_CHAIN (c) = list;
15259 list = c;
15264 release_tree_vector (args);
15265 parens.require_close (parser);
15266 return list;
15269 /* OpenACC 2.0, OpenMP 2.5:
15270 variable-list:
15271 identifier
15272 variable-list , identifier
15274 If KIND is nonzero, create the appropriate node and install the
15275 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
15276 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
15278 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
15279 return the list created.
15281 The optional ALLOW_DEREF argument is true if list items can use the deref
15282 (->) operator. */
15284 struct omp_dim
15286 tree low_bound, length;
15287 location_t loc;
15288 bool no_colon;
15289 omp_dim (tree lb, tree len, location_t lo, bool nc)
15290 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
15293 static tree
15294 c_parser_omp_variable_list (c_parser *parser,
15295 location_t clause_loc,
15296 enum omp_clause_code kind, tree list,
15297 bool map_lvalue = false)
15299 auto_vec<omp_dim> dims;
15300 bool array_section_p;
15301 auto_vec<c_token> tokens;
15302 unsigned int tokens_avail = 0;
15303 c_token *saved_tokens = NULL;
15304 bool first = true;
15306 while (1)
15308 tree t = NULL_TREE;
15310 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15312 if (c_parser_next_token_is_not (parser, CPP_NAME)
15313 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15315 struct c_expr expr;
15316 if (kind == OMP_CLAUSE_DEPEND
15317 && c_parser_next_token_is_keyword (parser,
15318 RID_OMP_ALL_MEMORY)
15319 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
15320 || (c_parser_peek_2nd_token (parser)->type
15321 == CPP_CLOSE_PAREN)))
15323 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
15324 c_parser_consume_token (parser);
15326 else
15327 expr = c_parser_expr_no_commas (parser, NULL);
15328 if (expr.value != error_mark_node)
15330 tree u = build_omp_clause (clause_loc, kind);
15331 OMP_CLAUSE_DECL (u) = expr.value;
15332 OMP_CLAUSE_CHAIN (u) = list;
15333 list = u;
15336 if (c_parser_next_token_is_not (parser, CPP_COMMA))
15337 break;
15339 c_parser_consume_token (parser);
15340 first = false;
15341 continue;
15344 tokens.truncate (0);
15345 unsigned int nesting_depth = 0;
15346 while (1)
15348 c_token *token = c_parser_peek_token (parser);
15349 switch (token->type)
15351 case CPP_EOF:
15352 case CPP_PRAGMA_EOL:
15353 break;
15354 case CPP_OPEN_BRACE:
15355 case CPP_OPEN_PAREN:
15356 case CPP_OPEN_SQUARE:
15357 ++nesting_depth;
15358 goto add;
15359 case CPP_CLOSE_BRACE:
15360 case CPP_CLOSE_PAREN:
15361 case CPP_CLOSE_SQUARE:
15362 if (nesting_depth-- == 0)
15363 break;
15364 goto add;
15365 case CPP_COMMA:
15366 if (nesting_depth == 0)
15367 break;
15368 goto add;
15369 default:
15370 add:
15371 tokens.safe_push (*token);
15372 c_parser_consume_token (parser);
15373 continue;
15375 break;
15378 /* Make sure nothing tries to read past the end of the tokens. */
15379 c_token eof_token;
15380 memset (&eof_token, 0, sizeof (eof_token));
15381 eof_token.type = CPP_EOF;
15382 tokens.safe_push (eof_token);
15383 tokens.safe_push (eof_token);
15385 saved_tokens = parser->tokens;
15386 tokens_avail = parser->tokens_avail;
15387 parser->tokens = tokens.address ();
15388 parser->tokens_avail = tokens.length ();
15390 else if (map_lvalue
15391 && (kind == OMP_CLAUSE_MAP
15392 || kind == OMP_CLAUSE_TO
15393 || kind == OMP_CLAUSE_FROM))
15395 location_t loc = c_parser_peek_token (parser)->location;
15396 bool save_c_omp_array_section_p = c_omp_array_section_p;
15397 c_omp_array_section_p = true;
15398 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15399 if (expr.value != error_mark_node)
15400 mark_exp_read (expr.value);
15401 c_omp_array_section_p = save_c_omp_array_section_p;
15402 tree decl = expr.value;
15404 /* This code rewrites a parsed expression containing various tree
15405 codes used to represent array accesses into a more uniform nest of
15406 OMP_ARRAY_SECTION nodes before it is processed by
15407 c-typeck.cc:handle_omp_array_sections_1. It might be more
15408 efficient to move this logic to that function instead, analysing
15409 the parsed expression directly rather than this preprocessed
15410 form. (See also equivalent code in cp/parser.cc,
15411 cp/semantics.cc). */
15412 dims.truncate (0);
15413 if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
15415 while (TREE_CODE (decl) == OMP_ARRAY_SECTION)
15417 tree low_bound = TREE_OPERAND (decl, 1);
15418 tree length = TREE_OPERAND (decl, 2);
15419 dims.safe_push (omp_dim (low_bound, length, loc, false));
15420 decl = TREE_OPERAND (decl, 0);
15423 while (TREE_CODE (decl) == ARRAY_REF
15424 || TREE_CODE (decl) == INDIRECT_REF
15425 || TREE_CODE (decl) == COMPOUND_EXPR)
15427 if (TREE_CODE (decl) == COMPOUND_EXPR)
15429 decl = TREE_OPERAND (decl, 1);
15430 STRIP_NOPS (decl);
15432 else if (TREE_CODE (decl) == INDIRECT_REF)
15434 dims.safe_push (omp_dim (integer_zero_node,
15435 integer_one_node, loc, true));
15436 decl = TREE_OPERAND (decl, 0);
15438 else /* ARRAY_REF. */
15440 tree index = TREE_OPERAND (decl, 1);
15441 dims.safe_push (omp_dim (index, integer_one_node, loc,
15442 true));
15443 decl = TREE_OPERAND (decl, 0);
15447 for (int i = dims.length () - 1; i >= 0; i--)
15448 decl = build_omp_array_section (loc, decl, dims[i].low_bound,
15449 dims[i].length);
15451 else if (TREE_CODE (decl) == INDIRECT_REF)
15453 /* Turn indirection of a pointer "*foo" into "foo[0:1]". */
15454 decl = TREE_OPERAND (decl, 0);
15455 STRIP_NOPS (decl);
15457 decl = build_omp_array_section (loc, decl, integer_zero_node,
15458 integer_one_node);
15460 else if (TREE_CODE (decl) == ARRAY_REF)
15462 tree idx = TREE_OPERAND (decl, 1);
15464 decl = TREE_OPERAND (decl, 0);
15465 STRIP_NOPS (decl);
15467 decl = build_omp_array_section (loc, decl, idx, integer_one_node);
15469 else if (TREE_CODE (decl) == NON_LVALUE_EXPR
15470 || CONVERT_EXPR_P (decl))
15471 decl = TREE_OPERAND (decl, 0);
15473 tree u = build_omp_clause (clause_loc, kind);
15474 OMP_CLAUSE_DECL (u) = decl;
15475 OMP_CLAUSE_CHAIN (u) = list;
15476 list = u;
15478 goto next_item;
15481 if (c_parser_next_token_is (parser, CPP_NAME)
15482 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15484 t = lookup_name (c_parser_peek_token (parser)->value);
15486 if (t == NULL_TREE)
15488 undeclared_variable (c_parser_peek_token (parser)->location,
15489 c_parser_peek_token (parser)->value);
15490 t = error_mark_node;
15493 c_parser_consume_token (parser);
15495 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
15496 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
15497 || (c_parser_peek_token (parser)->keyword
15498 == RID_PRETTY_FUNCTION_NAME)
15499 || (c_parser_peek_token (parser)->keyword
15500 == RID_C99_FUNCTION_NAME)))
15501 t = c_parser_predefined_identifier (parser).value;
15502 else
15504 if (first)
15505 c_parser_error (parser, "expected identifier");
15506 break;
15509 if (t == error_mark_node)
15511 else if (kind != 0)
15513 switch (kind)
15515 case OMP_CLAUSE__CACHE_:
15516 /* The OpenACC cache directive explicitly only allows "array
15517 elements or subarrays". */
15518 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
15520 c_parser_error (parser, "expected %<[%>");
15521 t = error_mark_node;
15522 break;
15524 /* FALLTHROUGH */
15525 case OMP_CLAUSE_MAP:
15526 case OMP_CLAUSE_FROM:
15527 case OMP_CLAUSE_TO:
15528 start_component_ref:
15529 while (c_parser_next_token_is (parser, CPP_DOT)
15530 || c_parser_next_token_is (parser, CPP_DEREF))
15532 location_t op_loc = c_parser_peek_token (parser)->location;
15533 location_t arrow_loc = UNKNOWN_LOCATION;
15534 if (c_parser_next_token_is (parser, CPP_DEREF))
15536 c_expr t_expr;
15537 t_expr.value = t;
15538 t_expr.original_code = ERROR_MARK;
15539 t_expr.original_type = NULL;
15540 set_c_expr_source_range (&t_expr, op_loc, op_loc);
15541 t_expr.m_decimal = 0;
15542 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
15543 true, false);
15544 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
15545 arrow_loc = t_expr.get_location ();
15547 c_parser_consume_token (parser);
15548 if (!c_parser_next_token_is (parser, CPP_NAME))
15550 c_parser_error (parser, "expected identifier");
15551 t = error_mark_node;
15552 break;
15555 c_token *comp_tok = c_parser_peek_token (parser);
15556 tree ident = comp_tok->value;
15557 location_t comp_loc = comp_tok->location;
15558 c_parser_consume_token (parser);
15559 t = build_component_ref (op_loc, t, ident, comp_loc,
15560 arrow_loc);
15562 /* FALLTHROUGH */
15563 case OMP_CLAUSE_AFFINITY:
15564 case OMP_CLAUSE_DEPEND:
15565 case OMP_CLAUSE_REDUCTION:
15566 case OMP_CLAUSE_IN_REDUCTION:
15567 case OMP_CLAUSE_TASK_REDUCTION:
15568 case OMP_CLAUSE_HAS_DEVICE_ADDR:
15569 array_section_p = false;
15570 dims.truncate (0);
15571 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
15573 location_t loc = UNKNOWN_LOCATION;
15574 tree low_bound = NULL_TREE, length = NULL_TREE;
15575 bool no_colon = false;
15577 c_parser_consume_token (parser);
15578 if (!c_parser_next_token_is (parser, CPP_COLON))
15580 location_t expr_loc
15581 = c_parser_peek_token (parser)->location;
15582 c_expr expr = c_parser_expression (parser);
15583 expr = convert_lvalue_to_rvalue (expr_loc, expr,
15584 false, true);
15585 low_bound = expr.value;
15586 loc = expr_loc;
15588 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
15590 length = integer_one_node;
15591 no_colon = true;
15593 else
15595 /* Look for `:'. */
15596 if (!c_parser_require (parser, CPP_COLON,
15597 "expected %<:%>"))
15599 t = error_mark_node;
15600 break;
15602 array_section_p = true;
15603 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
15605 location_t expr_loc
15606 = c_parser_peek_token (parser)->location;
15607 c_expr expr = c_parser_expression (parser);
15608 expr = convert_lvalue_to_rvalue (expr_loc, expr,
15609 false, true);
15610 length = expr.value;
15613 /* Look for the closing `]'. */
15614 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
15615 "expected %<]%>"))
15617 t = error_mark_node;
15618 break;
15621 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
15624 if (t != error_mark_node)
15626 if ((kind == OMP_CLAUSE_MAP
15627 || kind == OMP_CLAUSE_FROM
15628 || kind == OMP_CLAUSE_TO)
15629 && !array_section_p
15630 && (c_parser_next_token_is (parser, CPP_DOT)
15631 || c_parser_next_token_is (parser, CPP_DEREF)))
15633 for (unsigned i = 0; i < dims.length (); i++)
15635 gcc_assert (dims[i].length == integer_one_node);
15636 t = build_array_ref (dims[i].loc,
15637 t, dims[i].low_bound);
15639 goto start_component_ref;
15641 else
15642 for (unsigned i = 0; i < dims.length (); i++)
15643 t = build_omp_array_section (clause_loc, t,
15644 dims[i].low_bound,
15645 dims[i].length);
15648 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15649 && t != error_mark_node
15650 && parser->tokens_avail != 2)
15652 if (array_section_p)
15654 error_at (c_parser_peek_token (parser)->location,
15655 "expected %<)%> or %<,%>");
15656 t = error_mark_node;
15658 else
15660 parser->tokens = tokens.address ();
15661 parser->tokens_avail = tokens.length ();
15663 t = c_parser_expr_no_commas (parser, NULL).value;
15664 if (t != error_mark_node && parser->tokens_avail != 2)
15666 error_at (c_parser_peek_token (parser)->location,
15667 "expected %<)%> or %<,%>");
15668 t = error_mark_node;
15672 break;
15673 default:
15674 break;
15677 if (t != error_mark_node)
15679 tree u = build_omp_clause (clause_loc, kind);
15680 OMP_CLAUSE_DECL (u) = t;
15681 OMP_CLAUSE_CHAIN (u) = list;
15682 list = u;
15685 else
15686 list = tree_cons (t, NULL_TREE, list);
15688 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
15690 parser->tokens = saved_tokens;
15691 parser->tokens_avail = tokens_avail;
15694 next_item:
15695 if (c_parser_next_token_is_not (parser, CPP_COMMA))
15696 break;
15698 c_parser_consume_token (parser);
15699 first = false;
15702 return list;
15705 /* Similarly, but expect leading and trailing parenthesis. This is a very
15706 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
15707 argument is true if list items can use the deref (->) operator. */
15709 static tree
15710 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
15711 tree list, bool map_lvalue = false)
15713 /* The clauses location. */
15714 location_t loc = c_parser_peek_token (parser)->location;
15716 if (parser->in_omp_decl_attribute)
15718 if (kind)
15720 tree u = build_omp_clause (loc, kind);
15721 OMP_CLAUSE_DECL (u) = parser->in_omp_decl_attribute;
15722 OMP_CLAUSE_CHAIN (u) = list;
15723 return u;
15725 else
15726 return tree_cons (parser->in_omp_decl_attribute, NULL_TREE, list);
15729 matching_parens parens;
15730 if (parens.require_open (parser))
15732 list = c_parser_omp_variable_list (parser, loc, kind, list, map_lvalue);
15733 parens.skip_until_found_close (parser);
15735 return list;
15738 /* OpenACC 2.0:
15739 copy ( variable-list )
15740 copyin ( variable-list )
15741 copyout ( variable-list )
15742 create ( variable-list )
15743 delete ( variable-list )
15744 present ( variable-list )
15746 OpenACC 2.6:
15747 no_create ( variable-list )
15748 attach ( variable-list )
15749 detach ( variable-list )
15751 OpenACC 2.7:
15752 copyin (readonly : variable-list )
15755 static tree
15756 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
15757 tree list)
15759 enum gomp_map_kind kind;
15760 switch (c_kind)
15762 case PRAGMA_OACC_CLAUSE_ATTACH:
15763 kind = GOMP_MAP_ATTACH;
15764 break;
15765 case PRAGMA_OACC_CLAUSE_COPY:
15766 kind = GOMP_MAP_TOFROM;
15767 break;
15768 case PRAGMA_OACC_CLAUSE_COPYIN:
15769 kind = GOMP_MAP_TO;
15770 break;
15771 case PRAGMA_OACC_CLAUSE_COPYOUT:
15772 kind = GOMP_MAP_FROM;
15773 break;
15774 case PRAGMA_OACC_CLAUSE_CREATE:
15775 kind = GOMP_MAP_ALLOC;
15776 break;
15777 case PRAGMA_OACC_CLAUSE_DELETE:
15778 kind = GOMP_MAP_RELEASE;
15779 break;
15780 case PRAGMA_OACC_CLAUSE_DETACH:
15781 kind = GOMP_MAP_DETACH;
15782 break;
15783 case PRAGMA_OACC_CLAUSE_DEVICE:
15784 kind = GOMP_MAP_FORCE_TO;
15785 break;
15786 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
15787 kind = GOMP_MAP_DEVICE_RESIDENT;
15788 break;
15789 case PRAGMA_OACC_CLAUSE_LINK:
15790 kind = GOMP_MAP_LINK;
15791 break;
15792 case PRAGMA_OACC_CLAUSE_NO_CREATE:
15793 kind = GOMP_MAP_IF_PRESENT;
15794 break;
15795 case PRAGMA_OACC_CLAUSE_PRESENT:
15796 kind = GOMP_MAP_FORCE_PRESENT;
15797 break;
15798 case PRAGMA_OACC_CLAUSE_SELF:
15799 /* "The 'host' clause is a synonym for the 'self' clause." */
15800 case PRAGMA_OACC_CLAUSE_HOST:
15801 kind = GOMP_MAP_FORCE_FROM;
15802 break;
15803 default:
15804 gcc_unreachable ();
15807 tree nl = list;
15808 bool readonly = false;
15809 location_t open_loc = c_parser_peek_token (parser)->location;
15810 matching_parens parens;
15811 if (parens.require_open (parser))
15813 /* Turn on readonly modifier parsing for copyin clause. */
15814 if (c_kind == PRAGMA_OACC_CLAUSE_COPYIN)
15816 c_token *token = c_parser_peek_token (parser);
15817 if (token->type == CPP_NAME
15818 && !strcmp (IDENTIFIER_POINTER (token->value), "readonly")
15819 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15821 c_parser_consume_token (parser);
15822 c_parser_consume_token (parser);
15823 readonly = true;
15826 nl = c_parser_omp_variable_list (parser, open_loc, OMP_CLAUSE_MAP, list,
15827 false);
15828 parens.skip_until_found_close (parser);
15831 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15833 OMP_CLAUSE_SET_MAP_KIND (c, kind);
15834 if (readonly)
15835 OMP_CLAUSE_MAP_READONLY (c) = 1;
15838 return nl;
15841 /* OpenACC 2.0:
15842 deviceptr ( variable-list ) */
15844 static tree
15845 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
15847 location_t loc = c_parser_peek_token (parser)->location;
15848 tree vars, t;
15850 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
15851 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
15852 variable-list must only allow for pointer variables. */
15853 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
15854 for (t = vars; t && t; t = TREE_CHAIN (t))
15856 tree v = TREE_PURPOSE (t);
15858 /* FIXME diagnostics: Ideally we should keep individual
15859 locations for all the variables in the var list to make the
15860 following errors more precise. Perhaps
15861 c_parser_omp_var_list_parens() should construct a list of
15862 locations to go along with the var list. */
15864 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
15865 error_at (loc, "%qD is not a variable", v);
15866 else if (TREE_TYPE (v) == error_mark_node)
15868 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
15869 error_at (loc, "%qD is not a pointer variable", v);
15871 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
15872 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
15873 OMP_CLAUSE_DECL (u) = v;
15874 OMP_CLAUSE_CHAIN (u) = list;
15875 list = u;
15878 return list;
15881 /* OpenACC 2.0, OpenMP 3.0:
15882 collapse ( constant-expression ) */
15884 static tree
15885 c_parser_omp_clause_collapse (c_parser *parser, tree list)
15887 tree c, num = error_mark_node;
15888 HOST_WIDE_INT n;
15889 location_t loc;
15891 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
15892 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
15894 loc = c_parser_peek_token (parser)->location;
15895 matching_parens parens;
15896 if (parens.require_open (parser))
15898 num = c_parser_expr_no_commas (parser, NULL).value;
15899 parens.skip_until_found_close (parser);
15901 if (num == error_mark_node)
15902 return list;
15903 mark_exp_read (num);
15904 num = c_fully_fold (num, false, NULL);
15905 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
15906 || !tree_fits_shwi_p (num)
15907 || (n = tree_to_shwi (num)) <= 0
15908 || (int) n != n)
15910 error_at (loc,
15911 "collapse argument needs positive constant integer expression");
15912 return list;
15914 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
15915 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
15916 OMP_CLAUSE_CHAIN (c) = list;
15917 return c;
15920 /* OpenMP 2.5:
15921 copyin ( variable-list ) */
15923 static tree
15924 c_parser_omp_clause_copyin (c_parser *parser, tree list)
15926 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
15929 /* OpenMP 2.5:
15930 copyprivate ( variable-list ) */
15932 static tree
15933 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
15935 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
15938 /* OpenMP 2.5:
15939 default ( none | shared )
15941 OpenMP 5.1:
15942 default ( private | firstprivate )
15944 OpenACC:
15945 default ( none | present ) */
15947 static tree
15948 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
15950 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
15951 location_t loc = c_parser_peek_token (parser)->location;
15952 tree c;
15954 matching_parens parens;
15955 if (!parens.require_open (parser))
15956 return list;
15957 if (c_parser_next_token_is (parser, CPP_NAME))
15959 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15961 switch (p[0])
15963 case 'n':
15964 if (strcmp ("none", p) != 0)
15965 goto invalid_kind;
15966 kind = OMP_CLAUSE_DEFAULT_NONE;
15967 break;
15969 case 'p':
15970 if (is_oacc)
15972 if (strcmp ("present", p) != 0)
15973 goto invalid_kind;
15974 kind = OMP_CLAUSE_DEFAULT_PRESENT;
15976 else
15978 if (strcmp ("private", p) != 0)
15979 goto invalid_kind;
15980 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
15982 break;
15984 case 'f':
15985 if (strcmp ("firstprivate", p) != 0 || is_oacc)
15986 goto invalid_kind;
15987 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
15988 break;
15990 case 's':
15991 if (strcmp ("shared", p) != 0 || is_oacc)
15992 goto invalid_kind;
15993 kind = OMP_CLAUSE_DEFAULT_SHARED;
15994 break;
15996 default:
15997 goto invalid_kind;
16000 c_parser_consume_token (parser);
16002 else
16004 invalid_kind:
16005 if (is_oacc)
16006 c_parser_error (parser, "expected %<none%> or %<present%>");
16007 else
16008 c_parser_error (parser, "expected %<none%>, %<shared%>, "
16009 "%<private%> or %<firstprivate%>");
16011 parens.skip_until_found_close (parser);
16013 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
16014 return list;
16016 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
16017 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
16018 OMP_CLAUSE_CHAIN (c) = list;
16019 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
16021 return c;
16024 /* OpenMP 2.5:
16025 firstprivate ( variable-list ) */
16027 static tree
16028 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
16030 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
16033 /* OpenMP 3.1:
16034 final ( expression ) */
16036 static tree
16037 c_parser_omp_clause_final (c_parser *parser, tree list)
16039 location_t loc = c_parser_peek_token (parser)->location;
16040 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
16042 matching_parens parens;
16043 tree t, c;
16044 if (!parens.require_open (parser))
16045 t = error_mark_node;
16046 else
16048 location_t eloc = c_parser_peek_token (parser)->location;
16049 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16050 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
16051 t = c_objc_common_truthvalue_conversion (eloc, t);
16052 t = c_fully_fold (t, false, NULL);
16053 parens.skip_until_found_close (parser);
16056 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
16058 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
16059 OMP_CLAUSE_FINAL_EXPR (c) = t;
16060 OMP_CLAUSE_CHAIN (c) = list;
16061 list = c;
16063 else
16064 c_parser_error (parser, "expected %<(%>");
16066 return list;
16069 /* OpenMP 5.1:
16070 indirect [( expression )]
16073 static tree
16074 c_parser_omp_clause_indirect (c_parser *parser, tree list)
16076 location_t location = c_parser_peek_token (parser)->location;
16077 tree t;
16079 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
16081 matching_parens parens;
16082 if (!parens.require_open (parser))
16083 return list;
16085 location_t loc = c_parser_peek_token (parser)->location;
16086 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16087 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
16088 t = c_objc_common_truthvalue_conversion (loc, expr.value);
16089 t = c_fully_fold (t, false, NULL);
16090 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
16091 || TREE_CODE (t) != INTEGER_CST)
16093 c_parser_error (parser, "expected constant logical expression");
16094 return list;
16096 parens.skip_until_found_close (parser);
16098 else
16099 t = integer_one_node;
16101 check_no_duplicate_clause (list, OMP_CLAUSE_INDIRECT, "indirect");
16103 tree c = build_omp_clause (location, OMP_CLAUSE_INDIRECT);
16104 OMP_CLAUSE_INDIRECT_EXPR (c) = t;
16105 OMP_CLAUSE_CHAIN (c) = list;
16107 return c;
16110 /* OpenACC, OpenMP 2.5:
16111 if ( expression )
16113 OpenMP 4.5:
16114 if ( directive-name-modifier : expression )
16116 directive-name-modifier:
16117 parallel | task | taskloop | target data | target | target update
16118 | target enter data | target exit data
16120 OpenMP 5.0:
16121 directive-name-modifier:
16122 ... | simd | cancel */
16124 static tree
16125 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
16127 location_t location = c_parser_peek_token (parser)->location;
16128 enum tree_code if_modifier = ERROR_MARK;
16130 matching_parens parens;
16131 if (!parens.require_open (parser))
16132 return list;
16134 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
16136 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16137 int n = 2;
16138 if (strcmp (p, "cancel") == 0)
16139 if_modifier = VOID_CST;
16140 else if (strcmp (p, "parallel") == 0)
16141 if_modifier = OMP_PARALLEL;
16142 else if (strcmp (p, "simd") == 0)
16143 if_modifier = OMP_SIMD;
16144 else if (strcmp (p, "task") == 0)
16145 if_modifier = OMP_TASK;
16146 else if (strcmp (p, "taskloop") == 0)
16147 if_modifier = OMP_TASKLOOP;
16148 else if (strcmp (p, "target") == 0)
16150 if_modifier = OMP_TARGET;
16151 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
16153 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
16154 if (strcmp ("data", p) == 0)
16155 if_modifier = OMP_TARGET_DATA;
16156 else if (strcmp ("update", p) == 0)
16157 if_modifier = OMP_TARGET_UPDATE;
16158 else if (strcmp ("enter", p) == 0)
16159 if_modifier = OMP_TARGET_ENTER_DATA;
16160 else if (strcmp ("exit", p) == 0)
16161 if_modifier = OMP_TARGET_EXIT_DATA;
16162 if (if_modifier != OMP_TARGET)
16164 n = 3;
16165 c_parser_consume_token (parser);
16167 else
16169 location_t loc = c_parser_peek_2nd_token (parser)->location;
16170 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
16171 "or %<exit%>");
16172 if_modifier = ERROR_MARK;
16174 if (if_modifier == OMP_TARGET_ENTER_DATA
16175 || if_modifier == OMP_TARGET_EXIT_DATA)
16177 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
16179 p = IDENTIFIER_POINTER
16180 (c_parser_peek_2nd_token (parser)->value);
16181 if (strcmp ("data", p) == 0)
16182 n = 4;
16184 if (n == 4)
16185 c_parser_consume_token (parser);
16186 else
16188 location_t loc
16189 = c_parser_peek_2nd_token (parser)->location;
16190 error_at (loc, "expected %<data%>");
16191 if_modifier = ERROR_MARK;
16196 if (if_modifier != ERROR_MARK)
16198 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16200 c_parser_consume_token (parser);
16201 c_parser_consume_token (parser);
16203 else
16205 if (n > 2)
16207 location_t loc = c_parser_peek_2nd_token (parser)->location;
16208 error_at (loc, "expected %<:%>");
16210 if_modifier = ERROR_MARK;
16215 location_t loc = c_parser_peek_token (parser)->location;
16216 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16217 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
16218 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
16219 t = c_fully_fold (t, false, NULL);
16220 parens.skip_until_found_close (parser);
16222 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
16223 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
16225 if (if_modifier != ERROR_MARK
16226 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
16228 const char *p = NULL;
16229 switch (if_modifier)
16231 case VOID_CST: p = "cancel"; break;
16232 case OMP_PARALLEL: p = "parallel"; break;
16233 case OMP_SIMD: p = "simd"; break;
16234 case OMP_TASK: p = "task"; break;
16235 case OMP_TASKLOOP: p = "taskloop"; break;
16236 case OMP_TARGET_DATA: p = "target data"; break;
16237 case OMP_TARGET: p = "target"; break;
16238 case OMP_TARGET_UPDATE: p = "target update"; break;
16239 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
16240 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
16241 default: gcc_unreachable ();
16243 error_at (location, "too many %<if%> clauses with %qs modifier",
16245 return list;
16247 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
16249 if (!is_omp)
16250 error_at (location, "too many %<if%> clauses");
16251 else
16252 error_at (location, "too many %<if%> clauses without modifier");
16253 return list;
16255 else if (if_modifier == ERROR_MARK
16256 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
16258 error_at (location, "if any %<if%> clause has modifier, then all "
16259 "%<if%> clauses have to use modifier");
16260 return list;
16264 c = build_omp_clause (location, OMP_CLAUSE_IF);
16265 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
16266 OMP_CLAUSE_IF_EXPR (c) = t;
16267 OMP_CLAUSE_CHAIN (c) = list;
16268 return c;
16271 /* OpenMP 2.5:
16272 lastprivate ( variable-list )
16274 OpenMP 5.0:
16275 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
16277 static tree
16278 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
16280 /* The clauses location. */
16281 location_t loc = c_parser_peek_token (parser)->location;
16283 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
16285 bool conditional = false;
16286 if (c_parser_next_token_is (parser, CPP_NAME)
16287 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16289 const char *p
16290 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16291 if (strcmp (p, "conditional") == 0)
16293 conditional = true;
16294 c_parser_consume_token (parser);
16295 c_parser_consume_token (parser);
16298 tree nlist = c_parser_omp_variable_list (parser, loc,
16299 OMP_CLAUSE_LASTPRIVATE, list);
16300 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
16301 if (conditional)
16302 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
16303 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
16304 return nlist;
16306 return list;
16309 /* OpenMP 3.1:
16310 mergeable */
16312 static tree
16313 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
16315 tree c;
16317 /* FIXME: Should we allow duplicates? */
16318 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
16320 c = build_omp_clause (c_parser_peek_token (parser)->location,
16321 OMP_CLAUSE_MERGEABLE);
16322 OMP_CLAUSE_CHAIN (c) = list;
16324 return c;
16327 /* OpenMP 2.5:
16328 nowait */
16330 static tree
16331 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
16333 tree c;
16334 location_t loc = c_parser_peek_token (parser)->location;
16336 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
16338 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
16339 OMP_CLAUSE_CHAIN (c) = list;
16340 return c;
16343 /* OpenMP 2.5:
16344 num_threads ( expression ) */
16346 static tree
16347 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
16349 location_t num_threads_loc = c_parser_peek_token (parser)->location;
16350 matching_parens parens;
16351 if (parens.require_open (parser))
16353 location_t expr_loc = c_parser_peek_token (parser)->location;
16354 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16355 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16356 tree c, t = expr.value;
16357 t = c_fully_fold (t, false, NULL);
16359 parens.skip_until_found_close (parser);
16361 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16363 c_parser_error (parser, "expected integer expression");
16364 return list;
16367 /* Attempt to statically determine when the number isn't positive. */
16368 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16369 build_int_cst (TREE_TYPE (t), 0));
16370 protected_set_expr_location (c, expr_loc);
16371 if (c == boolean_true_node)
16373 warning_at (expr_loc, OPT_Wopenmp,
16374 "%<num_threads%> value must be positive");
16375 t = integer_one_node;
16378 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
16380 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
16381 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
16382 OMP_CLAUSE_CHAIN (c) = list;
16383 list = c;
16386 return list;
16389 /* OpenMP 4.5:
16390 num_tasks ( expression )
16392 OpenMP 5.1:
16393 num_tasks ( strict : expression ) */
16395 static tree
16396 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
16398 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
16399 matching_parens parens;
16400 if (parens.require_open (parser))
16402 bool strict = false;
16403 if (c_parser_next_token_is (parser, CPP_NAME)
16404 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
16405 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16406 "strict") == 0)
16408 strict = true;
16409 c_parser_consume_token (parser);
16410 c_parser_consume_token (parser);
16413 location_t expr_loc = c_parser_peek_token (parser)->location;
16414 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16415 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16416 tree c, t = expr.value;
16417 t = c_fully_fold (t, false, NULL);
16419 parens.skip_until_found_close (parser);
16421 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16423 c_parser_error (parser, "expected integer expression");
16424 return list;
16427 /* Attempt to statically determine when the number isn't positive. */
16428 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16429 build_int_cst (TREE_TYPE (t), 0));
16430 if (CAN_HAVE_LOCATION_P (c))
16431 SET_EXPR_LOCATION (c, expr_loc);
16432 if (c == boolean_true_node)
16434 warning_at (expr_loc, OPT_Wopenmp,
16435 "%<num_tasks%> value must be positive");
16436 t = integer_one_node;
16439 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
16441 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
16442 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
16443 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
16444 OMP_CLAUSE_CHAIN (c) = list;
16445 list = c;
16448 return list;
16451 /* OpenMP 4.5:
16452 grainsize ( expression )
16454 OpenMP 5.1:
16455 grainsize ( strict : expression ) */
16457 static tree
16458 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
16460 location_t grainsize_loc = c_parser_peek_token (parser)->location;
16461 matching_parens parens;
16462 if (parens.require_open (parser))
16464 bool strict = false;
16465 if (c_parser_next_token_is (parser, CPP_NAME)
16466 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
16467 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16468 "strict") == 0)
16470 strict = true;
16471 c_parser_consume_token (parser);
16472 c_parser_consume_token (parser);
16475 location_t expr_loc = c_parser_peek_token (parser)->location;
16476 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16477 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16478 tree c, t = expr.value;
16479 t = c_fully_fold (t, false, NULL);
16481 parens.skip_until_found_close (parser);
16483 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16485 c_parser_error (parser, "expected integer expression");
16486 return list;
16489 /* Attempt to statically determine when the number isn't positive. */
16490 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16491 build_int_cst (TREE_TYPE (t), 0));
16492 if (CAN_HAVE_LOCATION_P (c))
16493 SET_EXPR_LOCATION (c, expr_loc);
16494 if (c == boolean_true_node)
16496 warning_at (expr_loc, OPT_Wopenmp,
16497 "%<grainsize%> value must be positive");
16498 t = integer_one_node;
16501 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
16503 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
16504 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
16505 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
16506 OMP_CLAUSE_CHAIN (c) = list;
16507 list = c;
16510 return list;
16513 /* OpenMP 4.5:
16514 priority ( expression ) */
16516 static tree
16517 c_parser_omp_clause_priority (c_parser *parser, tree list)
16519 location_t priority_loc = c_parser_peek_token (parser)->location;
16520 matching_parens parens;
16521 if (parens.require_open (parser))
16523 location_t expr_loc = c_parser_peek_token (parser)->location;
16524 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16525 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16526 tree c, t = expr.value;
16527 t = c_fully_fold (t, false, NULL);
16529 parens.skip_until_found_close (parser);
16531 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16533 c_parser_error (parser, "expected integer expression");
16534 return list;
16537 /* Attempt to statically determine when the number isn't
16538 non-negative. */
16539 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
16540 build_int_cst (TREE_TYPE (t), 0));
16541 if (CAN_HAVE_LOCATION_P (c))
16542 SET_EXPR_LOCATION (c, expr_loc);
16543 if (c == boolean_true_node)
16545 warning_at (expr_loc, OPT_Wopenmp,
16546 "%<priority%> value must be non-negative");
16547 t = integer_one_node;
16550 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
16552 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
16553 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
16554 OMP_CLAUSE_CHAIN (c) = list;
16555 list = c;
16558 return list;
16561 /* OpenMP 4.5:
16562 hint ( expression ) */
16564 static tree
16565 c_parser_omp_clause_hint (c_parser *parser, tree list)
16567 location_t hint_loc = c_parser_peek_token (parser)->location;
16568 matching_parens parens;
16569 if (parens.require_open (parser))
16571 location_t expr_loc = c_parser_peek_token (parser)->location;
16572 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16573 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16574 tree c, t = expr.value;
16575 t = c_fully_fold (t, false, NULL);
16576 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
16577 || TREE_CODE (t) != INTEGER_CST
16578 || tree_int_cst_sgn (t) == -1)
16580 c_parser_error (parser, "expected constant integer expression "
16581 "with valid sync-hint value");
16582 return list;
16584 parens.skip_until_found_close (parser);
16585 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
16587 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
16588 OMP_CLAUSE_HINT_EXPR (c) = t;
16589 OMP_CLAUSE_CHAIN (c) = list;
16590 list = c;
16593 return list;
16596 /* OpenMP 5.1:
16597 filter ( integer-expression ) */
16599 static tree
16600 c_parser_omp_clause_filter (c_parser *parser, tree list)
16602 location_t hint_loc = c_parser_peek_token (parser)->location;
16603 matching_parens parens;
16604 if (parens.require_open (parser))
16606 location_t expr_loc = c_parser_peek_token (parser)->location;
16607 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16608 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16609 tree c, t = expr.value;
16610 t = c_fully_fold (t, false, NULL);
16611 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16613 c_parser_error (parser, "expected integer expression");
16614 return list;
16616 parens.skip_until_found_close (parser);
16617 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
16619 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
16620 OMP_CLAUSE_FILTER_EXPR (c) = t;
16621 OMP_CLAUSE_CHAIN (c) = list;
16622 list = c;
16625 return list;
16628 /* OpenMP 4.5:
16629 defaultmap ( tofrom : scalar )
16631 OpenMP 5.0:
16632 defaultmap ( implicit-behavior [ : variable-category ] ) */
16634 static tree
16635 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
16637 location_t loc = c_parser_peek_token (parser)->location;
16638 tree c;
16639 const char *p;
16640 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
16641 enum omp_clause_defaultmap_kind category
16642 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
16644 matching_parens parens;
16645 if (!parens.require_open (parser))
16646 return list;
16647 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
16648 p = "default";
16649 else if (!c_parser_next_token_is (parser, CPP_NAME))
16651 invalid_behavior:
16652 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
16653 "%<tofrom%>, %<firstprivate%>, %<none%> "
16654 "or %<default%>");
16655 goto out_err;
16657 else
16658 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16660 switch (p[0])
16662 case 'a':
16663 if (strcmp ("alloc", p) == 0)
16664 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
16665 else
16666 goto invalid_behavior;
16667 break;
16669 case 'd':
16670 if (strcmp ("default", p) == 0)
16671 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
16672 else
16673 goto invalid_behavior;
16674 break;
16676 case 'f':
16677 if (strcmp ("firstprivate", p) == 0)
16678 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
16679 else if (strcmp ("from", p) == 0)
16680 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
16681 else
16682 goto invalid_behavior;
16683 break;
16685 case 'n':
16686 if (strcmp ("none", p) == 0)
16687 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
16688 else
16689 goto invalid_behavior;
16690 break;
16692 case 'p':
16693 if (strcmp ("present", p) == 0)
16694 behavior = OMP_CLAUSE_DEFAULTMAP_PRESENT;
16695 else
16696 goto invalid_behavior;
16697 break;
16699 case 't':
16700 if (strcmp ("tofrom", p) == 0)
16701 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
16702 else if (strcmp ("to", p) == 0)
16703 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
16704 else
16705 goto invalid_behavior;
16706 break;
16708 default:
16709 goto invalid_behavior;
16711 c_parser_consume_token (parser);
16713 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16715 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16716 goto out_err;
16717 if (!c_parser_next_token_is (parser, CPP_NAME))
16719 invalid_category:
16720 c_parser_error (parser, "expected %<scalar%>, %<aggregate%>, "
16721 "%<pointer%> or %<all%>");
16722 goto out_err;
16724 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16725 switch (p[0])
16727 case 'a':
16728 if (strcmp ("aggregate", p) == 0)
16729 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
16730 else if (strcmp ("all", p) == 0)
16731 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
16732 else
16733 goto invalid_category;
16734 break;
16736 case 'p':
16737 if (strcmp ("pointer", p) == 0)
16738 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
16739 else
16740 goto invalid_category;
16741 break;
16743 case 's':
16744 if (strcmp ("scalar", p) == 0)
16745 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
16746 else
16747 goto invalid_category;
16748 break;
16750 default:
16751 goto invalid_category;
16754 c_parser_consume_token (parser);
16756 parens.skip_until_found_close (parser);
16758 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
16759 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
16760 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16761 || category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16762 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
16763 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16764 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
16765 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16766 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL)))
16768 enum omp_clause_defaultmap_kind cat = category;
16769 location_t loc = OMP_CLAUSE_LOCATION (c);
16770 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16771 || (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16772 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
16773 != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
16774 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
16775 p = NULL;
16776 switch (cat)
16778 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
16779 p = NULL;
16780 break;
16781 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
16782 p = "all";
16783 break;
16784 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
16785 p = "aggregate";
16786 break;
16787 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
16788 p = "pointer";
16789 break;
16790 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
16791 p = "scalar";
16792 break;
16793 default:
16794 gcc_unreachable ();
16796 if (p)
16797 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
16799 else
16800 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
16801 "category");
16802 break;
16805 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
16806 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
16807 OMP_CLAUSE_CHAIN (c) = list;
16808 return c;
16810 out_err:
16811 parens.skip_until_found_close (parser);
16812 return list;
16815 /* OpenACC 2.0:
16816 use_device ( variable-list )
16818 OpenMP 4.5:
16819 use_device_ptr ( variable-list ) */
16821 static tree
16822 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
16824 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
16825 list);
16828 /* OpenMP 5.0:
16829 use_device_addr ( variable-list ) */
16831 static tree
16832 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
16834 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
16835 list);
16838 /* OpenMP 5.1:
16839 has_device_addr ( variable-list ) */
16841 static tree
16842 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
16844 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
16845 list);
16848 /* OpenMP 4.5:
16849 is_device_ptr ( variable-list ) */
16851 static tree
16852 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
16854 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
16857 /* OpenACC:
16858 num_gangs ( expression )
16859 num_workers ( expression )
16860 vector_length ( expression ) */
16862 static tree
16863 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
16864 tree list)
16866 location_t loc = c_parser_peek_token (parser)->location;
16868 matching_parens parens;
16869 if (!parens.require_open (parser))
16870 return list;
16872 location_t expr_loc = c_parser_peek_token (parser)->location;
16873 c_expr expr = c_parser_expression (parser);
16874 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16875 tree c, t = expr.value;
16876 t = c_fully_fold (t, false, NULL);
16878 parens.skip_until_found_close (parser);
16880 if (t == error_mark_node)
16881 return list;
16882 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16884 error_at (expr_loc, "%qs expression must be integral",
16885 omp_clause_code_name[code]);
16886 return list;
16889 /* Attempt to statically determine when the number isn't positive. */
16890 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16891 build_int_cst (TREE_TYPE (t), 0));
16892 protected_set_expr_location (c, expr_loc);
16893 if (c == boolean_true_node)
16895 warning_at (expr_loc, 0,
16896 "%qs value must be positive",
16897 omp_clause_code_name[code]);
16898 t = integer_one_node;
16901 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
16903 c = build_omp_clause (loc, code);
16904 OMP_CLAUSE_OPERAND (c, 0) = t;
16905 OMP_CLAUSE_CHAIN (c) = list;
16906 return c;
16909 /* OpenACC:
16911 gang [( gang-arg-list )]
16912 worker [( [num:] int-expr )]
16913 vector [( [length:] int-expr )]
16915 where gang-arg is one of:
16917 [num:] int-expr
16918 static: size-expr
16920 and size-expr may be:
16923 int-expr
16926 static tree
16927 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
16928 omp_clause_code kind,
16929 const char *str, tree list)
16931 const char *id = "num";
16932 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
16934 if (kind == OMP_CLAUSE_VECTOR)
16935 id = "length";
16937 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
16939 c_parser_consume_token (parser);
16943 c_token *next = c_parser_peek_token (parser);
16944 int idx = 0;
16946 /* Gang static argument. */
16947 if (kind == OMP_CLAUSE_GANG
16948 && c_parser_next_token_is_keyword (parser, RID_STATIC))
16950 c_parser_consume_token (parser);
16952 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16953 goto cleanup_error;
16955 idx = 1;
16956 if (ops[idx] != NULL_TREE)
16958 c_parser_error (parser, "too many %<static%> arguments");
16959 goto cleanup_error;
16962 /* Check for the '*' argument. */
16963 if (c_parser_next_token_is (parser, CPP_MULT)
16964 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
16965 || c_parser_peek_2nd_token (parser)->type
16966 == CPP_CLOSE_PAREN))
16968 c_parser_consume_token (parser);
16969 ops[idx] = integer_minus_one_node;
16971 if (c_parser_next_token_is (parser, CPP_COMMA))
16973 c_parser_consume_token (parser);
16974 continue;
16976 else
16977 break;
16980 /* Worker num: argument and vector length: arguments. */
16981 else if (c_parser_next_token_is (parser, CPP_NAME)
16982 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
16983 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16985 c_parser_consume_token (parser); /* id */
16986 c_parser_consume_token (parser); /* ':' */
16989 /* Now collect the actual argument. */
16990 if (ops[idx] != NULL_TREE)
16992 c_parser_error (parser, "unexpected argument");
16993 goto cleanup_error;
16996 location_t expr_loc = c_parser_peek_token (parser)->location;
16997 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
16998 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
16999 tree expr = cexpr.value;
17000 if (expr == error_mark_node)
17001 goto cleanup_error;
17003 expr = c_fully_fold (expr, false, NULL);
17005 /* Attempt to statically determine when the number isn't a
17006 positive integer. */
17008 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
17010 c_parser_error (parser, "expected integer expression");
17011 return list;
17014 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
17015 build_int_cst (TREE_TYPE (expr), 0));
17016 if (c == boolean_true_node)
17018 warning_at (loc, 0,
17019 "%qs value must be positive", str);
17020 expr = integer_one_node;
17023 ops[idx] = expr;
17025 if (kind == OMP_CLAUSE_GANG
17026 && c_parser_next_token_is (parser, CPP_COMMA))
17028 c_parser_consume_token (parser);
17029 continue;
17031 break;
17033 while (1);
17035 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17036 goto cleanup_error;
17039 check_no_duplicate_clause (list, kind, str);
17041 c = build_omp_clause (loc, kind);
17043 if (ops[1])
17044 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
17046 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
17047 OMP_CLAUSE_CHAIN (c) = list;
17049 return c;
17051 cleanup_error:
17052 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
17053 return list;
17056 /* OpenACC 2.5:
17057 auto
17058 finalize
17059 independent
17060 nohost
17061 seq */
17063 static tree
17064 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
17065 tree list)
17067 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
17069 tree c = build_omp_clause (loc, code);
17070 OMP_CLAUSE_CHAIN (c) = list;
17072 return c;
17075 /* OpenACC:
17076 async [( int-expr )] */
17078 static tree
17079 c_parser_oacc_clause_async (c_parser *parser, tree list)
17081 tree c, t;
17082 location_t loc = c_parser_peek_token (parser)->location;
17084 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
17086 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17088 c_parser_consume_token (parser);
17090 t = c_parser_expr_no_commas (parser, NULL).value;
17091 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
17092 c_parser_error (parser, "expected integer expression");
17093 else if (t == error_mark_node
17094 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17095 return list;
17097 else
17098 t = c_fully_fold (t, false, NULL);
17100 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
17102 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
17103 OMP_CLAUSE_ASYNC_EXPR (c) = t;
17104 OMP_CLAUSE_CHAIN (c) = list;
17105 list = c;
17107 return list;
17110 /* OpenACC 2.0:
17111 tile ( size-expr-list ) */
17113 static tree
17114 c_parser_oacc_clause_tile (c_parser *parser, tree list)
17116 tree c, expr = error_mark_node;
17117 location_t loc;
17118 tree tile = NULL_TREE;
17120 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
17121 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
17123 loc = c_parser_peek_token (parser)->location;
17124 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
17125 return list;
17129 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
17130 return list;
17132 if (c_parser_next_token_is (parser, CPP_MULT)
17133 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
17134 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
17136 c_parser_consume_token (parser);
17137 expr = integer_zero_node;
17139 else
17141 location_t expr_loc = c_parser_peek_token (parser)->location;
17142 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
17143 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
17144 expr = cexpr.value;
17146 if (expr == error_mark_node)
17148 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17149 "expected %<)%>");
17150 return list;
17153 expr = c_fully_fold (expr, false, NULL);
17155 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
17156 || !tree_fits_shwi_p (expr)
17157 || tree_to_shwi (expr) <= 0)
17159 error_at (expr_loc, "%<tile%> argument needs positive"
17160 " integral constant");
17161 expr = integer_zero_node;
17165 tile = tree_cons (NULL_TREE, expr, tile);
17167 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
17169 /* Consume the trailing ')'. */
17170 c_parser_consume_token (parser);
17172 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
17173 tile = nreverse (tile);
17174 OMP_CLAUSE_TILE_LIST (c) = tile;
17175 OMP_CLAUSE_CHAIN (c) = list;
17176 return c;
17179 /* OpenACC:
17180 wait [( int-expr-list )] */
17182 static tree
17183 c_parser_oacc_clause_wait (c_parser *parser, tree list)
17185 location_t clause_loc = c_parser_peek_token (parser)->location;
17187 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17188 list = c_parser_oacc_wait_list (parser, clause_loc, list);
17189 else
17191 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
17193 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
17194 OMP_CLAUSE_CHAIN (c) = list;
17195 list = c;
17198 return list;
17201 /* OpenACC 2.7:
17202 self [( expression )] */
17204 static tree
17205 c_parser_oacc_compute_clause_self (c_parser *parser, tree list)
17207 tree t;
17208 location_t location = c_parser_peek_token (parser)->location;
17209 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17211 matching_parens parens;
17212 parens.consume_open (parser);
17214 location_t loc = c_parser_peek_token (parser)->location;
17215 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17216 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
17217 t = c_objc_common_truthvalue_conversion (loc, expr.value);
17218 t = c_fully_fold (t, false, NULL);
17219 parens.skip_until_found_close (parser);
17221 else
17222 t = truthvalue_true_node;
17224 for (tree c = list; c; c = OMP_CLAUSE_CHAIN (c))
17225 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
17227 error_at (location, "too many %<self%> clauses");
17228 return list;
17231 tree c = build_omp_clause (location, OMP_CLAUSE_SELF);
17232 OMP_CLAUSE_SELF_EXPR (c) = t;
17233 OMP_CLAUSE_CHAIN (c) = list;
17234 return c;
17237 /* OpenMP 5.0:
17238 order ( concurrent )
17240 OpenMP 5.1:
17241 order ( order-modifier : concurrent )
17243 order-modifier:
17244 reproducible
17245 unconstrained */
17247 static tree
17248 c_parser_omp_clause_order (c_parser *parser, tree list)
17250 location_t loc = c_parser_peek_token (parser)->location;
17251 tree c;
17252 const char *p;
17253 bool unconstrained = false;
17254 bool reproducible = false;
17256 matching_parens parens;
17257 if (!parens.require_open (parser))
17258 return list;
17259 if (c_parser_next_token_is (parser, CPP_NAME)
17260 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
17262 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17263 if (strcmp (p, "unconstrained") == 0)
17264 unconstrained = true;
17265 else if (strcmp (p, "reproducible") == 0)
17266 reproducible = true;
17267 else
17269 c_parser_error (parser, "expected %<reproducible%> or "
17270 "%<unconstrained%>");
17271 goto out_err;
17273 c_parser_consume_token (parser);
17274 c_parser_consume_token (parser);
17276 if (!c_parser_next_token_is (parser, CPP_NAME))
17278 c_parser_error (parser, "expected %<concurrent%>");
17279 goto out_err;
17281 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17282 if (strcmp (p, "concurrent") != 0)
17284 c_parser_error (parser, "expected %<concurrent%>");
17285 goto out_err;
17287 c_parser_consume_token (parser);
17288 parens.skip_until_found_close (parser);
17289 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
17290 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
17291 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
17292 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
17293 OMP_CLAUSE_CHAIN (c) = list;
17294 return c;
17296 out_err:
17297 parens.skip_until_found_close (parser);
17298 return list;
17302 /* OpenMP 5.0:
17303 bind ( teams | parallel | thread ) */
17305 static tree
17306 c_parser_omp_clause_bind (c_parser *parser, tree list)
17308 location_t loc = c_parser_peek_token (parser)->location;
17309 tree c;
17310 const char *p;
17311 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
17313 matching_parens parens;
17314 if (!parens.require_open (parser))
17315 return list;
17316 if (!c_parser_next_token_is (parser, CPP_NAME))
17318 invalid:
17319 c_parser_error (parser,
17320 "expected %<teams%>, %<parallel%> or %<thread%>");
17321 parens.skip_until_found_close (parser);
17322 return list;
17324 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17325 if (strcmp (p, "teams") == 0)
17326 kind = OMP_CLAUSE_BIND_TEAMS;
17327 else if (strcmp (p, "parallel") == 0)
17328 kind = OMP_CLAUSE_BIND_PARALLEL;
17329 else if (strcmp (p, "thread") != 0)
17330 goto invalid;
17331 c_parser_consume_token (parser);
17332 parens.skip_until_found_close (parser);
17333 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
17334 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
17335 OMP_CLAUSE_BIND_KIND (c) = kind;
17336 OMP_CLAUSE_CHAIN (c) = list;
17337 return c;
17341 /* OpenMP 2.5:
17342 ordered
17344 OpenMP 4.5:
17345 ordered ( constant-expression ) */
17347 static tree
17348 c_parser_omp_clause_ordered (c_parser *parser, tree list)
17350 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
17352 tree c, num = NULL_TREE;
17353 HOST_WIDE_INT n;
17354 location_t loc = c_parser_peek_token (parser)->location;
17355 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17357 matching_parens parens;
17358 parens.consume_open (parser);
17359 num = c_parser_expr_no_commas (parser, NULL).value;
17360 parens.skip_until_found_close (parser);
17362 if (num == error_mark_node)
17363 return list;
17364 if (num)
17366 mark_exp_read (num);
17367 num = c_fully_fold (num, false, NULL);
17368 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
17369 || !tree_fits_shwi_p (num)
17370 || (n = tree_to_shwi (num)) <= 0
17371 || (int) n != n)
17373 error_at (loc, "ordered argument needs positive "
17374 "constant integer expression");
17375 return list;
17378 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
17379 OMP_CLAUSE_ORDERED_EXPR (c) = num;
17380 OMP_CLAUSE_CHAIN (c) = list;
17381 return c;
17384 /* OpenMP 2.5:
17385 private ( variable-list ) */
17387 static tree
17388 c_parser_omp_clause_private (c_parser *parser, tree list)
17390 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
17393 /* OpenMP 2.5:
17394 reduction ( reduction-operator : variable-list )
17396 reduction-operator:
17397 One of: + * - & ^ | && ||
17399 OpenMP 3.1:
17401 reduction-operator:
17402 One of: + * - & ^ | && || max min
17404 OpenMP 4.0:
17406 reduction-operator:
17407 One of: + * - & ^ | && ||
17408 identifier
17410 OpenMP 5.0:
17411 reduction ( reduction-modifier, reduction-operator : variable-list )
17412 in_reduction ( reduction-operator : variable-list )
17413 task_reduction ( reduction-operator : variable-list ) */
17415 static tree
17416 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
17417 bool is_omp, tree list)
17419 location_t clause_loc = c_parser_peek_token (parser)->location;
17420 matching_parens parens;
17421 if (parens.require_open (parser))
17423 bool task = false;
17424 bool inscan = false;
17425 enum tree_code code = ERROR_MARK;
17426 tree reduc_id = NULL_TREE;
17428 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
17430 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
17431 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
17433 c_parser_consume_token (parser);
17434 c_parser_consume_token (parser);
17436 else if (c_parser_next_token_is (parser, CPP_NAME)
17437 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
17439 const char *p
17440 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17441 if (strcmp (p, "task") == 0)
17442 task = true;
17443 else if (strcmp (p, "inscan") == 0)
17444 inscan = true;
17445 if (task || inscan)
17447 c_parser_consume_token (parser);
17448 c_parser_consume_token (parser);
17453 switch (c_parser_peek_token (parser)->type)
17455 case CPP_PLUS:
17456 code = PLUS_EXPR;
17457 break;
17458 case CPP_MULT:
17459 code = MULT_EXPR;
17460 break;
17461 case CPP_MINUS:
17462 code = MINUS_EXPR;
17463 break;
17464 case CPP_AND:
17465 code = BIT_AND_EXPR;
17466 break;
17467 case CPP_XOR:
17468 code = BIT_XOR_EXPR;
17469 break;
17470 case CPP_OR:
17471 code = BIT_IOR_EXPR;
17472 break;
17473 case CPP_AND_AND:
17474 code = TRUTH_ANDIF_EXPR;
17475 break;
17476 case CPP_OR_OR:
17477 code = TRUTH_ORIF_EXPR;
17478 break;
17479 case CPP_NAME:
17481 const char *p
17482 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17483 if (strcmp (p, "min") == 0)
17485 code = MIN_EXPR;
17486 break;
17488 if (strcmp (p, "max") == 0)
17490 code = MAX_EXPR;
17491 break;
17493 reduc_id = c_parser_peek_token (parser)->value;
17494 break;
17496 default:
17497 c_parser_error (parser,
17498 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
17499 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
17500 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
17501 return list;
17503 c_parser_consume_token (parser);
17504 reduc_id = c_omp_reduction_id (code, reduc_id);
17505 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
17507 tree nl, c;
17509 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
17510 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17512 tree d = OMP_CLAUSE_DECL (c), type;
17513 if (TREE_CODE (d) != OMP_ARRAY_SECTION)
17514 type = TREE_TYPE (d);
17515 else
17517 int cnt = 0;
17518 tree t;
17519 for (t = d;
17520 TREE_CODE (t) == OMP_ARRAY_SECTION;
17521 t = TREE_OPERAND (t, 0))
17522 cnt++;
17523 type = TREE_TYPE (t);
17524 while (cnt > 0)
17526 if (TREE_CODE (type) != POINTER_TYPE
17527 && TREE_CODE (type) != ARRAY_TYPE)
17528 break;
17529 type = TREE_TYPE (type);
17530 cnt--;
17533 while (TREE_CODE (type) == ARRAY_TYPE)
17534 type = TREE_TYPE (type);
17535 OMP_CLAUSE_REDUCTION_CODE (c) = code;
17536 if (task)
17537 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
17538 else if (inscan)
17539 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
17540 if (code == ERROR_MARK
17541 || !(INTEGRAL_TYPE_P (type)
17542 || SCALAR_FLOAT_TYPE_P (type)
17543 || TREE_CODE (type) == COMPLEX_TYPE))
17544 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
17545 = c_omp_reduction_lookup (reduc_id,
17546 TYPE_MAIN_VARIANT (type));
17549 list = nl;
17551 parens.skip_until_found_close (parser);
17553 return list;
17556 /* OpenMP 2.5:
17557 schedule ( schedule-kind )
17558 schedule ( schedule-kind , expression )
17560 schedule-kind:
17561 static | dynamic | guided | runtime | auto
17563 OpenMP 4.5:
17564 schedule ( schedule-modifier : schedule-kind )
17565 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
17567 schedule-modifier:
17568 simd
17569 monotonic
17570 nonmonotonic */
17572 static tree
17573 c_parser_omp_clause_schedule (c_parser *parser, tree list)
17575 tree c, t;
17576 location_t loc = c_parser_peek_token (parser)->location;
17577 int modifiers = 0, nmodifiers = 0;
17579 matching_parens parens;
17580 if (!parens.require_open (parser))
17581 return list;
17583 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
17585 location_t comma = UNKNOWN_LOCATION;
17586 while (c_parser_next_token_is (parser, CPP_NAME))
17588 tree kind = c_parser_peek_token (parser)->value;
17589 const char *p = IDENTIFIER_POINTER (kind);
17590 if (strcmp ("simd", p) == 0)
17591 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
17592 else if (strcmp ("monotonic", p) == 0)
17593 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
17594 else if (strcmp ("nonmonotonic", p) == 0)
17595 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
17596 else
17597 break;
17598 comma = UNKNOWN_LOCATION;
17599 c_parser_consume_token (parser);
17600 if (nmodifiers++ == 0
17601 && c_parser_next_token_is (parser, CPP_COMMA))
17603 comma = c_parser_peek_token (parser)->location;
17604 c_parser_consume_token (parser);
17606 else
17608 c_parser_require (parser, CPP_COLON, "expected %<:%>");
17609 break;
17612 if (comma != UNKNOWN_LOCATION)
17613 error_at (comma, "expected %<:%>");
17615 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
17616 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
17617 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
17618 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
17620 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
17621 "specified");
17622 modifiers = 0;
17625 if (c_parser_next_token_is (parser, CPP_NAME))
17627 tree kind = c_parser_peek_token (parser)->value;
17628 const char *p = IDENTIFIER_POINTER (kind);
17630 switch (p[0])
17632 case 'd':
17633 if (strcmp ("dynamic", p) != 0)
17634 goto invalid_kind;
17635 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
17636 break;
17638 case 'g':
17639 if (strcmp ("guided", p) != 0)
17640 goto invalid_kind;
17641 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
17642 break;
17644 case 'r':
17645 if (strcmp ("runtime", p) != 0)
17646 goto invalid_kind;
17647 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
17648 break;
17650 default:
17651 goto invalid_kind;
17654 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
17655 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
17656 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
17657 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
17658 else
17659 goto invalid_kind;
17661 c_parser_consume_token (parser);
17662 if (c_parser_next_token_is (parser, CPP_COMMA))
17664 location_t here;
17665 c_parser_consume_token (parser);
17667 here = c_parser_peek_token (parser)->location;
17668 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17669 expr = convert_lvalue_to_rvalue (here, expr, false, true);
17670 t = expr.value;
17671 t = c_fully_fold (t, false, NULL);
17673 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
17674 error_at (here, "schedule %<runtime%> does not take "
17675 "a %<chunk_size%> parameter");
17676 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
17677 error_at (here,
17678 "schedule %<auto%> does not take "
17679 "a %<chunk_size%> parameter");
17680 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
17681 || TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE)
17683 /* Attempt to statically determine when the number isn't
17684 positive. */
17685 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
17686 build_int_cst (TREE_TYPE (t), 0));
17687 protected_set_expr_location (s, loc);
17688 if (s == boolean_true_node)
17690 warning_at (loc, OPT_Wopenmp,
17691 "chunk size value must be positive");
17692 t = integer_one_node;
17694 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
17696 else
17697 c_parser_error (parser, "expected integer expression");
17699 parens.skip_until_found_close (parser);
17701 else
17702 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17703 "expected %<,%> or %<)%>");
17705 OMP_CLAUSE_SCHEDULE_KIND (c)
17706 = (enum omp_clause_schedule_kind)
17707 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
17709 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
17710 OMP_CLAUSE_CHAIN (c) = list;
17711 return c;
17713 invalid_kind:
17714 c_parser_error (parser, "invalid schedule kind");
17715 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
17716 return list;
17719 /* OpenMP 2.5:
17720 shared ( variable-list ) */
17722 static tree
17723 c_parser_omp_clause_shared (c_parser *parser, tree list)
17725 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
17728 /* OpenMP 3.0:
17729 untied */
17731 static tree
17732 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
17734 tree c;
17736 /* FIXME: Should we allow duplicates? */
17737 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
17739 c = build_omp_clause (c_parser_peek_token (parser)->location,
17740 OMP_CLAUSE_UNTIED);
17741 OMP_CLAUSE_CHAIN (c) = list;
17743 return c;
17746 /* OpenMP 4.0:
17747 inbranch
17748 notinbranch */
17750 static tree
17751 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
17752 enum omp_clause_code code, tree list)
17754 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
17756 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17757 OMP_CLAUSE_CHAIN (c) = list;
17759 return c;
17762 /* OpenMP 4.0:
17763 parallel
17765 sections
17766 taskgroup */
17768 static tree
17769 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
17770 enum omp_clause_code code, tree list)
17772 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17773 OMP_CLAUSE_CHAIN (c) = list;
17775 return c;
17778 /* OpenMP 4.5:
17779 nogroup */
17781 static tree
17782 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
17784 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
17785 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
17786 OMP_CLAUSE_NOGROUP);
17787 OMP_CLAUSE_CHAIN (c) = list;
17788 return c;
17791 /* OpenMP 4.5:
17792 simd
17793 threads */
17795 static tree
17796 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
17797 enum omp_clause_code code, tree list)
17799 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
17800 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
17801 OMP_CLAUSE_CHAIN (c) = list;
17802 return c;
17805 /* OpenMP 4.0:
17806 num_teams ( expression )
17808 OpenMP 5.1:
17809 num_teams ( expression : expression ) */
17811 static tree
17812 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
17814 location_t num_teams_loc = c_parser_peek_token (parser)->location;
17815 matching_parens parens;
17816 if (parens.require_open (parser))
17818 location_t upper_loc = c_parser_peek_token (parser)->location;
17819 location_t lower_loc = UNKNOWN_LOCATION;
17820 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17821 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
17822 tree c, upper = expr.value, lower = NULL_TREE;
17823 upper = c_fully_fold (upper, false, NULL);
17825 if (c_parser_next_token_is (parser, CPP_COLON))
17827 c_parser_consume_token (parser);
17828 lower_loc = upper_loc;
17829 lower = upper;
17830 upper_loc = c_parser_peek_token (parser)->location;
17831 expr = c_parser_expr_no_commas (parser, NULL);
17832 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
17833 upper = expr.value;
17834 upper = c_fully_fold (upper, false, NULL);
17837 parens.skip_until_found_close (parser);
17839 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
17840 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
17842 c_parser_error (parser, "expected integer expression");
17843 return list;
17846 /* Attempt to statically determine when the number isn't positive. */
17847 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
17848 build_int_cst (TREE_TYPE (upper), 0));
17849 protected_set_expr_location (c, upper_loc);
17850 if (c == boolean_true_node)
17852 warning_at (upper_loc, OPT_Wopenmp,
17853 "%<num_teams%> value must be positive");
17854 upper = integer_one_node;
17856 if (lower)
17858 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
17859 build_int_cst (TREE_TYPE (lower), 0));
17860 protected_set_expr_location (c, lower_loc);
17861 if (c == boolean_true_node)
17863 warning_at (lower_loc, OPT_Wopenmp,
17864 "%<num_teams%> value must be positive");
17865 lower = NULL_TREE;
17867 else if (TREE_CODE (lower) == INTEGER_CST
17868 && TREE_CODE (upper) == INTEGER_CST
17869 && tree_int_cst_lt (upper, lower))
17871 warning_at (lower_loc, OPT_Wopenmp,
17872 "%<num_teams%> lower bound %qE bigger than upper "
17873 "bound %qE", lower, upper);
17874 lower = NULL_TREE;
17878 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
17880 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
17881 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
17882 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
17883 OMP_CLAUSE_CHAIN (c) = list;
17884 list = c;
17887 return list;
17890 /* OpenMP 4.0:
17891 thread_limit ( expression ) */
17893 static tree
17894 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
17896 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
17897 matching_parens parens;
17898 if (parens.require_open (parser))
17900 location_t expr_loc = c_parser_peek_token (parser)->location;
17901 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17902 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17903 tree c, t = expr.value;
17904 t = c_fully_fold (t, false, NULL);
17906 parens.skip_until_found_close (parser);
17908 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
17910 c_parser_error (parser, "expected integer expression");
17911 return list;
17914 /* Attempt to statically determine when the number isn't positive. */
17915 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
17916 build_int_cst (TREE_TYPE (t), 0));
17917 protected_set_expr_location (c, expr_loc);
17918 if (c == boolean_true_node)
17920 warning_at (expr_loc, OPT_Wopenmp,
17921 "%<thread_limit%> value must be positive");
17922 t = integer_one_node;
17925 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
17926 "thread_limit");
17928 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
17929 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
17930 OMP_CLAUSE_CHAIN (c) = list;
17931 list = c;
17934 return list;
17937 /* OpenMP 4.0:
17938 aligned ( variable-list )
17939 aligned ( variable-list : constant-expression ) */
17941 static tree
17942 c_parser_omp_clause_aligned (c_parser *parser, tree list)
17944 location_t clause_loc = c_parser_peek_token (parser)->location;
17945 tree nl, c;
17947 matching_parens parens;
17948 if (!parens.require_open (parser))
17949 return list;
17951 nl = c_parser_omp_variable_list (parser, clause_loc,
17952 OMP_CLAUSE_ALIGNED, list);
17954 if (c_parser_next_token_is (parser, CPP_COLON))
17956 c_parser_consume_token (parser);
17957 location_t expr_loc = c_parser_peek_token (parser)->location;
17958 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17959 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17960 tree alignment = expr.value;
17961 alignment = c_fully_fold (alignment, false, NULL);
17962 if (TREE_CODE (alignment) != INTEGER_CST
17963 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
17964 || tree_int_cst_sgn (alignment) != 1)
17966 error_at (clause_loc, "%<aligned%> clause alignment expression must "
17967 "be positive constant integer expression");
17968 alignment = NULL_TREE;
17971 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17972 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
17975 parens.skip_until_found_close (parser);
17976 return nl;
17979 /* OpenMP 5.0:
17980 allocate ( variable-list )
17981 allocate ( expression : variable-list )
17983 OpenMP 5.1:
17984 allocate ( allocator-modifier : variable-list )
17985 allocate ( allocator-modifier , allocator-modifier : variable-list )
17987 allocator-modifier:
17988 allocator ( expression )
17989 align ( expression ) */
17991 static tree
17992 c_parser_omp_clause_allocate (c_parser *parser, tree list)
17994 location_t clause_loc = c_parser_peek_token (parser)->location;
17995 tree nl, c;
17996 tree allocator = NULL_TREE;
17997 tree align = NULL_TREE;
17999 matching_parens parens;
18000 if (!parens.require_open (parser))
18001 return list;
18003 if ((c_parser_next_token_is_not (parser, CPP_NAME)
18004 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
18005 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
18006 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
18008 bool has_modifiers = false;
18009 tree orig_type = NULL_TREE;
18010 if (c_parser_next_token_is (parser, CPP_NAME)
18011 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
18013 unsigned int n = 3;
18014 const char *p
18015 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18016 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
18017 && c_parser_check_balanced_raw_token_sequence (parser, &n)
18018 && (c_parser_peek_nth_token_raw (parser, n)->type
18019 == CPP_CLOSE_PAREN))
18021 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
18022 == CPP_COLON)
18023 has_modifiers = true;
18024 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
18025 == CPP_COMMA
18026 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
18027 == CPP_NAME)
18028 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
18029 == CPP_OPEN_PAREN))
18031 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
18032 const char *q = IDENTIFIER_POINTER (tok->value);
18033 n += 4;
18034 if ((strcmp (q, "allocator") == 0
18035 || strcmp (q, "align") == 0)
18036 && c_parser_check_balanced_raw_token_sequence (parser,
18038 && (c_parser_peek_nth_token_raw (parser, n)->type
18039 == CPP_CLOSE_PAREN)
18040 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
18041 == CPP_COLON))
18042 has_modifiers = true;
18045 if (has_modifiers)
18047 c_parser_consume_token (parser);
18048 matching_parens parens2;
18049 parens2.require_open (parser);
18050 location_t expr_loc = c_parser_peek_token (parser)->location;
18051 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18052 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18053 if (expr.value == error_mark_node)
18055 else if (strcmp (p, "allocator") == 0)
18057 allocator = expr.value;
18058 allocator = c_fully_fold (allocator, false, NULL);
18059 orig_type = expr.original_type
18060 ? expr.original_type : TREE_TYPE (allocator);
18061 orig_type = TYPE_MAIN_VARIANT (orig_type);
18063 else
18065 align = expr.value;
18066 align = c_fully_fold (align, false, NULL);
18068 parens2.skip_until_found_close (parser);
18069 if (c_parser_next_token_is (parser, CPP_COMMA))
18071 c_parser_consume_token (parser);
18072 c_token *tok = c_parser_peek_token (parser);
18073 const char *q = "";
18074 if (c_parser_next_token_is (parser, CPP_NAME))
18075 q = IDENTIFIER_POINTER (tok->value);
18076 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
18078 c_parser_error (parser, "expected %<allocator%> or "
18079 "%<align%>");
18080 parens.skip_until_found_close (parser);
18081 return list;
18083 else if (strcmp (p, q) == 0)
18085 error_at (tok->location, "duplicate %qs modifier", p);
18086 parens.skip_until_found_close (parser);
18087 return list;
18089 c_parser_consume_token (parser);
18090 if (!parens2.require_open (parser))
18092 parens.skip_until_found_close (parser);
18093 return list;
18095 expr_loc = c_parser_peek_token (parser)->location;
18096 expr = c_parser_expr_no_commas (parser, NULL);
18097 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
18098 true);
18099 if (strcmp (q, "allocator") == 0)
18101 allocator = expr.value;
18102 allocator = c_fully_fold (allocator, false, NULL);
18103 orig_type = expr.original_type
18104 ? expr.original_type : TREE_TYPE (allocator);
18105 orig_type = TYPE_MAIN_VARIANT (orig_type);
18107 else
18109 align = expr.value;
18110 align = c_fully_fold (align, false, NULL);
18112 parens2.skip_until_found_close (parser);
18116 if (!has_modifiers)
18118 location_t expr_loc = c_parser_peek_token (parser)->location;
18119 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18120 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18121 allocator = expr.value;
18122 allocator = c_fully_fold (allocator, false, NULL);
18123 orig_type = expr.original_type
18124 ? expr.original_type : TREE_TYPE (allocator);
18125 orig_type = TYPE_MAIN_VARIANT (orig_type);
18127 if (allocator
18128 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
18129 || TREE_CODE (orig_type) != ENUMERAL_TYPE
18130 || (TYPE_NAME (orig_type)
18131 != get_identifier ("omp_allocator_handle_t"))))
18133 error_at (clause_loc, "%<allocate%> clause allocator expression "
18134 "has type %qT rather than "
18135 "%<omp_allocator_handle_t%>",
18136 TREE_TYPE (allocator));
18137 allocator = NULL_TREE;
18139 if (align
18140 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
18141 || !tree_fits_uhwi_p (align)
18142 || !integer_pow2p (align)))
18144 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
18145 "argument needs to be positive constant "
18146 "power of two integer expression");
18147 align = NULL_TREE;
18149 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18151 parens.skip_until_found_close (parser);
18152 return list;
18156 nl = c_parser_omp_variable_list (parser, clause_loc,
18157 OMP_CLAUSE_ALLOCATE, list);
18159 if (allocator || align)
18160 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18162 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18163 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
18166 parens.skip_until_found_close (parser);
18167 return nl;
18170 /* OpenMP 4.0:
18171 linear ( variable-list )
18172 linear ( variable-list : expression )
18174 OpenMP 4.5:
18175 linear ( modifier ( variable-list ) )
18176 linear ( modifier ( variable-list ) : expression )
18178 modifier:
18181 OpenMP 5.2:
18182 linear ( variable-list : modifiers-list )
18184 modifiers:
18186 step ( expression ) */
18188 static tree
18189 c_parser_omp_clause_linear (c_parser *parser, tree list)
18191 location_t clause_loc = c_parser_peek_token (parser)->location;
18192 tree nl, c, step;
18193 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
18194 bool old_linear_modifier = false;
18196 matching_parens parens;
18197 if (!parens.require_open (parser))
18198 return list;
18200 if (c_parser_next_token_is (parser, CPP_NAME))
18202 c_token *tok = c_parser_peek_token (parser);
18203 const char *p = IDENTIFIER_POINTER (tok->value);
18204 if (strcmp ("val", p) == 0)
18205 kind = OMP_CLAUSE_LINEAR_VAL;
18206 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
18207 kind = OMP_CLAUSE_LINEAR_DEFAULT;
18208 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18210 old_linear_modifier = true;
18211 c_parser_consume_token (parser);
18212 c_parser_consume_token (parser);
18216 nl = c_parser_omp_variable_list (parser, clause_loc,
18217 OMP_CLAUSE_LINEAR, list);
18219 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18220 parens.skip_until_found_close (parser);
18222 if (c_parser_next_token_is (parser, CPP_COLON))
18224 c_parser_consume_token (parser);
18225 location_t expr_loc = c_parser_peek_token (parser)->location;
18226 bool has_modifiers = false;
18227 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
18228 && c_parser_next_token_is (parser, CPP_NAME))
18230 c_token *tok = c_parser_peek_token (parser);
18231 const char *p = IDENTIFIER_POINTER (tok->value);
18232 unsigned int pos = 0;
18233 if (strcmp ("val", p) == 0)
18234 pos = 2;
18235 else if (strcmp ("step", p) == 0
18236 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
18238 pos = 3;
18239 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
18240 && (c_parser_peek_nth_token_raw (parser, pos)->type
18241 == CPP_CLOSE_PAREN))
18242 ++pos;
18243 else
18244 pos = 0;
18246 if (pos)
18248 tok = c_parser_peek_nth_token_raw (parser, pos);
18249 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
18250 has_modifiers = true;
18253 if (has_modifiers)
18255 step = NULL_TREE;
18256 while (c_parser_next_token_is (parser, CPP_NAME))
18258 c_token *tok = c_parser_peek_token (parser);
18259 const char *p = IDENTIFIER_POINTER (tok->value);
18260 if (strcmp ("val", p) == 0)
18262 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
18263 error_at (tok->location, "multiple linear modifiers");
18264 kind = OMP_CLAUSE_LINEAR_DEFAULT;
18265 c_parser_consume_token (parser);
18267 else if (strcmp ("step", p) == 0)
18269 c_parser_consume_token (parser);
18270 matching_parens parens2;
18271 if (parens2.require_open (parser))
18273 if (step)
18274 error_at (tok->location,
18275 "multiple %<step%> modifiers");
18276 expr_loc = c_parser_peek_token (parser)->location;
18277 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18278 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
18279 true);
18280 step = c_fully_fold (expr.value, false, NULL);
18281 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
18283 error_at (clause_loc, "%<linear%> clause step "
18284 "expression must be integral");
18285 step = integer_one_node;
18287 parens2.skip_until_found_close (parser);
18289 else
18290 break;
18292 else
18293 break;
18294 if (c_parser_next_token_is (parser, CPP_COMMA))
18296 c_parser_consume_token (parser);
18297 continue;
18299 break;
18301 if (!step)
18302 step = integer_one_node;
18304 else
18306 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18307 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18308 step = c_fully_fold (expr.value, false, NULL);
18309 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
18311 error_at (clause_loc, "%<linear%> clause step expression must "
18312 "be integral");
18313 step = integer_one_node;
18318 else
18319 step = integer_one_node;
18321 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18323 OMP_CLAUSE_LINEAR_STEP (c) = step;
18324 OMP_CLAUSE_LINEAR_KIND (c) = kind;
18325 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
18328 parens.skip_until_found_close (parser);
18329 return nl;
18332 /* OpenMP 5.0:
18333 nontemporal ( variable-list ) */
18335 static tree
18336 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
18338 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
18341 /* OpenMP 4.0:
18342 safelen ( constant-expression ) */
18344 static tree
18345 c_parser_omp_clause_safelen (c_parser *parser, tree list)
18347 location_t clause_loc = c_parser_peek_token (parser)->location;
18348 tree c, t;
18350 matching_parens parens;
18351 if (!parens.require_open (parser))
18352 return list;
18354 location_t expr_loc = c_parser_peek_token (parser)->location;
18355 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18356 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18357 t = expr.value;
18358 t = c_fully_fold (t, false, NULL);
18359 if (TREE_CODE (t) != INTEGER_CST
18360 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
18361 || tree_int_cst_sgn (t) != 1)
18363 error_at (clause_loc, "%<safelen%> clause expression must "
18364 "be positive constant integer expression");
18365 t = NULL_TREE;
18368 parens.skip_until_found_close (parser);
18369 if (t == NULL_TREE || t == error_mark_node)
18370 return list;
18372 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
18374 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
18375 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
18376 OMP_CLAUSE_CHAIN (c) = list;
18377 return c;
18380 /* OpenMP 4.0:
18381 simdlen ( constant-expression ) */
18383 static tree
18384 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
18386 location_t clause_loc = c_parser_peek_token (parser)->location;
18387 tree c, t;
18389 matching_parens parens;
18390 if (!parens.require_open (parser))
18391 return list;
18393 location_t expr_loc = c_parser_peek_token (parser)->location;
18394 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18395 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18396 t = expr.value;
18397 t = c_fully_fold (t, false, NULL);
18398 if (TREE_CODE (t) != INTEGER_CST
18399 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
18400 || tree_int_cst_sgn (t) != 1)
18402 error_at (clause_loc, "%<simdlen%> clause expression must "
18403 "be positive constant integer expression");
18404 t = NULL_TREE;
18407 parens.skip_until_found_close (parser);
18408 if (t == NULL_TREE || t == error_mark_node)
18409 return list;
18411 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
18413 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
18414 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
18415 OMP_CLAUSE_CHAIN (c) = list;
18416 return c;
18419 /* OpenMP 4.5:
18420 vec:
18421 identifier [+/- integer]
18422 vec , identifier [+/- integer]
18425 static tree
18426 c_parser_omp_clause_doacross_sink (c_parser *parser, location_t clause_loc,
18427 tree list, bool depend_p)
18429 tree vec = NULL;
18430 if (c_parser_next_token_is_not (parser, CPP_NAME)
18431 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
18433 c_parser_error (parser, "expected identifier");
18434 return list;
18437 if (!depend_p)
18439 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18440 if (strcmp (p, "omp_cur_iteration") == 0
18441 && c_parser_peek_2nd_token (parser)->type == CPP_MINUS
18442 && c_parser_peek_nth_token (parser, 3)->type == CPP_NUMBER
18443 && c_parser_peek_nth_token (parser, 4)->type == CPP_CLOSE_PAREN)
18445 tree val = c_parser_peek_nth_token (parser, 3)->value;
18446 if (integer_onep (val))
18448 c_parser_consume_token (parser);
18449 c_parser_consume_token (parser);
18450 c_parser_consume_token (parser);
18451 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18452 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
18453 OMP_CLAUSE_CHAIN (u) = list;
18454 return u;
18461 while (c_parser_next_token_is (parser, CPP_NAME)
18462 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
18464 tree t = lookup_name (c_parser_peek_token (parser)->value);
18465 tree addend = NULL;
18467 if (t == NULL_TREE)
18469 undeclared_variable (c_parser_peek_token (parser)->location,
18470 c_parser_peek_token (parser)->value);
18471 t = error_mark_node;
18474 c_parser_consume_token (parser);
18476 bool neg = false;
18477 if (c_parser_next_token_is (parser, CPP_MINUS))
18478 neg = true;
18479 else if (!c_parser_next_token_is (parser, CPP_PLUS))
18481 addend = integer_zero_node;
18482 neg = false;
18483 goto add_to_vector;
18485 c_parser_consume_token (parser);
18487 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
18489 c_parser_error (parser, "expected integer");
18490 return list;
18493 addend = c_parser_peek_token (parser)->value;
18494 if (TREE_CODE (addend) != INTEGER_CST)
18496 c_parser_error (parser, "expected integer");
18497 return list;
18499 c_parser_consume_token (parser);
18501 add_to_vector:
18502 if (t != error_mark_node)
18504 vec = tree_cons (addend, t, vec);
18505 if (neg)
18506 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
18509 if (c_parser_next_token_is_not (parser, CPP_COMMA)
18510 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
18511 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
18512 break;
18514 c_parser_consume_token (parser);
18517 if (vec == NULL_TREE)
18518 return list;
18520 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18521 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
18522 OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
18523 OMP_CLAUSE_DECL (u) = nreverse (vec);
18524 OMP_CLAUSE_CHAIN (u) = list;
18525 return u;
18528 /* OpenMP 5.0:
18529 iterators ( iterators-definition )
18531 iterators-definition:
18532 iterator-specifier
18533 iterator-specifier , iterators-definition
18535 iterator-specifier:
18536 identifier = range-specification
18537 iterator-type identifier = range-specification
18539 range-specification:
18540 begin : end
18541 begin : end : step */
18543 static tree
18544 c_parser_omp_iterators (c_parser *parser)
18546 tree ret = NULL_TREE, *last = &ret;
18547 c_parser_consume_token (parser);
18549 push_scope ();
18551 matching_parens parens;
18552 if (!parens.require_open (parser))
18553 return error_mark_node;
18557 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
18558 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
18560 struct c_type_name *type = c_parser_type_name (parser);
18561 if (type != NULL)
18562 iter_type = groktypename (type, &type_expr, NULL);
18564 if (iter_type == NULL_TREE)
18565 iter_type = integer_type_node;
18567 location_t loc = c_parser_peek_token (parser)->location;
18568 if (!c_parser_next_token_is (parser, CPP_NAME))
18570 c_parser_error (parser, "expected identifier");
18571 break;
18574 tree id = c_parser_peek_token (parser)->value;
18575 c_parser_consume_token (parser);
18577 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18578 break;
18580 location_t eloc = c_parser_peek_token (parser)->location;
18581 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18582 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18583 tree begin = expr.value;
18585 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18586 break;
18588 eloc = c_parser_peek_token (parser)->location;
18589 expr = c_parser_expr_no_commas (parser, NULL);
18590 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18591 tree end = expr.value;
18593 tree step = integer_one_node;
18594 if (c_parser_next_token_is (parser, CPP_COLON))
18596 c_parser_consume_token (parser);
18597 eloc = c_parser_peek_token (parser)->location;
18598 expr = c_parser_expr_no_commas (parser, NULL);
18599 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
18600 step = expr.value;
18603 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
18604 DECL_ARTIFICIAL (iter_var) = 1;
18605 DECL_CONTEXT (iter_var) = current_function_decl;
18606 pushdecl (iter_var);
18608 *last = make_tree_vec (6);
18609 TREE_VEC_ELT (*last, 0) = iter_var;
18610 TREE_VEC_ELT (*last, 1) = begin;
18611 TREE_VEC_ELT (*last, 2) = end;
18612 TREE_VEC_ELT (*last, 3) = step;
18613 last = &TREE_CHAIN (*last);
18615 if (c_parser_next_token_is (parser, CPP_COMMA))
18617 c_parser_consume_token (parser);
18618 continue;
18620 break;
18622 while (1);
18624 parens.skip_until_found_close (parser);
18625 return ret ? ret : error_mark_node;
18628 /* OpenMP 5.0:
18629 affinity ( [aff-modifier :] variable-list )
18630 aff-modifier:
18631 iterator ( iterators-definition ) */
18633 static tree
18634 c_parser_omp_clause_affinity (c_parser *parser, tree list)
18636 location_t clause_loc = c_parser_peek_token (parser)->location;
18637 tree nl, iterators = NULL_TREE;
18639 matching_parens parens;
18640 if (!parens.require_open (parser))
18641 return list;
18643 if (c_parser_next_token_is (parser, CPP_NAME))
18645 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18646 bool parse_iter = ((strcmp ("iterator", p) == 0)
18647 && (c_parser_peek_2nd_token (parser)->type
18648 == CPP_OPEN_PAREN));
18649 if (parse_iter)
18651 unsigned n = 3;
18652 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
18653 && (c_parser_peek_nth_token_raw (parser, n)->type
18654 == CPP_CLOSE_PAREN)
18655 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
18656 == CPP_COLON));
18658 if (parse_iter)
18660 iterators = c_parser_omp_iterators (parser);
18661 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18663 if (iterators)
18664 pop_scope ();
18665 parens.skip_until_found_close (parser);
18666 return list;
18670 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
18671 list);
18672 if (iterators)
18674 tree block = pop_scope ();
18675 if (iterators != error_mark_node)
18677 TREE_VEC_ELT (iterators, 5) = block;
18678 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18679 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
18680 OMP_CLAUSE_DECL (c));
18684 parens.skip_until_found_close (parser);
18685 return nl;
18689 /* OpenMP 4.0:
18690 depend ( depend-kind: variable-list )
18692 depend-kind:
18693 in | out | inout
18695 OpenMP 4.5:
18696 depend ( source )
18698 depend ( sink : vec )
18700 OpenMP 5.0:
18701 depend ( depend-modifier , depend-kind: variable-list )
18703 depend-kind:
18704 in | out | inout | mutexinoutset | depobj | inoutset
18706 depend-modifier:
18707 iterator ( iterators-definition ) */
18709 static tree
18710 c_parser_omp_clause_depend (c_parser *parser, tree list)
18712 location_t clause_loc = c_parser_peek_token (parser)->location;
18713 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
18714 enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
18715 tree nl, c, iterators = NULL_TREE;
18717 matching_parens parens;
18718 if (!parens.require_open (parser))
18719 return list;
18723 if (c_parser_next_token_is_not (parser, CPP_NAME))
18724 goto invalid_kind;
18726 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18727 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
18729 iterators = c_parser_omp_iterators (parser);
18730 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
18731 continue;
18733 if (strcmp ("in", p) == 0)
18734 kind = OMP_CLAUSE_DEPEND_IN;
18735 else if (strcmp ("inout", p) == 0)
18736 kind = OMP_CLAUSE_DEPEND_INOUT;
18737 else if (strcmp ("inoutset", p) == 0)
18738 kind = OMP_CLAUSE_DEPEND_INOUTSET;
18739 else if (strcmp ("mutexinoutset", p) == 0)
18740 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
18741 else if (strcmp ("out", p) == 0)
18742 kind = OMP_CLAUSE_DEPEND_OUT;
18743 else if (strcmp ("depobj", p) == 0)
18744 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
18745 else if (strcmp ("sink", p) == 0)
18746 dkind = OMP_CLAUSE_DOACROSS_SINK;
18747 else if (strcmp ("source", p) == 0)
18748 dkind = OMP_CLAUSE_DOACROSS_SOURCE;
18749 else
18750 goto invalid_kind;
18751 break;
18753 while (1);
18755 c_parser_consume_token (parser);
18757 if (iterators
18758 && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
18759 || dkind == OMP_CLAUSE_DOACROSS_SINK))
18761 pop_scope ();
18762 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
18763 dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
18764 iterators = NULL_TREE;
18767 if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
18769 c = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18770 OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
18771 OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
18772 OMP_CLAUSE_DECL (c) = NULL_TREE;
18773 OMP_CLAUSE_CHAIN (c) = list;
18774 parens.skip_until_found_close (parser);
18775 return c;
18778 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18779 goto resync_fail;
18781 if (dkind == OMP_CLAUSE_DOACROSS_SINK)
18782 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, true);
18783 else
18785 nl = c_parser_omp_variable_list (parser, clause_loc,
18786 OMP_CLAUSE_DEPEND, list);
18788 if (iterators)
18790 tree block = pop_scope ();
18791 if (iterators == error_mark_node)
18792 iterators = NULL_TREE;
18793 else
18794 TREE_VEC_ELT (iterators, 5) = block;
18797 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
18799 OMP_CLAUSE_DEPEND_KIND (c) = kind;
18800 if (iterators)
18801 OMP_CLAUSE_DECL (c)
18802 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
18806 parens.skip_until_found_close (parser);
18807 return nl;
18809 invalid_kind:
18810 c_parser_error (parser, "invalid depend kind");
18811 resync_fail:
18812 parens.skip_until_found_close (parser);
18813 if (iterators)
18814 pop_scope ();
18815 return list;
18818 /* OpenMP 5.2:
18819 doacross ( source : )
18820 doacross ( source : omp_cur_iteration )
18822 doacross ( sink : vec )
18823 doacross ( sink : omp_cur_iteration - logical_iteration ) */
18825 static tree
18826 c_parser_omp_clause_doacross (c_parser *parser, tree list)
18828 location_t clause_loc = c_parser_peek_token (parser)->location;
18829 enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
18830 tree nl;
18831 const char *p;
18833 matching_parens parens;
18834 if (!parens.require_open (parser))
18835 return list;
18837 if (c_parser_next_token_is_not (parser, CPP_NAME))
18838 goto invalid_kind;
18840 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18841 if (strcmp ("sink", p) == 0)
18842 kind = OMP_CLAUSE_DOACROSS_SINK;
18843 else if (strcmp ("source", p) == 0)
18844 kind = OMP_CLAUSE_DOACROSS_SOURCE;
18845 else
18846 goto invalid_kind;
18848 c_parser_consume_token (parser);
18850 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
18851 goto resync_fail;
18853 if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
18855 if (c_parser_next_token_is (parser, CPP_NAME)
18856 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
18857 "omp_cur_iteration") == 0)
18858 c_parser_consume_token (parser);
18859 nl = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
18860 OMP_CLAUSE_DOACROSS_KIND (nl) = OMP_CLAUSE_DOACROSS_SOURCE;
18861 OMP_CLAUSE_DECL (nl) = NULL_TREE;
18862 OMP_CLAUSE_CHAIN (nl) = list;
18864 else
18865 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, false);
18867 parens.skip_until_found_close (parser);
18868 return nl;
18870 invalid_kind:
18871 c_parser_error (parser, "invalid doacross kind");
18872 resync_fail:
18873 parens.skip_until_found_close (parser);
18874 return list;
18877 /* OpenMP 4.0:
18878 map ( map-kind: variable-list )
18879 map ( variable-list )
18881 map-kind:
18882 alloc | to | from | tofrom
18884 OpenMP 4.5:
18885 map-kind:
18886 alloc | to | from | tofrom | release | delete
18888 map ( always [,] map-kind: variable-list )
18890 OpenMP 5.0:
18891 map ( [map-type-modifier[,] ...] map-kind: variable-list )
18893 map-type-modifier:
18894 always | close */
18896 static tree
18897 c_parser_omp_clause_map (c_parser *parser, tree list)
18899 location_t clause_loc = c_parser_peek_token (parser)->location;
18900 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
18901 tree nl, c;
18903 matching_parens parens;
18904 if (!parens.require_open (parser))
18905 return list;
18907 int pos = 1;
18908 int map_kind_pos = 0;
18909 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
18911 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
18913 map_kind_pos = pos;
18914 break;
18917 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
18918 pos++;
18919 pos++;
18922 int always_modifier = 0;
18923 int close_modifier = 0;
18924 int present_modifier = 0;
18925 for (int pos = 1; pos < map_kind_pos; ++pos)
18927 c_token *tok = c_parser_peek_token (parser);
18929 if (tok->type == CPP_COMMA)
18931 c_parser_consume_token (parser);
18932 continue;
18935 const char *p = IDENTIFIER_POINTER (tok->value);
18936 if (strcmp ("always", p) == 0)
18938 if (always_modifier)
18940 c_parser_error (parser, "too many %<always%> modifiers");
18941 parens.skip_until_found_close (parser);
18942 return list;
18944 always_modifier++;
18946 else if (strcmp ("close", p) == 0)
18948 if (close_modifier)
18950 c_parser_error (parser, "too many %<close%> modifiers");
18951 parens.skip_until_found_close (parser);
18952 return list;
18954 close_modifier++;
18956 else if (strcmp ("present", p) == 0)
18958 if (present_modifier)
18960 c_parser_error (parser, "too many %<present%> modifiers");
18961 parens.skip_until_found_close (parser);
18962 return list;
18964 present_modifier++;
18966 else
18968 c_parser_error (parser, "%<map%> clause with map-type modifier other "
18969 "than %<always%>, %<close%> or %<present%>");
18970 parens.skip_until_found_close (parser);
18971 return list;
18974 c_parser_consume_token (parser);
18977 if (c_parser_next_token_is (parser, CPP_NAME)
18978 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
18980 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18981 int always_present_modifier = always_modifier && present_modifier;
18983 if (strcmp ("alloc", p) == 0)
18984 kind = present_modifier ? GOMP_MAP_PRESENT_ALLOC : GOMP_MAP_ALLOC;
18985 else if (strcmp ("to", p) == 0)
18986 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TO
18987 : present_modifier ? GOMP_MAP_PRESENT_TO
18988 : always_modifier ? GOMP_MAP_ALWAYS_TO
18989 : GOMP_MAP_TO);
18990 else if (strcmp ("from", p) == 0)
18991 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_FROM
18992 : present_modifier ? GOMP_MAP_PRESENT_FROM
18993 : always_modifier ? GOMP_MAP_ALWAYS_FROM
18994 : GOMP_MAP_FROM);
18995 else if (strcmp ("tofrom", p) == 0)
18996 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TOFROM
18997 : present_modifier ? GOMP_MAP_PRESENT_TOFROM
18998 : always_modifier ? GOMP_MAP_ALWAYS_TOFROM
18999 : GOMP_MAP_TOFROM);
19000 else if (strcmp ("release", p) == 0)
19001 kind = GOMP_MAP_RELEASE;
19002 else if (strcmp ("delete", p) == 0)
19003 kind = GOMP_MAP_DELETE;
19004 else
19006 c_parser_error (parser, "invalid map kind");
19007 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19008 "expected %<)%>");
19009 return list;
19011 c_parser_consume_token (parser);
19012 c_parser_consume_token (parser);
19015 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
19016 true);
19018 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
19019 OMP_CLAUSE_SET_MAP_KIND (c, kind);
19021 parens.skip_until_found_close (parser);
19022 return nl;
19025 /* OpenMP 4.0:
19026 device ( expression )
19028 OpenMP 5.0:
19029 device ( [device-modifier :] integer-expression )
19031 device-modifier:
19032 ancestor | device_num */
19034 static tree
19035 c_parser_omp_clause_device (c_parser *parser, tree list)
19037 location_t clause_loc = c_parser_peek_token (parser)->location;
19038 location_t expr_loc;
19039 c_expr expr;
19040 tree c, t;
19041 bool ancestor = false;
19043 matching_parens parens;
19044 if (!parens.require_open (parser))
19045 return list;
19047 if (c_parser_next_token_is (parser, CPP_NAME)
19048 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
19050 c_token *tok = c_parser_peek_token (parser);
19051 const char *p = IDENTIFIER_POINTER (tok->value);
19052 if (strcmp ("ancestor", p) == 0)
19054 /* A requires directive with the reverse_offload clause must be
19055 specified. */
19056 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
19058 error_at (tok->location, "%<ancestor%> device modifier not "
19059 "preceded by %<requires%> directive "
19060 "with %<reverse_offload%> clause");
19061 parens.skip_until_found_close (parser);
19062 return list;
19064 ancestor = true;
19066 else if (strcmp ("device_num", p) == 0)
19068 else
19070 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
19071 parens.skip_until_found_close (parser);
19072 return list;
19074 c_parser_consume_token (parser);
19075 c_parser_consume_token (parser);
19078 expr_loc = c_parser_peek_token (parser)->location;
19079 expr = c_parser_expr_no_commas (parser, NULL);
19080 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
19081 t = expr.value;
19082 t = c_fully_fold (t, false, NULL);
19084 parens.skip_until_found_close (parser);
19086 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
19088 c_parser_error (parser, "expected integer expression");
19089 return list;
19091 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
19093 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
19094 "%<1%>");
19095 return list;
19098 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
19100 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
19102 OMP_CLAUSE_DEVICE_ID (c) = t;
19103 OMP_CLAUSE_CHAIN (c) = list;
19104 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
19106 list = c;
19107 return list;
19110 /* OpenMP 4.0:
19111 dist_schedule ( static )
19112 dist_schedule ( static , expression ) */
19114 static tree
19115 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
19117 tree c, t = NULL_TREE;
19118 location_t loc = c_parser_peek_token (parser)->location;
19120 matching_parens parens;
19121 if (!parens.require_open (parser))
19122 return list;
19124 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
19126 c_parser_error (parser, "invalid dist_schedule kind");
19127 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19128 "expected %<)%>");
19129 return list;
19132 c_parser_consume_token (parser);
19133 if (c_parser_next_token_is (parser, CPP_COMMA))
19135 c_parser_consume_token (parser);
19137 location_t expr_loc = c_parser_peek_token (parser)->location;
19138 c_expr expr = c_parser_expr_no_commas (parser, NULL);
19139 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
19140 t = expr.value;
19141 t = c_fully_fold (t, false, NULL);
19142 parens.skip_until_found_close (parser);
19144 else
19145 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19146 "expected %<,%> or %<)%>");
19148 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
19149 "dist_schedule"); */
19150 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
19151 warning_at (loc, OPT_Wopenmp, "too many %qs clauses", "dist_schedule");
19152 if (t == error_mark_node)
19153 return list;
19155 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
19156 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
19157 OMP_CLAUSE_CHAIN (c) = list;
19158 return c;
19161 /* OpenMP 4.0:
19162 proc_bind ( proc-bind-kind )
19164 proc-bind-kind:
19165 primary | master | close | spread
19166 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
19168 static tree
19169 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
19171 location_t clause_loc = c_parser_peek_token (parser)->location;
19172 enum omp_clause_proc_bind_kind kind;
19173 tree c;
19175 matching_parens parens;
19176 if (!parens.require_open (parser))
19177 return list;
19179 if (c_parser_next_token_is (parser, CPP_NAME))
19181 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19182 if (strcmp ("primary", p) == 0)
19183 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
19184 else if (strcmp ("master", p) == 0)
19185 kind = OMP_CLAUSE_PROC_BIND_MASTER;
19186 else if (strcmp ("close", p) == 0)
19187 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
19188 else if (strcmp ("spread", p) == 0)
19189 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
19190 else
19191 goto invalid_kind;
19193 else
19194 goto invalid_kind;
19196 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
19197 c_parser_consume_token (parser);
19198 parens.skip_until_found_close (parser);
19199 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
19200 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
19201 OMP_CLAUSE_CHAIN (c) = list;
19202 return c;
19204 invalid_kind:
19205 c_parser_error (parser, "invalid proc_bind kind");
19206 parens.skip_until_found_close (parser);
19207 return list;
19210 /* OpenMP 5.0:
19211 device_type ( host | nohost | any ) */
19213 static tree
19214 c_parser_omp_clause_device_type (c_parser *parser, tree list)
19216 location_t clause_loc = c_parser_peek_token (parser)->location;
19217 enum omp_clause_device_type_kind kind;
19218 tree c;
19220 matching_parens parens;
19221 if (!parens.require_open (parser))
19222 return list;
19224 if (c_parser_next_token_is (parser, CPP_NAME))
19226 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19227 if (strcmp ("host", p) == 0)
19228 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
19229 else if (strcmp ("nohost", p) == 0)
19230 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
19231 else if (strcmp ("any", p) == 0)
19232 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
19233 else
19234 goto invalid_kind;
19236 else
19237 goto invalid_kind;
19239 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
19240 "device_type");
19241 c_parser_consume_token (parser);
19242 parens.skip_until_found_close (parser);
19243 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
19244 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
19245 OMP_CLAUSE_CHAIN (c) = list;
19246 return c;
19248 invalid_kind:
19249 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
19250 parens.skip_until_found_close (parser);
19251 return list;
19254 /* OpenMP 4.0:
19255 from ( variable-list )
19256 to ( variable-list )
19258 OpenMP 5.1:
19259 from ( [present :] variable-list )
19260 to ( [present :] variable-list ) */
19262 static tree
19263 c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
19264 tree list)
19266 location_t loc = c_parser_peek_token (parser)->location;
19267 matching_parens parens;
19268 if (!parens.require_open (parser))
19269 return list;
19271 bool present = false;
19272 c_token *token = c_parser_peek_token (parser);
19274 if (token->type == CPP_NAME
19275 && strcmp (IDENTIFIER_POINTER (token->value), "present") == 0
19276 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
19278 present = true;
19279 c_parser_consume_token (parser);
19280 c_parser_consume_token (parser);
19283 tree nl = c_parser_omp_variable_list (parser, loc, kind, list);
19284 parens.skip_until_found_close (parser);
19286 if (present)
19287 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
19288 OMP_CLAUSE_MOTION_PRESENT (c) = 1;
19290 return nl;
19293 /* OpenMP 4.0:
19294 uniform ( variable-list ) */
19296 static tree
19297 c_parser_omp_clause_uniform (c_parser *parser, tree list)
19299 /* The clauses location. */
19300 location_t loc = c_parser_peek_token (parser)->location;
19302 matching_parens parens;
19303 if (parens.require_open (parser))
19305 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
19306 list);
19307 parens.skip_until_found_close (parser);
19309 return list;
19312 /* OpenMP 5.1
19313 full */
19315 static tree
19316 c_parser_omp_clause_full (c_parser *parser, tree list)
19318 check_no_duplicate_clause (list, OMP_CLAUSE_FULL, "full");
19320 location_t loc = c_parser_peek_token (parser)->location;
19321 tree c = build_omp_clause (loc, OMP_CLAUSE_FULL);
19322 OMP_CLAUSE_CHAIN (c) = list;
19323 return c;
19326 /* OpenMP 5.1
19327 partial ( constant-expression ) */
19329 static tree
19330 c_parser_omp_clause_partial (c_parser *parser, tree list)
19332 tree num = NULL_TREE;
19333 location_t loc = c_parser_peek_token (parser)->location;
19335 check_no_duplicate_clause (list, OMP_CLAUSE_PARTIAL, "partial");
19337 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19339 matching_parens parens;
19340 parens.consume_open (parser);
19341 num = c_parser_expr_no_commas (parser, NULL).value;
19342 parens.skip_until_found_close (parser);
19344 if (num == error_mark_node)
19345 return list;
19347 mark_exp_read (num);
19348 num = c_fully_fold (num, false, NULL);
19349 HOST_WIDE_INT n;
19350 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
19351 || !tree_fits_shwi_p (num)
19352 || (n = tree_to_shwi (num)) <= 0
19353 || (int) n != n)
19355 error_at (loc, "%<partial%> argument needs positive constant "
19356 "integer expression");
19357 return list;
19361 tree c = build_omp_clause (loc, OMP_CLAUSE_PARTIAL);
19362 OMP_CLAUSE_PARTIAL_EXPR (c) = num;
19363 OMP_CLAUSE_CHAIN (c) = list;
19364 return c;
19367 /* OpenMP 5.0:
19368 detach ( event-handle ) */
19370 static tree
19371 c_parser_omp_clause_detach (c_parser *parser, tree list)
19373 matching_parens parens;
19374 location_t clause_loc = c_parser_peek_token (parser)->location;
19376 if (!parens.require_open (parser))
19377 return list;
19379 if (c_parser_next_token_is_not (parser, CPP_NAME)
19380 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
19382 c_parser_error (parser, "expected identifier");
19383 parens.skip_until_found_close (parser);
19384 return list;
19387 tree t = lookup_name (c_parser_peek_token (parser)->value);
19388 if (t == NULL_TREE)
19390 undeclared_variable (c_parser_peek_token (parser)->location,
19391 c_parser_peek_token (parser)->value);
19392 parens.skip_until_found_close (parser);
19393 return list;
19395 c_parser_consume_token (parser);
19397 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
19398 if (!INTEGRAL_TYPE_P (type)
19399 || TREE_CODE (type) != ENUMERAL_TYPE
19400 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
19402 error_at (clause_loc, "%<detach%> clause event handle "
19403 "has type %qT rather than "
19404 "%<omp_event_handle_t%>",
19405 type);
19406 parens.skip_until_found_close (parser);
19407 return list;
19410 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
19411 OMP_CLAUSE_DECL (u) = t;
19412 OMP_CLAUSE_CHAIN (u) = list;
19413 parens.skip_until_found_close (parser);
19414 return u;
19417 /* Parse all OpenACC clauses. The set clauses allowed by the directive
19418 is a bitmask in MASK. Return the list of clauses found. */
19420 static tree
19421 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
19422 const char *where, bool finish_p = true,
19423 bool target_p = false)
19425 tree clauses = NULL;
19426 bool first = true;
19428 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19430 location_t here;
19431 pragma_omp_clause c_kind;
19432 const char *c_name;
19433 tree prev = clauses;
19435 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
19436 c_parser_consume_token (parser);
19438 here = c_parser_peek_token (parser)->location;
19439 c_kind = c_parser_omp_clause_name (parser);
19441 switch (c_kind)
19443 case PRAGMA_OACC_CLAUSE_ASYNC:
19444 clauses = c_parser_oacc_clause_async (parser, clauses);
19445 c_name = "async";
19446 break;
19447 case PRAGMA_OACC_CLAUSE_AUTO:
19448 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
19449 clauses);
19450 c_name = "auto";
19451 break;
19452 case PRAGMA_OACC_CLAUSE_ATTACH:
19453 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19454 c_name = "attach";
19455 break;
19456 case PRAGMA_OACC_CLAUSE_COLLAPSE:
19457 clauses = c_parser_omp_clause_collapse (parser, clauses);
19458 c_name = "collapse";
19459 break;
19460 case PRAGMA_OACC_CLAUSE_COPY:
19461 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19462 c_name = "copy";
19463 break;
19464 case PRAGMA_OACC_CLAUSE_COPYIN:
19465 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19466 c_name = "copyin";
19467 break;
19468 case PRAGMA_OACC_CLAUSE_COPYOUT:
19469 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19470 c_name = "copyout";
19471 break;
19472 case PRAGMA_OACC_CLAUSE_CREATE:
19473 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19474 c_name = "create";
19475 break;
19476 case PRAGMA_OACC_CLAUSE_DELETE:
19477 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19478 c_name = "delete";
19479 break;
19480 case PRAGMA_OMP_CLAUSE_DEFAULT:
19481 clauses = c_parser_omp_clause_default (parser, clauses, true);
19482 c_name = "default";
19483 break;
19484 case PRAGMA_OACC_CLAUSE_DETACH:
19485 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19486 c_name = "detach";
19487 break;
19488 case PRAGMA_OACC_CLAUSE_DEVICE:
19489 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19490 c_name = "device";
19491 break;
19492 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
19493 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
19494 c_name = "deviceptr";
19495 break;
19496 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
19497 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19498 c_name = "device_resident";
19499 break;
19500 case PRAGMA_OACC_CLAUSE_FINALIZE:
19501 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
19502 clauses);
19503 c_name = "finalize";
19504 break;
19505 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
19506 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
19507 c_name = "firstprivate";
19508 break;
19509 case PRAGMA_OACC_CLAUSE_GANG:
19510 c_name = "gang";
19511 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
19512 c_name, clauses);
19513 break;
19514 case PRAGMA_OACC_CLAUSE_HOST:
19515 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19516 c_name = "host";
19517 break;
19518 case PRAGMA_OACC_CLAUSE_IF:
19519 clauses = c_parser_omp_clause_if (parser, clauses, false);
19520 c_name = "if";
19521 break;
19522 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
19523 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
19524 clauses);
19525 c_name = "if_present";
19526 break;
19527 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
19528 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
19529 clauses);
19530 c_name = "independent";
19531 break;
19532 case PRAGMA_OACC_CLAUSE_LINK:
19533 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19534 c_name = "link";
19535 break;
19536 case PRAGMA_OACC_CLAUSE_NO_CREATE:
19537 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19538 c_name = "no_create";
19539 break;
19540 case PRAGMA_OACC_CLAUSE_NOHOST:
19541 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
19542 clauses);
19543 c_name = "nohost";
19544 break;
19545 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
19546 clauses = c_parser_oacc_single_int_clause (parser,
19547 OMP_CLAUSE_NUM_GANGS,
19548 clauses);
19549 c_name = "num_gangs";
19550 break;
19551 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
19552 clauses = c_parser_oacc_single_int_clause (parser,
19553 OMP_CLAUSE_NUM_WORKERS,
19554 clauses);
19555 c_name = "num_workers";
19556 break;
19557 case PRAGMA_OACC_CLAUSE_PRESENT:
19558 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19559 c_name = "present";
19560 break;
19561 case PRAGMA_OACC_CLAUSE_PRIVATE:
19562 clauses = c_parser_omp_clause_private (parser, clauses);
19563 c_name = "private";
19564 break;
19565 case PRAGMA_OACC_CLAUSE_REDUCTION:
19566 clauses
19567 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
19568 false, clauses);
19569 c_name = "reduction";
19570 break;
19571 case PRAGMA_OACC_CLAUSE_SELF:
19572 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)) == 0)
19573 /* OpenACC compute construct */
19574 clauses = c_parser_oacc_compute_clause_self (parser, clauses);
19575 else
19576 /* OpenACC 'update' directive */
19577 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
19578 c_name = "self";
19579 break;
19580 case PRAGMA_OACC_CLAUSE_SEQ:
19581 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
19582 clauses);
19583 c_name = "seq";
19584 break;
19585 case PRAGMA_OACC_CLAUSE_TILE:
19586 clauses = c_parser_oacc_clause_tile (parser, clauses);
19587 c_name = "tile";
19588 break;
19589 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
19590 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
19591 c_name = "use_device";
19592 break;
19593 case PRAGMA_OACC_CLAUSE_VECTOR:
19594 c_name = "vector";
19595 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
19596 c_name, clauses);
19597 break;
19598 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
19599 clauses = c_parser_oacc_single_int_clause (parser,
19600 OMP_CLAUSE_VECTOR_LENGTH,
19601 clauses);
19602 c_name = "vector_length";
19603 break;
19604 case PRAGMA_OACC_CLAUSE_WAIT:
19605 clauses = c_parser_oacc_clause_wait (parser, clauses);
19606 c_name = "wait";
19607 break;
19608 case PRAGMA_OACC_CLAUSE_WORKER:
19609 c_name = "worker";
19610 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
19611 c_name, clauses);
19612 break;
19613 default:
19614 c_parser_error (parser, "expected an OpenACC clause");
19615 goto saw_error;
19618 first = false;
19620 if (((mask >> c_kind) & 1) == 0)
19622 /* Remove the invalid clause(s) from the list to avoid
19623 confusing the rest of the compiler. */
19624 clauses = prev;
19625 error_at (here, "%qs is not valid for %qs", c_name, where);
19629 saw_error:
19630 c_parser_skip_to_pragma_eol (parser);
19632 if (finish_p)
19633 return c_finish_omp_clauses (clauses, target_p ? C_ORT_ACC_TARGET
19634 : C_ORT_ACC);
19636 return clauses;
19639 /* Parse all OpenMP clauses. The set clauses allowed by the directive
19640 is a bitmask in MASK. Return the list of clauses found.
19641 FINISH_P set if c_finish_omp_clauses should be called.
19642 NESTED non-zero if clauses should be terminated by closing paren instead
19643 of end of pragma. If it is 2, additionally commas are required in between
19644 the clauses. */
19646 static tree
19647 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
19648 const char *where, bool finish_p = true,
19649 int nested = 0)
19651 tree clauses = NULL;
19652 bool first = true;
19654 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19656 location_t here;
19657 pragma_omp_clause c_kind;
19658 const char *c_name;
19659 tree prev = clauses;
19661 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
19662 break;
19664 if (!first || nested != 2)
19666 if (c_parser_next_token_is (parser, CPP_COMMA))
19667 c_parser_consume_token (parser);
19668 else if (nested == 2)
19669 error_at (c_parser_peek_token (parser)->location,
19670 "clauses in %<simd%> trait should be separated "
19671 "by %<,%>");
19674 here = c_parser_peek_token (parser)->location;
19675 c_kind = c_parser_omp_clause_name (parser);
19677 switch (c_kind)
19679 case PRAGMA_OMP_CLAUSE_BIND:
19680 clauses = c_parser_omp_clause_bind (parser, clauses);
19681 c_name = "bind";
19682 break;
19683 case PRAGMA_OMP_CLAUSE_COLLAPSE:
19684 clauses = c_parser_omp_clause_collapse (parser, clauses);
19685 c_name = "collapse";
19686 break;
19687 case PRAGMA_OMP_CLAUSE_COPYIN:
19688 clauses = c_parser_omp_clause_copyin (parser, clauses);
19689 c_name = "copyin";
19690 break;
19691 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
19692 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
19693 c_name = "copyprivate";
19694 break;
19695 case PRAGMA_OMP_CLAUSE_DEFAULT:
19696 clauses = c_parser_omp_clause_default (parser, clauses, false);
19697 c_name = "default";
19698 break;
19699 case PRAGMA_OMP_CLAUSE_DETACH:
19700 clauses = c_parser_omp_clause_detach (parser, clauses);
19701 c_name = "detach";
19702 break;
19703 case PRAGMA_OMP_CLAUSE_FILTER:
19704 clauses = c_parser_omp_clause_filter (parser, clauses);
19705 c_name = "filter";
19706 break;
19707 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
19708 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
19709 c_name = "firstprivate";
19710 break;
19711 case PRAGMA_OMP_CLAUSE_FINAL:
19712 clauses = c_parser_omp_clause_final (parser, clauses);
19713 c_name = "final";
19714 break;
19715 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
19716 clauses = c_parser_omp_clause_grainsize (parser, clauses);
19717 c_name = "grainsize";
19718 break;
19719 case PRAGMA_OMP_CLAUSE_HINT:
19720 clauses = c_parser_omp_clause_hint (parser, clauses);
19721 c_name = "hint";
19722 break;
19723 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
19724 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
19725 c_name = "defaultmap";
19726 break;
19727 case PRAGMA_OMP_CLAUSE_IF:
19728 clauses = c_parser_omp_clause_if (parser, clauses, true);
19729 c_name = "if";
19730 break;
19731 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
19732 clauses
19733 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
19734 true, clauses);
19735 c_name = "in_reduction";
19736 break;
19737 case PRAGMA_OMP_CLAUSE_INDIRECT:
19738 clauses = c_parser_omp_clause_indirect (parser, clauses);
19739 c_name = "indirect";
19740 break;
19741 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
19742 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
19743 c_name = "lastprivate";
19744 break;
19745 case PRAGMA_OMP_CLAUSE_MERGEABLE:
19746 clauses = c_parser_omp_clause_mergeable (parser, clauses);
19747 c_name = "mergeable";
19748 break;
19749 case PRAGMA_OMP_CLAUSE_NOWAIT:
19750 clauses = c_parser_omp_clause_nowait (parser, clauses);
19751 c_name = "nowait";
19752 break;
19753 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
19754 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
19755 c_name = "num_tasks";
19756 break;
19757 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
19758 clauses = c_parser_omp_clause_num_threads (parser, clauses);
19759 c_name = "num_threads";
19760 break;
19761 case PRAGMA_OMP_CLAUSE_ORDER:
19762 clauses = c_parser_omp_clause_order (parser, clauses);
19763 c_name = "order";
19764 break;
19765 case PRAGMA_OMP_CLAUSE_ORDERED:
19766 clauses = c_parser_omp_clause_ordered (parser, clauses);
19767 c_name = "ordered";
19768 break;
19769 case PRAGMA_OMP_CLAUSE_PRIORITY:
19770 clauses = c_parser_omp_clause_priority (parser, clauses);
19771 c_name = "priority";
19772 break;
19773 case PRAGMA_OMP_CLAUSE_PRIVATE:
19774 clauses = c_parser_omp_clause_private (parser, clauses);
19775 c_name = "private";
19776 break;
19777 case PRAGMA_OMP_CLAUSE_REDUCTION:
19778 clauses
19779 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
19780 true, clauses);
19781 c_name = "reduction";
19782 break;
19783 case PRAGMA_OMP_CLAUSE_SCHEDULE:
19784 clauses = c_parser_omp_clause_schedule (parser, clauses);
19785 c_name = "schedule";
19786 break;
19787 case PRAGMA_OMP_CLAUSE_SHARED:
19788 clauses = c_parser_omp_clause_shared (parser, clauses);
19789 c_name = "shared";
19790 break;
19791 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
19792 clauses
19793 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
19794 true, clauses);
19795 c_name = "task_reduction";
19796 break;
19797 case PRAGMA_OMP_CLAUSE_UNTIED:
19798 clauses = c_parser_omp_clause_untied (parser, clauses);
19799 c_name = "untied";
19800 break;
19801 case PRAGMA_OMP_CLAUSE_INBRANCH:
19802 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
19803 clauses);
19804 c_name = "inbranch";
19805 break;
19806 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
19807 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
19808 c_name = "nontemporal";
19809 break;
19810 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
19811 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
19812 clauses);
19813 c_name = "notinbranch";
19814 break;
19815 case PRAGMA_OMP_CLAUSE_PARALLEL:
19816 clauses
19817 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
19818 clauses);
19819 c_name = "parallel";
19820 if (!first)
19822 clause_not_first:
19823 error_at (here, "%qs must be the first clause of %qs",
19824 c_name, where);
19825 clauses = prev;
19827 break;
19828 case PRAGMA_OMP_CLAUSE_FOR:
19829 clauses
19830 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
19831 clauses);
19832 c_name = "for";
19833 if (!first)
19834 goto clause_not_first;
19835 break;
19836 case PRAGMA_OMP_CLAUSE_SECTIONS:
19837 clauses
19838 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
19839 clauses);
19840 c_name = "sections";
19841 if (!first)
19842 goto clause_not_first;
19843 break;
19844 case PRAGMA_OMP_CLAUSE_TASKGROUP:
19845 clauses
19846 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
19847 clauses);
19848 c_name = "taskgroup";
19849 if (!first)
19850 goto clause_not_first;
19851 break;
19852 case PRAGMA_OMP_CLAUSE_LINK:
19853 clauses
19854 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
19855 c_name = "link";
19856 break;
19857 case PRAGMA_OMP_CLAUSE_TO:
19858 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
19860 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
19861 clauses);
19862 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
19863 OMP_CLAUSE_ENTER_TO (c) = 1;
19864 clauses = nl;
19866 else
19867 clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_TO,
19868 clauses);
19869 c_name = "to";
19870 break;
19871 case PRAGMA_OMP_CLAUSE_FROM:
19872 clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_FROM,
19873 clauses);
19874 c_name = "from";
19875 break;
19876 case PRAGMA_OMP_CLAUSE_UNIFORM:
19877 clauses = c_parser_omp_clause_uniform (parser, clauses);
19878 c_name = "uniform";
19879 break;
19880 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
19881 clauses = c_parser_omp_clause_num_teams (parser, clauses);
19882 c_name = "num_teams";
19883 break;
19884 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
19885 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
19886 c_name = "thread_limit";
19887 break;
19888 case PRAGMA_OMP_CLAUSE_ALIGNED:
19889 clauses = c_parser_omp_clause_aligned (parser, clauses);
19890 c_name = "aligned";
19891 break;
19892 case PRAGMA_OMP_CLAUSE_ALLOCATE:
19893 clauses = c_parser_omp_clause_allocate (parser, clauses);
19894 c_name = "allocate";
19895 break;
19896 case PRAGMA_OMP_CLAUSE_LINEAR:
19897 clauses = c_parser_omp_clause_linear (parser, clauses);
19898 c_name = "linear";
19899 break;
19900 case PRAGMA_OMP_CLAUSE_AFFINITY:
19901 clauses = c_parser_omp_clause_affinity (parser, clauses);
19902 c_name = "affinity";
19903 break;
19904 case PRAGMA_OMP_CLAUSE_DEPEND:
19905 clauses = c_parser_omp_clause_depend (parser, clauses);
19906 c_name = "depend";
19907 break;
19908 case PRAGMA_OMP_CLAUSE_DOACROSS:
19909 clauses = c_parser_omp_clause_doacross (parser, clauses);
19910 c_name = "doacross";
19911 break;
19912 case PRAGMA_OMP_CLAUSE_MAP:
19913 clauses = c_parser_omp_clause_map (parser, clauses);
19914 c_name = "map";
19915 break;
19916 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
19917 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
19918 c_name = "use_device_ptr";
19919 break;
19920 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
19921 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
19922 c_name = "use_device_addr";
19923 break;
19924 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
19925 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
19926 c_name = "has_device_addr";
19927 break;
19928 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
19929 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
19930 c_name = "is_device_ptr";
19931 break;
19932 case PRAGMA_OMP_CLAUSE_DEVICE:
19933 clauses = c_parser_omp_clause_device (parser, clauses);
19934 c_name = "device";
19935 break;
19936 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
19937 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
19938 c_name = "dist_schedule";
19939 break;
19940 case PRAGMA_OMP_CLAUSE_PROC_BIND:
19941 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
19942 c_name = "proc_bind";
19943 break;
19944 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
19945 clauses = c_parser_omp_clause_device_type (parser, clauses);
19946 c_name = "device_type";
19947 break;
19948 case PRAGMA_OMP_CLAUSE_SAFELEN:
19949 clauses = c_parser_omp_clause_safelen (parser, clauses);
19950 c_name = "safelen";
19951 break;
19952 case PRAGMA_OMP_CLAUSE_SIMDLEN:
19953 clauses = c_parser_omp_clause_simdlen (parser, clauses);
19954 c_name = "simdlen";
19955 break;
19956 case PRAGMA_OMP_CLAUSE_NOGROUP:
19957 clauses = c_parser_omp_clause_nogroup (parser, clauses);
19958 c_name = "nogroup";
19959 break;
19960 case PRAGMA_OMP_CLAUSE_THREADS:
19961 clauses
19962 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
19963 clauses);
19964 c_name = "threads";
19965 break;
19966 case PRAGMA_OMP_CLAUSE_SIMD:
19967 clauses
19968 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
19969 clauses);
19970 c_name = "simd";
19971 break;
19972 case PRAGMA_OMP_CLAUSE_ENTER:
19973 clauses
19974 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
19975 clauses);
19976 c_name = "enter";
19977 break;
19978 case PRAGMA_OMP_CLAUSE_FULL:
19979 c_name = "full";
19980 clauses = c_parser_omp_clause_full (parser, clauses);
19981 break;
19982 case PRAGMA_OMP_CLAUSE_PARTIAL:
19983 c_name = "partial";
19984 clauses = c_parser_omp_clause_partial (parser, clauses);
19985 break;
19986 default:
19987 c_parser_error (parser, "expected an OpenMP clause");
19988 goto saw_error;
19991 first = false;
19993 if (((mask >> c_kind) & 1) == 0)
19995 /* Remove the invalid clause(s) from the list to avoid
19996 confusing the rest of the compiler. */
19997 clauses = prev;
19998 error_at (here, "%qs is not valid for %qs", c_name, where);
20002 saw_error:
20003 if (!nested)
20004 c_parser_skip_to_pragma_eol (parser);
20006 if (finish_p)
20008 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
20009 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
20010 return c_finish_omp_clauses (clauses, C_ORT_OMP);
20013 return clauses;
20016 /* OpenACC 2.0, OpenMP 2.5:
20017 structured-block:
20018 statement
20020 In practice, we're also interested in adding the statement to an
20021 outer node. So it is convenient if we work around the fact that
20022 c_parser_statement calls add_stmt. */
20024 static tree
20025 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
20027 tree stmt = push_stmt_list ();
20028 parser->omp_attrs_forbidden_p = true;
20029 c_parser_statement (parser, if_p);
20030 return pop_stmt_list (stmt);
20033 /* OpenACC 2.0:
20034 # pragma acc cache (variable-list) new-line
20036 OpenACC 2.7:
20037 # pragma acc cache (readonly: variable-list) new-line
20039 LOC is the location of the #pragma token.
20042 static tree
20043 c_parser_oacc_cache (location_t loc, c_parser *parser)
20045 tree stmt, clauses = NULL_TREE;
20046 bool readonly = false;
20047 location_t open_loc = c_parser_peek_token (parser)->location;
20048 matching_parens parens;
20049 if (parens.require_open (parser))
20051 c_token *token = c_parser_peek_token (parser);
20052 if (token->type == CPP_NAME
20053 && !strcmp (IDENTIFIER_POINTER (token->value), "readonly")
20054 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
20056 c_parser_consume_token (parser);
20057 c_parser_consume_token (parser);
20058 readonly = true;
20060 clauses = c_parser_omp_variable_list (parser, open_loc,
20061 OMP_CLAUSE__CACHE_, NULL_TREE);
20062 parens.skip_until_found_close (parser);
20065 if (readonly)
20066 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20067 OMP_CLAUSE__CACHE__READONLY (c) = 1;
20069 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
20071 c_parser_skip_to_pragma_eol (parser);
20073 stmt = make_node (OACC_CACHE);
20074 TREE_TYPE (stmt) = void_type_node;
20075 OACC_CACHE_CLAUSES (stmt) = clauses;
20076 SET_EXPR_LOCATION (stmt, loc);
20077 add_stmt (stmt);
20079 return stmt;
20082 /* OpenACC 2.0:
20083 # pragma acc data oacc-data-clause[optseq] new-line
20084 structured-block
20086 LOC is the location of the #pragma token.
20089 #define OACC_DATA_CLAUSE_MASK \
20090 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20094 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20098 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20099 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
20101 static tree
20102 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
20104 tree stmt, clauses, block;
20106 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
20107 "#pragma acc data");
20109 block = c_begin_omp_parallel ();
20110 add_stmt (c_parser_omp_structured_block (parser, if_p));
20112 stmt = c_finish_oacc_data (loc, clauses, block);
20114 return stmt;
20117 /* OpenACC 2.0:
20118 # pragma acc declare oacc-data-clause[optseq] new-line
20121 #define OACC_DECLARE_CLAUSE_MASK \
20122 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20123 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20124 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20126 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20127 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
20128 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
20129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
20131 static void
20132 c_parser_oacc_declare (c_parser *parser)
20134 location_t pragma_loc = c_parser_peek_token (parser)->location;
20135 tree clauses, stmt, t, decl;
20137 bool error = false;
20139 c_parser_consume_pragma (parser);
20141 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
20142 "#pragma acc declare");
20143 if (!clauses)
20145 error_at (pragma_loc,
20146 "no valid clauses specified in %<#pragma acc declare%>");
20147 return;
20150 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
20152 location_t loc = OMP_CLAUSE_LOCATION (t);
20153 decl = OMP_CLAUSE_DECL (t);
20154 if (!DECL_P (decl))
20156 error_at (loc, "array section in %<#pragma acc declare%>");
20157 error = true;
20158 continue;
20161 switch (OMP_CLAUSE_MAP_KIND (t))
20163 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20164 case GOMP_MAP_ALLOC:
20165 case GOMP_MAP_TO:
20166 case GOMP_MAP_FORCE_DEVICEPTR:
20167 case GOMP_MAP_DEVICE_RESIDENT:
20168 break;
20170 case GOMP_MAP_LINK:
20171 if (!global_bindings_p ()
20172 && (TREE_STATIC (decl)
20173 || !DECL_EXTERNAL (decl)))
20175 error_at (loc,
20176 "%qD must be a global variable in "
20177 "%<#pragma acc declare link%>",
20178 decl);
20179 error = true;
20180 continue;
20182 break;
20184 default:
20185 if (global_bindings_p ())
20187 error_at (loc, "invalid OpenACC clause at file scope");
20188 error = true;
20189 continue;
20191 if (DECL_EXTERNAL (decl))
20193 error_at (loc,
20194 "invalid use of %<extern%> variable %qD "
20195 "in %<#pragma acc declare%>", decl);
20196 error = true;
20197 continue;
20199 else if (TREE_PUBLIC (decl))
20201 error_at (loc,
20202 "invalid use of %<global%> variable %qD "
20203 "in %<#pragma acc declare%>", decl);
20204 error = true;
20205 continue;
20207 break;
20210 if (!c_check_in_current_scope (decl))
20212 error_at (loc,
20213 "%qD must be a variable declared in the same scope as "
20214 "%<#pragma acc declare%>", decl);
20215 error = true;
20216 continue;
20219 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
20220 || lookup_attribute ("omp declare target link",
20221 DECL_ATTRIBUTES (decl)))
20223 error_at (loc, "variable %qD used more than once with "
20224 "%<#pragma acc declare%>", decl);
20225 error = true;
20226 continue;
20229 if (!error)
20231 tree id;
20233 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
20234 id = get_identifier ("omp declare target link");
20235 else
20236 id = get_identifier ("omp declare target");
20238 DECL_ATTRIBUTES (decl)
20239 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
20241 if (global_bindings_p ())
20243 symtab_node *node = symtab_node::get (decl);
20244 if (node != NULL)
20246 node->offloadable = 1;
20247 if (ENABLE_OFFLOADING)
20249 g->have_offload = true;
20250 if (is_a <varpool_node *> (node))
20251 vec_safe_push (offload_vars, decl);
20258 if (error || global_bindings_p ())
20259 return;
20261 stmt = make_node (OACC_DECLARE);
20262 TREE_TYPE (stmt) = void_type_node;
20263 OACC_DECLARE_CLAUSES (stmt) = clauses;
20264 SET_EXPR_LOCATION (stmt, pragma_loc);
20266 add_stmt (stmt);
20268 return;
20271 /* OpenACC 2.0:
20272 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
20276 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
20279 LOC is the location of the #pragma token.
20282 #define OACC_ENTER_DATA_CLAUSE_MASK \
20283 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20284 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20285 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20286 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20287 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20288 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20290 #define OACC_EXIT_DATA_CLAUSE_MASK \
20291 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20292 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20293 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20294 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
20295 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
20296 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
20297 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20299 static void
20300 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
20302 location_t loc = c_parser_peek_token (parser)->location;
20303 tree clauses, stmt;
20304 const char *p = "";
20306 c_parser_consume_pragma (parser);
20308 if (c_parser_next_token_is (parser, CPP_NAME))
20310 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20311 c_parser_consume_token (parser);
20314 if (strcmp (p, "data") != 0)
20316 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
20317 enter ? "enter" : "exit");
20318 parser->error = true;
20319 c_parser_skip_to_pragma_eol (parser);
20320 return;
20323 if (enter)
20324 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
20325 "#pragma acc enter data");
20326 else
20327 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
20328 "#pragma acc exit data");
20330 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
20332 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
20333 enter ? "enter" : "exit");
20334 return;
20337 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
20338 TREE_TYPE (stmt) = void_type_node;
20339 OMP_STANDALONE_CLAUSES (stmt) = clauses;
20340 SET_EXPR_LOCATION (stmt, loc);
20341 add_stmt (stmt);
20345 /* OpenACC 2.0:
20346 # pragma acc host_data oacc-data-clause[optseq] new-line
20347 structured-block
20350 #define OACC_HOST_DATA_CLAUSE_MASK \
20351 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
20352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
20355 static tree
20356 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
20358 tree stmt, clauses, block;
20360 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
20361 "#pragma acc host_data", false);
20362 if (!omp_find_clause (clauses, OMP_CLAUSE_USE_DEVICE_PTR))
20364 error_at (loc, "%<host_data%> construct requires %<use_device%> clause");
20365 return error_mark_node;
20367 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
20368 block = c_begin_omp_parallel ();
20369 add_stmt (c_parser_omp_structured_block (parser, if_p));
20370 stmt = c_finish_oacc_host_data (loc, clauses, block);
20371 return stmt;
20375 /* OpenACC 2.0:
20377 # pragma acc loop oacc-loop-clause[optseq] new-line
20378 structured-block
20380 LOC is the location of the #pragma token.
20383 #define OACC_LOOP_CLAUSE_MASK \
20384 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
20385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20387 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20388 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20389 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20390 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
20391 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
20392 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20393 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
20394 static tree
20395 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
20396 omp_clause_mask mask, tree *cclauses, bool *if_p)
20398 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
20400 strcat (p_name, " loop");
20401 mask |= OACC_LOOP_CLAUSE_MASK;
20403 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
20404 /*finish_p=*/cclauses == NULL,
20405 /*target=*/is_parallel);
20406 if (cclauses)
20408 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
20409 if (*cclauses)
20410 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC_TARGET);
20411 if (clauses)
20412 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
20415 tree block = c_begin_compound_stmt (true);
20416 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
20417 if_p);
20418 block = c_end_compound_stmt (loc, block, true);
20419 add_stmt (block);
20421 return stmt;
20424 /* OpenACC 2.0:
20425 # pragma acc kernels oacc-kernels-clause[optseq] new-line
20426 structured-block
20430 # pragma acc parallel oacc-parallel-clause[optseq] new-line
20431 structured-block
20433 OpenACC 2.6:
20435 # pragma acc serial oacc-serial-clause[optseq] new-line
20436 structured-block
20438 LOC is the location of the #pragma token.
20441 #define OACC_KERNELS_CLAUSE_MASK \
20442 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20443 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20444 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20445 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20446 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20447 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20448 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20449 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20450 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20451 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20452 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20453 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20456 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20457 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20459 #define OACC_PARALLEL_CLAUSE_MASK \
20460 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20461 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20462 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20463 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20464 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20465 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20476 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20477 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20478 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20480 #define OACC_SERIAL_CLAUSE_MASK \
20481 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20486 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20487 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20488 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20489 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20490 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20498 static tree
20499 c_parser_oacc_compute (location_t loc, c_parser *parser,
20500 enum pragma_kind p_kind, char *p_name, bool *if_p)
20502 omp_clause_mask mask;
20503 enum tree_code code;
20504 switch (p_kind)
20506 case PRAGMA_OACC_KERNELS:
20507 strcat (p_name, " kernels");
20508 mask = OACC_KERNELS_CLAUSE_MASK;
20509 code = OACC_KERNELS;
20510 break;
20511 case PRAGMA_OACC_PARALLEL:
20512 strcat (p_name, " parallel");
20513 mask = OACC_PARALLEL_CLAUSE_MASK;
20514 code = OACC_PARALLEL;
20515 break;
20516 case PRAGMA_OACC_SERIAL:
20517 strcat (p_name, " serial");
20518 mask = OACC_SERIAL_CLAUSE_MASK;
20519 code = OACC_SERIAL;
20520 break;
20521 default:
20522 gcc_unreachable ();
20525 if (c_parser_next_token_is (parser, CPP_NAME))
20527 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20528 if (strcmp (p, "loop") == 0)
20530 c_parser_consume_token (parser);
20531 tree block = c_begin_omp_parallel ();
20532 tree clauses;
20533 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
20534 return c_finish_omp_construct (loc, code, block, clauses);
20538 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
20539 /*finish_p=*/true,
20540 /*target=*/true);
20542 tree block = c_begin_omp_parallel ();
20543 add_stmt (c_parser_omp_structured_block (parser, if_p));
20545 return c_finish_omp_construct (loc, code, block, clauses);
20548 /* OpenACC 2.0:
20549 # pragma acc routine oacc-routine-clause[optseq] new-line
20550 function-definition
20552 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
20555 #define OACC_ROUTINE_CLAUSE_MASK \
20556 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20558 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20559 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20560 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
20562 /* Parse an OpenACC routine directive. For named directives, we apply
20563 immediately to the named function. For unnamed ones we then parse
20564 a declaration or definition, which must be for a function. */
20566 static void
20567 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
20569 gcc_checking_assert (context == pragma_external);
20571 oacc_routine_data data;
20572 data.error_seen = false;
20573 data.fndecl_seen = false;
20574 data.loc = c_parser_peek_token (parser)->location;
20576 c_parser_consume_pragma (parser);
20578 /* Look for optional '( name )'. */
20579 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20581 c_parser_consume_token (parser); /* '(' */
20583 tree decl = NULL_TREE;
20584 c_token *name_token = c_parser_peek_token (parser);
20585 location_t name_loc = name_token->location;
20586 if (name_token->type == CPP_NAME
20587 && (name_token->id_kind == C_ID_ID
20588 || name_token->id_kind == C_ID_TYPENAME))
20590 decl = lookup_name (name_token->value);
20591 if (!decl)
20592 error_at (name_loc,
20593 "%qE has not been declared", name_token->value);
20594 c_parser_consume_token (parser);
20596 else
20597 c_parser_error (parser, "expected function name");
20599 if (!decl
20600 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20602 c_parser_skip_to_pragma_eol (parser, false);
20603 return;
20606 data.clauses
20607 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
20608 "#pragma acc routine");
20609 /* The clauses are in reverse order; fix that to make later diagnostic
20610 emission easier. */
20611 data.clauses = nreverse (data.clauses);
20613 if (TREE_CODE (decl) != FUNCTION_DECL)
20615 error_at (name_loc, "%qD does not refer to a function", decl);
20616 return;
20619 c_finish_oacc_routine (&data, decl, false);
20621 else /* No optional '( name )'. */
20623 data.clauses
20624 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
20625 "#pragma acc routine");
20626 /* The clauses are in reverse order; fix that to make later diagnostic
20627 emission easier. */
20628 data.clauses = nreverse (data.clauses);
20630 /* Emit a helpful diagnostic if there's another pragma following this
20631 one. Also don't allow a static assertion declaration, as in the
20632 following we'll just parse a *single* "declaration or function
20633 definition", and the static assertion counts an one. */
20634 if (c_parser_next_token_is (parser, CPP_PRAGMA)
20635 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
20637 error_at (data.loc,
20638 "%<#pragma acc routine%> not immediately followed by"
20639 " function declaration or definition");
20640 /* ..., and then just keep going. */
20641 return;
20644 /* We only have to consider the pragma_external case here. */
20645 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20646 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20648 int ext = disable_extension_diagnostics ();
20650 c_parser_consume_token (parser);
20651 while (c_parser_next_token_is (parser, CPP_KEYWORD)
20652 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20653 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20654 NULL, NULL, false, NULL, &data);
20655 restore_extension_diagnostics (ext);
20657 else
20658 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20659 NULL, NULL, false, NULL, &data);
20663 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
20664 IS_DEFN is true if we're applying it to the definition. */
20666 static void
20667 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
20668 bool is_defn)
20670 /* Keep going if we're in error reporting mode. */
20671 if (data->error_seen
20672 || fndecl == error_mark_node)
20673 return;
20675 if (data->fndecl_seen)
20677 error_at (data->loc,
20678 "%<#pragma acc routine%> not immediately followed by"
20679 " a single function declaration or definition");
20680 data->error_seen = true;
20681 return;
20683 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
20685 error_at (data->loc,
20686 "%<#pragma acc routine%> not immediately followed by"
20687 " function declaration or definition");
20688 data->error_seen = true;
20689 return;
20692 int compatible
20693 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
20694 "#pragma acc routine");
20695 if (compatible < 0)
20697 data->error_seen = true;
20698 return;
20700 if (compatible > 0)
20703 else
20705 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
20707 error_at (data->loc,
20708 TREE_USED (fndecl)
20709 ? G_("%<#pragma acc routine%> must be applied before use")
20710 : G_("%<#pragma acc routine%> must be applied before"
20711 " definition"));
20712 data->error_seen = true;
20713 return;
20716 /* Set the routine's level of parallelism. */
20717 tree dims = oacc_build_routine_dims (data->clauses);
20718 oacc_replace_fn_attrib (fndecl, dims);
20720 /* Add an "omp declare target" attribute. */
20721 DECL_ATTRIBUTES (fndecl)
20722 = tree_cons (get_identifier ("omp declare target"),
20723 data->clauses, DECL_ATTRIBUTES (fndecl));
20726 /* Remember that we've used this "#pragma acc routine". */
20727 data->fndecl_seen = true;
20730 /* OpenACC 2.0:
20731 # pragma acc update oacc-update-clause[optseq] new-line
20734 #define OACC_UPDATE_CLAUSE_MASK \
20735 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
20737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
20738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
20740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20743 static void
20744 c_parser_oacc_update (c_parser *parser)
20746 location_t loc = c_parser_peek_token (parser)->location;
20748 c_parser_consume_pragma (parser);
20750 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
20751 "#pragma acc update");
20752 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
20754 error_at (loc,
20755 "%<#pragma acc update%> must contain at least one "
20756 "%<device%> or %<host%> or %<self%> clause");
20757 return;
20760 if (parser->error)
20761 return;
20763 tree stmt = make_node (OACC_UPDATE);
20764 TREE_TYPE (stmt) = void_type_node;
20765 OACC_UPDATE_CLAUSES (stmt) = clauses;
20766 SET_EXPR_LOCATION (stmt, loc);
20767 add_stmt (stmt);
20770 /* OpenACC 2.0:
20771 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
20773 LOC is the location of the #pragma token.
20776 #define OACC_WAIT_CLAUSE_MASK \
20777 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
20779 static tree
20780 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
20782 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
20784 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
20785 list = c_parser_oacc_wait_list (parser, loc, list);
20787 strcpy (p_name, " wait");
20788 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
20789 stmt = c_finish_oacc_wait (loc, list, clauses);
20790 add_stmt (stmt);
20792 return stmt;
20795 struct c_omp_loc_tree
20797 location_t loc;
20798 tree var;
20801 /* Check whether the expression used in the allocator clause is declared or
20802 modified between the variable declaration and its allocate directive. */
20803 static tree
20804 c_check_omp_allocate_allocator_r (tree *tp, int *, void *data)
20806 tree var = ((struct c_omp_loc_tree *) data)->var;
20807 location_t loc = ((struct c_omp_loc_tree *) data)->loc;
20808 if (TREE_CODE (*tp) == VAR_DECL && c_check_in_current_scope (*tp))
20810 if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
20811 DECL_SOURCE_LOCATION (*tp)))
20813 error_at (loc, "variable %qD used in the %<allocator%> clause must "
20814 "be declared before %qD", *tp, var);
20815 inform (DECL_SOURCE_LOCATION (*tp), "declared here");
20816 inform (DECL_SOURCE_LOCATION (var),
20817 "to be allocated variable declared here");
20818 return *tp;
20820 else
20822 gcc_assert (cur_stmt_list
20823 && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
20825 tree_stmt_iterator l = tsi_last (cur_stmt_list);
20826 while (!tsi_end_p (l))
20828 if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
20829 DECL_SOURCE_LOCATION (var)))
20830 break;
20831 if (TREE_CODE (*l) == MODIFY_EXPR
20832 && TREE_OPERAND (*l, 0) == *tp)
20834 error_at (loc,
20835 "variable %qD used in the %<allocator%> clause "
20836 "must not be modified between declaration of %qD "
20837 "and its %<allocate%> directive", *tp, var);
20838 inform (EXPR_LOCATION (*l), "modified here");
20839 inform (DECL_SOURCE_LOCATION (var),
20840 "to be allocated variable declared here");
20841 return *tp;
20843 --l;
20847 return NULL_TREE;
20850 /* OpenMP 5.x:
20851 # pragma omp allocate (list) clauses
20853 OpenMP 5.0 clause:
20854 allocator (omp_allocator_handle_t expression)
20856 OpenMP 5.1 additional clause:
20857 align (constant-expression)] */
20859 static void
20860 c_parser_omp_allocate (c_parser *parser)
20862 tree alignment = NULL_TREE;
20863 tree allocator = NULL_TREE;
20864 c_parser_consume_pragma (parser);
20865 location_t loc = c_parser_peek_token (parser)->location;
20866 location_t allocator_loc = UNKNOWN_LOCATION;
20867 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
20870 if (c_parser_next_token_is (parser, CPP_COMMA)
20871 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
20872 c_parser_consume_token (parser);
20873 if (!c_parser_next_token_is (parser, CPP_NAME))
20874 break;
20875 matching_parens parens;
20876 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20877 c_parser_consume_token (parser);
20878 location_t expr_loc = c_parser_peek_token (parser)->location;
20879 if (strcmp ("align", p) != 0 && strcmp ("allocator", p) != 0)
20881 error_at (c_parser_peek_token (parser)->location,
20882 "expected %<allocator%> or %<align%>");
20883 break;
20885 if (!parens.require_open (parser))
20886 break;
20888 c_expr expr = c_parser_expr_no_commas (parser, NULL);
20889 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
20890 expr_loc = c_parser_peek_token (parser)->location;
20891 if (expr.value == error_mark_node)
20893 else if (p[2] == 'i' && alignment)
20895 error_at (expr_loc, "too many %qs clauses", "align");
20896 break;
20898 else if (p[2] == 'i')
20900 alignment = c_fully_fold (expr.value, false, NULL);
20901 if (TREE_CODE (alignment) != INTEGER_CST
20902 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
20903 || tree_int_cst_sgn (alignment) != 1
20904 || !integer_pow2p (alignment))
20906 error_at (expr_loc, "%<align%> clause argument needs to be "
20907 "positive constant power of two integer "
20908 "expression");
20909 alignment = NULL_TREE;
20912 else if (allocator)
20914 error_at (expr_loc, "too many %qs clauses", "allocator");
20915 break;
20917 else
20919 allocator = c_fully_fold (expr.value, false, NULL);
20920 allocator_loc = expr_loc;
20921 tree orig_type
20922 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
20923 orig_type = TYPE_MAIN_VARIANT (orig_type);
20924 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
20925 || TREE_CODE (orig_type) != ENUMERAL_TYPE
20926 || TYPE_NAME (orig_type)
20927 != get_identifier ("omp_allocator_handle_t"))
20929 error_at (expr_loc,
20930 "%<allocator%> clause allocator expression has type "
20931 "%qT rather than %<omp_allocator_handle_t%>",
20932 TREE_TYPE (allocator));
20933 allocator = NULL_TREE;
20936 parens.skip_until_found_close (parser);
20937 } while (true);
20938 c_parser_skip_to_pragma_eol (parser);
20940 c_mark_decl_jump_unsafe_in_current_scope ();
20941 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
20943 tree var = OMP_CLAUSE_DECL (c);
20944 if (TREE_CODE (var) == PARM_DECL)
20946 error_at (OMP_CLAUSE_LOCATION (nl),
20947 "function parameter %qD may not appear as list item in an "
20948 "%<allocate%> directive", var);
20949 continue;
20951 if (!c_check_in_current_scope (var))
20953 error_at (OMP_CLAUSE_LOCATION (nl),
20954 "%<allocate%> directive must be in the same scope as %qD",
20955 var);
20956 inform (DECL_SOURCE_LOCATION (var), "declared here");
20957 continue;
20959 if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var)))
20961 error_at (OMP_CLAUSE_LOCATION (nl),
20962 "%qD already appeared as list item in an "
20963 "%<allocate%> directive", var);
20964 continue;
20966 if (TREE_STATIC (var))
20968 if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION)
20969 error_at (loc, "%<allocator%> clause required for "
20970 "static variable %qD", var);
20971 else if (allocator
20972 && (wi::to_widest (allocator) < 1
20973 || wi::to_widest (allocator) > 8))
20974 /* 8 = largest predefined memory allocator. */
20975 error_at (allocator_loc,
20976 "%<allocator%> clause requires a predefined allocator as "
20977 "%qD is static", var);
20978 else
20979 sorry_at (OMP_CLAUSE_LOCATION (nl),
20980 "%<#pragma omp allocate%> for static variables like "
20981 "%qD not yet supported", var);
20982 continue;
20984 if (allocator)
20986 struct c_omp_loc_tree data
20987 = {EXPR_LOC_OR_LOC (allocator, OMP_CLAUSE_LOCATION (nl)), var};
20988 walk_tree (&allocator, c_check_omp_allocate_allocator_r, &data, NULL);
20990 DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"),
20991 build_tree_list (allocator, alignment),
20992 DECL_ATTRIBUTES (var));
20996 /* OpenMP 2.5:
20997 # pragma omp atomic new-line
20998 expression-stmt
21000 expression-stmt:
21001 x binop= expr | x++ | ++x | x-- | --x
21002 binop:
21003 +, *, -, /, &, ^, |, <<, >>
21005 where x is an lvalue expression with scalar type.
21007 OpenMP 3.1:
21008 # pragma omp atomic new-line
21009 update-stmt
21011 # pragma omp atomic read new-line
21012 read-stmt
21014 # pragma omp atomic write new-line
21015 write-stmt
21017 # pragma omp atomic update new-line
21018 update-stmt
21020 # pragma omp atomic capture new-line
21021 capture-stmt
21023 # pragma omp atomic capture new-line
21024 capture-block
21026 read-stmt:
21027 v = x
21028 write-stmt:
21029 x = expr
21030 update-stmt:
21031 expression-stmt | x = x binop expr
21032 capture-stmt:
21033 v = expression-stmt
21034 capture-block:
21035 { v = x; update-stmt; } | { update-stmt; v = x; }
21037 OpenMP 4.0:
21038 update-stmt:
21039 expression-stmt | x = x binop expr | x = expr binop x
21040 capture-stmt:
21041 v = update-stmt
21042 capture-block:
21043 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
21045 OpenMP 5.1:
21046 # pragma omp atomic compare new-line
21047 conditional-update-atomic
21049 # pragma omp atomic compare capture new-line
21050 conditional-update-capture-atomic
21052 conditional-update-atomic:
21053 cond-expr-stmt | cond-update-stmt
21054 cond-expr-stmt:
21055 x = expr ordop x ? expr : x;
21056 x = x ordop expr ? expr : x;
21057 x = x == e ? d : x;
21058 cond-update-stmt:
21059 if (expr ordop x) { x = expr; }
21060 if (x ordop expr) { x = expr; }
21061 if (x == e) { x = d; }
21062 ordop:
21063 <, >
21064 conditional-update-capture-atomic:
21065 v = cond-expr-stmt
21066 { v = x; cond-expr-stmt }
21067 { cond-expr-stmt v = x; }
21068 { v = x; cond-update-stmt }
21069 { cond-update-stmt v = x; }
21070 if (x == e) { x = d; } else { v = x; }
21071 { r = x == e; if (r) { x = d; } }
21072 { r = x == e; if (r) { x = d; } else { v = x; } }
21074 where x, r and v are lvalue expressions with scalar type,
21075 expr, e and d are expressions with scalar type and e might be
21076 the same as v.
21078 LOC is the location of the #pragma token. */
21080 static void
21081 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
21083 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
21084 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
21085 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
21086 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
21087 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
21088 struct c_expr expr;
21089 location_t eloc;
21090 bool structured_block = false;
21091 bool swapped = false;
21092 bool non_lvalue_p;
21093 tree clauses = NULL_TREE;
21094 bool capture = false;
21095 bool compare = false;
21096 bool weak = false;
21097 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
21098 bool no_semicolon = false;
21099 bool extra_scope = false;
21101 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21103 if (c_parser_next_token_is (parser, CPP_COMMA)
21104 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
21105 c_parser_consume_token (parser);
21107 if (c_parser_next_token_is (parser, CPP_NAME))
21109 const char *p
21110 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21111 location_t cloc = c_parser_peek_token (parser)->location;
21112 enum tree_code new_code = ERROR_MARK;
21113 enum omp_memory_order new_memory_order
21114 = OMP_MEMORY_ORDER_UNSPECIFIED;
21115 bool new_capture = false;
21116 bool new_compare = false;
21117 bool new_weak = false;
21118 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
21120 if (!strcmp (p, "read"))
21121 new_code = OMP_ATOMIC_READ;
21122 else if (!strcmp (p, "write"))
21123 new_code = NOP_EXPR;
21124 else if (!strcmp (p, "update"))
21125 new_code = OMP_ATOMIC;
21126 else if (openacc && !strcmp (p, "capture"))
21127 new_code = OMP_ATOMIC_CAPTURE_NEW;
21128 else if (openacc)
21130 p = NULL;
21131 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
21132 "or %<capture%> clause");
21134 else if (!strcmp (p, "capture"))
21135 new_capture = true;
21136 else if (!strcmp (p, "compare"))
21137 new_compare = true;
21138 else if (!strcmp (p, "weak"))
21139 new_weak = true;
21140 else if (!strcmp (p, "fail"))
21142 matching_parens parens;
21144 c_parser_consume_token (parser);
21145 if (!parens.require_open (parser))
21146 continue;
21148 if (c_parser_next_token_is (parser, CPP_NAME))
21150 const char *q
21151 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21153 if (!strcmp (q, "seq_cst"))
21154 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
21155 else if (!strcmp (q, "acquire"))
21156 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
21157 else if (!strcmp (q, "relaxed"))
21158 new_fail = OMP_MEMORY_ORDER_RELAXED;
21161 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
21163 c_parser_consume_token (parser);
21164 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
21165 error_at (cloc, "too many %qs clauses", "fail");
21166 else
21167 fail = new_fail;
21169 else
21170 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
21171 "or %<relaxed%>");
21172 parens.skip_until_found_close (parser);
21173 continue;
21175 else if (!strcmp (p, "seq_cst"))
21176 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21177 else if (!strcmp (p, "acq_rel"))
21178 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
21179 else if (!strcmp (p, "release"))
21180 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
21181 else if (!strcmp (p, "acquire"))
21182 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21183 else if (!strcmp (p, "relaxed"))
21184 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
21185 else if (!strcmp (p, "hint"))
21187 c_parser_consume_token (parser);
21188 clauses = c_parser_omp_clause_hint (parser, clauses);
21189 continue;
21191 else
21193 p = NULL;
21194 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
21195 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
21196 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
21197 "%<relaxed%> or %<hint%> clause");
21199 if (p)
21201 if (new_code != ERROR_MARK)
21203 /* OpenACC permits 'update capture'. */
21204 if (openacc
21205 && code == OMP_ATOMIC
21206 && new_code == OMP_ATOMIC_CAPTURE_NEW)
21207 code = new_code;
21208 else if (code != ERROR_MARK)
21209 error_at (cloc, "too many atomic clauses");
21210 else
21211 code = new_code;
21213 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
21215 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
21216 error_at (cloc, "too many memory order clauses");
21217 else
21218 memory_order = new_memory_order;
21220 else if (new_capture)
21222 if (capture)
21223 error_at (cloc, "too many %qs clauses", "capture");
21224 else
21225 capture = true;
21227 else if (new_compare)
21229 if (compare)
21230 error_at (cloc, "too many %qs clauses", "compare");
21231 else
21232 compare = true;
21234 else if (new_weak)
21236 if (weak)
21237 error_at (cloc, "too many %qs clauses", "weak");
21238 else
21239 weak = true;
21241 c_parser_consume_token (parser);
21242 continue;
21245 break;
21247 c_parser_skip_to_pragma_eol (parser);
21249 if (code == ERROR_MARK)
21250 code = OMP_ATOMIC;
21251 if (capture)
21253 if (code != OMP_ATOMIC)
21254 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
21255 "clauses", "capture");
21256 else
21257 code = OMP_ATOMIC_CAPTURE_NEW;
21259 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
21261 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
21262 "clauses", "compare");
21263 compare = false;
21265 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
21267 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
21268 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
21270 if (weak && !compare)
21272 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
21273 weak = false;
21275 if (openacc)
21276 memory_order = OMP_MEMORY_ORDER_RELAXED;
21277 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
21279 omp_requires_mask
21280 = (enum omp_requires) (omp_requires_mask
21281 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
21282 switch ((enum omp_memory_order)
21283 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
21285 case OMP_MEMORY_ORDER_UNSPECIFIED:
21286 case OMP_MEMORY_ORDER_RELAXED:
21287 memory_order = OMP_MEMORY_ORDER_RELAXED;
21288 break;
21289 case OMP_MEMORY_ORDER_SEQ_CST:
21290 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21291 break;
21292 case OMP_MEMORY_ORDER_ACQUIRE:
21293 if (code == NOP_EXPR) /* atomic write */
21295 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
21296 "%<acquire%> clause implicitly provided by a "
21297 "%<requires%> directive");
21298 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21300 else
21301 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21302 break;
21303 case OMP_MEMORY_ORDER_RELEASE:
21304 if (code == OMP_ATOMIC_READ)
21306 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
21307 "%<release%> clause implicitly provided by a "
21308 "%<requires%> directive");
21309 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21311 else
21312 memory_order = OMP_MEMORY_ORDER_RELEASE;
21313 break;
21314 case OMP_MEMORY_ORDER_ACQ_REL:
21315 switch (code)
21317 case OMP_ATOMIC_READ:
21318 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21319 break;
21320 case NOP_EXPR: /* atomic write */
21321 memory_order = OMP_MEMORY_ORDER_RELEASE;
21322 break;
21323 default:
21324 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
21325 break;
21327 break;
21328 default:
21329 gcc_unreachable ();
21332 else
21333 switch (code)
21335 case OMP_ATOMIC_READ:
21336 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
21338 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
21339 "%<release%> clause");
21340 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21342 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
21343 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
21344 break;
21345 case NOP_EXPR: /* atomic write */
21346 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
21348 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
21349 "%<acquire%> clause");
21350 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
21352 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
21353 memory_order = OMP_MEMORY_ORDER_RELEASE;
21354 break;
21355 default:
21356 break;
21358 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
21359 memory_order
21360 = (enum omp_memory_order) (memory_order
21361 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
21363 switch (code)
21365 case OMP_ATOMIC_READ:
21366 case NOP_EXPR: /* atomic write */
21367 v = c_parser_cast_expression (parser, NULL).value;
21368 non_lvalue_p = !lvalue_p (v);
21369 v = c_fully_fold (v, false, NULL, true);
21370 if (v == error_mark_node)
21371 goto saw_error;
21372 if (non_lvalue_p)
21373 v = non_lvalue (v);
21374 loc = c_parser_peek_token (parser)->location;
21375 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21376 goto saw_error;
21377 if (code == NOP_EXPR)
21379 lhs = c_parser_expression (parser).value;
21380 lhs = c_fully_fold (lhs, false, NULL);
21381 if (lhs == error_mark_node)
21382 goto saw_error;
21384 else
21386 lhs = c_parser_cast_expression (parser, NULL).value;
21387 non_lvalue_p = !lvalue_p (lhs);
21388 lhs = c_fully_fold (lhs, false, NULL, true);
21389 if (lhs == error_mark_node)
21390 goto saw_error;
21391 if (non_lvalue_p)
21392 lhs = non_lvalue (lhs);
21394 if (code == NOP_EXPR)
21396 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
21397 opcode. */
21398 code = OMP_ATOMIC;
21399 rhs = lhs;
21400 lhs = v;
21401 v = NULL_TREE;
21403 goto done;
21404 case OMP_ATOMIC_CAPTURE_NEW:
21405 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
21407 c_parser_consume_token (parser);
21408 structured_block = true;
21410 else if (compare
21411 && c_parser_next_token_is_keyword (parser, RID_IF))
21412 break;
21413 else
21415 v = c_parser_cast_expression (parser, NULL).value;
21416 non_lvalue_p = !lvalue_p (v);
21417 v = c_fully_fold (v, false, NULL, true);
21418 if (v == error_mark_node)
21419 goto saw_error;
21420 if (non_lvalue_p)
21421 v = non_lvalue (v);
21422 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21423 goto saw_error;
21424 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
21426 eloc = c_parser_peek_token (parser)->location;
21427 error_at (eloc, "expected expression");
21428 goto saw_error;
21431 break;
21432 default:
21433 break;
21436 /* For structured_block case we don't know yet whether
21437 old or new x should be captured. */
21438 restart:
21439 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
21441 c_parser_consume_token (parser);
21443 matching_parens parens;
21444 if (!parens.require_open (parser))
21445 goto saw_error;
21446 eloc = c_parser_peek_token (parser)->location;
21447 c_expr cmp_expr;
21448 if (r)
21450 cmp_expr = c_parser_cast_expression (parser, NULL);
21451 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
21453 else
21454 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
21455 parens.skip_until_found_close (parser);
21456 if (cmp_expr.value == error_mark_node)
21457 goto saw_error;
21458 if (r)
21460 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
21461 goto bad_if;
21462 cmp_expr.value = rhs1;
21463 rhs1 = NULL_TREE;
21464 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
21466 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21468 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
21470 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
21471 "expected %<==%> comparison in %<if%> condition");
21472 goto saw_error;
21474 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
21475 && TREE_CODE (cmp_expr.value) != LT_EXPR)
21477 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
21478 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
21479 "condition");
21480 goto saw_error;
21482 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21483 goto saw_error;
21485 extra_scope = true;
21486 eloc = c_parser_peek_token (parser)->location;
21487 expr = c_parser_cast_expression (parser, NULL);
21488 lhs = expr.value;
21489 expr = default_function_array_conversion (eloc, expr);
21490 unfolded_lhs = expr.value;
21491 lhs = c_fully_fold (lhs, false, NULL, true);
21492 orig_lhs = lhs;
21493 if (lhs == error_mark_node)
21494 goto saw_error;
21495 if (!lvalue_p (unfolded_lhs))
21496 lhs = non_lvalue (lhs);
21497 if (!c_parser_next_token_is (parser, CPP_EQ))
21499 c_parser_error (parser, "expected %<=%>");
21500 goto saw_error;
21502 c_parser_consume_token (parser);
21503 eloc = c_parser_peek_token (parser)->location;
21504 expr = c_parser_expr_no_commas (parser, NULL);
21505 rhs1 = expr.value;
21507 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21508 goto saw_error;
21510 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
21511 goto saw_error;
21513 extra_scope = false;
21514 no_semicolon = true;
21516 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
21518 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21520 opcode = COND_EXPR;
21521 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
21522 false, NULL, true);
21523 rhs1 = c_fully_fold (rhs1, false, NULL, true);
21525 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
21527 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
21528 ? MIN_EXPR : MAX_EXPR);
21529 rhs = c_fully_fold (rhs1, false, NULL, true);
21530 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
21531 false, NULL, true);
21533 else
21534 goto bad_if;
21536 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
21537 goto bad_if;
21538 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
21539 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
21541 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
21542 ? MAX_EXPR : MIN_EXPR);
21543 rhs = c_fully_fold (rhs1, false, NULL, true);
21544 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
21545 false, NULL, true);
21547 else
21549 bad_if:
21550 c_parser_error (parser,
21551 "invalid form of %<#pragma omp atomic compare%>");
21552 goto saw_error;
21555 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
21557 if (code != OMP_ATOMIC_CAPTURE_NEW
21558 || (structured_block && r == NULL_TREE)
21559 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
21561 eloc = c_parser_peek_token (parser)->location;
21562 error_at (eloc, "unexpected %<else%>");
21563 goto saw_error;
21566 c_parser_consume_token (parser);
21568 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21569 goto saw_error;
21571 extra_scope = true;
21572 v = c_parser_cast_expression (parser, NULL).value;
21573 non_lvalue_p = !lvalue_p (v);
21574 v = c_fully_fold (v, false, NULL, true);
21575 if (v == error_mark_node)
21576 goto saw_error;
21577 if (non_lvalue_p)
21578 v = non_lvalue (v);
21579 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21580 goto saw_error;
21582 expr = c_parser_expr_no_commas (parser, NULL);
21584 if (!c_tree_equal (expr.value, unfolded_lhs))
21585 goto bad_if;
21587 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21588 goto saw_error;
21590 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
21591 goto saw_error;
21593 extra_scope = false;
21594 code = OMP_ATOMIC_CAPTURE_OLD;
21595 if (r == NULL_TREE)
21596 /* Signal to c_finish_omp_atomic that in
21597 if (x == e) { x = d; } else { v = x; }
21598 case the store to v should be conditional. */
21599 r = void_list_node;
21601 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21603 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
21604 goto saw_error;
21606 else if (code == OMP_ATOMIC_CAPTURE_NEW
21607 && r != NULL_TREE
21608 && v == NULL_TREE)
21609 code = OMP_ATOMIC;
21610 goto stmt_done;
21612 eloc = c_parser_peek_token (parser)->location;
21613 expr = c_parser_cast_expression (parser, NULL);
21614 lhs = expr.value;
21615 expr = default_function_array_conversion (eloc, expr);
21616 unfolded_lhs = expr.value;
21617 lhs = c_fully_fold (lhs, false, NULL, true);
21618 orig_lhs = lhs;
21619 switch (TREE_CODE (lhs))
21621 invalid_compare:
21622 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
21623 /* FALLTHRU */
21624 case ERROR_MARK:
21625 saw_error:
21626 c_parser_skip_to_end_of_block_or_statement (parser);
21627 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21628 c_parser_consume_token (parser);
21629 if (structured_block)
21631 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21632 c_parser_consume_token (parser);
21633 else if (code == OMP_ATOMIC_CAPTURE_NEW)
21635 c_parser_skip_to_end_of_block_or_statement (parser);
21636 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21637 c_parser_consume_token (parser);
21640 return;
21642 case POSTINCREMENT_EXPR:
21643 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21644 code = OMP_ATOMIC_CAPTURE_OLD;
21645 /* FALLTHROUGH */
21646 case PREINCREMENT_EXPR:
21647 lhs = TREE_OPERAND (lhs, 0);
21648 unfolded_lhs = NULL_TREE;
21649 opcode = PLUS_EXPR;
21650 rhs = integer_one_node;
21651 if (compare)
21652 goto invalid_compare;
21653 break;
21655 case POSTDECREMENT_EXPR:
21656 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
21657 code = OMP_ATOMIC_CAPTURE_OLD;
21658 /* FALLTHROUGH */
21659 case PREDECREMENT_EXPR:
21660 lhs = TREE_OPERAND (lhs, 0);
21661 unfolded_lhs = NULL_TREE;
21662 opcode = MINUS_EXPR;
21663 rhs = integer_one_node;
21664 if (compare)
21665 goto invalid_compare;
21666 break;
21668 case COMPOUND_EXPR:
21669 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
21670 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
21671 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
21672 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
21673 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
21674 (TREE_OPERAND (lhs, 1), 0), 0))))
21675 /* Undo effects of boolean_increment for post {in,de}crement. */
21676 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
21677 /* FALLTHRU */
21678 case MODIFY_EXPR:
21679 if (TREE_CODE (lhs) == MODIFY_EXPR
21680 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))))
21682 /* Undo effects of boolean_increment. */
21683 if (integer_onep (TREE_OPERAND (lhs, 1)))
21685 /* This is pre or post increment. */
21686 rhs = TREE_OPERAND (lhs, 1);
21687 lhs = TREE_OPERAND (lhs, 0);
21688 unfolded_lhs = NULL_TREE;
21689 opcode = NOP_EXPR;
21690 if (code == OMP_ATOMIC_CAPTURE_NEW
21691 && !structured_block
21692 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
21693 code = OMP_ATOMIC_CAPTURE_OLD;
21694 if (compare)
21695 goto invalid_compare;
21696 break;
21698 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
21699 && TREE_OPERAND (lhs, 0)
21700 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
21702 /* This is pre or post decrement. */
21703 rhs = TREE_OPERAND (lhs, 1);
21704 lhs = TREE_OPERAND (lhs, 0);
21705 unfolded_lhs = NULL_TREE;
21706 opcode = NOP_EXPR;
21707 if (code == OMP_ATOMIC_CAPTURE_NEW
21708 && !structured_block
21709 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
21710 code = OMP_ATOMIC_CAPTURE_OLD;
21711 if (compare)
21712 goto invalid_compare;
21713 break;
21716 /* FALLTHRU */
21717 default:
21718 if (!lvalue_p (unfolded_lhs))
21719 lhs = non_lvalue (lhs);
21720 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
21722 c_parser_error (parser, "expected %<=%>");
21723 goto saw_error;
21725 switch (c_parser_peek_token (parser)->type)
21727 case CPP_MULT_EQ:
21728 opcode = MULT_EXPR;
21729 break;
21730 case CPP_DIV_EQ:
21731 opcode = TRUNC_DIV_EXPR;
21732 break;
21733 case CPP_PLUS_EQ:
21734 opcode = PLUS_EXPR;
21735 break;
21736 case CPP_MINUS_EQ:
21737 opcode = MINUS_EXPR;
21738 break;
21739 case CPP_LSHIFT_EQ:
21740 opcode = LSHIFT_EXPR;
21741 break;
21742 case CPP_RSHIFT_EQ:
21743 opcode = RSHIFT_EXPR;
21744 break;
21745 case CPP_AND_EQ:
21746 opcode = BIT_AND_EXPR;
21747 break;
21748 case CPP_OR_EQ:
21749 opcode = BIT_IOR_EXPR;
21750 break;
21751 case CPP_XOR_EQ:
21752 opcode = BIT_XOR_EXPR;
21753 break;
21754 case CPP_EQ:
21755 c_parser_consume_token (parser);
21756 eloc = c_parser_peek_token (parser)->location;
21757 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
21758 rhs1 = expr.value;
21759 switch (TREE_CODE (rhs1))
21761 case MULT_EXPR:
21762 case TRUNC_DIV_EXPR:
21763 case RDIV_EXPR:
21764 case PLUS_EXPR:
21765 case MINUS_EXPR:
21766 case LSHIFT_EXPR:
21767 case RSHIFT_EXPR:
21768 case BIT_AND_EXPR:
21769 case BIT_IOR_EXPR:
21770 case BIT_XOR_EXPR:
21771 if (compare)
21772 break;
21773 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
21775 opcode = TREE_CODE (rhs1);
21776 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21777 true);
21778 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
21779 true);
21780 goto stmt_done;
21782 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
21784 opcode = TREE_CODE (rhs1);
21785 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
21786 true);
21787 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21788 true);
21789 swapped = !commutative_tree_code (opcode);
21790 goto stmt_done;
21792 break;
21793 case COND_EXPR:
21794 if (!compare)
21795 break;
21796 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
21797 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
21798 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
21799 break;
21800 if (!TREE_OPERAND (rhs1, 1))
21801 break;
21802 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
21803 break;
21804 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
21805 unfolded_lhs))
21807 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
21809 opcode = COND_EXPR;
21810 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21811 0), 1),
21812 false, NULL, true);
21813 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
21814 NULL, true);
21815 goto stmt_done;
21817 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
21818 TREE_OPERAND (rhs1, 1)))
21820 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
21821 ? MIN_EXPR : MAX_EXPR);
21822 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21823 true);
21824 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21825 0), 0),
21826 false, NULL, true);
21827 goto stmt_done;
21830 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
21831 break;
21832 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
21833 unfolded_lhs))
21835 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
21836 TREE_OPERAND (rhs1, 1)))
21838 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
21839 ? MAX_EXPR : MIN_EXPR);
21840 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
21841 true);
21842 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
21843 0), 1),
21844 false, NULL, true);
21845 goto stmt_done;
21848 break;
21849 case EQ_EXPR:
21850 if (!compare
21851 || code != OMP_ATOMIC_CAPTURE_NEW
21852 || !structured_block
21853 || v
21854 || r)
21855 break;
21856 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
21857 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
21859 r = lhs;
21860 lhs = NULL_TREE;
21861 c_parser_consume_token (parser);
21862 goto restart;
21864 break;
21865 case ERROR_MARK:
21866 goto saw_error;
21867 default:
21868 break;
21870 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
21872 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
21874 code = OMP_ATOMIC_CAPTURE_OLD;
21875 v = lhs;
21876 lhs = NULL_TREE;
21877 expr = default_function_array_read_conversion (eloc, expr);
21878 unfolded_lhs1 = expr.value;
21879 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
21880 rhs1 = NULL_TREE;
21881 c_parser_consume_token (parser);
21882 goto restart;
21884 if (structured_block && !compare)
21886 opcode = NOP_EXPR;
21887 expr = default_function_array_read_conversion (eloc, expr);
21888 rhs = c_fully_fold (expr.value, false, NULL, true);
21889 rhs1 = NULL_TREE;
21890 goto stmt_done;
21893 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
21894 goto saw_error;
21895 default:
21896 c_parser_error (parser,
21897 "invalid operator for %<#pragma omp atomic%>");
21898 goto saw_error;
21901 /* Arrange to pass the location of the assignment operator to
21902 c_finish_omp_atomic. */
21903 loc = c_parser_peek_token (parser)->location;
21904 c_parser_consume_token (parser);
21905 eloc = c_parser_peek_token (parser)->location;
21906 expr = c_parser_expression (parser);
21907 expr = default_function_array_read_conversion (eloc, expr);
21908 rhs = expr.value;
21909 rhs = c_fully_fold (rhs, false, NULL, true);
21910 break;
21912 stmt_done:
21913 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
21915 if (!no_semicolon
21916 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
21917 goto saw_error;
21918 no_semicolon = false;
21919 v = c_parser_cast_expression (parser, NULL).value;
21920 non_lvalue_p = !lvalue_p (v);
21921 v = c_fully_fold (v, false, NULL, true);
21922 if (v == error_mark_node)
21923 goto saw_error;
21924 if (non_lvalue_p)
21925 v = non_lvalue (v);
21926 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21927 goto saw_error;
21928 eloc = c_parser_peek_token (parser)->location;
21929 expr = c_parser_cast_expression (parser, NULL);
21930 lhs1 = expr.value;
21931 expr = default_function_array_read_conversion (eloc, expr);
21932 unfolded_lhs1 = expr.value;
21933 lhs1 = c_fully_fold (lhs1, false, NULL, true);
21934 if (lhs1 == error_mark_node)
21935 goto saw_error;
21936 if (!lvalue_p (unfolded_lhs1))
21937 lhs1 = non_lvalue (lhs1);
21939 if (structured_block)
21941 if (!no_semicolon)
21942 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
21943 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
21945 done:
21946 if (weak && opcode != COND_EXPR)
21948 error_at (loc, "%<weak%> clause requires atomic equality comparison");
21949 weak = false;
21951 if (unfolded_lhs && unfolded_lhs1
21952 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
21954 error ("%<#pragma omp atomic capture%> uses two different "
21955 "expressions for memory");
21956 stmt = error_mark_node;
21958 else
21959 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
21960 swapped, memory_order, weak);
21961 if (stmt != error_mark_node)
21962 add_stmt (stmt);
21964 if (!structured_block && !no_semicolon)
21965 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
21969 /* OpenMP 2.5:
21970 # pragma omp barrier new-line
21973 static void
21974 c_parser_omp_barrier (c_parser *parser)
21976 location_t loc = c_parser_peek_token (parser)->location;
21977 c_parser_consume_pragma (parser);
21978 c_parser_skip_to_pragma_eol (parser);
21980 c_finish_omp_barrier (loc);
21983 /* OpenMP 2.5:
21984 # pragma omp critical [(name)] new-line
21985 structured-block
21987 OpenMP 4.5:
21988 # pragma omp critical [(name) [hint(expression)]] new-line
21990 LOC is the location of the #pragma itself. */
21992 #define OMP_CRITICAL_CLAUSE_MASK \
21993 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
21995 static tree
21996 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
21998 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
22000 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22002 c_parser_consume_token (parser);
22003 if (c_parser_next_token_is (parser, CPP_NAME))
22005 name = c_parser_peek_token (parser)->value;
22006 c_parser_consume_token (parser);
22007 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
22009 else
22010 c_parser_error (parser, "expected identifier");
22012 if (c_parser_next_token_is (parser, CPP_COMMA)
22013 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22014 c_parser_consume_token (parser);
22016 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
22017 "#pragma omp critical");
22018 stmt = c_parser_omp_structured_block (parser, if_p);
22019 return c_finish_omp_critical (loc, stmt, name, clauses);
22022 /* OpenMP 5.0:
22023 # pragma omp depobj ( depobj ) depobj-clause new-line
22025 depobj-clause:
22026 depend (dependence-type : locator)
22027 destroy
22028 update (dependence-type)
22030 OpenMP 5.2 additionally:
22031 destroy ( depobj )
22033 dependence-type:
22036 inout
22037 mutexinout */
22039 static void
22040 c_parser_omp_depobj (c_parser *parser)
22042 location_t loc = c_parser_peek_token (parser)->location;
22043 c_parser_consume_pragma (parser);
22044 matching_parens parens;
22045 if (!parens.require_open (parser))
22047 c_parser_skip_to_pragma_eol (parser);
22048 return;
22051 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
22052 if (depobj != error_mark_node)
22054 if (!lvalue_p (depobj))
22056 error_at (EXPR_LOC_OR_LOC (depobj, loc),
22057 "%<depobj%> expression is not lvalue expression");
22058 depobj = error_mark_node;
22060 else
22062 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
22063 depobj, false);
22064 if (addr == error_mark_node)
22065 depobj = error_mark_node;
22066 else
22067 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
22068 addr, RO_UNARY_STAR);
22072 parens.skip_until_found_close (parser);
22073 tree clause = NULL_TREE;
22074 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
22075 if (c_parser_next_token_is (parser, CPP_COMMA))
22076 c_parser_consume_token (parser);
22077 location_t c_loc = c_parser_peek_token (parser)->location;
22078 if (c_parser_next_token_is (parser, CPP_NAME))
22080 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22082 c_parser_consume_token (parser);
22083 if (!strcmp ("depend", p))
22085 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
22086 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
22087 if (!clause)
22088 clause = error_mark_node;
22090 else if (!strcmp ("destroy", p))
22092 matching_parens c_parens;
22093 kind = OMP_CLAUSE_DEPEND_LAST;
22094 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
22095 && c_parens.require_open (parser))
22097 tree destobj = c_parser_expr_no_commas (parser, NULL).value;
22098 if (!lvalue_p (destobj))
22099 error_at (EXPR_LOC_OR_LOC (destobj, c_loc),
22100 "%<destroy%> expression is not lvalue expression");
22101 else if (depobj != error_mark_node
22102 && !operand_equal_p (destobj, depobj,
22103 OEP_MATCH_SIDE_EFFECTS
22104 | OEP_LEXICOGRAPHIC))
22105 warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), OPT_Wopenmp,
22106 "the %<destroy%> expression %qE should be the same "
22107 "as the %<depobj%> argument %qE", destobj, depobj);
22108 c_parens.skip_until_found_close (parser);
22111 else if (!strcmp ("update", p))
22113 matching_parens c_parens;
22114 if (c_parens.require_open (parser))
22116 location_t c2_loc = c_parser_peek_token (parser)->location;
22117 if (c_parser_next_token_is (parser, CPP_NAME))
22119 const char *p2
22120 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22122 c_parser_consume_token (parser);
22123 if (!strcmp ("in", p2))
22124 kind = OMP_CLAUSE_DEPEND_IN;
22125 else if (!strcmp ("out", p2))
22126 kind = OMP_CLAUSE_DEPEND_OUT;
22127 else if (!strcmp ("inout", p2))
22128 kind = OMP_CLAUSE_DEPEND_INOUT;
22129 else if (!strcmp ("mutexinoutset", p2))
22130 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
22131 else if (!strcmp ("inoutset", p2))
22132 kind = OMP_CLAUSE_DEPEND_INOUTSET;
22134 if (kind == OMP_CLAUSE_DEPEND_INVALID)
22136 clause = error_mark_node;
22137 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
22138 "%<mutexinoutset%> or %<inoutset%>");
22140 c_parens.skip_until_found_close (parser);
22142 else
22143 clause = error_mark_node;
22146 if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
22148 clause = error_mark_node;
22149 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
22151 c_parser_skip_to_pragma_eol (parser);
22153 c_finish_omp_depobj (loc, depobj, kind, clause);
22157 /* OpenMP 2.5:
22158 # pragma omp flush flush-vars[opt] new-line
22160 flush-vars:
22161 ( variable-list )
22163 OpenMP 5.0:
22164 # pragma omp flush memory-order-clause new-line */
22166 static void
22167 c_parser_omp_flush (c_parser *parser)
22169 location_t loc = c_parser_peek_token (parser)->location;
22170 c_parser_consume_pragma (parser);
22171 enum memmodel mo = MEMMODEL_LAST;
22172 if (c_parser_next_token_is (parser, CPP_COMMA)
22173 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22174 c_parser_consume_token (parser);
22175 if (c_parser_next_token_is (parser, CPP_NAME))
22177 const char *p
22178 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22180 if (!strcmp (p, "seq_cst"))
22181 mo = MEMMODEL_SEQ_CST;
22182 else if (!strcmp (p, "acq_rel"))
22183 mo = MEMMODEL_ACQ_REL;
22184 else if (!strcmp (p, "release"))
22185 mo = MEMMODEL_RELEASE;
22186 else if (!strcmp (p, "acquire"))
22187 mo = MEMMODEL_ACQUIRE;
22188 else
22189 error_at (c_parser_peek_token (parser)->location,
22190 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
22191 "%<acquire%>");
22192 c_parser_consume_token (parser);
22194 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22196 if (mo != MEMMODEL_LAST)
22197 error_at (c_parser_peek_token (parser)->location,
22198 "%<flush%> list specified together with memory order "
22199 "clause");
22200 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
22202 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22203 c_parser_error (parser, "expected %<(%> or end of line");
22204 c_parser_skip_to_pragma_eol (parser);
22206 c_finish_omp_flush (loc, mo);
22209 /* Return true if next tokens contain a standard attribute that contains
22210 omp::directive (DIRECTIVE). */
22212 static bool
22213 c_parser_omp_section_scan (c_parser *parser, const char *directive,
22214 bool tentative)
22216 if (!c_parser_nth_token_starts_std_attributes (parser, 1))
22217 return false;
22218 unsigned int n = 3;
22219 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
22220 return false;
22221 c_token *token = c_parser_peek_nth_token_raw (parser, n);
22222 if (token->type != CPP_CLOSE_SQUARE)
22223 return false;
22224 token = c_parser_peek_nth_token_raw (parser, n + 1);
22225 if (token->type != CPP_CLOSE_SQUARE)
22226 return false;
22227 if (n < 9)
22228 return false;
22229 if (c_parser_peek_nth_token_raw (parser, 3)->type == CPP_NAME
22230 && c_parser_peek_nth_token_raw (parser, 4)->type == CPP_OPEN_PAREN
22231 && c_parser_peek_nth_token_raw (parser, 5)->type == CPP_NAME)
22233 tree first = c_parser_peek_nth_token_raw (parser, 3)->value;
22234 tree second = c_parser_peek_nth_token_raw (parser, 5)->value;
22235 if (strcmp (IDENTIFIER_POINTER (first), "directive")
22236 && strcmp (IDENTIFIER_POINTER (first), "__directive__"))
22237 return false;
22238 if (strcmp (IDENTIFIER_POINTER (second), directive))
22239 return false;
22241 if (tentative)
22242 return true;
22243 location_t first_loc = c_parser_peek_token (parser)->location;
22244 location_t last_loc = c_parser_peek_nth_token_raw (parser, n + 1)->location;
22245 location_t middle_loc = UNKNOWN_LOCATION;
22246 tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
22247 bool seen = false;
22248 int cnt = 0;
22249 for (tree attr = std_attrs; attr; attr = TREE_CHAIN (attr))
22250 if (is_attribute_namespace_p ("omp", attr)
22251 && is_attribute_p ("directive", get_attribute_name (attr)))
22253 for (tree a = TREE_VALUE (attr); a; a = TREE_CHAIN (a))
22255 tree d = TREE_VALUE (a);
22256 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
22257 c_token *first = C_TOKEN_VEC_TOKENS (d)->address ();
22258 cnt++;
22259 if (first->type == CPP_NAME
22260 && strcmp (IDENTIFIER_POINTER (first->value),
22261 directive) == 0)
22263 seen = true;
22264 if (middle_loc == UNKNOWN_LOCATION)
22265 middle_loc = first->location;
22269 if (!seen)
22270 return false;
22271 if (cnt != 1 || TREE_CHAIN (std_attrs))
22273 error_at (make_location (first_loc, last_loc, middle_loc),
22274 "%<[[omp::directive(%s)]]%> must be the only specified "
22275 "attribute on a statement", directive);
22276 return false;
22278 c_parser_handle_statement_omp_attributes (parser, std_attrs, NULL);
22279 return true;
22282 /* Parse an OpenMP structured block sequence. KIND is the corresponding
22283 separating directive. */
22285 static tree
22286 c_parser_omp_structured_block_sequence (c_parser *parser,
22287 enum pragma_kind kind)
22289 tree stmt = push_stmt_list ();
22290 c_parser_statement (parser, NULL);
22293 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
22294 break;
22295 if (c_parser_next_token_is (parser, CPP_EOF))
22296 break;
22298 if (kind != PRAGMA_NONE
22299 && c_parser_peek_token (parser)->pragma_kind == kind)
22300 break;
22302 if (kind != PRAGMA_NONE
22303 && c_parser_omp_section_scan (parser,
22304 kind == PRAGMA_OMP_SCAN
22305 ? "scan" : "section", false))
22306 break;
22308 c_parser_statement (parser, NULL);
22310 while (1);
22311 return pop_stmt_list (stmt);
22314 /* OpenMP 5.0:
22316 scan-loop-body:
22317 { structured-block scan-directive structured-block } */
22319 static void
22320 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
22322 tree substmt;
22323 location_t loc;
22324 tree clauses = NULL_TREE;
22325 bool found_scan = false;
22327 loc = c_parser_peek_token (parser)->location;
22328 if (!open_brace_parsed
22329 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
22331 /* Avoid skipping until the end of the block. */
22332 parser->error = false;
22333 return;
22336 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SCAN)
22337 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
22338 else
22340 warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
22341 "%<#pragma omp scan%> with zero preceding executable "
22342 "statements");
22343 substmt = build_empty_stmt (loc);
22345 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
22346 SET_EXPR_LOCATION (substmt, loc);
22347 add_stmt (substmt);
22349 loc = c_parser_peek_token (parser)->location;
22350 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
22352 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
22353 found_scan = true;
22355 c_parser_consume_pragma (parser);
22357 if (c_parser_next_token_is (parser, CPP_COMMA))
22358 c_parser_consume_token (parser);
22360 if (c_parser_next_token_is (parser, CPP_NAME))
22362 const char *p
22363 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22364 if (strcmp (p, "inclusive") == 0)
22365 clause = OMP_CLAUSE_INCLUSIVE;
22366 else if (strcmp (p, "exclusive") == 0)
22367 clause = OMP_CLAUSE_EXCLUSIVE;
22369 if (clause != OMP_CLAUSE_ERROR)
22371 c_parser_consume_token (parser);
22372 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
22374 else
22375 c_parser_error (parser, "expected %<inclusive%> or "
22376 "%<exclusive%> clause");
22377 c_parser_skip_to_pragma_eol (parser);
22379 else
22380 error ("expected %<#pragma omp scan%>");
22382 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22383 if (!c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
22384 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
22385 else
22387 if (found_scan)
22388 warning_at (loc, OPT_Wopenmp,
22389 "%<#pragma omp scan%> with zero succeeding executable "
22390 "statements");
22391 substmt = build_empty_stmt (loc);
22393 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
22394 SET_EXPR_LOCATION (substmt, loc);
22395 add_stmt (substmt);
22397 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
22398 "expected %<}%>");
22402 /* Check if the next tokens can start a canonical loop. Return true if yes,
22403 otherwise diagnose an error if ERROR_P is true, and return false. */
22404 static bool
22405 c_parser_omp_next_tokens_can_be_canon_loop (c_parser *parser,
22406 enum tree_code code,
22407 bool error_p)
22409 if (code == OACC_LOOP)
22411 if (c_parser_next_token_is_keyword (parser, RID_FOR))
22412 return true;
22413 if (error_p)
22414 c_parser_error (parser, "for statement expected");
22416 else
22418 if (c_parser_next_token_is_keyword (parser, RID_FOR))
22419 return true;
22421 if (c_parser_next_token_is (parser, CPP_PRAGMA))
22422 switch (c_parser_peek_token (parser)->pragma_kind)
22424 case PRAGMA_OMP_UNROLL:
22425 case PRAGMA_OMP_TILE:
22426 return true;
22427 default:
22428 break;
22431 /* Skip standard attributes on next for in case they are
22432 [[omp::directive (unroll partial (4))]] or
22433 [[omp::directive (tile sizes (1, 2, 3))]] etc. */
22434 size_t n = c_parser_skip_std_attribute_spec_seq (parser, 1);
22435 c_token *token = c_parser_peek_nth_token_raw (parser, n);
22436 /* TOKEN is a raw token that hasn't been converted to a keyword yet,
22437 we have to do the lookup explicitly. */
22438 if (token->type == CPP_NAME
22439 && C_IS_RESERVED_WORD (token->value)
22440 && C_RID_CODE (token->value) == RID_FOR)
22441 return true;
22442 if (error_p)
22443 c_parser_error (parser, "loop nest expected");
22446 return false;
22449 static tree c_parser_omp_tile (location_t, c_parser *, bool *);
22450 static tree c_parser_omp_unroll (location_t, c_parser *, bool *);
22452 /* This function parses a single level of a loop nest, invoking itself
22453 recursively if necessary.
22455 loop-nest :: for (...) loop-body
22456 loop-body :: loop-nest
22457 | { [intervening-code] loop-body [intervening-code] }
22458 | final-loop-body
22459 intervening-code :: structured-block-sequence
22460 final-loop-body :: structured-block
22462 For a collapsed loop nest, only a single OMP_FOR is built, pulling out
22463 all the iterator information from the inner loops into the
22464 parser->omp_for_parse_state structure.
22466 The iterator decl, init, cond, and incr are stored in vectors.
22468 Initialization code for iterator variables is collected into
22469 parser->omp_for_parse_state->pre_body and ends up inserted directly
22470 into the OMP_FOR structure. */
22472 static tree
22473 c_parser_omp_loop_nest (c_parser *parser, bool *if_p)
22475 tree decl = NULL_TREE, cond = NULL_TREE, incr = NULL_TREE, init = NULL_TREE;
22476 tree body = NULL_TREE;
22477 matching_parens parens;
22478 bool moreloops;
22479 unsigned char save_in_statement;
22480 tree loop_scope;
22481 location_t loc;
22482 struct omp_for_parse_data *omp_for_parse_state
22483 = parser->omp_for_parse_state;
22484 gcc_assert (omp_for_parse_state);
22485 int depth = omp_for_parse_state->depth;
22487 /* Arrange for C23 standard attribute syntax to be parsed as regular
22488 pragmas. */
22489 if (c_parser_nth_token_starts_std_attributes (parser, 1))
22491 tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
22492 c_parser_handle_statement_omp_attributes (parser, std_attrs, NULL);
22493 if (std_attrs)
22494 error_at (c_parser_peek_token (parser)->location,
22495 "attributes other than OpenMP directives "
22496 "are not allowed on %<for%> in loop nest");
22499 loc = c_parser_peek_token (parser)->location;
22501 /* Handle loop transformations first. */
22502 if (c_parser_next_token_is (parser, CPP_PRAGMA))
22504 tree transform = NULL_TREE, sizes, body = NULL_TREE;
22505 int count = 0;
22506 switch (c_parser_peek_token (parser)->pragma_kind)
22508 case PRAGMA_OMP_UNROLL:
22509 c_parser_consume_pragma (parser);
22510 body = push_stmt_list ();
22511 transform = c_parser_omp_unroll (loc, parser, if_p);
22512 body = pop_stmt_list (body);
22513 if (transform == NULL_TREE || transform == error_mark_node)
22515 transform = error_mark_node;
22516 break;
22518 gcc_assert (TREE_CODE (transform) == OMP_UNROLL);
22519 if (omp_find_clause (OMP_FOR_CLAUSES (transform),
22520 OMP_CLAUSE_PARTIAL))
22522 if (omp_for_parse_state->count - depth > 1)
22524 error_at (loc, "%<unroll%> construct with %<partial%> "
22525 "clause generates just one loop with "
22526 "canonical form but %d loops are needed",
22527 omp_for_parse_state->count - depth);
22528 transform = error_mark_node;
22530 else
22531 count = 1;
22533 else
22535 error_at (loc, "generated loop of %<unroll%> construct "
22536 "without %<partial%> clause does not have "
22537 "canonical form");
22538 transform = error_mark_node;
22540 break;
22541 case PRAGMA_OMP_TILE:
22542 c_parser_consume_pragma (parser);
22543 body = push_stmt_list ();
22544 transform = c_parser_omp_tile (loc, parser, if_p);
22545 body = pop_stmt_list (body);
22546 if (transform == NULL_TREE || transform == error_mark_node)
22548 transform = error_mark_node;
22549 break;
22551 gcc_assert (TREE_CODE (transform) == OMP_TILE);
22552 sizes = omp_find_clause (OMP_FOR_CLAUSES (transform),
22553 OMP_CLAUSE_SIZES);
22554 gcc_assert (sizes);
22555 count = list_length (OMP_CLAUSE_SIZES_LIST (sizes));
22556 if (depth + count < omp_for_parse_state->count)
22558 error_at (loc, "%<tile%> construct generates %d loops "
22559 "with canonical form but %d loops are needed",
22560 count, omp_for_parse_state->count - depth);
22561 transform = error_mark_node;
22563 break;
22564 default:
22565 c_parser_pragma (parser, pragma_stmt, NULL);
22566 break;
22568 if (transform == NULL_TREE)
22569 error_at (loc, "expected %<for%> loop or OpenMP loop "
22570 "transformation construct");
22571 if (transform == NULL_TREE || transform == error_mark_node)
22573 omp_for_parse_state->fail = true;
22574 return NULL_TREE;
22576 for (count = omp_for_parse_state->count; depth < count; ++depth)
22578 TREE_VEC_ELT (omp_for_parse_state->declv, depth) = NULL_TREE;
22579 TREE_VEC_ELT (omp_for_parse_state->initv, depth) = NULL_TREE;
22580 TREE_VEC_ELT (omp_for_parse_state->condv, depth) = NULL_TREE;
22581 TREE_VEC_ELT (omp_for_parse_state->incrv, depth) = NULL_TREE;
22583 omp_for_parse_state->want_nested_loop = false;
22584 return body;
22587 /* We have already matched the FOR token but not consumed it yet. */
22588 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
22589 c_parser_consume_token (parser);
22591 /* Forbid break/continue in the loop initializer, condition, and
22592 increment expressions. */
22593 save_in_statement = in_statement;
22594 in_statement = IN_OMP_BLOCK;
22596 /* We are not in intervening code now. */
22597 omp_for_parse_state->in_intervening_code = false;
22599 if (!parens.require_open (parser))
22601 omp_for_parse_state->fail = true;
22602 return NULL_TREE;
22605 /* An implicit scope block surrounds each level of FOR loop, for
22606 declarations of iteration variables at this loop depth. */
22607 loop_scope = c_begin_compound_stmt (true);
22609 /* Parse the initialization declaration or expression. */
22610 if (c_parser_next_tokens_start_declaration (parser))
22612 /* This is a declaration, which must be added to the pre_body code. */
22613 tree this_pre_body = push_stmt_list ();
22614 c_in_omp_for = true;
22615 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
22616 c_in_omp_for = false;
22617 this_pre_body = pop_stmt_list (this_pre_body);
22618 append_to_statement_list_force (this_pre_body,
22619 &(omp_for_parse_state->pre_body));
22620 decl = check_for_loop_decls (omp_for_parse_state->for_loc, flag_isoc99);
22621 if (decl == NULL)
22622 goto error_init;
22623 if (DECL_INITIAL (decl) == error_mark_node)
22624 decl = error_mark_node;
22625 init = decl;
22627 else if (c_parser_next_token_is (parser, CPP_NAME)
22628 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
22630 struct c_expr decl_exp;
22631 struct c_expr init_exp;
22632 location_t init_loc;
22634 decl_exp = c_parser_postfix_expression (parser);
22635 decl = decl_exp.value;
22637 c_parser_require (parser, CPP_EQ, "expected %<=%>");
22639 init_loc = c_parser_peek_token (parser)->location;
22640 init_exp = c_parser_expr_no_commas (parser, NULL);
22641 init_exp = default_function_array_read_conversion (init_loc,
22642 init_exp);
22643 c_in_omp_for = true;
22644 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
22645 NOP_EXPR, init_loc, init_exp.value,
22646 init_exp.original_type);
22647 c_in_omp_for = false;
22648 init = c_process_expr_stmt (init_loc, init);
22650 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
22652 else
22654 error_init:
22655 c_parser_error (parser,
22656 "expected iteration declaration or initialization");
22657 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
22658 "expected %<)%>");
22659 omp_for_parse_state->fail = true;
22660 goto parse_next;
22663 /* Parse the loop condition. */
22664 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
22666 location_t cond_loc = c_parser_peek_token (parser)->location;
22667 c_in_omp_for = true;
22668 struct c_expr cond_expr
22669 = c_parser_binary_expression (parser, NULL, NULL_TREE);
22670 c_in_omp_for = false;
22672 cond = cond_expr.value;
22673 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
22674 switch (cond_expr.original_code)
22676 case GT_EXPR:
22677 case GE_EXPR:
22678 case LT_EXPR:
22679 case LE_EXPR:
22680 break;
22681 case NE_EXPR:
22682 if (omp_for_parse_state->code != OACC_LOOP)
22683 break;
22684 /* FALLTHRU. */
22685 default:
22686 /* Can't be cond = error_mark_node, because we want to preserve
22687 the location until c_finish_omp_for. */
22688 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
22689 break;
22691 protected_set_expr_location (cond, cond_loc);
22693 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
22695 /* Parse the increment expression. */
22696 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
22698 location_t incr_loc = c_parser_peek_token (parser)->location;
22700 incr = c_process_expr_stmt (incr_loc,
22701 c_parser_expression (parser).value);
22703 parens.skip_until_found_close (parser);
22705 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
22706 omp_for_parse_state->fail = true;
22707 else
22709 TREE_VEC_ELT (omp_for_parse_state->declv, depth) = decl;
22710 TREE_VEC_ELT (omp_for_parse_state->initv, depth) = init;
22711 TREE_VEC_ELT (omp_for_parse_state->condv, depth) = cond;
22712 TREE_VEC_ELT (omp_for_parse_state->incrv, depth) = incr;
22715 parse_next:
22716 moreloops = depth < omp_for_parse_state->count - 1;
22717 omp_for_parse_state->want_nested_loop = moreloops;
22718 if (moreloops
22719 && c_parser_omp_next_tokens_can_be_canon_loop (parser,
22720 omp_for_parse_state->code,
22721 false))
22723 omp_for_parse_state->depth++;
22724 body = c_parser_omp_loop_nest (parser, if_p);
22725 omp_for_parse_state->depth--;
22727 else if (moreloops && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
22729 /* This is the open brace in the loop-body grammar production. Rather
22730 than trying to special-case braces, just parse it as a compound
22731 statement and handle the nested loop-body case there. Note that
22732 when we see a further open brace inside the compound statement
22733 loop-body, we don't know whether it is the start of intervening
22734 code that is a compound statement, or a level of braces
22735 surrounding a nested loop-body. Use the WANT_NESTED_LOOP state
22736 bit to ensure we have only one nested loop at each level. */
22737 omp_for_parse_state->in_intervening_code = true;
22738 body = c_parser_compound_statement (parser, NULL);
22739 omp_for_parse_state->in_intervening_code = false;
22740 if (omp_for_parse_state->want_nested_loop)
22742 /* We have already parsed the whole loop body and not found a
22743 nested loop. */
22744 error_at (omp_for_parse_state->for_loc,
22745 "not enough nested loops");
22746 omp_for_parse_state->fail = true;
22748 if_p = NULL;
22750 else
22752 /* This is the final-loop-body case in the grammar: we have
22753 something that is not a FOR and not an open brace. */
22754 if (moreloops)
22756 /* If we were expecting a nested loop, give an error and mark
22757 that parsing has failed, and try to recover by parsing the
22758 body as regular code without further collapsing. */
22759 error_at (omp_for_parse_state->for_loc,
22760 "not enough nested loops");
22761 omp_for_parse_state->fail = true;
22763 in_statement = IN_OMP_FOR;
22764 parser->omp_for_parse_state = NULL;
22765 body = push_stmt_list ();
22766 if (omp_for_parse_state->inscan)
22767 c_parser_omp_scan_loop_body (parser, false);
22768 else
22769 add_stmt (c_parser_c99_block_statement (parser, if_p));
22770 body = pop_stmt_list (body);
22771 parser->omp_for_parse_state = omp_for_parse_state;
22773 in_statement = save_in_statement;
22774 omp_for_parse_state->want_nested_loop = false;
22775 omp_for_parse_state->in_intervening_code = true;
22777 /* Pop and return the implicit scope surrounding this level of loop.
22778 If the iteration variable at this depth was bound in the for loop,
22779 pull out and save the binding. Later in c_parser_omp_for_loop,
22780 these bindings will be moved to the scope surrounding the entire
22781 OMP_FOR. That keeps the gimplifier happy later on, and meanwhile
22782 we have already resolved all references to the iteration variable
22783 in its true scope. */
22784 if (body)
22785 add_stmt (body);
22786 body = c_end_compound_stmt (loc, loop_scope, true);
22787 if (decl && TREE_CODE (body) == BIND_EXPR)
22789 tree t = BIND_EXPR_VARS (body);
22790 tree prev = NULL_TREE, next = NULL_TREE;
22791 while (t)
22793 next = DECL_CHAIN (t);
22794 if (t == decl)
22796 if (prev)
22797 DECL_CHAIN (prev) = next;
22798 else
22800 BIND_EXPR_VARS (body) = next;
22801 BLOCK_VARS (BIND_EXPR_BLOCK (body)) = next;
22803 DECL_CHAIN (t) = omp_for_parse_state->bindings;
22804 omp_for_parse_state->bindings = t;
22805 break;
22807 else
22809 prev = t;
22810 t = next;
22813 if (BIND_EXPR_VARS (body) == NULL_TREE)
22814 body = BIND_EXPR_BODY (body);
22817 return body;
22820 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
22821 The real trick here is to determine the loop control variable early
22822 so that we can push a new decl if necessary to make it private.
22823 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
22824 respectively. */
22826 static tree
22827 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
22828 tree clauses, tree *cclauses, bool *if_p)
22830 tree body, stmt, cl;
22831 tree ret = NULL_TREE;
22832 tree ordered_cl = NULL_TREE;
22833 int i, collapse = 1, ordered = 0, count;
22834 bool oacc_tiling = false;
22835 bool inscan = false;
22836 struct omp_for_parse_data data;
22837 struct omp_for_parse_data *save_data = parser->omp_for_parse_state;
22839 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
22840 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
22841 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
22842 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
22844 oacc_tiling = true;
22845 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
22847 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_SIZES)
22848 collapse = list_length (OMP_CLAUSE_SIZES_LIST (cl));
22849 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
22850 && OMP_CLAUSE_ORDERED_EXPR (cl))
22852 ordered_cl = cl;
22853 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
22855 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
22856 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
22857 && (code == OMP_SIMD || code == OMP_FOR))
22858 inscan = true;
22860 if (ordered && ordered < collapse)
22862 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
22863 "%<ordered%> clause parameter is less than %<collapse%>");
22864 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
22865 = build_int_cst (NULL_TREE, collapse);
22866 ordered = collapse;
22869 gcc_assert (oacc_tiling || (collapse >= 1 && ordered >= 0));
22870 count = ordered ? ordered : collapse;
22872 if (!c_parser_omp_next_tokens_can_be_canon_loop (parser, code, true))
22873 return NULL;
22875 /* Initialize parse state for recursive descent. */
22876 data.declv = make_tree_vec (count);
22877 data.initv = make_tree_vec (count);
22878 data.condv = make_tree_vec (count);
22879 data.incrv = make_tree_vec (count);
22880 data.pre_body = NULL_TREE;
22881 data.bindings = NULL_TREE;
22882 data.for_loc = c_parser_peek_token (parser)->location;
22883 data.count = count;
22884 data.depth = 0;
22885 data.want_nested_loop = true;
22886 data.ordered = ordered > 0;
22887 data.in_intervening_code = false;
22888 data.perfect_nesting_fail = false;
22889 data.fail = false;
22890 data.inscan = inscan;
22891 data.saw_intervening_code = false;
22892 data.code = code;
22893 parser->omp_for_parse_state = &data;
22895 body = c_parser_omp_loop_nest (parser, if_p);
22897 /* Add saved bindings for iteration variables that were declared in
22898 the nested for loop to the scope surrounding the entire loop. */
22899 for (tree t = data.bindings; t; )
22901 tree n = TREE_CHAIN (t);
22902 TREE_CHAIN (t) = NULL_TREE;
22903 pushdecl (t);
22904 t = n;
22907 /* Only bother calling c_finish_omp_for if we haven't already generated
22908 an error from the initialization parsing. */
22909 if (!data.fail)
22911 c_in_omp_for = true;
22912 stmt = c_finish_omp_for (loc, code, data.declv, NULL, data.initv,
22913 data.condv, data.incrv,
22914 body, data.pre_body, true);
22915 c_in_omp_for = false;
22917 /* Check for iterators appearing in lb, b or incr expressions. */
22918 if (stmt && !c_omp_check_loop_iv (stmt, data.declv, NULL))
22919 stmt = NULL_TREE;
22921 /* Check for errors involving lb/ub/incr expressions referencing
22922 variables declared in intervening code. */
22923 if (data.saw_intervening_code
22924 && stmt
22925 && !c_omp_check_loop_binding_exprs (stmt, NULL))
22926 stmt = NULL_TREE;
22928 if (stmt)
22930 add_stmt (stmt);
22932 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
22934 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
22935 if (init == NULL_TREE)
22936 break;
22937 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
22938 tree decl = TREE_OPERAND (init, 0);
22939 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
22940 gcc_assert (COMPARISON_CLASS_P (cond));
22941 gcc_assert (TREE_OPERAND (cond, 0) == decl);
22943 tree op0 = TREE_OPERAND (init, 1);
22944 if (!OMP_FOR_NON_RECTANGULAR (stmt)
22945 || TREE_CODE (op0) != TREE_VEC)
22946 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
22947 else
22949 TREE_VEC_ELT (op0, 1)
22950 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
22951 TREE_VEC_ELT (op0, 2)
22952 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
22955 tree op1 = TREE_OPERAND (cond, 1);
22956 if (!OMP_FOR_NON_RECTANGULAR (stmt)
22957 || TREE_CODE (op1) != TREE_VEC)
22958 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
22959 else
22961 TREE_VEC_ELT (op1, 1)
22962 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
22963 TREE_VEC_ELT (op1, 2)
22964 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
22968 if (cclauses != NULL
22969 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
22971 tree *c;
22972 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
22973 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
22974 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
22975 c = &OMP_CLAUSE_CHAIN (*c);
22976 else
22978 for (i = 0; i < count; i++)
22979 if (TREE_VEC_ELT (data.declv, i) == OMP_CLAUSE_DECL (*c))
22980 break;
22981 if (i == count)
22982 c = &OMP_CLAUSE_CHAIN (*c);
22983 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
22985 error_at (loc,
22986 "iteration variable %qD should not be firstprivate",
22987 OMP_CLAUSE_DECL (*c));
22988 *c = OMP_CLAUSE_CHAIN (*c);
22990 else
22992 /* Move lastprivate (decl) clause to
22993 OMP_FOR_CLAUSES. */
22994 tree l = *c;
22995 *c = OMP_CLAUSE_CHAIN (*c);
22996 if (code == OMP_SIMD)
22998 OMP_CLAUSE_CHAIN (l)
22999 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
23000 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
23002 else
23004 OMP_CLAUSE_CHAIN (l) = clauses;
23005 clauses = l;
23010 OMP_FOR_CLAUSES (stmt) = clauses;
23012 ret = stmt;
23015 parser->omp_for_parse_state = save_data;
23016 return ret;
23019 /* Helper function for OpenMP parsing, split clauses and call
23020 finish_omp_clauses on each of the set of clauses afterwards. */
23022 static void
23023 omp_split_clauses (location_t loc, enum tree_code code,
23024 omp_clause_mask mask, tree clauses, tree *cclauses)
23026 int i;
23027 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
23028 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
23029 if (cclauses[i])
23030 cclauses[i] = c_finish_omp_clauses (cclauses[i],
23031 i == C_OMP_CLAUSE_SPLIT_TARGET
23032 ? C_ORT_OMP_TARGET : C_ORT_OMP);
23035 /* OpenMP 5.0:
23036 #pragma omp loop loop-clause[optseq] new-line
23037 for-loop
23039 LOC is the location of the #pragma token.
23042 #define OMP_LOOP_CLAUSE_MASK \
23043 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23044 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23047 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
23048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23050 static tree
23051 c_parser_omp_loop (location_t loc, c_parser *parser,
23052 char *p_name, omp_clause_mask mask, tree *cclauses,
23053 bool *if_p)
23055 tree block, clauses, ret;
23057 strcat (p_name, " loop");
23058 mask |= OMP_LOOP_CLAUSE_MASK;
23060 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23061 if (cclauses)
23063 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
23064 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
23067 block = c_begin_compound_stmt (true);
23068 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
23069 block = c_end_compound_stmt (loc, block, true);
23070 add_stmt (block);
23072 return ret;
23075 /* OpenMP 4.0:
23076 #pragma omp simd simd-clause[optseq] new-line
23077 for-loop
23079 LOC is the location of the #pragma token.
23082 #define OMP_SIMD_CLAUSE_MASK \
23083 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
23084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
23085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
23086 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
23087 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23088 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23089 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23090 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
23093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23095 static tree
23096 c_parser_omp_simd (location_t loc, c_parser *parser,
23097 char *p_name, omp_clause_mask mask, tree *cclauses,
23098 bool *if_p)
23100 tree block, clauses, ret;
23102 strcat (p_name, " simd");
23103 mask |= OMP_SIMD_CLAUSE_MASK;
23105 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23106 if (cclauses)
23108 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
23109 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
23112 block = c_begin_compound_stmt (true);
23113 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
23114 block = c_end_compound_stmt (loc, block, true);
23115 add_stmt (block);
23117 return ret;
23120 /* OpenMP 2.5:
23121 #pragma omp for for-clause[optseq] new-line
23122 for-loop
23124 OpenMP 4.0:
23125 #pragma omp for simd for-simd-clause[optseq] new-line
23126 for-loop
23128 LOC is the location of the #pragma token.
23131 #define OMP_FOR_CLAUSE_MASK \
23132 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
23136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23137 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
23138 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
23139 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23140 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
23141 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23142 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23144 static tree
23145 c_parser_omp_for (location_t loc, c_parser *parser,
23146 char *p_name, omp_clause_mask mask, tree *cclauses,
23147 bool *if_p)
23149 tree block, clauses, ret;
23151 strcat (p_name, " for");
23152 mask |= OMP_FOR_CLAUSE_MASK;
23153 /* parallel for{, simd} disallows nowait clause, but for
23154 target {teams distribute ,}parallel for{, simd} it should be accepted. */
23155 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
23156 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
23157 /* Composite distribute parallel for{, simd} disallows ordered clause. */
23158 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
23159 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
23161 if (c_parser_next_token_is (parser, CPP_NAME))
23163 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23165 if (strcmp (p, "simd") == 0)
23167 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23168 if (cclauses == NULL)
23169 cclauses = cclauses_buf;
23171 c_parser_consume_token (parser);
23172 if (!flag_openmp) /* flag_openmp_simd */
23173 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23174 if_p);
23175 block = c_begin_compound_stmt (true);
23176 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
23177 block = c_end_compound_stmt (loc, block, true);
23178 if (ret == NULL_TREE)
23179 return ret;
23180 ret = make_node (OMP_FOR);
23181 TREE_TYPE (ret) = void_type_node;
23182 OMP_FOR_BODY (ret) = block;
23183 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
23184 SET_EXPR_LOCATION (ret, loc);
23185 add_stmt (ret);
23186 return ret;
23189 if (!flag_openmp) /* flag_openmp_simd */
23191 c_parser_skip_to_pragma_eol (parser, false);
23192 return NULL_TREE;
23195 /* Composite distribute parallel for disallows linear clause. */
23196 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
23197 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
23199 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23200 if (cclauses)
23202 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
23203 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
23206 block = c_begin_compound_stmt (true);
23207 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
23208 block = c_end_compound_stmt (loc, block, true);
23209 add_stmt (block);
23211 return ret;
23214 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
23215 omp_clause_mask, tree *, bool *);
23217 /* OpenMP 2.5:
23218 # pragma omp master new-line
23219 structured-block
23221 LOC is the location of the #pragma token.
23224 static tree
23225 c_parser_omp_master (location_t loc, c_parser *parser,
23226 char *p_name, omp_clause_mask mask, tree *cclauses,
23227 bool *if_p)
23229 tree block, clauses, ret;
23231 strcat (p_name, " master");
23233 if (c_parser_next_token_is (parser, CPP_NAME))
23235 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23237 if (strcmp (p, "taskloop") == 0)
23239 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23240 if (cclauses == NULL)
23241 cclauses = cclauses_buf;
23243 c_parser_consume_token (parser);
23244 if (!flag_openmp) /* flag_openmp_simd */
23245 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
23246 if_p);
23247 block = c_begin_compound_stmt (true);
23248 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
23249 if_p);
23250 block = c_end_compound_stmt (loc, block, true);
23251 if (ret == NULL_TREE)
23252 return ret;
23253 ret = c_finish_omp_master (loc, block);
23254 OMP_MASTER_COMBINED (ret) = 1;
23255 return ret;
23258 if (!flag_openmp) /* flag_openmp_simd */
23260 c_parser_skip_to_pragma_eol (parser, false);
23261 return NULL_TREE;
23264 if (cclauses)
23266 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
23267 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
23269 else
23270 c_parser_skip_to_pragma_eol (parser);
23272 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
23273 if_p));
23276 /* OpenMP 5.1:
23277 # pragma omp masked masked-clauses new-line
23278 structured-block
23280 LOC is the location of the #pragma token.
23283 #define OMP_MASKED_CLAUSE_MASK \
23284 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
23286 static tree
23287 c_parser_omp_masked (location_t loc, c_parser *parser,
23288 char *p_name, omp_clause_mask mask, tree *cclauses,
23289 bool *if_p)
23291 tree block, clauses, ret;
23293 strcat (p_name, " masked");
23294 mask |= OMP_MASKED_CLAUSE_MASK;
23296 if (c_parser_next_token_is (parser, CPP_NAME))
23298 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23300 if (strcmp (p, "taskloop") == 0)
23302 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23303 if (cclauses == NULL)
23304 cclauses = cclauses_buf;
23306 c_parser_consume_token (parser);
23307 if (!flag_openmp) /* flag_openmp_simd */
23308 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
23309 if_p);
23310 block = c_begin_compound_stmt (true);
23311 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
23312 if_p);
23313 block = c_end_compound_stmt (loc, block, true);
23314 if (ret == NULL_TREE)
23315 return ret;
23316 ret = c_finish_omp_masked (loc, block,
23317 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
23318 OMP_MASKED_COMBINED (ret) = 1;
23319 return ret;
23322 if (!flag_openmp) /* flag_openmp_simd */
23324 c_parser_skip_to_pragma_eol (parser, false);
23325 return NULL_TREE;
23328 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23329 if (cclauses)
23331 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
23332 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
23335 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
23336 if_p),
23337 clauses);
23340 /* OpenMP 2.5:
23341 # pragma omp ordered new-line
23342 structured-block
23344 OpenMP 4.5:
23345 # pragma omp ordered ordered-clauses new-line
23346 structured-block
23348 # pragma omp ordered depend-clauses new-line
23350 OpenMP 5.2
23351 # pragma omp ordered doacross-clauses new-line */
23353 #define OMP_ORDERED_CLAUSE_MASK \
23354 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
23355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
23357 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
23358 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
23361 static bool
23362 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
23363 bool *if_p)
23365 location_t loc = c_parser_peek_token (parser)->location;
23366 c_parser_consume_pragma (parser);
23368 if (context != pragma_stmt && context != pragma_compound)
23370 c_parser_error (parser, "expected declaration specifiers");
23371 c_parser_skip_to_pragma_eol (parser, false);
23372 return false;
23375 int n = 1;
23376 if (c_parser_next_token_is (parser, CPP_COMMA))
23377 n = 2;
23379 if (c_parser_peek_nth_token (parser, n)->type == CPP_NAME)
23381 const char *p
23382 = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser, n)->value);
23384 if (!strcmp ("depend", p) || !strcmp ("doacross", p))
23386 if (!flag_openmp) /* flag_openmp_simd */
23388 c_parser_skip_to_pragma_eol (parser, false);
23389 return false;
23391 if (context == pragma_stmt)
23393 error_at (loc,
23394 "%<#pragma omp ordered%> with %qs clause may "
23395 "only be used in compound statements", p);
23396 c_parser_skip_to_pragma_eol (parser, false);
23397 return true;
23400 tree clauses
23401 = c_parser_omp_all_clauses (parser,
23402 OMP_ORDERED_DEPEND_CLAUSE_MASK,
23403 "#pragma omp ordered");
23404 c_finish_omp_ordered (loc, clauses, NULL_TREE);
23405 return false;
23409 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
23410 "#pragma omp ordered");
23412 if (!flag_openmp /* flag_openmp_simd */
23413 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
23414 return false;
23416 c_finish_omp_ordered (loc, clauses,
23417 c_parser_omp_structured_block (parser, if_p));
23418 return true;
23421 /* OpenMP 2.5:
23423 section-scope:
23424 { section-sequence }
23426 section-sequence:
23427 section-directive[opt] structured-block
23428 section-sequence section-directive structured-block
23430 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
23432 SECTIONS_LOC is the location of the #pragma omp sections. */
23434 static tree
23435 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
23437 tree stmt, substmt;
23438 bool error_suppress = false;
23439 location_t loc;
23441 loc = c_parser_peek_token (parser)->location;
23442 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23444 /* Avoid skipping until the end of the block. */
23445 parser->error = false;
23446 return NULL_TREE;
23449 stmt = push_stmt_list ();
23451 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION
23452 && !c_parser_omp_section_scan (parser, "section", true))
23454 substmt = c_parser_omp_structured_block_sequence (parser,
23455 PRAGMA_OMP_SECTION);
23456 substmt = build1 (OMP_SECTION, void_type_node, substmt);
23457 SET_EXPR_LOCATION (substmt, loc);
23458 add_stmt (substmt);
23461 while (1)
23463 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
23464 break;
23465 if (c_parser_next_token_is (parser, CPP_EOF))
23466 break;
23468 loc = c_parser_peek_token (parser)->location;
23469 c_parser_omp_section_scan (parser, "section", false);
23470 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
23472 c_parser_consume_pragma (parser);
23473 c_parser_skip_to_pragma_eol (parser);
23474 error_suppress = false;
23476 else if (!error_suppress)
23478 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
23479 error_suppress = true;
23482 substmt = c_parser_omp_structured_block_sequence (parser,
23483 PRAGMA_OMP_SECTION);
23484 substmt = build1 (OMP_SECTION, void_type_node, substmt);
23485 SET_EXPR_LOCATION (substmt, loc);
23486 add_stmt (substmt);
23488 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
23489 "expected %<#pragma omp section%> or %<}%>");
23491 substmt = pop_stmt_list (stmt);
23493 stmt = make_node (OMP_SECTIONS);
23494 SET_EXPR_LOCATION (stmt, sections_loc);
23495 TREE_TYPE (stmt) = void_type_node;
23496 OMP_SECTIONS_BODY (stmt) = substmt;
23498 return add_stmt (stmt);
23501 /* OpenMP 2.5:
23502 # pragma omp sections sections-clause[optseq] newline
23503 sections-scope
23505 LOC is the location of the #pragma token.
23508 #define OMP_SECTIONS_CLAUSE_MASK \
23509 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23514 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23516 static tree
23517 c_parser_omp_sections (location_t loc, c_parser *parser,
23518 char *p_name, omp_clause_mask mask, tree *cclauses)
23520 tree block, clauses, ret;
23522 strcat (p_name, " sections");
23523 mask |= OMP_SECTIONS_CLAUSE_MASK;
23524 if (cclauses)
23525 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
23527 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23528 if (cclauses)
23530 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
23531 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
23534 block = c_begin_compound_stmt (true);
23535 ret = c_parser_omp_sections_scope (loc, parser);
23536 if (ret)
23537 OMP_SECTIONS_CLAUSES (ret) = clauses;
23538 block = c_end_compound_stmt (loc, block, true);
23539 add_stmt (block);
23541 return ret;
23544 /* OpenMP 2.5:
23545 # pragma omp parallel parallel-clause[optseq] new-line
23546 structured-block
23547 # pragma omp parallel for parallel-for-clause[optseq] new-line
23548 structured-block
23549 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
23550 structured-block
23552 OpenMP 4.0:
23553 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
23554 structured-block
23556 LOC is the location of the #pragma token.
23559 #define OMP_PARALLEL_CLAUSE_MASK \
23560 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23561 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23562 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23563 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
23566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23567 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
23568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
23571 static tree
23572 c_parser_omp_parallel (location_t loc, c_parser *parser,
23573 char *p_name, omp_clause_mask mask, tree *cclauses,
23574 bool *if_p)
23576 tree stmt, clauses, block;
23578 strcat (p_name, " parallel");
23579 mask |= OMP_PARALLEL_CLAUSE_MASK;
23580 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
23581 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
23582 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
23583 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
23585 if (c_parser_next_token_is_keyword (parser, RID_FOR))
23587 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23588 if (cclauses == NULL)
23589 cclauses = cclauses_buf;
23591 c_parser_consume_token (parser);
23592 if (!flag_openmp) /* flag_openmp_simd */
23593 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
23594 block = c_begin_omp_parallel ();
23595 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
23596 stmt
23597 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23598 block);
23599 if (ret == NULL_TREE)
23600 return ret;
23601 OMP_PARALLEL_COMBINED (stmt) = 1;
23602 return stmt;
23604 /* When combined with distribute, parallel has to be followed by for.
23605 #pragma omp target parallel is allowed though. */
23606 else if (cclauses
23607 && (mask & (OMP_CLAUSE_MASK_1
23608 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
23610 error_at (loc, "expected %<for%> after %qs", p_name);
23611 c_parser_skip_to_pragma_eol (parser);
23612 return NULL_TREE;
23614 else if (c_parser_next_token_is (parser, CPP_NAME))
23616 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23617 if (cclauses == NULL && strcmp (p, "masked") == 0)
23619 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23620 cclauses = cclauses_buf;
23622 c_parser_consume_token (parser);
23623 if (!flag_openmp) /* flag_openmp_simd */
23624 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
23625 if_p);
23626 block = c_begin_omp_parallel ();
23627 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
23628 if_p);
23629 stmt = c_finish_omp_parallel (loc,
23630 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23631 block);
23632 if (ret == NULL)
23633 return ret;
23634 /* masked does have just filter clause, but during gimplification
23635 isn't represented by a gimplification omp context, so for
23636 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
23637 so that
23638 #pragma omp parallel masked
23639 #pragma omp taskloop simd lastprivate (x)
23640 isn't confused with
23641 #pragma omp parallel masked taskloop simd lastprivate (x) */
23642 if (OMP_MASKED_COMBINED (ret))
23643 OMP_PARALLEL_COMBINED (stmt) = 1;
23644 return stmt;
23646 else if (cclauses == NULL && strcmp (p, "master") == 0)
23648 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23649 cclauses = cclauses_buf;
23651 c_parser_consume_token (parser);
23652 if (!flag_openmp) /* flag_openmp_simd */
23653 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
23654 if_p);
23655 block = c_begin_omp_parallel ();
23656 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
23657 if_p);
23658 stmt = c_finish_omp_parallel (loc,
23659 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23660 block);
23661 if (ret == NULL)
23662 return ret;
23663 /* master doesn't have any clauses and during gimplification
23664 isn't represented by a gimplification omp context, so for
23665 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
23666 so that
23667 #pragma omp parallel master
23668 #pragma omp taskloop simd lastprivate (x)
23669 isn't confused with
23670 #pragma omp parallel master taskloop simd lastprivate (x) */
23671 if (OMP_MASTER_COMBINED (ret))
23672 OMP_PARALLEL_COMBINED (stmt) = 1;
23673 return stmt;
23675 else if (strcmp (p, "loop") == 0)
23677 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23678 if (cclauses == NULL)
23679 cclauses = cclauses_buf;
23681 c_parser_consume_token (parser);
23682 if (!flag_openmp) /* flag_openmp_simd */
23683 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23684 if_p);
23685 block = c_begin_omp_parallel ();
23686 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
23687 if_p);
23688 stmt
23689 = c_finish_omp_parallel (loc,
23690 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23691 block);
23692 if (ret == NULL_TREE)
23693 return ret;
23694 OMP_PARALLEL_COMBINED (stmt) = 1;
23695 return stmt;
23697 else if (!flag_openmp) /* flag_openmp_simd */
23699 c_parser_skip_to_pragma_eol (parser, false);
23700 return NULL_TREE;
23702 else if (cclauses == NULL && strcmp (p, "sections") == 0)
23704 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23705 cclauses = cclauses_buf;
23707 c_parser_consume_token (parser);
23708 block = c_begin_omp_parallel ();
23709 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
23710 stmt = c_finish_omp_parallel (loc,
23711 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
23712 block);
23713 OMP_PARALLEL_COMBINED (stmt) = 1;
23714 return stmt;
23717 else if (!flag_openmp) /* flag_openmp_simd */
23719 c_parser_skip_to_pragma_eol (parser, false);
23720 return NULL_TREE;
23723 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23724 if (cclauses)
23726 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
23727 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
23730 block = c_begin_omp_parallel ();
23731 parser->omp_attrs_forbidden_p = true;
23732 c_parser_statement (parser, if_p);
23733 stmt = c_finish_omp_parallel (loc, clauses, block);
23735 return stmt;
23738 /* OpenMP 2.5:
23739 # pragma omp single single-clause[optseq] new-line
23740 structured-block
23742 LOC is the location of the #pragma.
23745 #define OMP_SINGLE_CLAUSE_MASK \
23746 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
23749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23752 static tree
23753 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
23755 tree stmt = make_node (OMP_SINGLE);
23756 SET_EXPR_LOCATION (stmt, loc);
23757 TREE_TYPE (stmt) = void_type_node;
23759 OMP_SINGLE_CLAUSES (stmt)
23760 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
23761 "#pragma omp single");
23762 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
23764 return add_stmt (stmt);
23767 /* OpenMP 5.1:
23768 # pragma omp scope scope-clause[optseq] new-line
23769 structured-block
23771 LOC is the location of the #pragma.
23774 #define OMP_SCOPE_CLAUSE_MASK \
23775 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23776 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23777 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23778 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23779 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23781 static tree
23782 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
23784 tree stmt = make_node (OMP_SCOPE);
23785 SET_EXPR_LOCATION (stmt, loc);
23786 TREE_TYPE (stmt) = void_type_node;
23788 OMP_SCOPE_CLAUSES (stmt)
23789 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
23790 "#pragma omp scope");
23791 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
23793 return add_stmt (stmt);
23796 /* OpenMP 3.0:
23797 # pragma omp task task-clause[optseq] new-line
23799 LOC is the location of the #pragma.
23802 #define OMP_TASK_CLAUSE_MASK \
23803 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
23815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
23816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
23818 static tree
23819 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
23821 tree clauses, block;
23823 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
23824 "#pragma omp task");
23826 block = c_begin_omp_task ();
23827 parser->omp_attrs_forbidden_p = true;
23828 c_parser_statement (parser, if_p);
23829 return c_finish_omp_task (loc, clauses, block);
23832 /* OpenMP 3.0:
23833 # pragma omp taskwait new-line
23835 OpenMP 5.0:
23836 # pragma omp taskwait taskwait-clause[optseq] new-line
23839 #define OMP_TASKWAIT_CLAUSE_MASK \
23840 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23843 static void
23844 c_parser_omp_taskwait (c_parser *parser)
23846 location_t loc = c_parser_peek_token (parser)->location;
23847 c_parser_consume_pragma (parser);
23849 tree clauses
23850 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
23851 "#pragma omp taskwait");
23853 if (clauses)
23855 tree stmt = make_node (OMP_TASK);
23856 TREE_TYPE (stmt) = void_node;
23857 OMP_TASK_CLAUSES (stmt) = clauses;
23858 OMP_TASK_BODY (stmt) = NULL_TREE;
23859 SET_EXPR_LOCATION (stmt, loc);
23860 add_stmt (stmt);
23862 else
23863 c_finish_omp_taskwait (loc);
23866 /* OpenMP 3.1:
23867 # pragma omp taskyield new-line
23870 static void
23871 c_parser_omp_taskyield (c_parser *parser)
23873 location_t loc = c_parser_peek_token (parser)->location;
23874 c_parser_consume_pragma (parser);
23875 c_parser_skip_to_pragma_eol (parser);
23877 c_finish_omp_taskyield (loc);
23880 /* OpenMP 4.0:
23881 # pragma omp taskgroup new-line
23883 OpenMP 5.0:
23884 # pragma omp taskgroup taskgroup-clause[optseq] new-line
23887 #define OMP_TASKGROUP_CLAUSE_MASK \
23888 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
23891 static tree
23892 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
23894 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
23895 "#pragma omp taskgroup");
23897 tree body = c_parser_omp_structured_block (parser, if_p);
23898 return c_finish_omp_taskgroup (loc, body, clauses);
23901 /* OpenMP 4.0:
23902 # pragma omp cancel cancel-clause[optseq] new-line
23904 LOC is the location of the #pragma.
23907 #define OMP_CANCEL_CLAUSE_MASK \
23908 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
23912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
23914 static void
23915 c_parser_omp_cancel (c_parser *parser)
23917 location_t loc = c_parser_peek_token (parser)->location;
23919 c_parser_consume_pragma (parser);
23920 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
23921 "#pragma omp cancel");
23923 c_finish_omp_cancel (loc, clauses);
23926 /* OpenMP 4.0:
23927 # pragma omp cancellation point cancelpt-clause[optseq] new-line
23929 LOC is the location of the #pragma.
23932 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
23933 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23936 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
23938 static bool
23939 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
23941 location_t loc = c_parser_peek_token (parser)->location;
23942 tree clauses;
23943 bool point_seen = false;
23945 c_parser_consume_pragma (parser);
23946 if (c_parser_next_token_is (parser, CPP_NAME))
23948 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23949 if (strcmp (p, "point") == 0)
23951 c_parser_consume_token (parser);
23952 point_seen = true;
23955 if (!point_seen)
23957 c_parser_error (parser, "expected %<point%>");
23958 c_parser_skip_to_pragma_eol (parser);
23959 return false;
23962 if (context != pragma_compound)
23964 if (context == pragma_stmt)
23965 error_at (loc,
23966 "%<#pragma %s%> may only be used in compound statements",
23967 "omp cancellation point");
23968 else
23969 c_parser_error (parser, "expected declaration specifiers");
23970 c_parser_skip_to_pragma_eol (parser, false);
23971 return true;
23974 clauses
23975 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
23976 "#pragma omp cancellation point");
23978 c_finish_omp_cancellation_point (loc, clauses);
23979 return true;
23982 /* OpenMP 4.0:
23983 #pragma omp distribute distribute-clause[optseq] new-line
23984 for-loop */
23986 #define OMP_DISTRIBUTE_CLAUSE_MASK \
23987 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
23991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23993 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23995 static tree
23996 c_parser_omp_distribute (location_t loc, c_parser *parser,
23997 char *p_name, omp_clause_mask mask, tree *cclauses,
23998 bool *if_p)
24000 tree clauses, block, ret;
24002 strcat (p_name, " distribute");
24003 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
24005 if (c_parser_next_token_is (parser, CPP_NAME))
24007 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24008 bool simd = false;
24009 bool parallel = false;
24011 if (strcmp (p, "simd") == 0)
24012 simd = true;
24013 else
24014 parallel = strcmp (p, "parallel") == 0;
24015 if (parallel || simd)
24017 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
24018 if (cclauses == NULL)
24019 cclauses = cclauses_buf;
24020 c_parser_consume_token (parser);
24021 if (!flag_openmp) /* flag_openmp_simd */
24023 if (simd)
24024 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
24025 if_p);
24026 else
24027 return c_parser_omp_parallel (loc, parser, p_name, mask,
24028 cclauses, if_p);
24030 block = c_begin_compound_stmt (true);
24031 if (simd)
24032 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
24033 if_p);
24034 else
24035 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
24036 if_p);
24037 block = c_end_compound_stmt (loc, block, true);
24038 if (ret == NULL)
24039 return ret;
24040 ret = make_node (OMP_DISTRIBUTE);
24041 TREE_TYPE (ret) = void_type_node;
24042 OMP_FOR_BODY (ret) = block;
24043 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
24044 SET_EXPR_LOCATION (ret, loc);
24045 add_stmt (ret);
24046 return ret;
24049 if (!flag_openmp) /* flag_openmp_simd */
24051 c_parser_skip_to_pragma_eol (parser, false);
24052 return NULL_TREE;
24055 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
24056 if (cclauses)
24058 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
24059 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
24062 block = c_begin_compound_stmt (true);
24063 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
24064 if_p);
24065 block = c_end_compound_stmt (loc, block, true);
24066 add_stmt (block);
24068 return ret;
24071 /* OpenMP 4.0:
24072 # pragma omp teams teams-clause[optseq] new-line
24073 structured-block */
24075 #define OMP_TEAMS_CLAUSE_MASK \
24076 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
24077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
24078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
24079 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
24080 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
24081 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
24082 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
24083 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
24085 static tree
24086 c_parser_omp_teams (location_t loc, c_parser *parser,
24087 char *p_name, omp_clause_mask mask, tree *cclauses,
24088 bool *if_p)
24090 tree clauses, block, ret;
24092 strcat (p_name, " teams");
24093 mask |= OMP_TEAMS_CLAUSE_MASK;
24095 if (c_parser_next_token_is (parser, CPP_NAME))
24097 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24098 if (strcmp (p, "distribute") == 0)
24100 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
24101 if (cclauses == NULL)
24102 cclauses = cclauses_buf;
24104 c_parser_consume_token (parser);
24105 if (!flag_openmp) /* flag_openmp_simd */
24106 return c_parser_omp_distribute (loc, parser, p_name, mask,
24107 cclauses, if_p);
24108 block = c_begin_omp_parallel ();
24109 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
24110 if_p);
24111 block = c_end_compound_stmt (loc, block, true);
24112 if (ret == NULL)
24113 return ret;
24114 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
24115 ret = make_node (OMP_TEAMS);
24116 TREE_TYPE (ret) = void_type_node;
24117 OMP_TEAMS_CLAUSES (ret) = clauses;
24118 OMP_TEAMS_BODY (ret) = block;
24119 OMP_TEAMS_COMBINED (ret) = 1;
24120 SET_EXPR_LOCATION (ret, loc);
24121 return add_stmt (ret);
24123 else if (strcmp (p, "loop") == 0)
24125 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
24126 if (cclauses == NULL)
24127 cclauses = cclauses_buf;
24129 c_parser_consume_token (parser);
24130 if (!flag_openmp) /* flag_openmp_simd */
24131 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
24132 if_p);
24133 block = c_begin_omp_parallel ();
24134 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
24135 block = c_end_compound_stmt (loc, block, true);
24136 if (ret == NULL)
24137 return ret;
24138 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
24139 ret = make_node (OMP_TEAMS);
24140 TREE_TYPE (ret) = void_type_node;
24141 OMP_TEAMS_CLAUSES (ret) = clauses;
24142 OMP_TEAMS_BODY (ret) = block;
24143 OMP_TEAMS_COMBINED (ret) = 1;
24144 SET_EXPR_LOCATION (ret, loc);
24145 return add_stmt (ret);
24148 if (!flag_openmp) /* flag_openmp_simd */
24150 c_parser_skip_to_pragma_eol (parser, false);
24151 return NULL_TREE;
24154 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
24155 if (cclauses)
24157 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
24158 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
24161 tree stmt = make_node (OMP_TEAMS);
24162 TREE_TYPE (stmt) = void_type_node;
24163 OMP_TEAMS_CLAUSES (stmt) = clauses;
24164 block = c_begin_omp_parallel ();
24165 add_stmt (c_parser_omp_structured_block (parser, if_p));
24166 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
24167 SET_EXPR_LOCATION (stmt, loc);
24169 return add_stmt (stmt);
24172 /* OpenMP 4.0:
24173 # pragma omp target data target-data-clause[optseq] new-line
24174 structured-block */
24176 #define OMP_TARGET_DATA_CLAUSE_MASK \
24177 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24180 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
24181 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
24183 static tree
24184 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
24186 if (flag_openmp)
24187 omp_requires_mask
24188 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24190 tree clauses
24191 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
24192 "#pragma omp target data");
24193 c_omp_adjust_map_clauses (clauses, false);
24194 int map_seen = 0;
24195 for (tree *pc = &clauses; *pc;)
24197 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24198 switch (OMP_CLAUSE_MAP_KIND (*pc))
24200 case GOMP_MAP_TO:
24201 case GOMP_MAP_ALWAYS_TO:
24202 case GOMP_MAP_PRESENT_TO:
24203 case GOMP_MAP_ALWAYS_PRESENT_TO:
24204 case GOMP_MAP_FROM:
24205 case GOMP_MAP_ALWAYS_FROM:
24206 case GOMP_MAP_PRESENT_FROM:
24207 case GOMP_MAP_ALWAYS_PRESENT_FROM:
24208 case GOMP_MAP_TOFROM:
24209 case GOMP_MAP_ALWAYS_TOFROM:
24210 case GOMP_MAP_PRESENT_TOFROM:
24211 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24212 case GOMP_MAP_ALLOC:
24213 case GOMP_MAP_PRESENT_ALLOC:
24214 map_seen = 3;
24215 break;
24216 case GOMP_MAP_FIRSTPRIVATE_POINTER:
24217 case GOMP_MAP_ALWAYS_POINTER:
24218 case GOMP_MAP_ATTACH_DETACH:
24219 case GOMP_MAP_ATTACH:
24220 break;
24221 default:
24222 map_seen |= 1;
24223 error_at (OMP_CLAUSE_LOCATION (*pc),
24224 "%<#pragma omp target data%> with map-type other "
24225 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
24226 "on %<map%> clause");
24227 *pc = OMP_CLAUSE_CHAIN (*pc);
24228 continue;
24230 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
24231 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
24232 map_seen = 3;
24233 pc = &OMP_CLAUSE_CHAIN (*pc);
24236 if (map_seen != 3)
24238 if (map_seen == 0)
24239 error_at (loc,
24240 "%<#pragma omp target data%> must contain at least "
24241 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
24242 "clause");
24243 return NULL_TREE;
24246 tree stmt = make_node (OMP_TARGET_DATA);
24247 TREE_TYPE (stmt) = void_type_node;
24248 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
24249 keep_next_level ();
24250 tree block = c_begin_compound_stmt (true);
24251 add_stmt (c_parser_omp_structured_block (parser, if_p));
24252 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
24254 SET_EXPR_LOCATION (stmt, loc);
24255 return add_stmt (stmt);
24258 /* OpenMP 4.0:
24259 # pragma omp target update target-update-clause[optseq] new-line */
24261 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
24262 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
24263 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
24264 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24265 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24266 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24269 static bool
24270 c_parser_omp_target_update (location_t loc, c_parser *parser,
24271 enum pragma_context context)
24273 if (context == pragma_stmt)
24275 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
24276 "omp target update");
24277 c_parser_skip_to_pragma_eol (parser, false);
24278 return true;
24281 tree clauses
24282 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
24283 "#pragma omp target update");
24284 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
24285 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
24287 error_at (loc,
24288 "%<#pragma omp target update%> must contain at least one "
24289 "%<from%> or %<to%> clauses");
24290 return false;
24293 if (flag_openmp)
24294 omp_requires_mask
24295 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24297 tree stmt = make_node (OMP_TARGET_UPDATE);
24298 TREE_TYPE (stmt) = void_type_node;
24299 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
24300 SET_EXPR_LOCATION (stmt, loc);
24301 add_stmt (stmt);
24302 return false;
24305 /* OpenMP 4.5:
24306 # pragma omp target enter data target-data-clause[optseq] new-line */
24308 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
24309 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24310 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24311 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24312 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24313 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24315 static bool
24316 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
24317 enum pragma_context context)
24319 bool data_seen = false;
24320 if (c_parser_next_token_is (parser, CPP_NAME))
24322 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24323 if (strcmp (p, "data") == 0)
24325 c_parser_consume_token (parser);
24326 data_seen = true;
24329 if (!data_seen)
24331 c_parser_error (parser, "expected %<data%>");
24332 c_parser_skip_to_pragma_eol (parser);
24333 return false;
24336 if (context == pragma_stmt)
24338 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
24339 "omp target enter data");
24340 c_parser_skip_to_pragma_eol (parser, false);
24341 return true;
24344 if (flag_openmp)
24345 omp_requires_mask
24346 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24348 tree clauses
24349 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
24350 "#pragma omp target enter data");
24351 c_omp_adjust_map_clauses (clauses, false);
24352 int map_seen = 0;
24353 for (tree *pc = &clauses; *pc;)
24355 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24356 switch (OMP_CLAUSE_MAP_KIND (*pc))
24358 case GOMP_MAP_TO:
24359 case GOMP_MAP_ALWAYS_TO:
24360 case GOMP_MAP_PRESENT_TO:
24361 case GOMP_MAP_ALWAYS_PRESENT_TO:
24362 case GOMP_MAP_ALLOC:
24363 case GOMP_MAP_PRESENT_ALLOC:
24364 map_seen = 3;
24365 break;
24366 case GOMP_MAP_TOFROM:
24367 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
24368 map_seen = 3;
24369 break;
24370 case GOMP_MAP_ALWAYS_TOFROM:
24371 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
24372 map_seen = 3;
24373 break;
24374 case GOMP_MAP_PRESENT_TOFROM:
24375 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_TO);
24376 map_seen = 3;
24377 break;
24378 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24379 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_TO);
24380 map_seen = 3;
24381 break;
24382 case GOMP_MAP_FIRSTPRIVATE_POINTER:
24383 case GOMP_MAP_ALWAYS_POINTER:
24384 case GOMP_MAP_ATTACH_DETACH:
24385 case GOMP_MAP_ATTACH:
24386 break;
24387 default:
24388 map_seen |= 1;
24389 error_at (OMP_CLAUSE_LOCATION (*pc),
24390 "%<#pragma omp target enter data%> with map-type other "
24391 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
24392 *pc = OMP_CLAUSE_CHAIN (*pc);
24393 continue;
24395 pc = &OMP_CLAUSE_CHAIN (*pc);
24398 if (map_seen != 3)
24400 if (map_seen == 0)
24401 error_at (loc,
24402 "%<#pragma omp target enter data%> must contain at least "
24403 "one %<map%> clause");
24404 return true;
24407 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
24408 TREE_TYPE (stmt) = void_type_node;
24409 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
24410 SET_EXPR_LOCATION (stmt, loc);
24411 add_stmt (stmt);
24412 return true;
24415 /* OpenMP 4.5:
24416 # pragma omp target exit data target-data-clause[optseq] new-line */
24418 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
24419 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24423 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24425 static bool
24426 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
24427 enum pragma_context context)
24429 bool data_seen = false;
24430 if (c_parser_next_token_is (parser, CPP_NAME))
24432 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24433 if (strcmp (p, "data") == 0)
24435 c_parser_consume_token (parser);
24436 data_seen = true;
24439 if (!data_seen)
24441 c_parser_error (parser, "expected %<data%>");
24442 c_parser_skip_to_pragma_eol (parser);
24443 return false;
24446 if (context == pragma_stmt)
24448 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
24449 "omp target exit data");
24450 c_parser_skip_to_pragma_eol (parser, false);
24451 return true;
24454 if (flag_openmp)
24455 omp_requires_mask
24456 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24458 tree clauses
24459 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
24460 "#pragma omp target exit data", false);
24461 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP_EXIT_DATA);
24462 c_omp_adjust_map_clauses (clauses, false);
24463 int map_seen = 0;
24464 for (tree *pc = &clauses; *pc;)
24466 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24467 switch (OMP_CLAUSE_MAP_KIND (*pc))
24469 case GOMP_MAP_FROM:
24470 case GOMP_MAP_ALWAYS_FROM:
24471 case GOMP_MAP_PRESENT_FROM:
24472 case GOMP_MAP_ALWAYS_PRESENT_FROM:
24473 case GOMP_MAP_RELEASE:
24474 case GOMP_MAP_DELETE:
24475 map_seen = 3;
24476 break;
24477 case GOMP_MAP_TOFROM:
24478 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
24479 map_seen = 3;
24480 break;
24481 case GOMP_MAP_ALWAYS_TOFROM:
24482 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
24483 map_seen = 3;
24484 break;
24485 case GOMP_MAP_PRESENT_TOFROM:
24486 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_FROM);
24487 map_seen = 3;
24488 break;
24489 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24490 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_FROM);
24491 map_seen = 3;
24492 break;
24493 case GOMP_MAP_FIRSTPRIVATE_POINTER:
24494 case GOMP_MAP_ALWAYS_POINTER:
24495 case GOMP_MAP_ATTACH_DETACH:
24496 case GOMP_MAP_DETACH:
24497 break;
24498 default:
24499 map_seen |= 1;
24500 error_at (OMP_CLAUSE_LOCATION (*pc),
24501 "%<#pragma omp target exit data%> with map-type other "
24502 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
24503 "on %<map%> clause");
24504 *pc = OMP_CLAUSE_CHAIN (*pc);
24505 continue;
24507 pc = &OMP_CLAUSE_CHAIN (*pc);
24510 if (map_seen != 3)
24512 if (map_seen == 0)
24513 error_at (loc,
24514 "%<#pragma omp target exit data%> must contain at least one "
24515 "%<map%> clause");
24516 return true;
24519 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
24520 TREE_TYPE (stmt) = void_type_node;
24521 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
24522 SET_EXPR_LOCATION (stmt, loc);
24523 add_stmt (stmt);
24524 return true;
24527 /* OpenMP 4.0:
24528 # pragma omp target target-clause[optseq] new-line
24529 structured-block */
24531 #define OMP_TARGET_CLAUSE_MASK \
24532 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24533 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24534 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24535 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24536 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
24537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
24538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
24539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
24540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
24541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
24542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
24543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
24544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
24546 static bool
24547 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
24549 location_t loc = c_parser_peek_token (parser)->location;
24550 c_parser_consume_pragma (parser);
24551 tree *pc = NULL, stmt, block;
24553 if (context != pragma_stmt && context != pragma_compound)
24555 c_parser_error (parser, "expected declaration specifiers");
24556 c_parser_skip_to_pragma_eol (parser);
24557 return false;
24560 if (flag_openmp)
24561 omp_requires_mask
24562 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
24564 if (c_parser_next_token_is (parser, CPP_NAME))
24566 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24567 enum tree_code ccode = ERROR_MARK;
24569 if (strcmp (p, "teams") == 0)
24570 ccode = OMP_TEAMS;
24571 else if (strcmp (p, "parallel") == 0)
24572 ccode = OMP_PARALLEL;
24573 else if (strcmp (p, "simd") == 0)
24574 ccode = OMP_SIMD;
24575 if (ccode != ERROR_MARK)
24577 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
24578 char p_name[sizeof ("#pragma omp target teams distribute "
24579 "parallel for simd")];
24581 c_parser_consume_token (parser);
24582 strcpy (p_name, "#pragma omp target");
24583 if (!flag_openmp) /* flag_openmp_simd */
24585 tree stmt;
24586 switch (ccode)
24588 case OMP_TEAMS:
24589 stmt = c_parser_omp_teams (loc, parser, p_name,
24590 OMP_TARGET_CLAUSE_MASK,
24591 cclauses, if_p);
24592 break;
24593 case OMP_PARALLEL:
24594 stmt = c_parser_omp_parallel (loc, parser, p_name,
24595 OMP_TARGET_CLAUSE_MASK,
24596 cclauses, if_p);
24597 break;
24598 case OMP_SIMD:
24599 stmt = c_parser_omp_simd (loc, parser, p_name,
24600 OMP_TARGET_CLAUSE_MASK,
24601 cclauses, if_p);
24602 break;
24603 default:
24604 gcc_unreachable ();
24606 return stmt != NULL_TREE;
24608 keep_next_level ();
24609 tree block = c_begin_compound_stmt (true), ret;
24610 switch (ccode)
24612 case OMP_TEAMS:
24613 ret = c_parser_omp_teams (loc, parser, p_name,
24614 OMP_TARGET_CLAUSE_MASK, cclauses,
24615 if_p);
24616 break;
24617 case OMP_PARALLEL:
24618 ret = c_parser_omp_parallel (loc, parser, p_name,
24619 OMP_TARGET_CLAUSE_MASK, cclauses,
24620 if_p);
24621 break;
24622 case OMP_SIMD:
24623 ret = c_parser_omp_simd (loc, parser, p_name,
24624 OMP_TARGET_CLAUSE_MASK, cclauses,
24625 if_p);
24626 break;
24627 default:
24628 gcc_unreachable ();
24630 block = c_end_compound_stmt (loc, block, true);
24631 if (ret == NULL_TREE)
24632 return false;
24633 if (ccode == OMP_TEAMS)
24634 /* For combined target teams, ensure the num_teams and
24635 thread_limit clause expressions are evaluated on the host,
24636 before entering the target construct. */
24637 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
24638 c; c = OMP_CLAUSE_CHAIN (c))
24639 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
24640 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
24641 for (int i = 0;
24642 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
24643 if (OMP_CLAUSE_OPERAND (c, i)
24644 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
24646 tree expr = OMP_CLAUSE_OPERAND (c, i);
24647 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
24648 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
24649 expr, NULL_TREE, NULL_TREE);
24650 add_stmt (expr);
24651 OMP_CLAUSE_OPERAND (c, i) = expr;
24652 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
24653 OMP_CLAUSE_FIRSTPRIVATE);
24654 OMP_CLAUSE_DECL (tc) = tmp;
24655 OMP_CLAUSE_CHAIN (tc)
24656 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
24657 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
24659 tree stmt = make_node (OMP_TARGET);
24660 TREE_TYPE (stmt) = void_type_node;
24661 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
24662 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
24663 OMP_TARGET_BODY (stmt) = block;
24664 OMP_TARGET_COMBINED (stmt) = 1;
24665 SET_EXPR_LOCATION (stmt, loc);
24666 add_stmt (stmt);
24667 pc = &OMP_TARGET_CLAUSES (stmt);
24668 goto check_clauses;
24670 else if (!flag_openmp) /* flag_openmp_simd */
24672 c_parser_skip_to_pragma_eol (parser, false);
24673 return false;
24675 else if (strcmp (p, "data") == 0)
24677 c_parser_consume_token (parser);
24678 c_parser_omp_target_data (loc, parser, if_p);
24679 return true;
24681 else if (strcmp (p, "enter") == 0)
24683 c_parser_consume_token (parser);
24684 return c_parser_omp_target_enter_data (loc, parser, context);
24686 else if (strcmp (p, "exit") == 0)
24688 c_parser_consume_token (parser);
24689 return c_parser_omp_target_exit_data (loc, parser, context);
24691 else if (strcmp (p, "update") == 0)
24693 c_parser_consume_token (parser);
24694 return c_parser_omp_target_update (loc, parser, context);
24697 if (!flag_openmp) /* flag_openmp_simd */
24699 c_parser_skip_to_pragma_eol (parser, false);
24700 return false;
24703 stmt = make_node (OMP_TARGET);
24704 TREE_TYPE (stmt) = void_type_node;
24706 OMP_TARGET_CLAUSES (stmt)
24707 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
24708 "#pragma omp target", false);
24709 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
24710 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
24712 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
24713 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
24714 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
24715 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
24716 OMP_CLAUSE_CHAIN (c) = nc;
24718 OMP_TARGET_CLAUSES (stmt)
24719 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
24720 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
24722 pc = &OMP_TARGET_CLAUSES (stmt);
24723 keep_next_level ();
24724 block = c_begin_compound_stmt (true);
24725 add_stmt (c_parser_omp_structured_block (parser, if_p));
24726 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
24728 SET_EXPR_LOCATION (stmt, loc);
24729 add_stmt (stmt);
24731 check_clauses:
24732 while (*pc)
24734 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
24735 switch (OMP_CLAUSE_MAP_KIND (*pc))
24737 case GOMP_MAP_TO:
24738 case GOMP_MAP_ALWAYS_TO:
24739 case GOMP_MAP_PRESENT_TO:
24740 case GOMP_MAP_ALWAYS_PRESENT_TO:
24741 case GOMP_MAP_FROM:
24742 case GOMP_MAP_ALWAYS_FROM:
24743 case GOMP_MAP_PRESENT_FROM:
24744 case GOMP_MAP_ALWAYS_PRESENT_FROM:
24745 case GOMP_MAP_TOFROM:
24746 case GOMP_MAP_ALWAYS_TOFROM:
24747 case GOMP_MAP_PRESENT_TOFROM:
24748 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
24749 case GOMP_MAP_ALLOC:
24750 case GOMP_MAP_PRESENT_ALLOC:
24751 case GOMP_MAP_FIRSTPRIVATE_POINTER:
24752 case GOMP_MAP_ALWAYS_POINTER:
24753 case GOMP_MAP_POINTER:
24754 case GOMP_MAP_ATTACH_DETACH:
24755 case GOMP_MAP_ATTACH:
24756 break;
24757 default:
24758 error_at (OMP_CLAUSE_LOCATION (*pc),
24759 "%<#pragma omp target%> with map-type other "
24760 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
24761 "on %<map%> clause");
24762 *pc = OMP_CLAUSE_CHAIN (*pc);
24763 continue;
24765 pc = &OMP_CLAUSE_CHAIN (*pc);
24767 cfun->has_omp_target = true;
24768 return true;
24771 /* OpenMP 4.0:
24772 # pragma omp declare simd declare-simd-clauses[optseq] new-line
24774 OpenMP 5.0:
24775 # pragma omp declare variant (identifier) match(context-selector) new-line
24778 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
24779 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
24780 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
24781 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
24782 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
24783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
24784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
24786 static void
24787 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
24789 c_token *token = c_parser_peek_token (parser);
24790 gcc_assert (token->type == CPP_NAME);
24791 tree kind = token->value;
24792 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
24793 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
24795 auto_vec<c_token> clauses;
24796 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
24798 c_token *token = c_parser_peek_token (parser);
24799 if (token->type == CPP_EOF)
24801 c_parser_skip_to_pragma_eol (parser);
24802 return;
24804 clauses.safe_push (*token);
24805 c_parser_consume_token (parser);
24807 clauses.safe_push (*c_parser_peek_token (parser));
24808 c_parser_skip_to_pragma_eol (parser);
24810 while (c_parser_next_token_is (parser, CPP_PRAGMA))
24812 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
24813 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
24814 || c_parser_peek_2nd_token (parser)->value != kind)
24816 error ("%<#pragma omp declare %s%> must be followed by "
24817 "function declaration or definition or another "
24818 "%<#pragma omp declare %s%>",
24819 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
24820 return;
24822 c_parser_consume_pragma (parser);
24823 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
24825 c_token *token = c_parser_peek_token (parser);
24826 if (token->type == CPP_EOF)
24828 c_parser_skip_to_pragma_eol (parser);
24829 return;
24831 clauses.safe_push (*token);
24832 c_parser_consume_token (parser);
24834 clauses.safe_push (*c_parser_peek_token (parser));
24835 c_parser_skip_to_pragma_eol (parser);
24838 /* Make sure nothing tries to read past the end of the tokens. */
24839 c_token eof_token;
24840 memset (&eof_token, 0, sizeof (eof_token));
24841 eof_token.type = CPP_EOF;
24842 clauses.safe_push (eof_token);
24843 clauses.safe_push (eof_token);
24845 switch (context)
24847 case pragma_external:
24848 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24849 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
24851 int ext = disable_extension_diagnostics ();
24853 c_parser_consume_token (parser);
24854 while (c_parser_next_token_is (parser, CPP_KEYWORD)
24855 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
24856 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
24857 NULL, &clauses);
24858 restore_extension_diagnostics (ext);
24860 else
24861 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
24862 NULL, &clauses);
24863 break;
24864 case pragma_struct:
24865 case pragma_param:
24866 case pragma_stmt:
24867 error ("%<#pragma omp declare %s%> must be followed by "
24868 "function declaration or definition",
24869 IDENTIFIER_POINTER (kind));
24870 break;
24871 case pragma_compound:
24872 bool have_std_attrs;
24873 tree std_attrs;
24874 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
24875 if (have_std_attrs)
24876 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
24877 else
24878 std_attrs = NULL_TREE;
24879 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24880 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
24882 int ext = disable_extension_diagnostics ();
24884 c_parser_consume_token (parser);
24885 while (c_parser_next_token_is (parser, CPP_KEYWORD)
24886 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
24887 if (c_parser_next_tokens_start_declaration (parser)
24888 || c_parser_nth_token_starts_std_attributes (parser, 1))
24890 c_parser_declaration_or_fndef (parser, true, true, true, true,
24891 true, NULL, &clauses,
24892 have_std_attrs, std_attrs);
24893 restore_extension_diagnostics (ext);
24894 break;
24896 restore_extension_diagnostics (ext);
24898 else if (c_parser_next_tokens_start_declaration (parser))
24900 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
24901 NULL, &clauses, have_std_attrs,
24902 std_attrs);
24903 break;
24905 error ("%<#pragma omp declare %s%> must be followed by "
24906 "function declaration or definition",
24907 IDENTIFIER_POINTER (kind));
24908 break;
24909 default:
24910 gcc_unreachable ();
24914 /* OpenMP 5.0:
24916 trait-selector:
24917 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
24919 trait-score:
24920 score(score-expression)
24922 Note that this function returns a list of trait selectors for the
24923 trait-selector-set SET. */
24925 static tree
24926 c_parser_omp_context_selector (c_parser *parser, enum omp_tss_code set,
24927 tree parms)
24929 tree ret = NULL_TREE;
24932 tree selector;
24933 if (c_parser_next_token_is (parser, CPP_KEYWORD)
24934 || c_parser_next_token_is (parser, CPP_NAME))
24935 selector = c_parser_peek_token (parser)->value;
24936 else
24938 c_parser_error (parser, "expected trait selector name");
24939 return error_mark_node;
24941 enum omp_ts_code sel
24942 = omp_lookup_ts_code (set, IDENTIFIER_POINTER (selector));
24944 if (sel == OMP_TRAIT_INVALID)
24946 /* Per the spec, "Implementations can ignore specified selectors
24947 that are not those described in this section"; however, we
24948 must record such selectors because they cause match failures. */
24949 warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
24950 "unknown selector %qs for context selector set %qs",
24951 IDENTIFIER_POINTER (selector), omp_tss_map[set]);
24952 c_parser_consume_token (parser);
24953 ret = make_trait_selector (sel, NULL_TREE, NULL_TREE, ret);
24954 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
24955 c_parser_balanced_token_sequence (parser);
24956 if (c_parser_next_token_is (parser, CPP_COMMA))
24958 c_parser_consume_token (parser);
24959 continue;
24961 else
24962 break;
24965 c_parser_consume_token (parser);
24967 tree properties = NULL_TREE;
24968 tree scoreval = NULL_TREE;
24969 enum omp_tp_type property_kind = omp_ts_map[sel].tp_type;
24970 bool allow_score = omp_ts_map[sel].allow_score;
24971 tree t;
24973 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
24975 if (property_kind == OMP_TRAIT_PROPERTY_NONE)
24977 error_at (c_parser_peek_token (parser)->location,
24978 "selector %qs does not accept any properties",
24979 IDENTIFIER_POINTER (selector));
24980 return error_mark_node;
24983 matching_parens parens;
24984 parens.require_open (parser);
24986 c_token *token = c_parser_peek_token (parser);
24987 if (c_parser_next_token_is (parser, CPP_NAME)
24988 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
24989 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
24991 c_parser_consume_token (parser);
24993 matching_parens parens2;
24994 parens2.require_open (parser);
24995 tree score = c_parser_expr_no_commas (parser, NULL).value;
24996 parens2.skip_until_found_close (parser);
24997 c_parser_require (parser, CPP_COLON, "expected %<:%>");
24998 if (!allow_score)
24999 error_at (token->location,
25000 "%<score%> cannot be specified in traits "
25001 "in the %qs trait-selector-set",
25002 omp_tss_map[set]);
25003 else if (score != error_mark_node)
25005 mark_exp_read (score);
25006 score = c_fully_fold (score, false, NULL);
25007 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
25008 || TREE_CODE (score) != INTEGER_CST)
25009 error_at (token->location, "%<score%> argument must "
25010 "be constant integer expression");
25011 else if (tree_int_cst_sgn (score) < 0)
25012 error_at (token->location, "%<score%> argument must "
25013 "be non-negative");
25014 else
25015 scoreval = score;
25017 token = c_parser_peek_token (parser);
25020 switch (property_kind)
25022 case OMP_TRAIT_PROPERTY_ID:
25023 if (c_parser_next_token_is (parser, CPP_KEYWORD)
25024 || c_parser_next_token_is (parser, CPP_NAME))
25026 tree prop = c_parser_peek_token (parser)->value;
25027 c_parser_consume_token (parser);
25028 properties = make_trait_property (prop, NULL_TREE,
25029 properties);
25031 else
25033 c_parser_error (parser, "expected identifier");
25034 return error_mark_node;
25036 break;
25037 case OMP_TRAIT_PROPERTY_NAME_LIST:
25040 tree prop = OMP_TP_NAMELIST_NODE;
25041 tree value = NULL_TREE;
25042 if (c_parser_next_token_is (parser, CPP_KEYWORD)
25043 || c_parser_next_token_is (parser, CPP_NAME))
25045 value = c_parser_peek_token (parser)->value;
25046 c_parser_consume_token (parser);
25048 else if (c_parser_next_token_is (parser, CPP_STRING))
25049 value = c_parser_string_literal (parser, false,
25050 false).value;
25051 else
25053 c_parser_error (parser, "expected identifier or "
25054 "string literal");
25055 return error_mark_node;
25058 properties = make_trait_property (prop, value, properties);
25060 if (c_parser_next_token_is (parser, CPP_COMMA))
25061 c_parser_consume_token (parser);
25062 else
25063 break;
25065 while (1);
25066 break;
25067 case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR:
25068 case OMP_TRAIT_PROPERTY_BOOL_EXPR:
25069 t = c_parser_expr_no_commas (parser, NULL).value;
25070 if (t != error_mark_node)
25072 mark_exp_read (t);
25073 t = c_fully_fold (t, false, NULL);
25074 /* FIXME: this is bogus, both device_num and
25075 condition selectors allow arbitrary expressions. */
25076 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
25077 || !tree_fits_shwi_p (t))
25078 error_at (token->location, "property must be "
25079 "constant integer expression");
25080 else
25081 properties = make_trait_property (NULL_TREE, t,
25082 properties);
25084 else
25085 return error_mark_node;
25086 break;
25087 case OMP_TRAIT_PROPERTY_CLAUSE_LIST:
25088 if (sel == OMP_TRAIT_CONSTRUCT_SIMD)
25090 if (parms == NULL_TREE)
25092 error_at (token->location, "properties for %<simd%> "
25093 "selector may not be specified in "
25094 "%<metadirective%>");
25095 return error_mark_node;
25097 tree c;
25098 c = c_parser_omp_all_clauses (parser,
25099 OMP_DECLARE_SIMD_CLAUSE_MASK,
25100 "simd", true, 2);
25101 c = c_omp_declare_simd_clauses_to_numbers (parms
25102 == error_mark_node
25103 ? NULL_TREE : parms,
25105 properties = c;
25107 else if (sel == OMP_TRAIT_IMPLEMENTATION_REQUIRES)
25109 /* FIXME: The "requires" selector was added in OpenMP 5.1.
25110 Currently only the now-deprecated syntax
25111 from OpenMP 5.0 is supported. */
25112 sorry_at (token->location,
25113 "%<requires%> selector is not supported yet");
25114 return error_mark_node;
25116 else
25117 gcc_unreachable ();
25118 break;
25119 default:
25120 gcc_unreachable ();
25123 parens.skip_until_found_close (parser);
25124 properties = nreverse (properties);
25126 else if (property_kind != OMP_TRAIT_PROPERTY_NONE
25127 && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST
25128 && property_kind != OMP_TRAIT_PROPERTY_EXTENSION)
25130 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
25131 return error_mark_node;
25134 ret = make_trait_selector (sel, scoreval, properties, ret);
25136 if (c_parser_next_token_is (parser, CPP_COMMA))
25137 c_parser_consume_token (parser);
25138 else
25139 break;
25141 while (1);
25143 return nreverse (ret);
25146 /* OpenMP 5.0:
25148 trait-set-selector[,trait-set-selector[,...]]
25150 trait-set-selector:
25151 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
25153 trait-set-selector-name:
25154 constructor
25155 device
25156 implementation
25157 user */
25159 static tree
25160 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
25162 tree ret = NULL_TREE;
25165 const char *setp = "";
25166 if (c_parser_next_token_is (parser, CPP_NAME))
25167 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25168 enum omp_tss_code set = omp_lookup_tss_code (setp);
25170 if (set == OMP_TRAIT_SET_INVALID)
25172 c_parser_error (parser, "expected context selector set name");
25173 return error_mark_node;
25176 c_parser_consume_token (parser);
25178 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
25179 return error_mark_node;
25181 matching_braces braces;
25182 if (!braces.require_open (parser))
25183 return error_mark_node;
25185 tree selectors = c_parser_omp_context_selector (parser, set, parms);
25186 if (selectors == error_mark_node)
25187 ret = error_mark_node;
25188 else if (ret != error_mark_node)
25189 ret = make_trait_set_selector (set, selectors, ret);
25191 braces.skip_until_found_close (parser);
25193 if (c_parser_next_token_is (parser, CPP_COMMA))
25194 c_parser_consume_token (parser);
25195 else
25196 break;
25198 while (1);
25200 if (ret == error_mark_node)
25201 return ret;
25202 return nreverse (ret);
25205 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
25206 that into "omp declare variant base" attribute. */
25208 static void
25209 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
25211 matching_parens parens;
25212 if (!parens.require_open (parser))
25214 fail:
25215 c_parser_skip_to_pragma_eol (parser, false);
25216 return;
25219 if (c_parser_next_token_is_not (parser, CPP_NAME)
25220 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
25222 c_parser_error (parser, "expected identifier");
25223 goto fail;
25226 c_token *token = c_parser_peek_token (parser);
25227 tree variant = lookup_name (token->value);
25229 if (variant == NULL_TREE)
25231 undeclared_variable (token->location, token->value);
25232 variant = error_mark_node;
25235 c_parser_consume_token (parser);
25237 parens.require_close (parser);
25239 if (c_parser_next_token_is (parser, CPP_COMMA)
25240 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
25241 c_parser_consume_token (parser);
25243 const char *clause = "";
25244 location_t match_loc = c_parser_peek_token (parser)->location;
25245 if (c_parser_next_token_is (parser, CPP_NAME))
25246 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25247 if (strcmp (clause, "match"))
25249 c_parser_error (parser, "expected %<match%>");
25250 goto fail;
25253 c_parser_consume_token (parser);
25255 if (!parens.require_open (parser))
25256 goto fail;
25258 if (parms == NULL_TREE)
25259 parms = error_mark_node;
25261 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
25262 if (ctx == error_mark_node)
25263 goto fail;
25264 ctx = omp_check_context_selector (match_loc, ctx);
25265 if (ctx != error_mark_node && variant != error_mark_node)
25267 if (TREE_CODE (variant) != FUNCTION_DECL)
25269 error_at (token->location, "variant %qD is not a function", variant);
25270 variant = error_mark_node;
25272 else if (!omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
25273 OMP_TRAIT_CONSTRUCT_SIMD)
25274 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
25276 error_at (token->location, "variant %qD and base %qD have "
25277 "incompatible types", variant, fndecl);
25278 variant = error_mark_node;
25280 else if (fndecl_built_in_p (variant)
25281 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
25282 "__builtin_", strlen ("__builtin_")) == 0
25283 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
25284 "__sync_", strlen ("__sync_")) == 0
25285 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
25286 "__atomic_", strlen ("__atomic_")) == 0))
25288 error_at (token->location, "variant %qD is a built-in", variant);
25289 variant = error_mark_node;
25291 if (variant != error_mark_node)
25293 C_DECL_USED (variant) = 1;
25294 tree construct
25295 = omp_get_context_selector_list (ctx, OMP_TRAIT_SET_CONSTRUCT);
25296 omp_mark_declare_variant (match_loc, variant, construct);
25297 if (omp_context_selector_matches (ctx))
25299 tree attr
25300 = tree_cons (get_identifier ("omp declare variant base"),
25301 build_tree_list (variant, ctx),
25302 DECL_ATTRIBUTES (fndecl));
25303 DECL_ATTRIBUTES (fndecl) = attr;
25308 parens.require_close (parser);
25309 c_parser_skip_to_pragma_eol (parser);
25312 /* Finalize #pragma omp declare simd or #pragma omp declare variant
25313 clauses after FNDECL has been parsed, and put that into "omp declare simd"
25314 or "omp declare variant base" attribute. */
25316 static void
25317 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
25318 vec<c_token> *pclauses)
25320 vec<c_token> &clauses = *pclauses;
25322 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
25323 indicates error has been reported and CPP_PRAGMA that
25324 c_finish_omp_declare_simd has already processed the tokens. */
25325 if (clauses.exists () && clauses[0].type == CPP_EOF)
25326 return;
25327 const char *kind = "simd";
25328 if (clauses.exists ()
25329 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
25330 kind = IDENTIFIER_POINTER (clauses[0].value);
25331 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
25332 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
25334 error ("%<#pragma omp declare %s%> not immediately followed by "
25335 "a function declaration or definition", kind);
25336 clauses[0].type = CPP_EOF;
25337 return;
25339 if (clauses.exists () && clauses[0].type != CPP_NAME)
25341 error_at (DECL_SOURCE_LOCATION (fndecl),
25342 "%<#pragma omp declare %s%> not immediately followed by "
25343 "a single function declaration or definition", kind);
25344 clauses[0].type = CPP_EOF;
25345 return;
25348 if (parms == NULL_TREE)
25349 parms = DECL_ARGUMENTS (fndecl);
25351 unsigned int tokens_avail = parser->tokens_avail;
25352 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
25354 parser->tokens = clauses.address ();
25355 parser->tokens_avail = clauses.length ();
25357 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
25358 while (parser->tokens_avail > 3)
25360 c_token *token = c_parser_peek_token (parser);
25361 gcc_assert (token->type == CPP_NAME);
25362 kind = IDENTIFIER_POINTER (token->value);
25363 c_parser_consume_token (parser);
25364 parser->in_pragma = true;
25366 if (strcmp (kind, "simd") == 0)
25368 tree c;
25369 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
25370 "#pragma omp declare simd");
25371 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
25372 if (c != NULL_TREE)
25373 c = tree_cons (NULL_TREE, c, NULL_TREE);
25374 c = build_tree_list (get_identifier ("omp declare simd"), c);
25375 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
25376 DECL_ATTRIBUTES (fndecl) = c;
25378 else
25380 gcc_assert (strcmp (kind, "variant") == 0);
25381 c_finish_omp_declare_variant (parser, fndecl, parms);
25385 parser->tokens = &parser->tokens_buf[0];
25386 parser->tokens_avail = tokens_avail;
25387 if (clauses.exists ())
25388 clauses[0].type = CPP_PRAGMA;
25391 /* D should be C_TOKEN_VEC from omp::decl attribute. If it contains
25392 a threadprivate, groupprivate, allocate or declare target directive,
25393 return true and parse it for DECL. */
25395 bool
25396 c_maybe_parse_omp_decl (tree decl, tree d)
25398 gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
25399 vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
25400 c_token *first = toks->address ();
25401 c_token *last = first + toks->length ();
25402 const char *directive[3] = {};
25403 for (int j = 0; j < 3; j++)
25405 tree id = NULL_TREE;
25406 if (first + j == last)
25407 break;
25408 if (first[j].type == CPP_NAME)
25409 id = first[j].value;
25410 else if (first[j].type == CPP_KEYWORD)
25411 id = ridpointers[(int) first[j].keyword];
25412 else
25413 break;
25414 directive[j] = IDENTIFIER_POINTER (id);
25416 const c_omp_directive *dir = NULL;
25417 if (directive[0])
25418 dir = c_omp_categorize_directive (directive[0], directive[1],
25419 directive[2]);
25420 if (dir == NULL)
25422 error_at (first->location,
25423 "unknown OpenMP directive name in "
25424 "%qs attribute argument", "omp::decl");
25425 return false;
25427 if (dir->id != PRAGMA_OMP_THREADPRIVATE
25428 /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
25429 && dir->id != PRAGMA_OMP_ALLOCATE
25430 && (dir->id != PRAGMA_OMP_DECLARE
25431 || strcmp (directive[1], "target") != 0))
25432 return false;
25434 if (!flag_openmp && !dir->simd)
25435 return true;
25437 c_parser *parser = the_parser;
25438 unsigned int tokens_avail = parser->tokens_avail;
25439 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
25440 toks = NULL;
25441 vec_safe_reserve (toks, last - first + 2, true);
25442 c_token tok = {};
25443 tok.type = CPP_PRAGMA;
25444 tok.keyword = RID_MAX;
25445 tok.pragma_kind = pragma_kind (dir->id);
25446 tok.location = first->location;
25447 toks->quick_push (tok);
25448 while (++first < last)
25449 toks->quick_push (*first);
25450 tok = {};
25451 tok.type = CPP_PRAGMA_EOL;
25452 tok.keyword = RID_MAX;
25453 tok.location = last[-1].location;
25454 toks->quick_push (tok);
25455 tok = {};
25456 tok.type = CPP_EOF;
25457 tok.keyword = RID_MAX;
25458 tok.location = last[-1].location;
25459 tok.flags = tokens_avail;
25460 toks->quick_push (tok);
25461 parser->in_omp_decl_attribute = decl;
25462 parser->tokens = toks->address ();
25463 parser->tokens_avail = toks->length ();
25464 parser->in_omp_attribute_pragma = toks;
25465 c_parser_pragma (parser, pragma_external, NULL);
25466 parser->in_omp_decl_attribute = NULL_TREE;
25467 return true;
25470 /* OpenMP 4.0:
25471 # pragma omp declare target new-line
25472 declarations and definitions
25473 # pragma omp end declare target new-line
25475 OpenMP 4.5:
25476 # pragma omp declare target ( extended-list ) new-line
25478 # pragma omp declare target declare-target-clauses[seq] new-line */
25480 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
25481 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
25482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
25483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
25484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25487 static void
25488 c_parser_omp_declare_target (c_parser *parser)
25490 tree clauses = NULL_TREE;
25491 int device_type = 0;
25492 bool indirect = false;
25493 bool only_device_type_or_indirect = true;
25494 if (c_parser_next_token_is (parser, CPP_NAME)
25495 || (c_parser_next_token_is (parser, CPP_COMMA)
25496 && c_parser_peek_2nd_token (parser)->type == CPP_NAME))
25497 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
25498 "#pragma omp declare target");
25499 else if (parser->in_omp_decl_attribute
25500 || c_parser_next_token_is (parser, CPP_OPEN_PAREN))
25502 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
25503 clauses);
25504 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
25505 c_parser_skip_to_pragma_eol (parser);
25507 else
25509 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25510 c_parser_skip_to_pragma_eol (parser);
25511 c_omp_declare_target_attr attr = { attr_syntax, -1, 0 };
25512 vec_safe_push (current_omp_declare_target_attribute, attr);
25513 return;
25515 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25517 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
25518 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
25519 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25520 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
25522 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25524 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE
25525 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25526 continue;
25527 tree t = OMP_CLAUSE_DECL (c), id;
25528 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
25529 tree at2 = lookup_attribute ("omp declare target link",
25530 DECL_ATTRIBUTES (t));
25531 only_device_type_or_indirect = false;
25532 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
25534 id = get_identifier ("omp declare target link");
25535 std::swap (at1, at2);
25537 else
25538 id = get_identifier ("omp declare target");
25539 if (at2)
25541 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
25542 error_at (OMP_CLAUSE_LOCATION (c),
25543 "%qD specified both in declare target %<link%> and %qs"
25544 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
25545 else
25546 error_at (OMP_CLAUSE_LOCATION (c),
25547 "%qD specified both in declare target %<link%> and "
25548 "%<to%> or %<enter%> clauses", t);
25549 continue;
25551 if (!at1)
25553 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25554 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
25555 continue;
25557 symtab_node *node = symtab_node::get (t);
25558 if (node != NULL)
25560 node->offloadable = 1;
25561 if (ENABLE_OFFLOADING)
25563 g->have_offload = true;
25564 if (is_a <varpool_node *> (node))
25565 vec_safe_push (offload_vars, t);
25569 if (TREE_CODE (t) != FUNCTION_DECL)
25570 continue;
25571 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
25573 tree at3 = lookup_attribute ("omp declare target host",
25574 DECL_ATTRIBUTES (t));
25575 if (at3 == NULL_TREE)
25577 id = get_identifier ("omp declare target host");
25578 DECL_ATTRIBUTES (t)
25579 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25582 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
25584 tree at3 = lookup_attribute ("omp declare target nohost",
25585 DECL_ATTRIBUTES (t));
25586 if (at3 == NULL_TREE)
25588 id = get_identifier ("omp declare target nohost");
25589 DECL_ATTRIBUTES (t)
25590 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25593 if (indirect)
25595 tree at4 = lookup_attribute ("omp declare target indirect",
25596 DECL_ATTRIBUTES (t));
25597 if (at4 == NULL_TREE)
25599 id = get_identifier ("omp declare target indirect");
25600 DECL_ATTRIBUTES (t)
25601 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
25605 if ((device_type || indirect) && only_device_type_or_indirect)
25606 error_at (OMP_CLAUSE_LOCATION (clauses),
25607 "directive with only %<device_type%> or %<indirect%> clauses");
25608 if (indirect && device_type && device_type != OMP_CLAUSE_DEVICE_TYPE_ANY)
25609 error_at (OMP_CLAUSE_LOCATION (clauses),
25610 "%<device_type%> clause must specify 'any' when used with "
25611 "an %<indirect%> clause");
25614 /* OpenMP 5.1
25615 #pragma omp begin assumes clauses[optseq] new-line
25617 #pragma omp begin declare target clauses[optseq] new-line */
25619 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
25620 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25621 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25623 static void
25624 c_parser_omp_begin (c_parser *parser)
25626 const char *p = "";
25627 c_parser_consume_pragma (parser);
25628 if (c_parser_next_token_is (parser, CPP_NAME))
25629 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25630 if (strcmp (p, "declare") == 0)
25632 c_parser_consume_token (parser);
25633 p = "";
25634 if (c_parser_next_token_is (parser, CPP_NAME))
25635 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25636 if (strcmp (p, "target") == 0)
25638 c_parser_consume_token (parser);
25639 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25640 tree clauses
25641 = c_parser_omp_all_clauses (parser,
25642 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
25643 "#pragma omp begin declare target");
25644 int device_type = 0;
25645 int indirect = 0;
25646 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
25648 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
25649 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
25650 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
25651 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
25653 c_omp_declare_target_attr attr = { attr_syntax, device_type,
25654 indirect };
25655 vec_safe_push (current_omp_declare_target_attribute, attr);
25657 else
25659 c_parser_error (parser, "expected %<target%>");
25660 c_parser_skip_to_pragma_eol (parser);
25663 else if (strcmp (p, "assumes") == 0)
25665 c_parser_consume_token (parser);
25666 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25667 c_parser_omp_assumption_clauses (parser, false);
25668 struct c_omp_begin_assumes_data a = { attr_syntax };
25669 vec_safe_push (current_omp_begin_assumes, a);
25671 else
25673 c_parser_error (parser, "expected %<declare target%> or %<assumes%>");
25674 c_parser_skip_to_pragma_eol (parser);
25678 /* OpenMP 4.0
25679 #pragma omp end declare target
25681 OpenMP 5.1
25682 #pragma omp end assumes */
25684 static void
25685 c_parser_omp_end (c_parser *parser)
25687 location_t loc = c_parser_peek_token (parser)->location;
25688 const char *p = "";
25689 c_parser_consume_pragma (parser);
25690 if (c_parser_next_token_is (parser, CPP_NAME))
25691 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25692 if (strcmp (p, "declare") == 0)
25694 c_parser_consume_token (parser);
25695 if (c_parser_next_token_is (parser, CPP_NAME)
25696 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
25697 "target") == 0)
25698 c_parser_consume_token (parser);
25699 else
25701 c_parser_error (parser, "expected %<target%>");
25702 c_parser_skip_to_pragma_eol (parser);
25703 return;
25705 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25706 c_parser_skip_to_pragma_eol (parser);
25707 if (!vec_safe_length (current_omp_declare_target_attribute))
25708 error_at (loc, "%<#pragma omp end declare target%> without "
25709 "corresponding %<#pragma omp declare target%> or "
25710 "%<#pragma omp begin declare target%>");
25711 else
25713 c_omp_declare_target_attr
25714 a = current_omp_declare_target_attribute->pop ();
25715 if (a.attr_syntax != attr_syntax)
25717 if (a.attr_syntax)
25718 error_at (loc,
25719 "%qs in attribute syntax terminated "
25720 "with %qs in pragma syntax",
25721 a.device_type >= 0 ? "begin declare target"
25722 : "declare target",
25723 "end declare target");
25724 else
25725 error_at (loc,
25726 "%qs in pragma syntax terminated "
25727 "with %qs in attribute syntax",
25728 a.device_type >= 0 ? "begin declare target"
25729 : "declare target",
25730 "end declare target");
25734 else if (strcmp (p, "assumes") == 0)
25736 c_parser_consume_token (parser);
25737 bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
25738 c_parser_skip_to_pragma_eol (parser);
25739 if (!vec_safe_length (current_omp_begin_assumes))
25740 error_at (loc, "%qs without corresponding %qs",
25741 "#pragma omp end assumes", "#pragma omp begin assumes");
25742 else
25744 c_omp_begin_assumes_data
25745 a = current_omp_begin_assumes->pop ();
25746 if (a.attr_syntax != attr_syntax)
25748 if (a.attr_syntax)
25749 error_at (loc,
25750 "%qs in attribute syntax terminated "
25751 "with %qs in pragma syntax",
25752 "begin assumes", "end assumes");
25753 else
25754 error_at (loc,
25755 "%qs in pragma syntax terminated "
25756 "with %qs in attribute syntax",
25757 "begin assumes", "end assumes");
25761 else
25763 c_parser_error (parser, "expected %<declare%> or %<assumes%>");
25764 c_parser_skip_to_pragma_eol (parser);
25768 /* OpenMP 4.0
25769 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25770 initializer-clause[opt] new-line
25772 initializer-clause:
25773 initializer (omp_priv = initializer)
25774 initializer (function-name (argument-list)) */
25776 static void
25777 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
25779 unsigned int tokens_avail = 0, i;
25780 c_token *saved_tokens = NULL;
25781 vec<tree> types = vNULL;
25782 vec<c_token> clauses = vNULL;
25783 enum tree_code reduc_code = ERROR_MARK;
25784 tree reduc_id = NULL_TREE;
25785 tree type;
25786 location_t rloc = c_parser_peek_token (parser)->location;
25788 if (context == pragma_struct || context == pragma_param)
25790 error ("%<#pragma omp declare reduction%> not at file or block scope");
25791 goto fail;
25794 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
25795 goto fail;
25797 switch (c_parser_peek_token (parser)->type)
25799 case CPP_PLUS:
25800 reduc_code = PLUS_EXPR;
25801 break;
25802 case CPP_MULT:
25803 reduc_code = MULT_EXPR;
25804 break;
25805 case CPP_MINUS:
25806 reduc_code = MINUS_EXPR;
25807 break;
25808 case CPP_AND:
25809 reduc_code = BIT_AND_EXPR;
25810 break;
25811 case CPP_XOR:
25812 reduc_code = BIT_XOR_EXPR;
25813 break;
25814 case CPP_OR:
25815 reduc_code = BIT_IOR_EXPR;
25816 break;
25817 case CPP_AND_AND:
25818 reduc_code = TRUTH_ANDIF_EXPR;
25819 break;
25820 case CPP_OR_OR:
25821 reduc_code = TRUTH_ORIF_EXPR;
25822 break;
25823 case CPP_NAME:
25824 const char *p;
25825 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
25826 if (strcmp (p, "min") == 0)
25828 reduc_code = MIN_EXPR;
25829 break;
25831 if (strcmp (p, "max") == 0)
25833 reduc_code = MAX_EXPR;
25834 break;
25836 reduc_id = c_parser_peek_token (parser)->value;
25837 break;
25838 default:
25839 c_parser_error (parser,
25840 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
25841 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
25842 goto fail;
25845 tree orig_reduc_id, reduc_decl;
25846 orig_reduc_id = reduc_id;
25847 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
25848 reduc_decl = c_omp_reduction_decl (reduc_id);
25849 c_parser_consume_token (parser);
25851 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
25852 goto fail;
25854 while (true)
25856 location_t loc = c_parser_peek_token (parser)->location;
25857 struct c_type_name *ctype = c_parser_type_name (parser);
25858 if (ctype != NULL)
25860 type = groktypename (ctype, NULL, NULL);
25861 if (type == error_mark_node)
25863 else if ((INTEGRAL_TYPE_P (type)
25864 || SCALAR_FLOAT_TYPE_P (type)
25865 || TREE_CODE (type) == COMPLEX_TYPE)
25866 && orig_reduc_id == NULL_TREE)
25867 error_at (loc, "predeclared arithmetic type in "
25868 "%<#pragma omp declare reduction%>");
25869 else if (TREE_CODE (type) == FUNCTION_TYPE
25870 || TREE_CODE (type) == ARRAY_TYPE)
25871 error_at (loc, "function or array type in "
25872 "%<#pragma omp declare reduction%>");
25873 else if (TYPE_ATOMIC (type))
25874 error_at (loc, "%<_Atomic%> qualified type in "
25875 "%<#pragma omp declare reduction%>");
25876 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
25877 error_at (loc, "const, volatile or restrict qualified type in "
25878 "%<#pragma omp declare reduction%>");
25879 else
25881 tree t;
25882 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
25883 if (comptypes (TREE_PURPOSE (t), type))
25885 error_at (loc, "redeclaration of %qs "
25886 "%<#pragma omp declare reduction%> for "
25887 "type %qT",
25888 IDENTIFIER_POINTER (reduc_id)
25889 + sizeof ("omp declare reduction ") - 1,
25890 type);
25891 location_t ploc
25892 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
25893 0));
25894 error_at (ploc, "previous %<#pragma omp declare "
25895 "reduction%>");
25896 break;
25898 if (t == NULL_TREE)
25899 types.safe_push (type);
25901 if (c_parser_next_token_is (parser, CPP_COMMA))
25902 c_parser_consume_token (parser);
25903 else
25904 break;
25906 else
25907 break;
25910 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
25911 || types.is_empty ())
25913 fail:
25914 clauses.release ();
25915 types.release ();
25916 while (true)
25918 c_token *token = c_parser_peek_token (parser);
25919 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
25920 break;
25921 c_parser_consume_token (parser);
25923 c_parser_skip_to_pragma_eol (parser);
25924 return;
25927 if (types.length () > 1)
25929 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
25931 c_token *token = c_parser_peek_token (parser);
25932 if (token->type == CPP_EOF)
25933 goto fail;
25934 clauses.safe_push (*token);
25935 c_parser_consume_token (parser);
25937 clauses.safe_push (*c_parser_peek_token (parser));
25938 c_parser_skip_to_pragma_eol (parser);
25940 /* Make sure nothing tries to read past the end of the tokens. */
25941 c_token eof_token;
25942 memset (&eof_token, 0, sizeof (eof_token));
25943 eof_token.type = CPP_EOF;
25944 clauses.safe_push (eof_token);
25945 clauses.safe_push (eof_token);
25948 int errs = errorcount;
25949 FOR_EACH_VEC_ELT (types, i, type)
25951 saved_tokens = parser->tokens;
25952 tokens_avail = parser->tokens_avail;
25953 if (!clauses.is_empty ())
25955 parser->tokens = clauses.address ();
25956 parser->tokens_avail = clauses.length ();
25957 parser->in_pragma = true;
25960 bool nested = current_function_decl != NULL_TREE;
25961 if (nested)
25962 c_push_function_context ();
25963 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
25964 reduc_id, default_function_type);
25965 current_function_decl = fndecl;
25966 allocate_struct_function (fndecl, true);
25967 push_scope ();
25968 tree stmt = push_stmt_list ();
25969 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
25970 warn about these. */
25971 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
25972 get_identifier ("omp_out"), type);
25973 DECL_ARTIFICIAL (omp_out) = 1;
25974 DECL_CONTEXT (omp_out) = fndecl;
25975 pushdecl (omp_out);
25976 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
25977 get_identifier ("omp_in"), type);
25978 DECL_ARTIFICIAL (omp_in) = 1;
25979 DECL_CONTEXT (omp_in) = fndecl;
25980 pushdecl (omp_in);
25981 struct c_expr combiner = c_parser_expression (parser);
25982 struct c_expr initializer;
25983 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
25984 bool bad = false;
25985 initializer.set_error ();
25986 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
25987 bad = true;
25988 else if (c_parser_next_token_is (parser, CPP_COMMA)
25989 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
25990 c_parser_consume_token (parser);
25991 if (!bad
25992 && (c_parser_next_token_is (parser, CPP_NAME)
25993 && strcmp (IDENTIFIER_POINTER
25994 (c_parser_peek_token (parser)->value),
25995 "initializer") == 0))
25997 c_parser_consume_token (parser);
25998 pop_scope ();
25999 push_scope ();
26000 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
26001 get_identifier ("omp_priv"), type);
26002 DECL_ARTIFICIAL (omp_priv) = 1;
26003 DECL_INITIAL (omp_priv) = error_mark_node;
26004 DECL_CONTEXT (omp_priv) = fndecl;
26005 pushdecl (omp_priv);
26006 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
26007 get_identifier ("omp_orig"), type);
26008 DECL_ARTIFICIAL (omp_orig) = 1;
26009 DECL_CONTEXT (omp_orig) = fndecl;
26010 pushdecl (omp_orig);
26011 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
26012 bad = true;
26013 else if (!c_parser_next_token_is (parser, CPP_NAME))
26015 c_parser_error (parser, "expected %<omp_priv%> or "
26016 "function-name");
26017 bad = true;
26019 else if (strcmp (IDENTIFIER_POINTER
26020 (c_parser_peek_token (parser)->value),
26021 "omp_priv") != 0)
26023 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
26024 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
26026 c_parser_error (parser, "expected function-name %<(%>");
26027 bad = true;
26029 else
26030 initializer = c_parser_postfix_expression (parser);
26031 if (initializer.value
26032 && TREE_CODE (initializer.value) == CALL_EXPR)
26034 int j;
26035 tree c = initializer.value;
26036 for (j = 0; j < call_expr_nargs (c); j++)
26038 tree a = CALL_EXPR_ARG (c, j);
26039 STRIP_NOPS (a);
26040 if (TREE_CODE (a) == ADDR_EXPR
26041 && TREE_OPERAND (a, 0) == omp_priv)
26042 break;
26044 if (j == call_expr_nargs (c))
26045 error ("one of the initializer call arguments should be "
26046 "%<&omp_priv%>");
26049 else
26051 c_parser_consume_token (parser);
26052 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
26053 bad = true;
26054 else
26056 tree st = push_stmt_list ();
26057 location_t loc = c_parser_peek_token (parser)->location;
26058 rich_location richloc (line_table, loc);
26059 start_init (omp_priv, NULL_TREE, false, false, &richloc);
26060 struct c_expr init = c_parser_initializer (parser, omp_priv);
26061 finish_init ();
26062 finish_decl (omp_priv, loc, init.value,
26063 init.original_type, NULL_TREE);
26064 pop_stmt_list (st);
26067 if (!bad
26068 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
26069 bad = true;
26072 if (!bad)
26074 c_parser_skip_to_pragma_eol (parser);
26076 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
26077 DECL_INITIAL (reduc_decl));
26078 DECL_INITIAL (reduc_decl) = t;
26079 DECL_SOURCE_LOCATION (omp_out) = rloc;
26080 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
26081 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
26082 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
26083 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
26084 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
26085 if (omp_priv)
26087 DECL_SOURCE_LOCATION (omp_priv) = rloc;
26088 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
26089 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
26090 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
26091 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
26092 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
26093 walk_tree (&DECL_INITIAL (omp_priv),
26094 c_check_omp_declare_reduction_r,
26095 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
26099 pop_stmt_list (stmt);
26100 pop_scope ();
26101 if (cfun->language != NULL)
26103 ggc_free (cfun->language);
26104 cfun->language = NULL;
26106 set_cfun (NULL);
26107 current_function_decl = NULL_TREE;
26108 if (nested)
26109 c_pop_function_context ();
26111 if (!clauses.is_empty ())
26113 parser->tokens = saved_tokens;
26114 parser->tokens_avail = tokens_avail;
26116 if (bad)
26117 goto fail;
26118 if (errs != errorcount)
26119 break;
26122 clauses.release ();
26123 types.release ();
26127 /* OpenMP 4.0
26128 #pragma omp declare simd declare-simd-clauses[optseq] new-line
26129 #pragma omp declare reduction (reduction-id : typename-list : expression) \
26130 initializer-clause[opt] new-line
26131 #pragma omp declare target new-line
26133 OpenMP 5.0
26134 #pragma omp declare variant (identifier) match (context-selector) */
26136 static bool
26137 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
26139 c_parser_consume_pragma (parser);
26140 if (c_parser_next_token_is (parser, CPP_NAME))
26142 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26143 if (strcmp (p, "simd") == 0)
26145 /* c_parser_consume_token (parser); done in
26146 c_parser_omp_declare_simd. */
26147 c_parser_omp_declare_simd (parser, context);
26148 return true;
26150 if (strcmp (p, "reduction") == 0)
26152 c_parser_consume_token (parser);
26153 c_parser_omp_declare_reduction (parser, context);
26154 return false;
26156 if (!flag_openmp) /* flag_openmp_simd */
26158 c_parser_skip_to_pragma_eol (parser, false);
26159 return false;
26161 if (strcmp (p, "target") == 0)
26163 c_parser_consume_token (parser);
26164 c_parser_omp_declare_target (parser);
26165 return false;
26167 if (strcmp (p, "variant") == 0)
26169 /* c_parser_consume_token (parser); done in
26170 c_parser_omp_declare_simd. */
26171 c_parser_omp_declare_simd (parser, context);
26172 return true;
26176 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
26177 "%<target%> or %<variant%>");
26178 c_parser_skip_to_pragma_eol (parser);
26179 return false;
26182 /* OpenMP 5.0
26183 #pragma omp requires clauses[optseq] new-line */
26185 static void
26186 c_parser_omp_requires (c_parser *parser)
26188 enum omp_requires new_req = (enum omp_requires) 0;
26190 c_parser_consume_pragma (parser);
26192 location_t loc = c_parser_peek_token (parser)->location;
26193 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
26195 if (c_parser_next_token_is (parser, CPP_COMMA)
26196 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
26197 c_parser_consume_token (parser);
26199 if (c_parser_next_token_is (parser, CPP_NAME))
26201 const char *p
26202 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26203 location_t cloc = c_parser_peek_token (parser)->location;
26204 enum omp_requires this_req = (enum omp_requires) 0;
26206 if (!strcmp (p, "unified_address"))
26207 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
26208 else if (!strcmp (p, "unified_shared_memory"))
26209 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
26210 else if (!strcmp (p, "dynamic_allocators"))
26211 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
26212 else if (!strcmp (p, "reverse_offload"))
26213 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
26214 else if (!strcmp (p, "atomic_default_mem_order"))
26216 c_parser_consume_token (parser);
26218 matching_parens parens;
26219 if (parens.require_open (parser))
26221 if (c_parser_next_token_is (parser, CPP_NAME))
26223 tree v = c_parser_peek_token (parser)->value;
26224 p = IDENTIFIER_POINTER (v);
26226 if (!strcmp (p, "seq_cst"))
26227 this_req
26228 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
26229 else if (!strcmp (p, "relaxed"))
26230 this_req
26231 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
26232 else if (!strcmp (p, "release"))
26233 this_req
26234 = (enum omp_requires) OMP_MEMORY_ORDER_RELEASE;
26235 else if (!strcmp (p, "acq_rel"))
26236 this_req
26237 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
26238 else if (!strcmp (p, "acquire"))
26239 this_req
26240 = (enum omp_requires) OMP_MEMORY_ORDER_ACQUIRE;
26242 if (this_req == 0)
26244 error_at (c_parser_peek_token (parser)->location,
26245 "expected %<acq_rel%>, %<acquire%>, "
26246 "%<relaxed%>, %<release%> or %<seq_cst%>");
26247 switch (c_parser_peek_token (parser)->type)
26249 case CPP_EOF:
26250 case CPP_PRAGMA_EOL:
26251 case CPP_CLOSE_PAREN:
26252 break;
26253 default:
26254 if (c_parser_peek_2nd_token (parser)->type
26255 == CPP_CLOSE_PAREN)
26256 c_parser_consume_token (parser);
26257 break;
26260 else
26261 c_parser_consume_token (parser);
26263 parens.skip_until_found_close (parser);
26264 if (this_req == 0)
26266 c_parser_skip_to_pragma_eol (parser, false);
26267 return;
26270 p = NULL;
26272 else
26274 error_at (cloc, "expected %<unified_address%>, "
26275 "%<unified_shared_memory%>, "
26276 "%<dynamic_allocators%>, "
26277 "%<reverse_offload%> "
26278 "or %<atomic_default_mem_order%> clause");
26279 c_parser_skip_to_pragma_eol (parser, false);
26280 return;
26282 if (p)
26283 c_parser_consume_token (parser);
26284 if (this_req)
26286 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
26288 if ((this_req & new_req) != 0)
26289 error_at (cloc, "too many %qs clauses", p);
26290 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
26291 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
26292 error_at (cloc, "%qs clause used lexically after first "
26293 "target construct or offloading API", p);
26295 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
26297 error_at (cloc, "too many %qs clauses",
26298 "atomic_default_mem_order");
26299 this_req = (enum omp_requires) 0;
26301 else if ((omp_requires_mask
26302 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
26304 error_at (cloc, "more than one %<atomic_default_mem_order%>"
26305 " clause in a single compilation unit");
26306 this_req
26307 = (enum omp_requires)
26308 (omp_requires_mask
26309 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
26311 else if ((omp_requires_mask
26312 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
26313 error_at (cloc, "%<atomic_default_mem_order%> clause used "
26314 "lexically after first %<atomic%> construct "
26315 "without memory order clause");
26316 new_req = (enum omp_requires) (new_req | this_req);
26317 omp_requires_mask
26318 = (enum omp_requires) (omp_requires_mask | this_req);
26319 continue;
26322 break;
26324 c_parser_skip_to_pragma_eol (parser);
26326 if (new_req == 0)
26327 error_at (loc, "%<pragma omp requires%> requires at least one clause");
26330 /* Helper function for c_parser_omp_taskloop.
26331 Disallow zero sized or potentially zero sized task reductions. */
26333 static tree
26334 c_finish_taskloop_clauses (tree clauses)
26336 tree *pc = &clauses;
26337 for (tree c = clauses; c; c = *pc)
26339 bool remove = false;
26340 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
26342 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
26343 if (integer_zerop (TYPE_SIZE_UNIT (type)))
26345 error_at (OMP_CLAUSE_LOCATION (c),
26346 "zero sized type %qT in %<reduction%> clause", type);
26347 remove = true;
26349 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
26351 error_at (OMP_CLAUSE_LOCATION (c),
26352 "variable sized type %qT in %<reduction%> clause",
26353 type);
26354 remove = true;
26357 if (remove)
26358 *pc = OMP_CLAUSE_CHAIN (c);
26359 else
26360 pc = &OMP_CLAUSE_CHAIN (c);
26362 return clauses;
26365 /* OpenMP 4.5:
26366 #pragma omp taskloop taskloop-clause[optseq] new-line
26367 for-loop
26369 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
26370 for-loop */
26372 #define OMP_TASKLOOP_CLAUSE_MASK \
26373 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
26374 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
26375 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
26376 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
26377 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
26378 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
26379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
26380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
26381 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
26382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
26383 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
26384 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
26385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
26386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
26387 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
26388 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
26389 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
26391 static tree
26392 c_parser_omp_taskloop (location_t loc, c_parser *parser,
26393 char *p_name, omp_clause_mask mask, tree *cclauses,
26394 bool *if_p)
26396 tree clauses, block, ret;
26398 strcat (p_name, " taskloop");
26399 mask |= OMP_TASKLOOP_CLAUSE_MASK;
26400 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
26401 clause. */
26402 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
26403 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
26405 if (c_parser_next_token_is (parser, CPP_NAME))
26407 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26409 if (strcmp (p, "simd") == 0)
26411 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
26412 if (cclauses == NULL)
26413 cclauses = cclauses_buf;
26414 c_parser_consume_token (parser);
26415 if (!flag_openmp) /* flag_openmp_simd */
26416 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
26417 if_p);
26418 block = c_begin_compound_stmt (true);
26419 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
26420 block = c_end_compound_stmt (loc, block, true);
26421 if (ret == NULL)
26422 return ret;
26423 ret = make_node (OMP_TASKLOOP);
26424 TREE_TYPE (ret) = void_type_node;
26425 OMP_FOR_BODY (ret) = block;
26426 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
26427 OMP_FOR_CLAUSES (ret)
26428 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
26429 SET_EXPR_LOCATION (ret, loc);
26430 add_stmt (ret);
26431 return ret;
26434 if (!flag_openmp) /* flag_openmp_simd */
26436 c_parser_skip_to_pragma_eol (parser, false);
26437 return NULL_TREE;
26440 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
26441 if (cclauses)
26443 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
26444 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
26447 clauses = c_finish_taskloop_clauses (clauses);
26448 block = c_begin_compound_stmt (true);
26449 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
26450 block = c_end_compound_stmt (loc, block, true);
26451 add_stmt (block);
26453 return ret;
26456 /* OpenMP 5.1: Parse sizes list for "omp tile sizes"
26457 sizes ( size-expr-list ) */
26458 static tree
26459 c_parser_omp_tile_sizes (c_parser *parser, location_t loc)
26461 tree sizes = NULL_TREE;
26463 if (c_parser_next_token_is (parser, CPP_COMMA))
26464 c_parser_consume_token (parser);
26466 c_token *tok = c_parser_peek_token (parser);
26467 if (tok->type != CPP_NAME
26468 || strcmp ("sizes", IDENTIFIER_POINTER (tok->value)))
26470 c_parser_error (parser, "expected %<sizes%>");
26471 return error_mark_node;
26473 c_parser_consume_token (parser);
26475 matching_parens parens;
26476 if (!parens.require_open (parser))
26477 return error_mark_node;
26479 vec<tree, va_gc> *sizes_vec
26480 = c_parser_expr_list (parser, true, true, NULL, NULL, NULL, NULL);
26481 sizes = build_tree_list_vec (sizes_vec);
26482 release_tree_vector (sizes_vec);
26484 for (tree s = sizes; s; s = TREE_CHAIN (s))
26486 tree expr = TREE_VALUE (s);
26487 if (expr == error_mark_node)
26489 parens.skip_until_found_close (parser);
26490 return error_mark_node;
26493 HOST_WIDE_INT n;
26494 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
26495 || !tree_fits_shwi_p (expr)
26496 || (n = tree_to_shwi (expr)) <= 0
26497 || (int) n != n)
26499 c_parser_error (parser, "%<sizes%> argument needs positive"
26500 " integral constant");
26501 TREE_VALUE (s) = integer_one_node;
26504 parens.require_close (parser);
26506 gcc_assert (sizes);
26507 tree c = build_omp_clause (loc, OMP_CLAUSE_SIZES);
26508 OMP_CLAUSE_SIZES_LIST (c) = sizes;
26510 return c;
26513 /* OpenMP 5.1:
26514 #pragma omp tile sizes ( size-expr-list ) new-line
26515 for-loop
26517 LOC is the location of the #pragma token. */
26519 static tree
26520 c_parser_omp_tile (location_t loc, c_parser *parser, bool *if_p)
26522 tree clauses = c_parser_omp_tile_sizes (parser, loc);
26523 c_parser_skip_to_pragma_eol (parser);
26525 if (!clauses || clauses == error_mark_node)
26526 return error_mark_node;
26528 tree block = c_begin_compound_stmt (true);
26529 tree ret = c_parser_omp_for_loop (loc, parser, OMP_TILE, clauses,
26530 NULL, if_p);
26531 block = c_end_compound_stmt (loc, block, true);
26532 add_stmt (block);
26534 return ret;
26537 #define OMP_UNROLL_CLAUSE_MASK \
26538 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARTIAL) \
26539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FULL))
26541 /* OpenMP 5.1
26542 #pragma omp unroll unroll-clause[optseq] new-line
26543 for-loop
26545 LOC is the location of the #pragma token. */
26547 static tree
26548 c_parser_omp_unroll (location_t loc, c_parser *parser, bool *if_p)
26550 tree clauses = c_parser_omp_all_clauses (parser, OMP_UNROLL_CLAUSE_MASK,
26551 "#pragma omp unroll", true);
26553 tree block = c_begin_compound_stmt (true);
26554 tree ret = c_parser_omp_for_loop (loc, parser, OMP_UNROLL, clauses,
26555 NULL, if_p);
26556 block = c_end_compound_stmt (loc, block, true);
26557 add_stmt (block);
26559 return ret;
26562 /* OpenMP 5.1
26563 #pragma omp nothing new-line */
26565 static void
26566 c_parser_omp_nothing (c_parser *parser)
26568 c_parser_consume_pragma (parser);
26569 c_parser_skip_to_pragma_eol (parser);
26572 /* OpenMP 5.1
26573 #pragma omp error clauses[optseq] new-line */
26575 static bool
26576 c_parser_omp_error (c_parser *parser, enum pragma_context context)
26578 int at_compilation = -1;
26579 int severity_fatal = -1;
26580 tree message = NULL_TREE;
26581 bool bad = false;
26582 location_t loc = c_parser_peek_token (parser)->location;
26584 c_parser_consume_pragma (parser);
26586 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
26588 if (c_parser_next_token_is (parser, CPP_COMMA)
26589 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
26590 c_parser_consume_token (parser);
26592 if (!c_parser_next_token_is (parser, CPP_NAME))
26593 break;
26595 const char *p
26596 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26597 location_t cloc = c_parser_peek_token (parser)->location;
26598 static const char *args[] = {
26599 "execution", "compilation", "warning", "fatal"
26601 int *v = NULL;
26602 int idx = 0, n = -1;
26603 tree m = NULL_TREE;
26605 if (!strcmp (p, "at"))
26606 v = &at_compilation;
26607 else if (!strcmp (p, "severity"))
26609 v = &severity_fatal;
26610 idx += 2;
26612 else if (strcmp (p, "message"))
26614 error_at (cloc,
26615 "expected %<at%>, %<severity%> or %<message%> clause");
26616 c_parser_skip_to_pragma_eol (parser, false);
26617 return false;
26620 c_parser_consume_token (parser);
26622 matching_parens parens;
26623 if (parens.require_open (parser))
26625 if (v == NULL)
26627 location_t expr_loc = c_parser_peek_token (parser)->location;
26628 c_expr expr = c_parser_expr_no_commas (parser, NULL);
26629 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
26630 m = convert (const_string_type_node, expr.value);
26631 m = c_fully_fold (m, false, NULL);
26633 else
26635 if (c_parser_next_token_is (parser, CPP_NAME))
26637 tree val = c_parser_peek_token (parser)->value;
26638 const char *q = IDENTIFIER_POINTER (val);
26640 if (!strcmp (q, args[idx]))
26641 n = 0;
26642 else if (!strcmp (q, args[idx + 1]))
26643 n = 1;
26645 if (n == -1)
26647 error_at (c_parser_peek_token (parser)->location,
26648 "expected %qs or %qs", args[idx], args[idx + 1]);
26649 bad = true;
26650 switch (c_parser_peek_token (parser)->type)
26652 case CPP_EOF:
26653 case CPP_PRAGMA_EOL:
26654 case CPP_CLOSE_PAREN:
26655 break;
26656 default:
26657 if (c_parser_peek_2nd_token (parser)->type
26658 == CPP_CLOSE_PAREN)
26659 c_parser_consume_token (parser);
26660 break;
26663 else
26664 c_parser_consume_token (parser);
26667 parens.skip_until_found_close (parser);
26669 if (v == NULL)
26671 if (message)
26673 error_at (cloc, "too many %qs clauses", p);
26674 bad = true;
26676 else
26677 message = m;
26679 else if (n != -1)
26681 if (*v != -1)
26683 error_at (cloc, "too many %qs clauses", p);
26684 bad = true;
26686 else
26687 *v = n;
26690 else
26691 bad = true;
26693 c_parser_skip_to_pragma_eol (parser);
26694 if (bad)
26695 return true;
26697 if (at_compilation == -1)
26698 at_compilation = 1;
26699 if (severity_fatal == -1)
26700 severity_fatal = 1;
26701 if (!at_compilation)
26703 if (context != pragma_compound)
26705 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
26706 "may only be used in compound statements");
26707 return true;
26709 tree fndecl
26710 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
26711 : BUILT_IN_GOMP_WARNING);
26712 if (!message)
26713 message = build_zero_cst (const_string_type_node);
26714 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
26715 build_all_ones_cst (size_type_node));
26716 add_stmt (stmt);
26717 return true;
26719 const char *msg = NULL;
26720 if (message)
26722 msg = c_getstr (message);
26723 if (msg == NULL)
26724 msg = _("<message unknown at compile time>");
26726 if (msg)
26727 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
26728 "%<pragma omp error%> encountered: %s", msg);
26729 else
26730 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
26731 "%<pragma omp error%> encountered");
26732 return false;
26735 /* Assumption clauses:
26736 OpenMP 5.1
26737 absent (directive-name-list)
26738 contains (directive-name-list)
26739 holds (expression)
26740 no_openmp
26741 no_openmp_routines
26742 no_parallelism */
26744 static void
26745 c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
26747 bool no_openmp = false;
26748 bool no_openmp_routines = false;
26749 bool no_parallelism = false;
26750 bitmap_head absent_head, contains_head;
26752 bitmap_obstack_initialize (NULL);
26753 bitmap_initialize (&absent_head, &bitmap_default_obstack);
26754 bitmap_initialize (&contains_head, &bitmap_default_obstack);
26756 if (c_parser_next_token_is (parser, CPP_PRAGMA_EOL))
26757 error_at (c_parser_peek_token (parser)->location,
26758 "expected at least one assumption clause");
26760 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
26762 if (c_parser_next_token_is (parser, CPP_COMMA)
26763 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
26764 c_parser_consume_token (parser);
26766 if (!c_parser_next_token_is (parser, CPP_NAME))
26767 break;
26769 const char *p
26770 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
26771 location_t cloc = c_parser_peek_token (parser)->location;
26773 if (!strcmp (p, "no_openmp"))
26775 c_parser_consume_token (parser);
26776 if (no_openmp)
26777 error_at (cloc, "too many %qs clauses", "no_openmp");
26778 no_openmp = true;
26780 else if (!strcmp (p, "no_openmp_routines"))
26782 c_parser_consume_token (parser);
26783 if (no_openmp_routines)
26784 error_at (cloc, "too many %qs clauses", "no_openmp_routines");
26785 no_openmp_routines = true;
26787 else if (!strcmp (p, "no_parallelism"))
26789 c_parser_consume_token (parser);
26790 if (no_parallelism)
26791 error_at (cloc, "too many %qs clauses", "no_parallelism");
26792 no_parallelism = true;
26794 else if (!strcmp (p, "holds"))
26796 c_parser_consume_token (parser);
26797 matching_parens parens;
26798 if (parens.require_open (parser))
26800 location_t eloc = c_parser_peek_token (parser)->location;
26801 c_expr expr = c_parser_expr_no_commas (parser, NULL);
26802 tree t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
26803 t = c_objc_common_truthvalue_conversion (eloc, t);
26804 t = c_fully_fold (t, false, NULL);
26805 if (is_assume && t != error_mark_node)
26807 tree fn = build_call_expr_internal_loc (eloc, IFN_ASSUME,
26808 void_type_node, 1,
26810 add_stmt (fn);
26812 parens.skip_until_found_close (parser);
26815 else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
26817 c_parser_consume_token (parser);
26818 matching_parens parens;
26819 if (parens.require_open (parser))
26823 const char *directive[3] = {};
26824 int i;
26825 location_t dloc = c_parser_peek_token (parser)->location;
26826 for (i = 0; i < 3; i++)
26828 tree id;
26829 if (c_parser_peek_nth_token (parser, i + 1)->type
26830 == CPP_NAME)
26831 id = c_parser_peek_nth_token (parser, i + 1)->value;
26832 else if (c_parser_peek_nth_token (parser, i + 1)->keyword
26833 != RID_MAX)
26835 enum rid rid
26836 = c_parser_peek_nth_token (parser, i + 1)->keyword;
26837 id = ridpointers[rid];
26839 else
26840 break;
26841 directive[i] = IDENTIFIER_POINTER (id);
26843 if (i == 0)
26844 error_at (dloc, "expected directive name");
26845 else
26847 const struct c_omp_directive *dir
26848 = c_omp_categorize_directive (directive[0],
26849 directive[1],
26850 directive[2]);
26851 if (dir == NULL
26852 || dir->kind == C_OMP_DIR_DECLARATIVE
26853 || dir->kind == C_OMP_DIR_INFORMATIONAL
26854 || dir->id == PRAGMA_OMP_END
26855 || (!dir->second && directive[1])
26856 || (!dir->third && directive[2]))
26857 error_at (dloc, "unknown OpenMP directive name in "
26858 "%qs clause argument", p);
26859 else
26861 int id = dir - c_omp_directives;
26862 if (bitmap_bit_p (p[0] == 'a' ? &contains_head
26863 : &absent_head, id))
26864 error_at (dloc, "%<%s%s%s%s%s%> directive "
26865 "mentioned in both %<absent%> and "
26866 "%<contains%> clauses",
26867 directive[0],
26868 directive[1] ? " " : "",
26869 directive[1] ? directive[1] : "",
26870 directive[2] ? " " : "",
26871 directive[2] ? directive[2] : "");
26872 else if (!bitmap_set_bit (p[0] == 'a'
26873 ? &absent_head
26874 : &contains_head, id))
26875 error_at (dloc, "%<%s%s%s%s%s%> directive "
26876 "mentioned multiple times in %qs "
26877 "clauses",
26878 directive[0],
26879 directive[1] ? " " : "",
26880 directive[1] ? directive[1] : "",
26881 directive[2] ? " " : "",
26882 directive[2] ? directive[2] : "", p);
26884 for (; i; --i)
26885 c_parser_consume_token (parser);
26887 if (c_parser_next_token_is (parser, CPP_COMMA))
26888 c_parser_consume_token (parser);
26889 else
26890 break;
26892 while (1);
26893 parens.skip_until_found_close (parser);
26896 else if (startswith (p, "ext_"))
26898 warning_at (cloc, OPT_Wopenmp, "unknown assumption clause %qs", p);
26899 c_parser_consume_token (parser);
26900 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
26902 matching_parens parens;
26903 parens.consume_open (parser);
26904 c_parser_balanced_token_sequence (parser);
26905 parens.require_close (parser);
26908 else
26910 c_parser_consume_token (parser);
26911 error_at (cloc, "expected assumption clause");
26912 break;
26915 c_parser_skip_to_pragma_eol (parser);
26918 /* OpenMP 5.1
26919 #pragma omp assume clauses[optseq] new-line */
26921 static void
26922 c_parser_omp_assume (c_parser *parser, bool *if_p)
26924 c_parser_omp_assumption_clauses (parser, true);
26925 add_stmt (c_parser_omp_structured_block (parser, if_p));
26928 /* OpenMP 5.1
26929 #pragma omp assumes clauses[optseq] new-line */
26931 static void
26932 c_parser_omp_assumes (c_parser *parser)
26934 c_parser_consume_pragma (parser);
26935 c_parser_omp_assumption_clauses (parser, false);
26938 /* Main entry point to parsing most OpenMP pragmas. */
26940 static void
26941 c_parser_omp_construct (c_parser *parser, bool *if_p)
26943 enum pragma_kind p_kind;
26944 location_t loc;
26945 tree stmt;
26946 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
26947 omp_clause_mask mask (0);
26949 loc = c_parser_peek_token (parser)->location;
26950 p_kind = c_parser_peek_token (parser)->pragma_kind;
26951 c_parser_consume_pragma (parser);
26953 switch (p_kind)
26955 case PRAGMA_OACC_ATOMIC:
26956 c_parser_omp_atomic (loc, parser, true);
26957 return;
26958 case PRAGMA_OACC_CACHE:
26959 strcpy (p_name, "#pragma acc");
26960 stmt = c_parser_oacc_cache (loc, parser);
26961 break;
26962 case PRAGMA_OACC_DATA:
26963 stmt = c_parser_oacc_data (loc, parser, if_p);
26964 break;
26965 case PRAGMA_OACC_HOST_DATA:
26966 stmt = c_parser_oacc_host_data (loc, parser, if_p);
26967 break;
26968 case PRAGMA_OACC_KERNELS:
26969 case PRAGMA_OACC_PARALLEL:
26970 case PRAGMA_OACC_SERIAL:
26971 strcpy (p_name, "#pragma acc");
26972 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
26973 break;
26974 case PRAGMA_OACC_LOOP:
26975 strcpy (p_name, "#pragma acc");
26976 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
26977 break;
26978 case PRAGMA_OACC_WAIT:
26979 strcpy (p_name, "#pragma wait");
26980 stmt = c_parser_oacc_wait (loc, parser, p_name);
26981 break;
26982 case PRAGMA_OMP_ATOMIC:
26983 c_parser_omp_atomic (loc, parser, false);
26984 return;
26985 case PRAGMA_OMP_CRITICAL:
26986 stmt = c_parser_omp_critical (loc, parser, if_p);
26987 break;
26988 case PRAGMA_OMP_DISTRIBUTE:
26989 strcpy (p_name, "#pragma omp");
26990 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
26991 break;
26992 case PRAGMA_OMP_FOR:
26993 strcpy (p_name, "#pragma omp");
26994 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
26995 break;
26996 case PRAGMA_OMP_LOOP:
26997 strcpy (p_name, "#pragma omp");
26998 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
26999 break;
27000 case PRAGMA_OMP_MASKED:
27001 strcpy (p_name, "#pragma omp");
27002 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
27003 break;
27004 case PRAGMA_OMP_MASTER:
27005 strcpy (p_name, "#pragma omp");
27006 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
27007 break;
27008 case PRAGMA_OMP_PARALLEL:
27009 strcpy (p_name, "#pragma omp");
27010 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
27011 break;
27012 case PRAGMA_OMP_SCOPE:
27013 stmt = c_parser_omp_scope (loc, parser, if_p);
27014 break;
27015 case PRAGMA_OMP_SECTIONS:
27016 strcpy (p_name, "#pragma omp");
27017 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
27018 break;
27019 case PRAGMA_OMP_SIMD:
27020 strcpy (p_name, "#pragma omp");
27021 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
27022 break;
27023 case PRAGMA_OMP_SINGLE:
27024 stmt = c_parser_omp_single (loc, parser, if_p);
27025 break;
27026 case PRAGMA_OMP_TASK:
27027 stmt = c_parser_omp_task (loc, parser, if_p);
27028 break;
27029 case PRAGMA_OMP_TASKGROUP:
27030 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
27031 break;
27032 case PRAGMA_OMP_TASKLOOP:
27033 strcpy (p_name, "#pragma omp");
27034 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
27035 break;
27036 case PRAGMA_OMP_TEAMS:
27037 strcpy (p_name, "#pragma omp");
27038 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
27039 break;
27040 case PRAGMA_OMP_ASSUME:
27041 c_parser_omp_assume (parser, if_p);
27042 return;
27043 case PRAGMA_OMP_TILE:
27044 stmt = c_parser_omp_tile (loc, parser, if_p);
27045 break;
27046 case PRAGMA_OMP_UNROLL:
27047 stmt = c_parser_omp_unroll (loc, parser, if_p);
27048 break;
27049 default:
27050 gcc_unreachable ();
27053 if (stmt && stmt != error_mark_node)
27054 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
27058 /* OpenMP 2.5:
27059 # pragma omp threadprivate (variable-list) */
27061 static void
27062 c_parser_omp_threadprivate (c_parser *parser)
27064 tree vars, t;
27065 location_t loc;
27067 c_parser_consume_pragma (parser);
27068 loc = c_parser_peek_token (parser)->location;
27069 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
27071 /* Mark every variable in VARS to be assigned thread local storage. */
27072 for (t = vars; t; t = TREE_CHAIN (t))
27074 tree v = TREE_PURPOSE (t);
27076 /* FIXME diagnostics: Ideally we should keep individual
27077 locations for all the variables in the var list to make the
27078 following errors more precise. Perhaps
27079 c_parser_omp_var_list_parens() should construct a list of
27080 locations to go along with the var list. */
27082 /* If V had already been marked threadprivate, it doesn't matter
27083 whether it had been used prior to this point. */
27084 if (!VAR_P (v))
27085 error_at (loc, "%qD is not a variable", v);
27086 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
27087 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
27088 else if (! is_global_var (v))
27089 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
27090 else if (TREE_TYPE (v) == error_mark_node)
27092 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
27093 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
27094 else
27096 if (! DECL_THREAD_LOCAL_P (v))
27098 set_decl_tls_model (v, decl_default_tls_model (v));
27099 /* If rtl has been already set for this var, call
27100 make_decl_rtl once again, so that encode_section_info
27101 has a chance to look at the new decl flags. */
27102 if (DECL_RTL_SET_P (v))
27103 make_decl_rtl (v);
27105 C_DECL_THREADPRIVATE_P (v) = 1;
27109 c_parser_skip_to_pragma_eol (parser);
27112 /* Parse a transaction attribute (GCC Extension).
27114 transaction-attribute:
27115 gnu-attributes
27116 attribute-specifier
27119 static tree
27120 c_parser_transaction_attributes (c_parser *parser)
27122 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
27123 return c_parser_gnu_attributes (parser);
27125 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
27126 return NULL_TREE;
27127 return c_parser_std_attribute_specifier (parser, true);
27130 /* Parse a __transaction_atomic or __transaction_relaxed statement
27131 (GCC Extension).
27133 transaction-statement:
27134 __transaction_atomic transaction-attribute[opt] compound-statement
27135 __transaction_relaxed compound-statement
27137 Note that the only valid attribute is: "outer".
27140 static tree
27141 c_parser_transaction (c_parser *parser, enum rid keyword)
27143 unsigned int old_in = parser->in_transaction;
27144 unsigned int this_in = 1, new_in;
27145 location_t loc = c_parser_peek_token (parser)->location;
27146 tree stmt, attrs;
27148 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
27149 || keyword == RID_TRANSACTION_RELAXED)
27150 && c_parser_next_token_is_keyword (parser, keyword));
27151 c_parser_consume_token (parser);
27153 if (keyword == RID_TRANSACTION_RELAXED)
27154 this_in |= TM_STMT_ATTR_RELAXED;
27155 else
27157 attrs = c_parser_transaction_attributes (parser);
27158 if (attrs)
27159 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
27162 /* Keep track if we're in the lexical scope of an outer transaction. */
27163 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
27165 parser->in_transaction = new_in;
27166 stmt = c_parser_compound_statement (parser);
27167 parser->in_transaction = old_in;
27169 if (flag_tm)
27170 stmt = c_finish_transaction (loc, stmt, this_in);
27171 else
27172 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
27173 "%<__transaction_atomic%> without transactional memory support enabled"
27174 : "%<__transaction_relaxed %> "
27175 "without transactional memory support enabled"));
27177 return stmt;
27180 /* Parse a __transaction_atomic or __transaction_relaxed expression
27181 (GCC Extension).
27183 transaction-expression:
27184 __transaction_atomic ( expression )
27185 __transaction_relaxed ( expression )
27188 static struct c_expr
27189 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
27191 struct c_expr ret;
27192 unsigned int old_in = parser->in_transaction;
27193 unsigned int this_in = 1;
27194 location_t loc = c_parser_peek_token (parser)->location;
27195 tree attrs;
27197 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
27198 || keyword == RID_TRANSACTION_RELAXED)
27199 && c_parser_next_token_is_keyword (parser, keyword));
27200 c_parser_consume_token (parser);
27202 if (keyword == RID_TRANSACTION_RELAXED)
27203 this_in |= TM_STMT_ATTR_RELAXED;
27204 else
27206 attrs = c_parser_transaction_attributes (parser);
27207 if (attrs)
27208 this_in |= parse_tm_stmt_attr (attrs, 0);
27211 parser->in_transaction = this_in;
27212 matching_parens parens;
27213 if (parens.require_open (parser))
27215 tree expr = c_parser_expression (parser).value;
27216 ret.original_type = TREE_TYPE (expr);
27217 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
27218 if (this_in & TM_STMT_ATTR_RELAXED)
27219 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
27220 SET_EXPR_LOCATION (ret.value, loc);
27221 ret.original_code = TRANSACTION_EXPR;
27222 ret.m_decimal = 0;
27223 if (!parens.require_close (parser))
27225 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
27226 goto error;
27229 else
27231 error:
27232 ret.set_error ();
27233 ret.original_code = ERROR_MARK;
27234 ret.original_type = NULL;
27236 parser->in_transaction = old_in;
27238 if (!flag_tm)
27239 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
27240 "%<__transaction_atomic%> without transactional memory support enabled"
27241 : "%<__transaction_relaxed %> "
27242 "without transactional memory support enabled"));
27244 set_c_expr_source_range (&ret, loc, loc);
27246 return ret;
27249 /* Parse a __transaction_cancel statement (GCC Extension).
27251 transaction-cancel-statement:
27252 __transaction_cancel transaction-attribute[opt] ;
27254 Note that the only valid attribute is "outer".
27257 static tree
27258 c_parser_transaction_cancel (c_parser *parser)
27260 location_t loc = c_parser_peek_token (parser)->location;
27261 tree attrs;
27262 bool is_outer = false;
27264 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
27265 c_parser_consume_token (parser);
27267 attrs = c_parser_transaction_attributes (parser);
27268 if (attrs)
27269 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
27271 if (!flag_tm)
27273 error_at (loc, "%<__transaction_cancel%> without "
27274 "transactional memory support enabled");
27275 goto ret_error;
27277 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
27279 error_at (loc, "%<__transaction_cancel%> within a "
27280 "%<__transaction_relaxed%>");
27281 goto ret_error;
27283 else if (is_outer)
27285 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
27286 && !is_tm_may_cancel_outer (current_function_decl))
27288 error_at (loc, "outer %<__transaction_cancel%> not "
27289 "within outer %<__transaction_atomic%> or "
27290 "a %<transaction_may_cancel_outer%> function");
27291 goto ret_error;
27294 else if (parser->in_transaction == 0)
27296 error_at (loc, "%<__transaction_cancel%> not within "
27297 "%<__transaction_atomic%>");
27298 goto ret_error;
27301 return add_stmt (build_tm_abort_call (loc, is_outer));
27303 ret_error:
27304 return build1 (NOP_EXPR, void_type_node, error_mark_node);
27307 /* Parse a single source file. */
27309 void
27310 c_parse_file (void)
27312 /* Use local storage to begin. If the first token is a pragma, parse it.
27313 If it is #pragma GCC pch_preprocess, then this will load a PCH file
27314 which will cause garbage collection. */
27315 c_parser tparser;
27317 memset (&tparser, 0, sizeof tparser);
27318 tparser.translate_strings_p = true;
27319 tparser.tokens = &tparser.tokens_buf[0];
27320 the_parser = &tparser;
27322 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
27323 c_parser_pragma_pch_preprocess (&tparser);
27324 else
27325 c_common_no_more_pch ();
27327 the_parser = ggc_alloc<c_parser> ();
27328 *the_parser = tparser;
27329 if (tparser.tokens == &tparser.tokens_buf[0])
27330 the_parser->tokens = &the_parser->tokens_buf[0];
27332 /* Initialize EH, if we've been told to do so. */
27333 if (flag_exceptions)
27334 using_eh_for_cleanups ();
27336 c_parser_translation_unit (the_parser);
27337 the_parser = NULL;
27340 void
27341 c_init_preprocess (void)
27343 /* Create a parser for use by pragma_lex during preprocessing. */
27344 the_parser = ggc_alloc<c_parser> ();
27345 memset (the_parser, 0, sizeof (c_parser));
27346 the_parser->tokens = &the_parser->tokens_buf[0];
27349 /* Parse the body of a function declaration marked with "__RTL".
27351 The RTL parser works on the level of characters read from a
27352 FILE *, whereas c_parser works at the level of tokens.
27353 Square this circle by consuming all of the tokens up to and
27354 including the closing brace, recording the start/end of the RTL
27355 fragment, and reopening the file and re-reading the relevant
27356 lines within the RTL parser.
27358 This requires the opening and closing braces of the C function
27359 to be on separate lines from the RTL they wrap.
27361 Take ownership of START_WITH_PASS, if non-NULL. */
27363 location_t
27364 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
27366 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
27368 free (start_with_pass);
27369 return c_parser_peek_token (parser)->location;
27372 location_t start_loc = c_parser_peek_token (parser)->location;
27374 /* Consume all tokens, up to the closing brace, handling
27375 matching pairs of braces in the rtl dump. */
27376 int num_open_braces = 1;
27377 while (1)
27379 switch (c_parser_peek_token (parser)->type)
27381 case CPP_OPEN_BRACE:
27382 num_open_braces++;
27383 break;
27384 case CPP_CLOSE_BRACE:
27385 if (--num_open_braces == 0)
27386 goto found_closing_brace;
27387 break;
27388 case CPP_EOF:
27389 error_at (start_loc, "no closing brace");
27390 free (start_with_pass);
27391 return c_parser_peek_token (parser)->location;
27392 default:
27393 break;
27395 c_parser_consume_token (parser);
27398 found_closing_brace:
27399 /* At the closing brace; record its location. */
27400 location_t end_loc = c_parser_peek_token (parser)->location;
27402 /* Consume the closing brace. */
27403 c_parser_consume_token (parser);
27405 /* Invoke the RTL parser. */
27406 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
27408 free (start_with_pass);
27409 return end_loc;
27412 /* Run the backend on the cfun created above, transferring ownership of
27413 START_WITH_PASS. */
27414 run_rtl_passes (start_with_pass);
27415 return end_loc;
27418 #include "gt-c-c-parser.h"