Fix ICE on view conversion between struct and integer
[official-gcc.git] / gcc / c / c-parser.cc
blob92049d1a101da86db8b000ac676b30c63e5947b3
1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2022 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"
75 /* We need to walk over decls with incomplete struct/union/enum types
76 after parsing the whole translation unit.
77 In finish_decl(), if the decl is static, has incomplete
78 struct/union/enum type, it is appended to incomplete_record_decls.
79 In c_parser_translation_unit(), we iterate over incomplete_record_decls
80 and report error if any of the decls are still incomplete. */
82 vec<tree> incomplete_record_decls;
84 void
85 set_c_expr_source_range (c_expr *expr,
86 location_t start, location_t finish)
88 expr->src_range.m_start = start;
89 expr->src_range.m_finish = finish;
90 if (expr->value)
91 set_source_range (expr->value, start, finish);
94 void
95 set_c_expr_source_range (c_expr *expr,
96 source_range src_range)
98 expr->src_range = src_range;
99 if (expr->value)
100 set_source_range (expr->value, src_range);
104 /* Initialization routine for this file. */
106 void
107 c_parse_init (void)
109 /* The only initialization required is of the reserved word
110 identifiers. */
111 unsigned int i;
112 tree id;
113 int mask = 0;
115 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
116 the c_token structure. */
117 gcc_assert (RID_MAX <= 255);
119 mask |= D_CXXONLY;
120 if (!flag_isoc99)
121 mask |= D_C99;
122 if (flag_no_asm)
124 mask |= D_ASM | D_EXT;
125 if (!flag_isoc99)
126 mask |= D_EXT89;
128 if (!c_dialect_objc ())
129 mask |= D_OBJC | D_CXX_OBJC;
131 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
132 for (i = 0; i < num_c_common_reswords; i++)
134 /* If a keyword is disabled, do not enter it into the table
135 and so create a canonical spelling that isn't a keyword. */
136 if (c_common_reswords[i].disable & mask)
138 if (warn_cxx_compat
139 && (c_common_reswords[i].disable & D_CXXWARN))
141 id = get_identifier (c_common_reswords[i].word);
142 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
143 C_IS_RESERVED_WORD (id) = 1;
145 continue;
148 id = get_identifier (c_common_reswords[i].word);
149 C_SET_RID_CODE (id, c_common_reswords[i].rid);
150 C_IS_RESERVED_WORD (id) = 1;
151 ridpointers [(int) c_common_reswords[i].rid] = id;
154 for (i = 0; i < NUM_INT_N_ENTS; i++)
156 /* We always create the symbols but they aren't always supported. */
157 char name[50];
158 sprintf (name, "__int%d", int_n_data[i].bitsize);
159 id = get_identifier (name);
160 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
161 C_IS_RESERVED_WORD (id) = 1;
163 sprintf (name, "__int%d__", int_n_data[i].bitsize);
164 id = get_identifier (name);
165 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
166 C_IS_RESERVED_WORD (id) = 1;
169 if (flag_openmp)
171 id = get_identifier ("omp_all_memory");
172 C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
173 C_IS_RESERVED_WORD (id) = 1;
174 ridpointers [RID_OMP_ALL_MEMORY] = id;
178 /* A parser structure recording information about the state and
179 context of parsing. Includes lexer information with up to two
180 tokens of look-ahead; more are not needed for C. */
181 struct GTY(()) c_parser {
182 /* The look-ahead tokens. */
183 c_token * GTY((skip)) tokens;
184 /* Buffer for look-ahead tokens. */
185 c_token tokens_buf[4];
186 /* How many look-ahead tokens are available (0 - 4, or
187 more if parsing from pre-lexed tokens). */
188 unsigned int tokens_avail;
189 /* Raw look-ahead tokens, used only for checking in Objective-C
190 whether '[[' starts attributes. */
191 vec<c_token, va_gc> *raw_tokens;
192 /* The number of raw look-ahead tokens that have since been fully
193 lexed. */
194 unsigned int raw_tokens_used;
195 /* True if a syntax error is being recovered from; false otherwise.
196 c_parser_error sets this flag. It should clear this flag when
197 enough tokens have been consumed to recover from the error. */
198 BOOL_BITFIELD error : 1;
199 /* True if we're processing a pragma, and shouldn't automatically
200 consume CPP_PRAGMA_EOL. */
201 BOOL_BITFIELD in_pragma : 1;
202 /* True if we're parsing the outermost block of an if statement. */
203 BOOL_BITFIELD in_if_block : 1;
204 /* True if we want to lex a translated, joined string (for an
205 initial #pragma pch_preprocess). Otherwise the parser is
206 responsible for concatenating strings and translating to the
207 execution character set as needed. */
208 BOOL_BITFIELD lex_joined_string : 1;
209 /* True if, when the parser is concatenating string literals, it
210 should translate them to the execution character set (false
211 inside attributes). */
212 BOOL_BITFIELD translate_strings_p : 1;
214 /* Objective-C specific parser/lexer information. */
216 /* True if we are in a context where the Objective-C "PQ" keywords
217 are considered keywords. */
218 BOOL_BITFIELD objc_pq_context : 1;
219 /* True if we are parsing a (potential) Objective-C foreach
220 statement. This is set to true after we parsed 'for (' and while
221 we wait for 'in' or ';' to decide if it's a standard C for loop or an
222 Objective-C foreach loop. */
223 BOOL_BITFIELD objc_could_be_foreach_context : 1;
224 /* The following flag is needed to contextualize Objective-C lexical
225 analysis. In some cases (e.g., 'int NSObject;'), it is
226 undesirable to bind an identifier to an Objective-C class, even
227 if a class with that name exists. */
228 BOOL_BITFIELD objc_need_raw_identifier : 1;
229 /* Nonzero if we're processing a __transaction statement. The value
230 is 1 | TM_STMT_ATTR_*. */
231 unsigned int in_transaction : 4;
232 /* True if we are in a context where the Objective-C "Property attribute"
233 keywords are valid. */
234 BOOL_BITFIELD objc_property_attr_context : 1;
236 /* Whether we have just seen/constructed a string-literal. Set when
237 returning a string-literal from c_parser_string_literal. Reset
238 in consume_token. Useful when we get a parse error and see an
239 unknown token, which could have been a string-literal constant
240 macro. */
241 BOOL_BITFIELD seen_string_literal : 1;
243 /* Location of the last consumed token. */
244 location_t last_token_location;
247 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
249 c_token *
250 c_parser_tokens_buf (c_parser *parser, unsigned n)
252 return &parser->tokens_buf[n];
255 /* Return the error state of PARSER. */
257 bool
258 c_parser_error (c_parser *parser)
260 return parser->error;
263 /* Set the error state of PARSER to ERR. */
265 void
266 c_parser_set_error (c_parser *parser, bool err)
268 parser->error = err;
272 /* The actual parser and external interface. ??? Does this need to be
273 garbage-collected? */
275 static GTY (()) c_parser *the_parser;
277 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
278 context-sensitive postprocessing of the token is not done. */
280 static void
281 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
283 timevar_push (TV_LEX);
285 if (raw || vec_safe_length (parser->raw_tokens) == 0)
287 token->type = c_lex_with_flags (&token->value, &token->location,
288 &token->flags,
289 (parser->lex_joined_string
290 ? 0 : C_LEX_STRING_NO_JOIN));
291 token->id_kind = C_ID_NONE;
292 token->keyword = RID_MAX;
293 token->pragma_kind = PRAGMA_NONE;
295 else
297 /* Use a token previously lexed as a raw look-ahead token, and
298 complete the processing on it. */
299 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
300 ++parser->raw_tokens_used;
301 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
303 vec_free (parser->raw_tokens);
304 parser->raw_tokens_used = 0;
308 if (raw)
309 goto out;
311 switch (token->type)
313 case CPP_NAME:
315 tree decl;
317 bool objc_force_identifier = parser->objc_need_raw_identifier;
318 if (c_dialect_objc ())
319 parser->objc_need_raw_identifier = false;
321 if (C_IS_RESERVED_WORD (token->value))
323 enum rid rid_code = C_RID_CODE (token->value);
325 if (rid_code == RID_CXX_COMPAT_WARN)
327 warning_at (token->location,
328 OPT_Wc___compat,
329 "identifier %qE conflicts with C++ keyword",
330 token->value);
332 else if (rid_code >= RID_FIRST_ADDR_SPACE
333 && rid_code <= RID_LAST_ADDR_SPACE)
335 addr_space_t as;
336 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
337 targetm.addr_space.diagnose_usage (as, token->location);
338 token->id_kind = C_ID_ADDRSPACE;
339 token->keyword = rid_code;
340 break;
342 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
344 /* We found an Objective-C "pq" keyword (in, out,
345 inout, bycopy, byref, oneway). They need special
346 care because the interpretation depends on the
347 context. */
348 if (parser->objc_pq_context)
350 token->type = CPP_KEYWORD;
351 token->keyword = rid_code;
352 break;
354 else if (parser->objc_could_be_foreach_context
355 && rid_code == RID_IN)
357 /* We are in Objective-C, inside a (potential)
358 foreach context (which means after having
359 parsed 'for (', but before having parsed ';'),
360 and we found 'in'. We consider it the keyword
361 which terminates the declaration at the
362 beginning of a foreach-statement. Note that
363 this means you can't use 'in' for anything else
364 in that context; in particular, in Objective-C
365 you can't use 'in' as the name of the running
366 variable in a C for loop. We could potentially
367 try to add code here to disambiguate, but it
368 seems a reasonable limitation. */
369 token->type = CPP_KEYWORD;
370 token->keyword = rid_code;
371 break;
373 /* Else, "pq" keywords outside of the "pq" context are
374 not keywords, and we fall through to the code for
375 normal tokens. */
377 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
379 /* We found an Objective-C "property attribute"
380 keyword (getter, setter, readonly, etc). These are
381 only valid in the property context. */
382 if (parser->objc_property_attr_context)
384 token->type = CPP_KEYWORD;
385 token->keyword = rid_code;
386 break;
388 /* Else they are not special keywords.
391 else if (c_dialect_objc ()
392 && (OBJC_IS_AT_KEYWORD (rid_code)
393 || OBJC_IS_CXX_KEYWORD (rid_code)))
395 /* We found one of the Objective-C "@" keywords (defs,
396 selector, synchronized, etc) or one of the
397 Objective-C "cxx" keywords (class, private,
398 protected, public, try, catch, throw) without a
399 preceding '@' sign. Do nothing and fall through to
400 the code for normal tokens (in C++ we would still
401 consider the CXX ones keywords, but not in C). */
404 else
406 token->type = CPP_KEYWORD;
407 token->keyword = rid_code;
408 break;
412 decl = lookup_name (token->value);
413 if (decl)
415 if (TREE_CODE (decl) == TYPE_DECL)
417 token->id_kind = C_ID_TYPENAME;
418 break;
421 else if (c_dialect_objc ())
423 tree objc_interface_decl = objc_is_class_name (token->value);
424 /* Objective-C class names are in the same namespace as
425 variables and typedefs, and hence are shadowed by local
426 declarations. */
427 if (objc_interface_decl
428 && (!objc_force_identifier || global_bindings_p ()))
430 token->value = objc_interface_decl;
431 token->id_kind = C_ID_CLASSNAME;
432 break;
435 token->id_kind = C_ID_ID;
437 break;
438 case CPP_AT_NAME:
439 /* This only happens in Objective-C; it must be a keyword. */
440 token->type = CPP_KEYWORD;
441 switch (C_RID_CODE (token->value))
443 /* Replace 'class' with '@class', 'private' with '@private',
444 etc. This prevents confusion with the C++ keyword
445 'class', and makes the tokens consistent with other
446 Objective-C 'AT' keywords. For example '@class' is
447 reported as RID_AT_CLASS which is consistent with
448 '@synchronized', which is reported as
449 RID_AT_SYNCHRONIZED.
451 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
452 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
453 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
454 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
455 case RID_THROW: token->keyword = RID_AT_THROW; break;
456 case RID_TRY: token->keyword = RID_AT_TRY; break;
457 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
458 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
459 default: token->keyword = C_RID_CODE (token->value);
461 break;
462 case CPP_COLON:
463 case CPP_COMMA:
464 case CPP_CLOSE_PAREN:
465 case CPP_SEMICOLON:
466 /* These tokens may affect the interpretation of any identifiers
467 following, if doing Objective-C. */
468 if (c_dialect_objc ())
469 parser->objc_need_raw_identifier = false;
470 break;
471 case CPP_PRAGMA:
472 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
473 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
474 token->value = NULL;
475 break;
476 default:
477 break;
479 out:
480 timevar_pop (TV_LEX);
483 /* Return a pointer to the next token from PARSER, reading it in if
484 necessary. */
486 c_token *
487 c_parser_peek_token (c_parser *parser)
489 if (parser->tokens_avail == 0)
491 c_lex_one_token (parser, &parser->tokens[0]);
492 parser->tokens_avail = 1;
494 return &parser->tokens[0];
497 /* Return a pointer to the next-but-one token from PARSER, reading it
498 in if necessary. The next token is already read in. */
500 c_token *
501 c_parser_peek_2nd_token (c_parser *parser)
503 if (parser->tokens_avail >= 2)
504 return &parser->tokens[1];
505 gcc_assert (parser->tokens_avail == 1);
506 gcc_assert (parser->tokens[0].type != CPP_EOF);
507 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
508 c_lex_one_token (parser, &parser->tokens[1]);
509 parser->tokens_avail = 2;
510 return &parser->tokens[1];
513 /* Return a pointer to the Nth token from PARSER, reading it
514 in if necessary. The N-1th token is already read in. */
516 c_token *
517 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
519 /* N is 1-based, not zero-based. */
520 gcc_assert (n > 0);
522 if (parser->tokens_avail >= n)
523 return &parser->tokens[n - 1];
524 gcc_assert (parser->tokens_avail == n - 1);
525 c_lex_one_token (parser, &parser->tokens[n - 1]);
526 parser->tokens_avail = n;
527 return &parser->tokens[n - 1];
530 /* Return a pointer to the Nth token from PARSER, reading it in as a
531 raw look-ahead token if necessary. The N-1th token is already read
532 in. Raw look-ahead tokens remain available for when the non-raw
533 functions above are called. */
535 c_token *
536 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
538 /* N is 1-based, not zero-based. */
539 gcc_assert (n > 0);
541 if (parser->tokens_avail >= n)
542 return &parser->tokens[n - 1];
543 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
544 unsigned int raw_avail
545 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
546 gcc_assert (raw_avail >= n - 1);
547 if (raw_avail >= n)
548 return &(*parser->raw_tokens)[parser->raw_tokens_used
549 + n - 1 - parser->tokens_avail];
550 vec_safe_reserve (parser->raw_tokens, 1);
551 parser->raw_tokens->quick_grow (raw_len + 1);
552 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
553 return &(*parser->raw_tokens)[raw_len];
556 bool
557 c_keyword_starts_typename (enum rid keyword)
559 switch (keyword)
561 case RID_UNSIGNED:
562 case RID_LONG:
563 case RID_SHORT:
564 case RID_SIGNED:
565 case RID_COMPLEX:
566 case RID_INT:
567 case RID_CHAR:
568 case RID_FLOAT:
569 case RID_DOUBLE:
570 case RID_VOID:
571 case RID_DFLOAT32:
572 case RID_DFLOAT64:
573 case RID_DFLOAT128:
574 CASE_RID_FLOATN_NX:
575 case RID_BOOL:
576 case RID_ENUM:
577 case RID_STRUCT:
578 case RID_UNION:
579 case RID_TYPEOF:
580 case RID_CONST:
581 case RID_ATOMIC:
582 case RID_VOLATILE:
583 case RID_RESTRICT:
584 case RID_ATTRIBUTE:
585 case RID_FRACT:
586 case RID_ACCUM:
587 case RID_SAT:
588 case RID_AUTO_TYPE:
589 case RID_ALIGNAS:
590 return true;
591 default:
592 if (keyword >= RID_FIRST_INT_N
593 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
594 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
595 return true;
596 return false;
600 /* Return true if TOKEN can start a type name,
601 false otherwise. */
602 bool
603 c_token_starts_typename (c_token *token)
605 switch (token->type)
607 case CPP_NAME:
608 switch (token->id_kind)
610 case C_ID_ID:
611 return false;
612 case C_ID_ADDRSPACE:
613 return true;
614 case C_ID_TYPENAME:
615 return true;
616 case C_ID_CLASSNAME:
617 gcc_assert (c_dialect_objc ());
618 return true;
619 default:
620 gcc_unreachable ();
622 case CPP_KEYWORD:
623 return c_keyword_starts_typename (token->keyword);
624 case CPP_LESS:
625 if (c_dialect_objc ())
626 return true;
627 return false;
628 default:
629 return false;
633 /* Return true if the next token from PARSER can start a type name,
634 false otherwise. LA specifies how to do lookahead in order to
635 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
637 static inline bool
638 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
640 c_token *token = c_parser_peek_token (parser);
641 if (c_token_starts_typename (token))
642 return true;
644 /* Try a bit harder to detect an unknown typename. */
645 if (la != cla_prefer_id
646 && token->type == CPP_NAME
647 && token->id_kind == C_ID_ID
649 /* Do not try too hard when we could have "object in array". */
650 && !parser->objc_could_be_foreach_context
652 && (la == cla_prefer_type
653 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
654 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
656 /* Only unknown identifiers. */
657 && !lookup_name (token->value))
658 return true;
660 return false;
663 /* Return true if TOKEN is a type qualifier, false otherwise. */
664 static bool
665 c_token_is_qualifier (c_token *token)
667 switch (token->type)
669 case CPP_NAME:
670 switch (token->id_kind)
672 case C_ID_ADDRSPACE:
673 return true;
674 default:
675 return false;
677 case CPP_KEYWORD:
678 switch (token->keyword)
680 case RID_CONST:
681 case RID_VOLATILE:
682 case RID_RESTRICT:
683 case RID_ATTRIBUTE:
684 case RID_ATOMIC:
685 return true;
686 default:
687 return false;
689 case CPP_LESS:
690 return false;
691 default:
692 gcc_unreachable ();
696 /* Return true if the next token from PARSER is a type qualifier,
697 false otherwise. */
698 static inline bool
699 c_parser_next_token_is_qualifier (c_parser *parser)
701 c_token *token = c_parser_peek_token (parser);
702 return c_token_is_qualifier (token);
705 /* Return true if TOKEN can start declaration specifiers (not
706 including standard attributes), false otherwise. */
707 static bool
708 c_token_starts_declspecs (c_token *token)
710 switch (token->type)
712 case CPP_NAME:
713 switch (token->id_kind)
715 case C_ID_ID:
716 return false;
717 case C_ID_ADDRSPACE:
718 return true;
719 case C_ID_TYPENAME:
720 return true;
721 case C_ID_CLASSNAME:
722 gcc_assert (c_dialect_objc ());
723 return true;
724 default:
725 gcc_unreachable ();
727 case CPP_KEYWORD:
728 switch (token->keyword)
730 case RID_STATIC:
731 case RID_EXTERN:
732 case RID_REGISTER:
733 case RID_TYPEDEF:
734 case RID_INLINE:
735 case RID_NORETURN:
736 case RID_AUTO:
737 case RID_THREAD:
738 case RID_UNSIGNED:
739 case RID_LONG:
740 case RID_SHORT:
741 case RID_SIGNED:
742 case RID_COMPLEX:
743 case RID_INT:
744 case RID_CHAR:
745 case RID_FLOAT:
746 case RID_DOUBLE:
747 case RID_VOID:
748 case RID_DFLOAT32:
749 case RID_DFLOAT64:
750 case RID_DFLOAT128:
751 CASE_RID_FLOATN_NX:
752 case RID_BOOL:
753 case RID_ENUM:
754 case RID_STRUCT:
755 case RID_UNION:
756 case RID_TYPEOF:
757 case RID_CONST:
758 case RID_VOLATILE:
759 case RID_RESTRICT:
760 case RID_ATTRIBUTE:
761 case RID_FRACT:
762 case RID_ACCUM:
763 case RID_SAT:
764 case RID_ALIGNAS:
765 case RID_ATOMIC:
766 case RID_AUTO_TYPE:
767 return true;
768 default:
769 if (token->keyword >= RID_FIRST_INT_N
770 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
771 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
772 return true;
773 return false;
775 case CPP_LESS:
776 if (c_dialect_objc ())
777 return true;
778 return false;
779 default:
780 return false;
785 /* Return true if TOKEN can start declaration specifiers (not
786 including standard attributes) or a static assertion, false
787 otherwise. */
788 static bool
789 c_token_starts_declaration (c_token *token)
791 if (c_token_starts_declspecs (token)
792 || token->keyword == RID_STATIC_ASSERT)
793 return true;
794 else
795 return false;
798 /* Return true if the next token from PARSER can start declaration
799 specifiers (not including standard attributes), false
800 otherwise. */
801 bool
802 c_parser_next_token_starts_declspecs (c_parser *parser)
804 c_token *token = c_parser_peek_token (parser);
806 /* In Objective-C, a classname normally starts a declspecs unless it
807 is immediately followed by a dot. In that case, it is the
808 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
809 setter/getter on the class. c_token_starts_declspecs() can't
810 differentiate between the two cases because it only checks the
811 current token, so we have a special check here. */
812 if (c_dialect_objc ()
813 && token->type == CPP_NAME
814 && token->id_kind == C_ID_CLASSNAME
815 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
816 return false;
818 return c_token_starts_declspecs (token);
821 /* Return true if the next tokens from PARSER can start declaration
822 specifiers (not including standard attributes) or a static
823 assertion, false otherwise. */
824 bool
825 c_parser_next_tokens_start_declaration (c_parser *parser)
827 c_token *token = c_parser_peek_token (parser);
829 /* Same as above. */
830 if (c_dialect_objc ()
831 && token->type == CPP_NAME
832 && token->id_kind == C_ID_CLASSNAME
833 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
834 return false;
836 /* Labels do not start declarations. */
837 if (token->type == CPP_NAME
838 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
839 return false;
841 if (c_token_starts_declaration (token))
842 return true;
844 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
845 return true;
847 return false;
850 /* Consume the next token from PARSER. */
852 void
853 c_parser_consume_token (c_parser *parser)
855 gcc_assert (parser->tokens_avail >= 1);
856 gcc_assert (parser->tokens[0].type != CPP_EOF);
857 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
858 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
859 parser->last_token_location = parser->tokens[0].location;
860 if (parser->tokens != &parser->tokens_buf[0])
861 parser->tokens++;
862 else if (parser->tokens_avail >= 2)
864 parser->tokens[0] = parser->tokens[1];
865 if (parser->tokens_avail >= 3)
867 parser->tokens[1] = parser->tokens[2];
868 if (parser->tokens_avail >= 4)
869 parser->tokens[2] = parser->tokens[3];
872 parser->tokens_avail--;
873 parser->seen_string_literal = false;
876 /* Expect the current token to be a #pragma. Consume it and remember
877 that we've begun parsing a pragma. */
879 static void
880 c_parser_consume_pragma (c_parser *parser)
882 gcc_assert (!parser->in_pragma);
883 gcc_assert (parser->tokens_avail >= 1);
884 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
885 if (parser->tokens != &parser->tokens_buf[0])
886 parser->tokens++;
887 else if (parser->tokens_avail >= 2)
889 parser->tokens[0] = parser->tokens[1];
890 if (parser->tokens_avail >= 3)
891 parser->tokens[1] = parser->tokens[2];
893 parser->tokens_avail--;
894 parser->in_pragma = true;
897 /* Update the global input_location from TOKEN. */
898 static inline void
899 c_parser_set_source_position_from_token (c_token *token)
901 if (token->type != CPP_EOF)
903 input_location = token->location;
907 /* Helper function for c_parser_error.
908 Having peeked a token of kind TOK1_KIND that might signify
909 a conflict marker, peek successor tokens to determine
910 if we actually do have a conflict marker.
911 Specifically, we consider a run of 7 '<', '=' or '>' characters
912 at the start of a line as a conflict marker.
913 These come through the lexer as three pairs and a single,
914 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
915 If it returns true, *OUT_LOC is written to with the location/range
916 of the marker. */
918 static bool
919 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
920 location_t *out_loc)
922 c_token *token2 = c_parser_peek_2nd_token (parser);
923 if (token2->type != tok1_kind)
924 return false;
925 c_token *token3 = c_parser_peek_nth_token (parser, 3);
926 if (token3->type != tok1_kind)
927 return false;
928 c_token *token4 = c_parser_peek_nth_token (parser, 4);
929 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
930 return false;
932 /* It must be at the start of the line. */
933 location_t start_loc = c_parser_peek_token (parser)->location;
934 if (LOCATION_COLUMN (start_loc) != 1)
935 return false;
937 /* We have a conflict marker. Construct a location of the form:
938 <<<<<<<
939 ^~~~~~~
940 with start == caret, finishing at the end of the marker. */
941 location_t finish_loc = get_finish (token4->location);
942 *out_loc = make_location (start_loc, start_loc, finish_loc);
944 return true;
947 /* Issue a diagnostic of the form
948 FILE:LINE: MESSAGE before TOKEN
949 where TOKEN is the next token in the input stream of PARSER.
950 MESSAGE (specified by the caller) is usually of the form "expected
951 OTHER-TOKEN".
953 Use RICHLOC as the location of the diagnostic.
955 Do not issue a diagnostic if still recovering from an error.
957 Return true iff an error was actually emitted.
959 ??? This is taken from the C++ parser, but building up messages in
960 this way is not i18n-friendly and some other approach should be
961 used. */
963 static bool
964 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
965 rich_location *richloc)
967 c_token *token = c_parser_peek_token (parser);
968 if (parser->error)
969 return false;
970 parser->error = true;
971 if (!gmsgid)
972 return false;
974 /* If this is actually a conflict marker, report it as such. */
975 if (token->type == CPP_LSHIFT
976 || token->type == CPP_RSHIFT
977 || token->type == CPP_EQ_EQ)
979 location_t loc;
980 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
982 error_at (loc, "version control conflict marker in file");
983 return true;
987 /* If we were parsing a string-literal and there is an unknown name
988 token right after, then check to see if that could also have been
989 a literal string by checking the name against a list of known
990 standard string literal constants defined in header files. If
991 there is one, then add that as an hint to the error message. */
992 auto_diagnostic_group d;
993 name_hint h;
994 if (parser->seen_string_literal && token->type == CPP_NAME)
996 tree name = token->value;
997 const char *token_name = IDENTIFIER_POINTER (name);
998 const char *header_hint
999 = get_c_stdlib_header_for_string_macro_name (token_name);
1000 if (header_hint != NULL)
1001 h = name_hint (NULL, new suggest_missing_header (token->location,
1002 token_name,
1003 header_hint));
1006 c_parse_error (gmsgid,
1007 /* Because c_parse_error does not understand
1008 CPP_KEYWORD, keywords are treated like
1009 identifiers. */
1010 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1011 /* ??? The C parser does not save the cpp flags of a
1012 token, we need to pass 0 here and we will not get
1013 the source spelling of some tokens but rather the
1014 canonical spelling. */
1015 token->value, /*flags=*/0, richloc);
1016 return true;
1019 /* As c_parser_error_richloc, but issue the message at the
1020 location of PARSER's next token, or at input_location
1021 if the next token is EOF. */
1023 bool
1024 c_parser_error (c_parser *parser, const char *gmsgid)
1026 c_token *token = c_parser_peek_token (parser);
1027 c_parser_set_source_position_from_token (token);
1028 rich_location richloc (line_table, input_location);
1029 return c_parser_error_richloc (parser, gmsgid, &richloc);
1032 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1033 This class is for tracking such a matching pair of symbols.
1034 In particular, it tracks the location of the first token,
1035 so that if the second token is missing, we can highlight the
1036 location of the first token when notifying the user about the
1037 problem. */
1039 template <typename traits_t>
1040 class token_pair
1042 public:
1043 /* token_pair's ctor. */
1044 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1046 /* If the next token is the opening symbol for this pair, consume it and
1047 return true.
1048 Otherwise, issue an error and return false.
1049 In either case, record the location of the opening token. */
1051 bool require_open (c_parser *parser)
1053 c_token *token = c_parser_peek_token (parser);
1054 if (token)
1055 m_open_loc = token->location;
1057 return c_parser_require (parser, traits_t::open_token_type,
1058 traits_t::open_gmsgid);
1061 /* Consume the next token from PARSER, recording its location as
1062 that of the opening token within the pair. */
1064 void consume_open (c_parser *parser)
1066 c_token *token = c_parser_peek_token (parser);
1067 gcc_assert (token->type == traits_t::open_token_type);
1068 m_open_loc = token->location;
1069 c_parser_consume_token (parser);
1072 /* If the next token is the closing symbol for this pair, consume it
1073 and return true.
1074 Otherwise, issue an error, highlighting the location of the
1075 corresponding opening token, and return false. */
1077 bool require_close (c_parser *parser) const
1079 return c_parser_require (parser, traits_t::close_token_type,
1080 traits_t::close_gmsgid, m_open_loc);
1083 /* Like token_pair::require_close, except that tokens will be skipped
1084 until the desired token is found. An error message is still produced
1085 if the next token is not as expected. */
1087 void skip_until_found_close (c_parser *parser) const
1089 c_parser_skip_until_found (parser, traits_t::close_token_type,
1090 traits_t::close_gmsgid, m_open_loc);
1093 private:
1094 location_t m_open_loc;
1097 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1099 struct matching_paren_traits
1101 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1102 static const char * const open_gmsgid;
1103 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1104 static const char * const close_gmsgid;
1107 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1108 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1110 /* "matching_parens" is a token_pair<T> class for tracking matching
1111 pairs of parentheses. */
1113 typedef token_pair<matching_paren_traits> matching_parens;
1115 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1117 struct matching_brace_traits
1119 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1120 static const char * const open_gmsgid;
1121 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1122 static const char * const close_gmsgid;
1125 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1126 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1128 /* "matching_braces" is a token_pair<T> class for tracking matching
1129 pairs of braces. */
1131 typedef token_pair<matching_brace_traits> matching_braces;
1133 /* Get a description of the matching symbol to TYPE e.g. "(" for
1134 CPP_CLOSE_PAREN. */
1136 static const char *
1137 get_matching_symbol (enum cpp_ttype type)
1139 switch (type)
1141 default:
1142 gcc_unreachable ();
1143 case CPP_CLOSE_PAREN:
1144 return "(";
1145 case CPP_CLOSE_BRACE:
1146 return "{";
1150 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1151 issue the error MSGID. If MSGID is NULL then a message has already
1152 been produced and no message will be produced this time. Returns
1153 true if found, false otherwise.
1155 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1156 within any error as the location of an "opening" token matching
1157 the close token TYPE (e.g. the location of the '(' when TYPE is
1158 CPP_CLOSE_PAREN).
1160 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1161 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1162 attempt to generate a fix-it hint for the problem.
1163 Otherwise msgid describes multiple token types (e.g.
1164 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1165 generate a fix-it hint. */
1167 bool
1168 c_parser_require (c_parser *parser,
1169 enum cpp_ttype type,
1170 const char *msgid,
1171 location_t matching_location,
1172 bool type_is_unique)
1174 if (c_parser_next_token_is (parser, type))
1176 c_parser_consume_token (parser);
1177 return true;
1179 else
1181 location_t next_token_loc = c_parser_peek_token (parser)->location;
1182 gcc_rich_location richloc (next_token_loc);
1184 /* Potentially supply a fix-it hint, suggesting to add the
1185 missing token immediately after the *previous* token.
1186 This may move the primary location within richloc. */
1187 if (!parser->error && type_is_unique)
1188 maybe_suggest_missing_token_insertion (&richloc, type,
1189 parser->last_token_location);
1191 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1192 Attempt to consolidate diagnostics by printing it as a
1193 secondary range within the main diagnostic. */
1194 bool added_matching_location = false;
1195 if (matching_location != UNKNOWN_LOCATION)
1196 added_matching_location
1197 = richloc.add_location_if_nearby (matching_location);
1199 if (c_parser_error_richloc (parser, msgid, &richloc))
1200 /* If we weren't able to consolidate matching_location, then
1201 print it as a secondary diagnostic. */
1202 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1203 inform (matching_location, "to match this %qs",
1204 get_matching_symbol (type));
1206 return false;
1210 /* If the next token is the indicated keyword, consume it. Otherwise,
1211 issue the error MSGID. Returns true if found, false otherwise. */
1213 static bool
1214 c_parser_require_keyword (c_parser *parser,
1215 enum rid keyword,
1216 const char *msgid)
1218 if (c_parser_next_token_is_keyword (parser, keyword))
1220 c_parser_consume_token (parser);
1221 return true;
1223 else
1225 c_parser_error (parser, msgid);
1226 return false;
1230 /* Like c_parser_require, except that tokens will be skipped until the
1231 desired token is found. An error message is still produced if the
1232 next token is not as expected. If MSGID is NULL then a message has
1233 already been produced and no message will be produced this
1234 time.
1236 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1237 within any error as the location of an "opening" token matching
1238 the close token TYPE (e.g. the location of the '(' when TYPE is
1239 CPP_CLOSE_PAREN). */
1241 void
1242 c_parser_skip_until_found (c_parser *parser,
1243 enum cpp_ttype type,
1244 const char *msgid,
1245 location_t matching_location)
1247 unsigned nesting_depth = 0;
1249 if (c_parser_require (parser, type, msgid, matching_location))
1250 return;
1252 /* Skip tokens until the desired token is found. */
1253 while (true)
1255 /* Peek at the next token. */
1256 c_token *token = c_parser_peek_token (parser);
1257 /* If we've reached the token we want, consume it and stop. */
1258 if (token->type == type && !nesting_depth)
1260 c_parser_consume_token (parser);
1261 break;
1264 /* If we've run out of tokens, stop. */
1265 if (token->type == CPP_EOF)
1266 return;
1267 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1268 return;
1269 if (token->type == CPP_OPEN_BRACE
1270 || token->type == CPP_OPEN_PAREN
1271 || token->type == CPP_OPEN_SQUARE)
1272 ++nesting_depth;
1273 else if (token->type == CPP_CLOSE_BRACE
1274 || token->type == CPP_CLOSE_PAREN
1275 || token->type == CPP_CLOSE_SQUARE)
1277 if (nesting_depth-- == 0)
1278 break;
1280 /* Consume this token. */
1281 c_parser_consume_token (parser);
1283 parser->error = false;
1286 /* Skip tokens until the end of a parameter is found, but do not
1287 consume the comma, semicolon or closing delimiter. */
1289 static void
1290 c_parser_skip_to_end_of_parameter (c_parser *parser)
1292 unsigned nesting_depth = 0;
1294 while (true)
1296 c_token *token = c_parser_peek_token (parser);
1297 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1298 && !nesting_depth)
1299 break;
1300 /* If we've run out of tokens, stop. */
1301 if (token->type == CPP_EOF)
1302 return;
1303 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1304 return;
1305 if (token->type == CPP_OPEN_BRACE
1306 || token->type == CPP_OPEN_PAREN
1307 || token->type == CPP_OPEN_SQUARE)
1308 ++nesting_depth;
1309 else if (token->type == CPP_CLOSE_BRACE
1310 || token->type == CPP_CLOSE_PAREN
1311 || token->type == CPP_CLOSE_SQUARE)
1313 if (nesting_depth-- == 0)
1314 break;
1316 /* Consume this token. */
1317 c_parser_consume_token (parser);
1319 parser->error = false;
1322 /* Expect to be at the end of the pragma directive and consume an
1323 end of line marker. */
1325 static void
1326 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1328 gcc_assert (parser->in_pragma);
1329 parser->in_pragma = false;
1331 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1332 c_parser_error (parser, "expected end of line");
1334 cpp_ttype token_type;
1337 c_token *token = c_parser_peek_token (parser);
1338 token_type = token->type;
1339 if (token_type == CPP_EOF)
1340 break;
1341 c_parser_consume_token (parser);
1343 while (token_type != CPP_PRAGMA_EOL);
1345 parser->error = false;
1348 /* Skip tokens until we have consumed an entire block, or until we
1349 have consumed a non-nested ';'. */
1351 static void
1352 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1354 unsigned nesting_depth = 0;
1355 bool save_error = parser->error;
1357 while (true)
1359 c_token *token;
1361 /* Peek at the next token. */
1362 token = c_parser_peek_token (parser);
1364 switch (token->type)
1366 case CPP_EOF:
1367 return;
1369 case CPP_PRAGMA_EOL:
1370 if (parser->in_pragma)
1371 return;
1372 break;
1374 case CPP_SEMICOLON:
1375 /* If the next token is a ';', we have reached the
1376 end of the statement. */
1377 if (!nesting_depth)
1379 /* Consume the ';'. */
1380 c_parser_consume_token (parser);
1381 goto finished;
1383 break;
1385 case CPP_CLOSE_BRACE:
1386 /* If the next token is a non-nested '}', then we have
1387 reached the end of the current block. */
1388 if (nesting_depth == 0 || --nesting_depth == 0)
1390 c_parser_consume_token (parser);
1391 goto finished;
1393 break;
1395 case CPP_OPEN_BRACE:
1396 /* If it the next token is a '{', then we are entering a new
1397 block. Consume the entire block. */
1398 ++nesting_depth;
1399 break;
1401 case CPP_PRAGMA:
1402 /* If we see a pragma, consume the whole thing at once. We
1403 have some safeguards against consuming pragmas willy-nilly.
1404 Normally, we'd expect to be here with parser->error set,
1405 which disables these safeguards. But it's possible to get
1406 here for secondary error recovery, after parser->error has
1407 been cleared. */
1408 c_parser_consume_pragma (parser);
1409 c_parser_skip_to_pragma_eol (parser);
1410 parser->error = save_error;
1411 continue;
1413 default:
1414 break;
1417 c_parser_consume_token (parser);
1420 finished:
1421 parser->error = false;
1424 /* CPP's options (initialized by c-opts.cc). */
1425 extern cpp_options *cpp_opts;
1427 /* Save the warning flags which are controlled by __extension__. */
1429 static inline int
1430 disable_extension_diagnostics (void)
1432 int ret = (pedantic
1433 | (warn_pointer_arith << 1)
1434 | (warn_traditional << 2)
1435 | (flag_iso << 3)
1436 | (warn_long_long << 4)
1437 | (warn_cxx_compat << 5)
1438 | (warn_overlength_strings << 6)
1439 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1440 play tricks to properly restore it. */
1441 | ((warn_c90_c99_compat == 1) << 7)
1442 | ((warn_c90_c99_compat == -1) << 8)
1443 /* Similarly for warn_c99_c11_compat. */
1444 | ((warn_c99_c11_compat == 1) << 9)
1445 | ((warn_c99_c11_compat == -1) << 10)
1446 /* Similarly for warn_c11_c2x_compat. */
1447 | ((warn_c11_c2x_compat == 1) << 11)
1448 | ((warn_c11_c2x_compat == -1) << 12)
1450 cpp_opts->cpp_pedantic = pedantic = 0;
1451 warn_pointer_arith = 0;
1452 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1453 flag_iso = 0;
1454 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1455 warn_cxx_compat = 0;
1456 warn_overlength_strings = 0;
1457 warn_c90_c99_compat = 0;
1458 warn_c99_c11_compat = 0;
1459 warn_c11_c2x_compat = 0;
1460 return ret;
1463 /* Restore the warning flags which are controlled by __extension__.
1464 FLAGS is the return value from disable_extension_diagnostics. */
1466 static inline void
1467 restore_extension_diagnostics (int flags)
1469 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1470 warn_pointer_arith = (flags >> 1) & 1;
1471 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1472 flag_iso = (flags >> 3) & 1;
1473 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1474 warn_cxx_compat = (flags >> 5) & 1;
1475 warn_overlength_strings = (flags >> 6) & 1;
1476 /* See above for why is this needed. */
1477 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1478 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1479 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1482 /* Helper data structure for parsing #pragma acc routine. */
1483 struct oacc_routine_data {
1484 bool error_seen; /* Set if error has been reported. */
1485 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1486 tree clauses;
1487 location_t loc;
1490 /* Used for parsing objc foreach statements. */
1491 static tree objc_foreach_break_label, objc_foreach_continue_label;
1493 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1494 unsigned int);
1495 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1496 static void c_parser_external_declaration (c_parser *);
1497 static void c_parser_asm_definition (c_parser *);
1498 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1499 bool, bool, tree * = NULL,
1500 vec<c_token> * = NULL,
1501 bool have_attrs = false,
1502 tree attrs = NULL,
1503 struct oacc_routine_data * = NULL,
1504 bool * = NULL);
1505 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1506 static void c_parser_static_assert_declaration (c_parser *);
1507 static struct c_typespec c_parser_enum_specifier (c_parser *);
1508 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1509 static tree c_parser_struct_declaration (c_parser *);
1510 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1511 static tree c_parser_alignas_specifier (c_parser *);
1512 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1513 c_dtr_syn, bool *);
1514 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1515 bool,
1516 struct c_declarator *);
1517 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1518 bool);
1519 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1520 tree, bool);
1521 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1522 static tree c_parser_simple_asm_expr (c_parser *);
1523 static tree c_parser_gnu_attributes (c_parser *);
1524 static struct c_expr c_parser_initializer (c_parser *);
1525 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1526 struct obstack *);
1527 static void c_parser_initelt (c_parser *, struct obstack *);
1528 static void c_parser_initval (c_parser *, struct c_expr *,
1529 struct obstack *);
1530 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1531 static location_t c_parser_compound_statement_nostart (c_parser *);
1532 static void c_parser_label (c_parser *, tree);
1533 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1534 static void c_parser_statement_after_labels (c_parser *, bool *,
1535 vec<tree> * = NULL);
1536 static tree c_parser_c99_block_statement (c_parser *, bool *,
1537 location_t * = NULL);
1538 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1539 static void c_parser_switch_statement (c_parser *, bool *);
1540 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1541 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1542 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1543 static tree c_parser_asm_statement (c_parser *);
1544 static tree c_parser_asm_operands (c_parser *);
1545 static tree c_parser_asm_goto_operands (c_parser *);
1546 static tree c_parser_asm_clobbers (c_parser *);
1547 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1548 tree = NULL_TREE);
1549 static struct c_expr c_parser_conditional_expression (c_parser *,
1550 struct c_expr *, tree);
1551 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1552 tree);
1553 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1554 static struct c_expr c_parser_unary_expression (c_parser *);
1555 static struct c_expr c_parser_sizeof_expression (c_parser *);
1556 static struct c_expr c_parser_alignof_expression (c_parser *);
1557 static struct c_expr c_parser_postfix_expression (c_parser *);
1558 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1559 struct c_type_name *,
1560 location_t);
1561 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1562 location_t loc,
1563 struct c_expr);
1564 static tree c_parser_transaction (c_parser *, enum rid);
1565 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1566 static tree c_parser_transaction_cancel (c_parser *);
1567 static struct c_expr c_parser_expression (c_parser *);
1568 static struct c_expr c_parser_expression_conv (c_parser *);
1569 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1570 vec<tree, va_gc> **, location_t *,
1571 tree *, vec<location_t> *,
1572 unsigned int * = NULL);
1573 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1575 static void c_parser_oacc_declare (c_parser *);
1576 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1577 static void c_parser_oacc_update (c_parser *);
1578 static void c_parser_omp_construct (c_parser *, bool *);
1579 static void c_parser_omp_threadprivate (c_parser *);
1580 static void c_parser_omp_barrier (c_parser *);
1581 static void c_parser_omp_depobj (c_parser *);
1582 static void c_parser_omp_flush (c_parser *);
1583 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1584 tree, tree *, bool *);
1585 static void c_parser_omp_taskwait (c_parser *);
1586 static void c_parser_omp_taskyield (c_parser *);
1587 static void c_parser_omp_cancel (c_parser *);
1588 static void c_parser_omp_nothing (c_parser *);
1590 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1591 pragma_stmt, pragma_compound };
1592 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1593 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1594 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1595 static void c_parser_omp_end_declare_target (c_parser *);
1596 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1597 static void c_parser_omp_requires (c_parser *);
1598 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1599 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1600 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1602 /* These Objective-C parser functions are only ever called when
1603 compiling Objective-C. */
1604 static void c_parser_objc_class_definition (c_parser *, tree);
1605 static void c_parser_objc_class_instance_variables (c_parser *);
1606 static void c_parser_objc_class_declaration (c_parser *);
1607 static void c_parser_objc_alias_declaration (c_parser *);
1608 static void c_parser_objc_protocol_definition (c_parser *, tree);
1609 static bool c_parser_objc_method_type (c_parser *);
1610 static void c_parser_objc_method_definition (c_parser *);
1611 static void c_parser_objc_methodprotolist (c_parser *);
1612 static void c_parser_objc_methodproto (c_parser *);
1613 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1614 static tree c_parser_objc_type_name (c_parser *);
1615 static tree c_parser_objc_protocol_refs (c_parser *);
1616 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1617 static void c_parser_objc_synchronized_statement (c_parser *);
1618 static tree c_parser_objc_selector (c_parser *);
1619 static tree c_parser_objc_selector_arg (c_parser *);
1620 static tree c_parser_objc_receiver (c_parser *);
1621 static tree c_parser_objc_message_args (c_parser *);
1622 static tree c_parser_objc_keywordexpr (c_parser *);
1623 static void c_parser_objc_at_property_declaration (c_parser *);
1624 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1625 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1626 static bool c_parser_objc_diagnose_bad_element_prefix
1627 (c_parser *, struct c_declspecs *);
1628 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1630 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1632 translation-unit:
1633 external-declarations
1635 external-declarations:
1636 external-declaration
1637 external-declarations external-declaration
1639 GNU extensions:
1641 translation-unit:
1642 empty
1645 static void
1646 c_parser_translation_unit (c_parser *parser)
1648 if (c_parser_next_token_is (parser, CPP_EOF))
1650 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1651 "ISO C forbids an empty translation unit");
1653 else
1655 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1656 mark_valid_location_for_stdc_pragma (false);
1659 ggc_collect ();
1660 c_parser_external_declaration (parser);
1661 obstack_free (&parser_obstack, obstack_position);
1663 while (c_parser_next_token_is_not (parser, CPP_EOF));
1666 unsigned int i;
1667 tree decl;
1668 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1669 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1670 error ("storage size of %q+D isn%'t known", decl);
1672 if (current_omp_declare_target_attribute)
1674 if (!errorcount)
1675 error ("%<#pragma omp declare target%> without corresponding "
1676 "%<#pragma omp end declare target%>");
1677 current_omp_declare_target_attribute = 0;
1681 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1683 external-declaration:
1684 function-definition
1685 declaration
1687 GNU extensions:
1689 external-declaration:
1690 asm-definition
1692 __extension__ external-declaration
1694 Objective-C:
1696 external-declaration:
1697 objc-class-definition
1698 objc-class-declaration
1699 objc-alias-declaration
1700 objc-protocol-definition
1701 objc-method-definition
1702 @end
1705 static void
1706 c_parser_external_declaration (c_parser *parser)
1708 int ext;
1709 switch (c_parser_peek_token (parser)->type)
1711 case CPP_KEYWORD:
1712 switch (c_parser_peek_token (parser)->keyword)
1714 case RID_EXTENSION:
1715 ext = disable_extension_diagnostics ();
1716 c_parser_consume_token (parser);
1717 c_parser_external_declaration (parser);
1718 restore_extension_diagnostics (ext);
1719 break;
1720 case RID_ASM:
1721 c_parser_asm_definition (parser);
1722 break;
1723 case RID_AT_INTERFACE:
1724 case RID_AT_IMPLEMENTATION:
1725 gcc_assert (c_dialect_objc ());
1726 c_parser_objc_class_definition (parser, NULL_TREE);
1727 break;
1728 case RID_AT_CLASS:
1729 gcc_assert (c_dialect_objc ());
1730 c_parser_objc_class_declaration (parser);
1731 break;
1732 case RID_AT_ALIAS:
1733 gcc_assert (c_dialect_objc ());
1734 c_parser_objc_alias_declaration (parser);
1735 break;
1736 case RID_AT_PROTOCOL:
1737 gcc_assert (c_dialect_objc ());
1738 c_parser_objc_protocol_definition (parser, NULL_TREE);
1739 break;
1740 case RID_AT_PROPERTY:
1741 gcc_assert (c_dialect_objc ());
1742 c_parser_objc_at_property_declaration (parser);
1743 break;
1744 case RID_AT_SYNTHESIZE:
1745 gcc_assert (c_dialect_objc ());
1746 c_parser_objc_at_synthesize_declaration (parser);
1747 break;
1748 case RID_AT_DYNAMIC:
1749 gcc_assert (c_dialect_objc ());
1750 c_parser_objc_at_dynamic_declaration (parser);
1751 break;
1752 case RID_AT_END:
1753 gcc_assert (c_dialect_objc ());
1754 c_parser_consume_token (parser);
1755 objc_finish_implementation ();
1756 break;
1757 default:
1758 goto decl_or_fndef;
1760 break;
1761 case CPP_SEMICOLON:
1762 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1763 "ISO C does not allow extra %<;%> outside of a function");
1764 c_parser_consume_token (parser);
1765 break;
1766 case CPP_PRAGMA:
1767 mark_valid_location_for_stdc_pragma (true);
1768 c_parser_pragma (parser, pragma_external, NULL);
1769 mark_valid_location_for_stdc_pragma (false);
1770 break;
1771 case CPP_PLUS:
1772 case CPP_MINUS:
1773 if (c_dialect_objc ())
1775 c_parser_objc_method_definition (parser);
1776 break;
1778 /* Else fall through, and yield a syntax error trying to parse
1779 as a declaration or function definition. */
1780 /* FALLTHRU */
1781 default:
1782 decl_or_fndef:
1783 /* A declaration or a function definition (or, in Objective-C,
1784 an @interface or @protocol with prefix attributes). We can
1785 only tell which after parsing the declaration specifiers, if
1786 any, and the first declarator. */
1787 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1788 break;
1792 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1793 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1795 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1797 static void
1798 add_debug_begin_stmt (location_t loc)
1800 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1801 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1802 return;
1804 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1805 SET_EXPR_LOCATION (stmt, loc);
1806 add_stmt (stmt);
1809 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1810 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1811 is accepted; otherwise (old-style parameter declarations) only other
1812 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1813 assertion is accepted; otherwise (old-style parameter declarations)
1814 it is not. If NESTED is true, we are inside a function or parsing
1815 old-style parameter declarations; any functions encountered are
1816 nested functions and declaration specifiers are required; otherwise
1817 we are at top level and functions are normal functions and
1818 declaration specifiers may be optional. If EMPTY_OK is true, empty
1819 declarations are OK (subject to all other constraints); otherwise
1820 (old-style parameter declarations) they are diagnosed. If
1821 START_ATTR_OK is true, the declaration specifiers may start with
1822 attributes (GNU or standard); otherwise they may not.
1823 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1824 declaration when parsing an Objective-C foreach statement.
1825 FALLTHRU_ATTR_P is used to signal whether this function parsed
1826 "__attribute__((fallthrough));". ATTRS are any standard attributes
1827 parsed in the caller (in contexts where such attributes had to be
1828 parsed to determine whether what follows is a declaration or a
1829 statement); HAVE_ATTRS says whether there were any such attributes
1830 (even empty).
1832 declaration:
1833 declaration-specifiers init-declarator-list[opt] ;
1834 static_assert-declaration
1836 function-definition:
1837 declaration-specifiers[opt] declarator declaration-list[opt]
1838 compound-statement
1840 declaration-list:
1841 declaration
1842 declaration-list declaration
1844 init-declarator-list:
1845 init-declarator
1846 init-declarator-list , init-declarator
1848 init-declarator:
1849 declarator simple-asm-expr[opt] gnu-attributes[opt]
1850 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1852 GNU extensions:
1854 nested-function-definition:
1855 declaration-specifiers declarator declaration-list[opt]
1856 compound-statement
1858 attribute ;
1860 Objective-C:
1861 gnu-attributes objc-class-definition
1862 gnu-attributes objc-category-definition
1863 gnu-attributes objc-protocol-definition
1865 The simple-asm-expr and gnu-attributes are GNU extensions.
1867 This function does not handle __extension__; that is handled in its
1868 callers. ??? Following the old parser, __extension__ may start
1869 external declarations, declarations in functions and declarations
1870 at the start of "for" loops, but not old-style parameter
1871 declarations.
1873 C99 requires declaration specifiers in a function definition; the
1874 absence is diagnosed through the diagnosis of implicit int. In GNU
1875 C we also allow but diagnose declarations without declaration
1876 specifiers, but only at top level (elsewhere they conflict with
1877 other syntax).
1879 In Objective-C, declarations of the looping variable in a foreach
1880 statement are exceptionally terminated by 'in' (for example, 'for
1881 (NSObject *object in array) { ... }').
1883 OpenMP:
1885 declaration:
1886 threadprivate-directive
1888 GIMPLE:
1890 gimple-function-definition:
1891 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1892 declaration-list[opt] compound-statement
1894 rtl-function-definition:
1895 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1896 declaration-list[opt] compound-statement */
1898 static void
1899 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1900 bool static_assert_ok, bool empty_ok,
1901 bool nested, bool start_attr_ok,
1902 tree *objc_foreach_object_declaration
1903 /* = NULL */,
1904 vec<c_token> *omp_declare_simd_clauses
1905 /* = NULL */,
1906 bool have_attrs /* = false */,
1907 tree attrs /* = NULL_TREE */,
1908 struct oacc_routine_data *oacc_routine_data
1909 /* = NULL */,
1910 bool *fallthru_attr_p /* = NULL */)
1912 struct c_declspecs *specs;
1913 tree prefix_attrs;
1914 tree all_prefix_attrs;
1915 bool diagnosed_no_specs = false;
1916 location_t here = c_parser_peek_token (parser)->location;
1918 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1920 if (static_assert_ok
1921 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1923 c_parser_static_assert_declaration (parser);
1924 return;
1926 specs = build_null_declspecs ();
1928 /* Handle any standard attributes parsed in the caller. */
1929 if (have_attrs)
1931 declspecs_add_attrs (here, specs, attrs);
1932 specs->non_std_attrs_seen_p = false;
1935 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1936 if (c_parser_peek_token (parser)->type == CPP_NAME
1937 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1938 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1939 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1940 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1942 tree name = c_parser_peek_token (parser)->value;
1944 /* Issue a warning about NAME being an unknown type name, perhaps
1945 with some kind of hint.
1946 If the user forgot a "struct" etc, suggest inserting
1947 it. Otherwise, attempt to look for misspellings. */
1948 gcc_rich_location richloc (here);
1949 if (tag_exists_p (RECORD_TYPE, name))
1951 /* This is not C++ with its implicit typedef. */
1952 richloc.add_fixit_insert_before ("struct ");
1953 error_at (&richloc,
1954 "unknown type name %qE;"
1955 " use %<struct%> keyword to refer to the type",
1956 name);
1958 else if (tag_exists_p (UNION_TYPE, name))
1960 richloc.add_fixit_insert_before ("union ");
1961 error_at (&richloc,
1962 "unknown type name %qE;"
1963 " use %<union%> keyword to refer to the type",
1964 name);
1966 else if (tag_exists_p (ENUMERAL_TYPE, name))
1968 richloc.add_fixit_insert_before ("enum ");
1969 error_at (&richloc,
1970 "unknown type name %qE;"
1971 " use %<enum%> keyword to refer to the type",
1972 name);
1974 else
1976 auto_diagnostic_group d;
1977 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1978 here);
1979 if (const char *suggestion = hint.suggestion ())
1981 richloc.add_fixit_replace (suggestion);
1982 error_at (&richloc,
1983 "unknown type name %qE; did you mean %qs?",
1984 name, suggestion);
1986 else
1987 error_at (here, "unknown type name %qE", name);
1990 /* Parse declspecs normally to get a correct pointer type, but avoid
1991 a further "fails to be a type name" error. Refuse nested functions
1992 since it is not how the user likely wants us to recover. */
1993 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1994 c_parser_peek_token (parser)->keyword = RID_VOID;
1995 c_parser_peek_token (parser)->value = error_mark_node;
1996 fndef_ok = !nested;
1999 /* When there are standard attributes at the start of the
2000 declaration (to apply to the entity being declared), an
2001 init-declarator-list or function definition must be present. */
2002 if (c_parser_nth_token_starts_std_attributes (parser, 1))
2003 have_attrs = true;
2005 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2006 true, true, start_attr_ok, true, cla_nonabstract_decl);
2007 if (parser->error)
2009 c_parser_skip_to_end_of_block_or_statement (parser);
2010 return;
2012 if (nested && !specs->declspecs_seen_p)
2014 c_parser_error (parser, "expected declaration specifiers");
2015 c_parser_skip_to_end_of_block_or_statement (parser);
2016 return;
2019 finish_declspecs (specs);
2020 bool auto_type_p = specs->typespec_word == cts_auto_type;
2021 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2023 if (auto_type_p)
2024 error_at (here, "%<__auto_type%> in empty declaration");
2025 else if (specs->typespec_kind == ctsk_none
2026 && attribute_fallthrough_p (specs->attrs))
2028 if (fallthru_attr_p != NULL)
2029 *fallthru_attr_p = true;
2030 if (nested)
2032 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2033 void_type_node, 0);
2034 add_stmt (fn);
2036 else
2037 pedwarn (here, OPT_Wattributes,
2038 "%<fallthrough%> attribute at top level");
2040 else if (empty_ok && !(have_attrs
2041 && specs->non_std_attrs_seen_p))
2042 shadow_tag (specs);
2043 else
2045 shadow_tag_warned (specs, 1);
2046 pedwarn (here, 0, "empty declaration");
2048 c_parser_consume_token (parser);
2049 if (oacc_routine_data)
2050 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2051 return;
2054 /* Provide better error recovery. Note that a type name here is usually
2055 better diagnosed as a redeclaration. */
2056 if (empty_ok
2057 && specs->typespec_kind == ctsk_tagdef
2058 && c_parser_next_token_starts_declspecs (parser)
2059 && !c_parser_next_token_is (parser, CPP_NAME))
2061 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2062 parser->error = false;
2063 shadow_tag_warned (specs, 1);
2064 return;
2066 else if (c_dialect_objc () && !auto_type_p)
2068 /* Prefix attributes are an error on method decls. */
2069 switch (c_parser_peek_token (parser)->type)
2071 case CPP_PLUS:
2072 case CPP_MINUS:
2073 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2074 return;
2075 if (specs->attrs)
2077 warning_at (c_parser_peek_token (parser)->location,
2078 OPT_Wattributes,
2079 "prefix attributes are ignored for methods");
2080 specs->attrs = NULL_TREE;
2082 if (fndef_ok)
2083 c_parser_objc_method_definition (parser);
2084 else
2085 c_parser_objc_methodproto (parser);
2086 return;
2087 break;
2088 default:
2089 break;
2091 /* This is where we parse 'attributes @interface ...',
2092 'attributes @implementation ...', 'attributes @protocol ...'
2093 (where attributes could be, for example, __attribute__
2094 ((deprecated)).
2096 switch (c_parser_peek_token (parser)->keyword)
2098 case RID_AT_INTERFACE:
2100 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2101 return;
2102 c_parser_objc_class_definition (parser, specs->attrs);
2103 return;
2105 break;
2106 case RID_AT_IMPLEMENTATION:
2108 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2109 return;
2110 if (specs->attrs)
2112 warning_at (c_parser_peek_token (parser)->location,
2113 OPT_Wattributes,
2114 "prefix attributes are ignored for implementations");
2115 specs->attrs = NULL_TREE;
2117 c_parser_objc_class_definition (parser, NULL_TREE);
2118 return;
2120 break;
2121 case RID_AT_PROTOCOL:
2123 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2124 return;
2125 c_parser_objc_protocol_definition (parser, specs->attrs);
2126 return;
2128 break;
2129 case RID_AT_ALIAS:
2130 case RID_AT_CLASS:
2131 case RID_AT_END:
2132 case RID_AT_PROPERTY:
2133 if (specs->attrs)
2135 c_parser_error (parser, "unexpected attribute");
2136 specs->attrs = NULL;
2138 break;
2139 default:
2140 break;
2143 else if (attribute_fallthrough_p (specs->attrs))
2144 warning_at (here, OPT_Wattributes,
2145 "%<fallthrough%> attribute not followed by %<;%>");
2147 pending_xref_error ();
2148 prefix_attrs = specs->attrs;
2149 all_prefix_attrs = prefix_attrs;
2150 specs->attrs = NULL_TREE;
2151 while (true)
2153 struct c_declarator *declarator;
2154 bool dummy = false;
2155 timevar_id_t tv;
2156 tree fnbody = NULL_TREE;
2157 /* Declaring either one or more declarators (in which case we
2158 should diagnose if there were no declaration specifiers) or a
2159 function definition (in which case the diagnostic for
2160 implicit int suffices). */
2161 declarator = c_parser_declarator (parser,
2162 specs->typespec_kind != ctsk_none,
2163 C_DTR_NORMAL, &dummy);
2164 if (declarator == NULL)
2166 if (omp_declare_simd_clauses)
2167 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2168 omp_declare_simd_clauses);
2169 if (oacc_routine_data)
2170 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2171 c_parser_skip_to_end_of_block_or_statement (parser);
2172 return;
2174 if (auto_type_p && declarator->kind != cdk_id)
2176 error_at (here,
2177 "%<__auto_type%> requires a plain identifier"
2178 " as declarator");
2179 c_parser_skip_to_end_of_block_or_statement (parser);
2180 return;
2182 if (c_parser_next_token_is (parser, CPP_EQ)
2183 || c_parser_next_token_is (parser, CPP_COMMA)
2184 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2185 || c_parser_next_token_is_keyword (parser, RID_ASM)
2186 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2187 || c_parser_next_token_is_keyword (parser, RID_IN))
2189 tree asm_name = NULL_TREE;
2190 tree postfix_attrs = NULL_TREE;
2191 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2193 diagnosed_no_specs = true;
2194 pedwarn (here, 0, "data definition has no type or storage class");
2196 /* Having seen a data definition, there cannot now be a
2197 function definition. */
2198 fndef_ok = false;
2199 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2200 asm_name = c_parser_simple_asm_expr (parser);
2201 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2203 postfix_attrs = c_parser_gnu_attributes (parser);
2204 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2206 /* This means there is an attribute specifier after
2207 the declarator in a function definition. Provide
2208 some more information for the user. */
2209 error_at (here, "attributes should be specified before the "
2210 "declarator in a function definition");
2211 c_parser_skip_to_end_of_block_or_statement (parser);
2212 return;
2215 if (c_parser_next_token_is (parser, CPP_EQ))
2217 tree d;
2218 struct c_expr init;
2219 location_t init_loc;
2220 c_parser_consume_token (parser);
2221 if (auto_type_p)
2223 init_loc = c_parser_peek_token (parser)->location;
2224 rich_location richloc (line_table, init_loc);
2225 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2226 /* A parameter is initialized, which is invalid. Don't
2227 attempt to instrument the initializer. */
2228 int flag_sanitize_save = flag_sanitize;
2229 if (nested && !empty_ok)
2230 flag_sanitize = 0;
2231 init = c_parser_expr_no_commas (parser, NULL);
2232 flag_sanitize = flag_sanitize_save;
2233 if (TREE_CODE (init.value) == COMPONENT_REF
2234 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2235 error_at (here,
2236 "%<__auto_type%> used with a bit-field"
2237 " initializer");
2238 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2239 tree init_type = TREE_TYPE (init.value);
2240 bool vm_type = variably_modified_type_p (init_type,
2241 NULL_TREE);
2242 if (vm_type)
2243 init.value = save_expr (init.value);
2244 finish_init ();
2245 specs->typespec_kind = ctsk_typeof;
2246 specs->locations[cdw_typedef] = init_loc;
2247 specs->typedef_p = true;
2248 specs->type = init_type;
2249 if (vm_type)
2251 bool maybe_const = true;
2252 tree type_expr = c_fully_fold (init.value, false,
2253 &maybe_const);
2254 specs->expr_const_operands &= maybe_const;
2255 if (specs->expr)
2256 specs->expr = build2 (COMPOUND_EXPR,
2257 TREE_TYPE (type_expr),
2258 specs->expr, type_expr);
2259 else
2260 specs->expr = type_expr;
2262 d = start_decl (declarator, specs, true,
2263 chainon (postfix_attrs, all_prefix_attrs));
2264 if (!d)
2265 d = error_mark_node;
2266 if (omp_declare_simd_clauses)
2267 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2268 omp_declare_simd_clauses);
2270 else
2272 /* The declaration of the variable is in effect while
2273 its initializer is parsed. */
2274 d = start_decl (declarator, specs, true,
2275 chainon (postfix_attrs, all_prefix_attrs));
2276 if (!d)
2277 d = error_mark_node;
2278 if (omp_declare_simd_clauses)
2279 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2280 omp_declare_simd_clauses);
2281 init_loc = c_parser_peek_token (parser)->location;
2282 rich_location richloc (line_table, init_loc);
2283 start_init (d, asm_name, global_bindings_p (), &richloc);
2284 /* A parameter is initialized, which is invalid. Don't
2285 attempt to instrument the initializer. */
2286 int flag_sanitize_save = flag_sanitize;
2287 if (TREE_CODE (d) == PARM_DECL)
2288 flag_sanitize = 0;
2289 init = c_parser_initializer (parser);
2290 flag_sanitize = flag_sanitize_save;
2291 finish_init ();
2293 if (oacc_routine_data)
2294 c_finish_oacc_routine (oacc_routine_data, d, false);
2295 if (d != error_mark_node)
2297 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2298 finish_decl (d, init_loc, init.value,
2299 init.original_type, asm_name);
2302 else
2304 if (auto_type_p)
2306 error_at (here,
2307 "%<__auto_type%> requires an initialized "
2308 "data declaration");
2309 c_parser_skip_to_end_of_block_or_statement (parser);
2310 return;
2313 location_t lastloc = UNKNOWN_LOCATION;
2314 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2315 tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2316 if (d && TREE_CODE (d) == FUNCTION_DECL)
2318 /* Find the innermost declarator that is neither cdk_id
2319 nor cdk_attrs. */
2320 const struct c_declarator *decl = declarator;
2321 const struct c_declarator *last_non_id_attrs = NULL;
2323 while (decl)
2324 switch (decl->kind)
2326 case cdk_array:
2327 case cdk_function:
2328 case cdk_pointer:
2329 last_non_id_attrs = decl;
2330 decl = decl->declarator;
2331 break;
2333 case cdk_attrs:
2334 decl = decl->declarator;
2335 break;
2337 case cdk_id:
2338 decl = 0;
2339 break;
2341 default:
2342 gcc_unreachable ();
2345 /* If it exists and is cdk_function declaration whose
2346 arguments have not been set yet, use its arguments. */
2347 if (last_non_id_attrs
2348 && last_non_id_attrs->kind == cdk_function)
2350 tree parms = last_non_id_attrs->u.arg_info->parms;
2351 if (DECL_ARGUMENTS (d) == NULL_TREE
2352 && DECL_INITIAL (d) == NULL_TREE)
2353 DECL_ARGUMENTS (d) = parms;
2355 warn_parm_array_mismatch (lastloc, d, parms);
2358 if (omp_declare_simd_clauses)
2360 tree parms = NULL_TREE;
2361 if (d && TREE_CODE (d) == FUNCTION_DECL)
2363 struct c_declarator *ce = declarator;
2364 while (ce != NULL)
2365 if (ce->kind == cdk_function)
2367 parms = ce->u.arg_info->parms;
2368 break;
2370 else
2371 ce = ce->declarator;
2373 if (parms)
2374 temp_store_parm_decls (d, parms);
2375 c_finish_omp_declare_simd (parser, d, parms,
2376 omp_declare_simd_clauses);
2377 if (parms)
2378 temp_pop_parm_decls ();
2380 if (oacc_routine_data)
2381 c_finish_oacc_routine (oacc_routine_data, d, false);
2382 if (d)
2383 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2384 NULL_TREE, asm_name);
2386 if (c_parser_next_token_is_keyword (parser, RID_IN))
2388 if (d)
2389 *objc_foreach_object_declaration = d;
2390 else
2391 *objc_foreach_object_declaration = error_mark_node;
2394 if (c_parser_next_token_is (parser, CPP_COMMA))
2396 if (auto_type_p)
2398 error_at (here,
2399 "%<__auto_type%> may only be used with"
2400 " a single declarator");
2401 c_parser_skip_to_end_of_block_or_statement (parser);
2402 return;
2404 c_parser_consume_token (parser);
2405 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2406 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2407 prefix_attrs);
2408 else
2409 all_prefix_attrs = prefix_attrs;
2410 continue;
2412 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2414 c_parser_consume_token (parser);
2415 return;
2417 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2419 /* This can only happen in Objective-C: we found the
2420 'in' that terminates the declaration inside an
2421 Objective-C foreach statement. Do not consume the
2422 token, so that the caller can use it to determine
2423 that this indeed is a foreach context. */
2424 return;
2426 else
2428 c_parser_error (parser, "expected %<,%> or %<;%>");
2429 c_parser_skip_to_end_of_block_or_statement (parser);
2430 return;
2433 else if (auto_type_p)
2435 error_at (here,
2436 "%<__auto_type%> requires an initialized data declaration");
2437 c_parser_skip_to_end_of_block_or_statement (parser);
2438 return;
2440 else if (!fndef_ok)
2442 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2443 "%<asm%> or %<__attribute__%>");
2444 c_parser_skip_to_end_of_block_or_statement (parser);
2445 return;
2447 /* Function definition (nested or otherwise). */
2448 if (nested)
2450 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2451 c_push_function_context ();
2453 if (!start_function (specs, declarator, all_prefix_attrs))
2455 /* At this point we've consumed:
2456 declaration-specifiers declarator
2457 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2458 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2459 but the
2460 declaration-specifiers declarator
2461 aren't grokkable as a function definition, so we have
2462 an error. */
2463 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2464 if (c_parser_next_token_starts_declspecs (parser))
2466 /* If we have
2467 declaration-specifiers declarator decl-specs
2468 then assume we have a missing semicolon, which would
2469 give us:
2470 declaration-specifiers declarator decl-specs
2473 <~~~~~~~~~ declaration ~~~~~~~~~~>
2474 Use c_parser_require to get an error with a fix-it hint. */
2475 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2476 parser->error = false;
2478 else
2480 /* This can appear in many cases looking nothing like a
2481 function definition, so we don't give a more specific
2482 error suggesting there was one. */
2483 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2484 "or %<__attribute__%>");
2486 if (nested)
2487 c_pop_function_context ();
2488 break;
2491 if (DECL_DECLARED_INLINE_P (current_function_decl))
2492 tv = TV_PARSE_INLINE;
2493 else
2494 tv = TV_PARSE_FUNC;
2495 auto_timevar at (g_timer, tv);
2497 /* Parse old-style parameter declarations. ??? Attributes are
2498 not allowed to start declaration specifiers here because of a
2499 syntax conflict between a function declaration with attribute
2500 suffix and a function definition with an attribute prefix on
2501 first old-style parameter declaration. Following the old
2502 parser, they are not accepted on subsequent old-style
2503 parameter declarations either. However, there is no
2504 ambiguity after the first declaration, nor indeed on the
2505 first as long as we don't allow postfix attributes after a
2506 declarator with a nonempty identifier list in a definition;
2507 and postfix attributes have never been accepted here in
2508 function definitions either. */
2509 while (c_parser_next_token_is_not (parser, CPP_EOF)
2510 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2511 c_parser_declaration_or_fndef (parser, false, false, false,
2512 true, false);
2513 store_parm_decls ();
2514 if (omp_declare_simd_clauses)
2515 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2516 omp_declare_simd_clauses);
2517 if (oacc_routine_data)
2518 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2519 location_t startloc = c_parser_peek_token (parser)->location;
2520 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2521 = startloc;
2522 location_t endloc = startloc;
2524 /* If the definition was marked with __RTL, use the RTL parser now,
2525 consuming the function body. */
2526 if (specs->declspec_il == cdil_rtl)
2528 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2530 /* Normally, store_parm_decls sets next_is_function_body,
2531 anticipating a function body. We need a push_scope/pop_scope
2532 pair to flush out this state, or subsequent function parsing
2533 will go wrong. */
2534 push_scope ();
2535 pop_scope ();
2537 finish_function (endloc);
2538 return;
2540 /* If the definition was marked with __GIMPLE then parse the
2541 function body as GIMPLE. */
2542 else if (specs->declspec_il != cdil_none)
2544 bool saved = in_late_binary_op;
2545 in_late_binary_op = true;
2546 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2547 specs->declspec_il,
2548 specs->entry_bb_count);
2549 in_late_binary_op = saved;
2551 else
2552 fnbody = c_parser_compound_statement (parser, &endloc);
2553 tree fndecl = current_function_decl;
2554 if (nested)
2556 tree decl = current_function_decl;
2557 /* Mark nested functions as needing static-chain initially.
2558 lower_nested_functions will recompute it but the
2559 DECL_STATIC_CHAIN flag is also used before that happens,
2560 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2561 DECL_STATIC_CHAIN (decl) = 1;
2562 add_stmt (fnbody);
2563 finish_function (endloc);
2564 c_pop_function_context ();
2565 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2567 else
2569 if (fnbody)
2570 add_stmt (fnbody);
2571 finish_function (endloc);
2573 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2574 if (specs->declspec_il != cdil_none)
2575 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2577 break;
2581 /* Parse an asm-definition (asm() outside a function body). This is a
2582 GNU extension.
2584 asm-definition:
2585 simple-asm-expr ;
2588 static void
2589 c_parser_asm_definition (c_parser *parser)
2591 tree asm_str = c_parser_simple_asm_expr (parser);
2592 if (asm_str)
2593 symtab->finalize_toplevel_asm (asm_str);
2594 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2597 /* Parse a static assertion (C11 6.7.10).
2599 static_assert-declaration:
2600 static_assert-declaration-no-semi ;
2603 static void
2604 c_parser_static_assert_declaration (c_parser *parser)
2606 c_parser_static_assert_declaration_no_semi (parser);
2607 if (parser->error
2608 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2609 c_parser_skip_to_end_of_block_or_statement (parser);
2612 /* Parse a static assertion (C11 6.7.10), without the trailing
2613 semicolon.
2615 static_assert-declaration-no-semi:
2616 _Static_assert ( constant-expression , string-literal )
2618 C2X:
2619 static_assert-declaration-no-semi:
2620 _Static_assert ( constant-expression )
2623 static void
2624 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2626 location_t assert_loc, value_loc;
2627 tree value;
2628 tree string = NULL_TREE;
2630 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2631 assert_loc = c_parser_peek_token (parser)->location;
2632 if (flag_isoc99)
2633 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2634 "ISO C99 does not support %<_Static_assert%>");
2635 else
2636 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2637 "ISO C90 does not support %<_Static_assert%>");
2638 c_parser_consume_token (parser);
2639 matching_parens parens;
2640 if (!parens.require_open (parser))
2641 return;
2642 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2643 value = c_parser_expr_no_commas (parser, NULL).value;
2644 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2645 if (c_parser_next_token_is (parser, CPP_COMMA))
2647 c_parser_consume_token (parser);
2648 switch (c_parser_peek_token (parser)->type)
2650 case CPP_STRING:
2651 case CPP_STRING16:
2652 case CPP_STRING32:
2653 case CPP_WSTRING:
2654 case CPP_UTF8STRING:
2655 string = c_parser_string_literal (parser, false, true).value;
2656 break;
2657 default:
2658 c_parser_error (parser, "expected string literal");
2659 return;
2662 else if (flag_isoc11)
2663 /* If pedantic for pre-C11, the use of _Static_assert itself will
2664 have been diagnosed, so do not also diagnose the use of this
2665 new C2X feature of _Static_assert. */
2666 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2667 "ISO C11 does not support omitting the string in "
2668 "%<_Static_assert%>");
2669 parens.require_close (parser);
2671 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2673 error_at (value_loc, "expression in static assertion is not an integer");
2674 return;
2676 if (TREE_CODE (value) != INTEGER_CST)
2678 value = c_fully_fold (value, false, NULL);
2679 /* Strip no-op conversions. */
2680 STRIP_TYPE_NOPS (value);
2681 if (TREE_CODE (value) == INTEGER_CST)
2682 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2683 "is not an integer constant expression");
2685 if (TREE_CODE (value) != INTEGER_CST)
2687 error_at (value_loc, "expression in static assertion is not constant");
2688 return;
2690 constant_expression_warning (value);
2691 if (integer_zerop (value))
2693 if (string)
2694 error_at (assert_loc, "static assertion failed: %E", string);
2695 else
2696 error_at (assert_loc, "static assertion failed");
2700 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2701 6.7, C11 6.7), adding them to SPECS (which may already include some).
2702 Storage class specifiers are accepted iff SCSPEC_OK; type
2703 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2704 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2705 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2706 addition to the syntax shown, standard attributes are accepted at
2707 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2708 unlike gnu-attributes, they are not accepted in the middle of the
2709 list. (This combines various different syntax productions in the C
2710 standard, and in some cases gnu-attributes and standard attributes
2711 at the start may already have been parsed before this function is
2712 called.)
2714 declaration-specifiers:
2715 storage-class-specifier declaration-specifiers[opt]
2716 type-specifier declaration-specifiers[opt]
2717 type-qualifier declaration-specifiers[opt]
2718 function-specifier declaration-specifiers[opt]
2719 alignment-specifier declaration-specifiers[opt]
2721 Function specifiers (inline) are from C99, and are currently
2722 handled as storage class specifiers, as is __thread. Alignment
2723 specifiers are from C11.
2725 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2726 storage-class-specifier:
2727 typedef
2728 extern
2729 static
2730 auto
2731 register
2732 _Thread_local
2734 (_Thread_local is new in C11.)
2736 C99 6.7.4, C11 6.7.4:
2737 function-specifier:
2738 inline
2739 _Noreturn
2741 (_Noreturn is new in C11.)
2743 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2744 type-specifier:
2745 void
2746 char
2747 short
2749 long
2750 float
2751 double
2752 signed
2753 unsigned
2754 _Bool
2755 _Complex
2756 [_Imaginary removed in C99 TC2]
2757 struct-or-union-specifier
2758 enum-specifier
2759 typedef-name
2760 atomic-type-specifier
2762 (_Bool and _Complex are new in C99.)
2763 (atomic-type-specifier is new in C11.)
2765 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2767 type-qualifier:
2768 const
2769 restrict
2770 volatile
2771 address-space-qualifier
2772 _Atomic
2774 (restrict is new in C99.)
2775 (_Atomic is new in C11.)
2777 GNU extensions:
2779 declaration-specifiers:
2780 gnu-attributes declaration-specifiers[opt]
2782 type-qualifier:
2783 address-space
2785 address-space:
2786 identifier recognized by the target
2788 storage-class-specifier:
2789 __thread
2791 type-specifier:
2792 typeof-specifier
2793 __auto_type
2794 __intN
2795 _Decimal32
2796 _Decimal64
2797 _Decimal128
2798 _Fract
2799 _Accum
2800 _Sat
2802 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2803 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2805 atomic-type-specifier
2806 _Atomic ( type-name )
2808 Objective-C:
2810 type-specifier:
2811 class-name objc-protocol-refs[opt]
2812 typedef-name objc-protocol-refs
2813 objc-protocol-refs
2816 void
2817 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2818 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2819 bool alignspec_ok, bool auto_type_ok,
2820 bool start_std_attr_ok, bool end_std_attr_ok,
2821 enum c_lookahead_kind la)
2823 bool attrs_ok = start_attr_ok;
2824 bool seen_type = specs->typespec_kind != ctsk_none;
2826 if (!typespec_ok)
2827 gcc_assert (la == cla_prefer_id);
2829 if (start_std_attr_ok
2830 && c_parser_nth_token_starts_std_attributes (parser, 1))
2832 gcc_assert (!specs->non_std_attrs_seen_p);
2833 location_t loc = c_parser_peek_token (parser)->location;
2834 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2835 declspecs_add_attrs (loc, specs, attrs);
2836 specs->non_std_attrs_seen_p = false;
2839 while (c_parser_next_token_is (parser, CPP_NAME)
2840 || c_parser_next_token_is (parser, CPP_KEYWORD)
2841 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2843 struct c_typespec t;
2844 tree attrs;
2845 tree align;
2846 location_t loc = c_parser_peek_token (parser)->location;
2848 /* If we cannot accept a type, exit if the next token must start
2849 one. Also, if we already have seen a tagged definition,
2850 a typename would be an error anyway and likely the user
2851 has simply forgotten a semicolon, so we exit. */
2852 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2853 && c_parser_next_tokens_start_typename (parser, la)
2854 && !c_parser_next_token_is_qualifier (parser)
2855 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2856 break;
2858 if (c_parser_next_token_is (parser, CPP_NAME))
2860 c_token *name_token = c_parser_peek_token (parser);
2861 tree value = name_token->value;
2862 c_id_kind kind = name_token->id_kind;
2864 if (kind == C_ID_ADDRSPACE)
2866 addr_space_t as
2867 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2868 declspecs_add_addrspace (name_token->location, specs, as);
2869 c_parser_consume_token (parser);
2870 attrs_ok = true;
2871 continue;
2874 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2876 /* If we cannot accept a type, and the next token must start one,
2877 exit. Do the same if we already have seen a tagged definition,
2878 since it would be an error anyway and likely the user has simply
2879 forgotten a semicolon. */
2880 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2881 break;
2883 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2884 a C_ID_CLASSNAME. */
2885 c_parser_consume_token (parser);
2886 seen_type = true;
2887 attrs_ok = true;
2888 if (kind == C_ID_ID)
2890 error_at (loc, "unknown type name %qE", value);
2891 t.kind = ctsk_typedef;
2892 t.spec = error_mark_node;
2894 else if (kind == C_ID_TYPENAME
2895 && (!c_dialect_objc ()
2896 || c_parser_next_token_is_not (parser, CPP_LESS)))
2898 t.kind = ctsk_typedef;
2899 /* For a typedef name, record the meaning, not the name.
2900 In case of 'foo foo, bar;'. */
2901 t.spec = lookup_name (value);
2903 else
2905 tree proto = NULL_TREE;
2906 gcc_assert (c_dialect_objc ());
2907 t.kind = ctsk_objc;
2908 if (c_parser_next_token_is (parser, CPP_LESS))
2909 proto = c_parser_objc_protocol_refs (parser);
2910 t.spec = objc_get_protocol_qualified_type (value, proto);
2912 t.expr = NULL_TREE;
2913 t.expr_const_operands = true;
2914 declspecs_add_type (name_token->location, specs, t);
2915 continue;
2917 if (c_parser_next_token_is (parser, CPP_LESS))
2919 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2920 nisse@lysator.liu.se. */
2921 tree proto;
2922 gcc_assert (c_dialect_objc ());
2923 if (!typespec_ok || seen_type)
2924 break;
2925 proto = c_parser_objc_protocol_refs (parser);
2926 t.kind = ctsk_objc;
2927 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2928 t.expr = NULL_TREE;
2929 t.expr_const_operands = true;
2930 declspecs_add_type (loc, specs, t);
2931 continue;
2933 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2934 switch (c_parser_peek_token (parser)->keyword)
2936 case RID_STATIC:
2937 case RID_EXTERN:
2938 case RID_REGISTER:
2939 case RID_TYPEDEF:
2940 case RID_INLINE:
2941 case RID_NORETURN:
2942 case RID_AUTO:
2943 case RID_THREAD:
2944 if (!scspec_ok)
2945 goto out;
2946 attrs_ok = true;
2947 /* TODO: Distinguish between function specifiers (inline, noreturn)
2948 and storage class specifiers, either here or in
2949 declspecs_add_scspec. */
2950 declspecs_add_scspec (loc, specs,
2951 c_parser_peek_token (parser)->value);
2952 c_parser_consume_token (parser);
2953 break;
2954 case RID_AUTO_TYPE:
2955 if (!auto_type_ok)
2956 goto out;
2957 /* Fall through. */
2958 case RID_UNSIGNED:
2959 case RID_LONG:
2960 case RID_SHORT:
2961 case RID_SIGNED:
2962 case RID_COMPLEX:
2963 case RID_INT:
2964 case RID_CHAR:
2965 case RID_FLOAT:
2966 case RID_DOUBLE:
2967 case RID_VOID:
2968 case RID_DFLOAT32:
2969 case RID_DFLOAT64:
2970 case RID_DFLOAT128:
2971 CASE_RID_FLOATN_NX:
2972 case RID_BOOL:
2973 case RID_FRACT:
2974 case RID_ACCUM:
2975 case RID_SAT:
2976 case RID_INT_N_0:
2977 case RID_INT_N_1:
2978 case RID_INT_N_2:
2979 case RID_INT_N_3:
2980 if (!typespec_ok)
2981 goto out;
2982 attrs_ok = true;
2983 seen_type = true;
2984 if (c_dialect_objc ())
2985 parser->objc_need_raw_identifier = true;
2986 t.kind = ctsk_resword;
2987 t.spec = c_parser_peek_token (parser)->value;
2988 t.expr = NULL_TREE;
2989 t.expr_const_operands = true;
2990 declspecs_add_type (loc, specs, t);
2991 c_parser_consume_token (parser);
2992 break;
2993 case RID_ENUM:
2994 if (!typespec_ok)
2995 goto out;
2996 attrs_ok = true;
2997 seen_type = true;
2998 t = c_parser_enum_specifier (parser);
2999 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3000 declspecs_add_type (loc, specs, t);
3001 break;
3002 case RID_STRUCT:
3003 case RID_UNION:
3004 if (!typespec_ok)
3005 goto out;
3006 attrs_ok = true;
3007 seen_type = true;
3008 t = c_parser_struct_or_union_specifier (parser);
3009 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3010 declspecs_add_type (loc, specs, t);
3011 break;
3012 case RID_TYPEOF:
3013 /* ??? The old parser rejected typeof after other type
3014 specifiers, but is a syntax error the best way of
3015 handling this? */
3016 if (!typespec_ok || seen_type)
3017 goto out;
3018 attrs_ok = true;
3019 seen_type = true;
3020 t = c_parser_typeof_specifier (parser);
3021 declspecs_add_type (loc, specs, t);
3022 break;
3023 case RID_ATOMIC:
3024 /* C parser handling of Objective-C constructs needs
3025 checking for correct lvalue-to-rvalue conversions, and
3026 the code in build_modify_expr handling various
3027 Objective-C cases, and that in build_unary_op handling
3028 Objective-C cases for increment / decrement, also needs
3029 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3030 and objc_types_are_equivalent may also need updates. */
3031 if (c_dialect_objc ())
3032 sorry ("%<_Atomic%> in Objective-C");
3033 if (flag_isoc99)
3034 pedwarn_c99 (loc, OPT_Wpedantic,
3035 "ISO C99 does not support the %<_Atomic%> qualifier");
3036 else
3037 pedwarn_c99 (loc, OPT_Wpedantic,
3038 "ISO C90 does not support the %<_Atomic%> qualifier");
3039 attrs_ok = true;
3040 tree value;
3041 value = c_parser_peek_token (parser)->value;
3042 c_parser_consume_token (parser);
3043 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3045 /* _Atomic ( type-name ). */
3046 seen_type = true;
3047 c_parser_consume_token (parser);
3048 struct c_type_name *type = c_parser_type_name (parser);
3049 t.kind = ctsk_typeof;
3050 t.spec = error_mark_node;
3051 t.expr = NULL_TREE;
3052 t.expr_const_operands = true;
3053 if (type != NULL)
3054 t.spec = groktypename (type, &t.expr,
3055 &t.expr_const_operands);
3056 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3057 "expected %<)%>");
3058 if (t.spec != error_mark_node)
3060 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3061 error_at (loc, "%<_Atomic%>-qualified array type");
3062 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3063 error_at (loc, "%<_Atomic%>-qualified function type");
3064 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3065 error_at (loc, "%<_Atomic%> applied to a qualified type");
3066 else
3067 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3069 declspecs_add_type (loc, specs, t);
3071 else
3072 declspecs_add_qual (loc, specs, value);
3073 break;
3074 case RID_CONST:
3075 case RID_VOLATILE:
3076 case RID_RESTRICT:
3077 attrs_ok = true;
3078 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3079 c_parser_consume_token (parser);
3080 break;
3081 case RID_ATTRIBUTE:
3082 if (!attrs_ok)
3083 goto out;
3084 attrs = c_parser_gnu_attributes (parser);
3085 declspecs_add_attrs (loc, specs, attrs);
3086 break;
3087 case RID_ALIGNAS:
3088 if (!alignspec_ok)
3089 goto out;
3090 align = c_parser_alignas_specifier (parser);
3091 declspecs_add_alignas (loc, specs, align);
3092 break;
3093 case RID_GIMPLE:
3094 if (! flag_gimple)
3095 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3096 c_parser_consume_token (parser);
3097 specs->declspec_il = cdil_gimple;
3098 specs->locations[cdw_gimple] = loc;
3099 c_parser_gimple_or_rtl_pass_list (parser, specs);
3100 break;
3101 case RID_RTL:
3102 c_parser_consume_token (parser);
3103 specs->declspec_il = cdil_rtl;
3104 specs->locations[cdw_rtl] = loc;
3105 c_parser_gimple_or_rtl_pass_list (parser, specs);
3106 break;
3107 default:
3108 goto out;
3111 out:
3112 if (end_std_attr_ok
3113 && c_parser_nth_token_starts_std_attributes (parser, 1))
3114 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3117 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3119 enum-specifier:
3120 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3121 gnu-attributes[opt]
3122 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3123 gnu-attributes[opt]
3124 enum gnu-attributes[opt] identifier
3126 The form with trailing comma is new in C99. The forms with
3127 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3128 without commas in the syntax (assignment expressions, not just
3129 conditional expressions); assignment expressions will be diagnosed
3130 as non-constant.
3132 enumerator-list:
3133 enumerator
3134 enumerator-list , enumerator
3136 enumerator:
3137 enumeration-constant attribute-specifier-sequence[opt]
3138 enumeration-constant attribute-specifier-sequence[opt]
3139 = constant-expression
3141 GNU Extensions:
3143 enumerator:
3144 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3145 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3146 = constant-expression
3150 static struct c_typespec
3151 c_parser_enum_specifier (c_parser *parser)
3153 struct c_typespec ret;
3154 bool have_std_attrs;
3155 tree std_attrs = NULL_TREE;
3156 tree attrs;
3157 tree ident = NULL_TREE;
3158 location_t enum_loc;
3159 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3160 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3161 c_parser_consume_token (parser);
3162 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3163 if (have_std_attrs)
3164 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3165 attrs = c_parser_gnu_attributes (parser);
3166 enum_loc = c_parser_peek_token (parser)->location;
3167 /* Set the location in case we create a decl now. */
3168 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3169 if (c_parser_next_token_is (parser, CPP_NAME))
3171 ident = c_parser_peek_token (parser)->value;
3172 ident_loc = c_parser_peek_token (parser)->location;
3173 enum_loc = ident_loc;
3174 c_parser_consume_token (parser);
3176 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3178 /* Parse an enum definition. */
3179 struct c_enum_contents the_enum;
3180 tree type;
3181 tree postfix_attrs;
3182 /* We chain the enumerators in reverse order, then put them in
3183 forward order at the end. */
3184 tree values;
3185 timevar_push (TV_PARSE_ENUM);
3186 type = start_enum (enum_loc, &the_enum, ident);
3187 values = NULL_TREE;
3188 c_parser_consume_token (parser);
3189 while (true)
3191 tree enum_id;
3192 tree enum_value;
3193 tree enum_decl;
3194 bool seen_comma;
3195 c_token *token;
3196 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3197 location_t decl_loc, value_loc;
3198 if (c_parser_next_token_is_not (parser, CPP_NAME))
3200 /* Give a nicer error for "enum {}". */
3201 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3202 && !parser->error)
3204 error_at (c_parser_peek_token (parser)->location,
3205 "empty enum is invalid");
3206 parser->error = true;
3208 else
3209 c_parser_error (parser, "expected identifier");
3210 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3211 values = error_mark_node;
3212 break;
3214 token = c_parser_peek_token (parser);
3215 enum_id = token->value;
3216 /* Set the location in case we create a decl now. */
3217 c_parser_set_source_position_from_token (token);
3218 decl_loc = value_loc = token->location;
3219 c_parser_consume_token (parser);
3220 /* Parse any specified attributes. */
3221 tree std_attrs = NULL_TREE;
3222 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3223 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3224 tree enum_attrs = chainon (std_attrs,
3225 c_parser_gnu_attributes (parser));
3226 if (c_parser_next_token_is (parser, CPP_EQ))
3228 c_parser_consume_token (parser);
3229 value_loc = c_parser_peek_token (parser)->location;
3230 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3232 else
3233 enum_value = NULL_TREE;
3234 enum_decl = build_enumerator (decl_loc, value_loc,
3235 &the_enum, enum_id, enum_value);
3236 if (enum_attrs)
3237 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3238 TREE_CHAIN (enum_decl) = values;
3239 values = enum_decl;
3240 seen_comma = false;
3241 if (c_parser_next_token_is (parser, CPP_COMMA))
3243 comma_loc = c_parser_peek_token (parser)->location;
3244 seen_comma = true;
3245 c_parser_consume_token (parser);
3247 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3249 if (seen_comma)
3250 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3251 "comma at end of enumerator list");
3252 c_parser_consume_token (parser);
3253 break;
3255 if (!seen_comma)
3257 c_parser_error (parser, "expected %<,%> or %<}%>");
3258 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3259 values = error_mark_node;
3260 break;
3263 postfix_attrs = c_parser_gnu_attributes (parser);
3264 ret.spec = finish_enum (type, nreverse (values),
3265 chainon (std_attrs,
3266 chainon (attrs, postfix_attrs)));
3267 ret.kind = ctsk_tagdef;
3268 ret.expr = NULL_TREE;
3269 ret.expr_const_operands = true;
3270 timevar_pop (TV_PARSE_ENUM);
3271 return ret;
3273 else if (!ident)
3275 c_parser_error (parser, "expected %<{%>");
3276 ret.spec = error_mark_node;
3277 ret.kind = ctsk_tagref;
3278 ret.expr = NULL_TREE;
3279 ret.expr_const_operands = true;
3280 return ret;
3282 /* Attributes may only appear when the members are defined or in
3283 certain forward declarations (treat enum forward declarations in
3284 GNU C analogously to struct and union forward declarations in
3285 standard C). */
3286 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3287 c_parser_error (parser, "expected %<;%>");
3288 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3289 std_attrs);
3290 /* In ISO C, enumerated types can be referred to only if already
3291 defined. */
3292 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3294 gcc_assert (ident);
3295 pedwarn (enum_loc, OPT_Wpedantic,
3296 "ISO C forbids forward references to %<enum%> types");
3298 return ret;
3301 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3303 struct-or-union-specifier:
3304 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3305 identifier[opt] { struct-contents } gnu-attributes[opt]
3306 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3307 identifier
3309 struct-contents:
3310 struct-declaration-list
3312 struct-declaration-list:
3313 struct-declaration ;
3314 struct-declaration-list struct-declaration ;
3316 GNU extensions:
3318 struct-contents:
3319 empty
3320 struct-declaration
3321 struct-declaration-list struct-declaration
3323 struct-declaration-list:
3324 struct-declaration-list ;
3327 (Note that in the syntax here, unlike that in ISO C, the semicolons
3328 are included here rather than in struct-declaration, in order to
3329 describe the syntax with extra semicolons and missing semicolon at
3330 end.)
3332 Objective-C:
3334 struct-declaration-list:
3335 @defs ( class-name )
3337 (Note this does not include a trailing semicolon, but can be
3338 followed by further declarations, and gets a pedwarn-if-pedantic
3339 when followed by a semicolon.) */
3341 static struct c_typespec
3342 c_parser_struct_or_union_specifier (c_parser *parser)
3344 struct c_typespec ret;
3345 bool have_std_attrs;
3346 tree std_attrs = NULL_TREE;
3347 tree attrs;
3348 tree ident = NULL_TREE;
3349 location_t struct_loc;
3350 location_t ident_loc = UNKNOWN_LOCATION;
3351 enum tree_code code;
3352 switch (c_parser_peek_token (parser)->keyword)
3354 case RID_STRUCT:
3355 code = RECORD_TYPE;
3356 break;
3357 case RID_UNION:
3358 code = UNION_TYPE;
3359 break;
3360 default:
3361 gcc_unreachable ();
3363 struct_loc = c_parser_peek_token (parser)->location;
3364 c_parser_consume_token (parser);
3365 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3366 if (have_std_attrs)
3367 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3368 attrs = c_parser_gnu_attributes (parser);
3370 /* Set the location in case we create a decl now. */
3371 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3373 if (c_parser_next_token_is (parser, CPP_NAME))
3375 ident = c_parser_peek_token (parser)->value;
3376 ident_loc = c_parser_peek_token (parser)->location;
3377 struct_loc = ident_loc;
3378 c_parser_consume_token (parser);
3380 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3382 /* Parse a struct or union definition. Start the scope of the
3383 tag before parsing components. */
3384 class c_struct_parse_info *struct_info;
3385 tree type = start_struct (struct_loc, code, ident, &struct_info);
3386 tree postfix_attrs;
3387 /* We chain the components in reverse order, then put them in
3388 forward order at the end. Each struct-declaration may
3389 declare multiple components (comma-separated), so we must use
3390 chainon to join them, although when parsing each
3391 struct-declaration we can use TREE_CHAIN directly.
3393 The theory behind all this is that there will be more
3394 semicolon separated fields than comma separated fields, and
3395 so we'll be minimizing the number of node traversals required
3396 by chainon. */
3397 tree contents;
3398 timevar_push (TV_PARSE_STRUCT);
3399 contents = NULL_TREE;
3400 c_parser_consume_token (parser);
3401 /* Handle the Objective-C @defs construct,
3402 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3403 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3405 tree name;
3406 gcc_assert (c_dialect_objc ());
3407 c_parser_consume_token (parser);
3408 matching_parens parens;
3409 if (!parens.require_open (parser))
3410 goto end_at_defs;
3411 if (c_parser_next_token_is (parser, CPP_NAME)
3412 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3414 name = c_parser_peek_token (parser)->value;
3415 c_parser_consume_token (parser);
3417 else
3419 c_parser_error (parser, "expected class name");
3420 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3421 goto end_at_defs;
3423 parens.skip_until_found_close (parser);
3424 contents = nreverse (objc_get_class_ivars (name));
3426 end_at_defs:
3427 /* Parse the struct-declarations and semicolons. Problems with
3428 semicolons are diagnosed here; empty structures are diagnosed
3429 elsewhere. */
3430 while (true)
3432 tree decls;
3433 /* Parse any stray semicolon. */
3434 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3436 location_t semicolon_loc
3437 = c_parser_peek_token (parser)->location;
3438 gcc_rich_location richloc (semicolon_loc);
3439 richloc.add_fixit_remove ();
3440 pedwarn (&richloc, OPT_Wpedantic,
3441 "extra semicolon in struct or union specified");
3442 c_parser_consume_token (parser);
3443 continue;
3445 /* Stop if at the end of the struct or union contents. */
3446 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3448 c_parser_consume_token (parser);
3449 break;
3451 /* Accept #pragmas at struct scope. */
3452 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3454 c_parser_pragma (parser, pragma_struct, NULL);
3455 continue;
3457 /* Parse some comma-separated declarations, but not the
3458 trailing semicolon if any. */
3459 decls = c_parser_struct_declaration (parser);
3460 contents = chainon (decls, contents);
3461 /* If no semicolon follows, either we have a parse error or
3462 are at the end of the struct or union and should
3463 pedwarn. */
3464 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3465 c_parser_consume_token (parser);
3466 else
3468 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3469 pedwarn (c_parser_peek_token (parser)->location, 0,
3470 "no semicolon at end of struct or union");
3471 else if (parser->error
3472 || !c_parser_next_token_starts_declspecs (parser))
3474 c_parser_error (parser, "expected %<;%>");
3475 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3476 break;
3479 /* If we come here, we have already emitted an error
3480 for an expected `;', identifier or `(', and we also
3481 recovered already. Go on with the next field. */
3484 postfix_attrs = c_parser_gnu_attributes (parser);
3485 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3486 chainon (std_attrs,
3487 chainon (attrs, postfix_attrs)),
3488 struct_info);
3489 ret.kind = ctsk_tagdef;
3490 ret.expr = NULL_TREE;
3491 ret.expr_const_operands = true;
3492 timevar_pop (TV_PARSE_STRUCT);
3493 return ret;
3495 else if (!ident)
3497 c_parser_error (parser, "expected %<{%>");
3498 ret.spec = error_mark_node;
3499 ret.kind = ctsk_tagref;
3500 ret.expr = NULL_TREE;
3501 ret.expr_const_operands = true;
3502 return ret;
3504 /* Attributes may only appear when the members are defined or in
3505 certain forward declarations. */
3506 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3507 c_parser_error (parser, "expected %<;%>");
3508 /* ??? Existing practice is that GNU attributes are ignored after
3509 the struct or union keyword when not defining the members. */
3510 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3511 return ret;
3514 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3515 *without* the trailing semicolon.
3517 struct-declaration:
3518 attribute-specifier-sequence[opt] specifier-qualifier-list
3519 attribute-specifier-sequence[opt] struct-declarator-list
3520 static_assert-declaration-no-semi
3522 specifier-qualifier-list:
3523 type-specifier specifier-qualifier-list[opt]
3524 type-qualifier specifier-qualifier-list[opt]
3525 alignment-specifier specifier-qualifier-list[opt]
3526 gnu-attributes specifier-qualifier-list[opt]
3528 struct-declarator-list:
3529 struct-declarator
3530 struct-declarator-list , gnu-attributes[opt] struct-declarator
3532 struct-declarator:
3533 declarator gnu-attributes[opt]
3534 declarator[opt] : constant-expression gnu-attributes[opt]
3536 GNU extensions:
3538 struct-declaration:
3539 __extension__ struct-declaration
3540 specifier-qualifier-list
3542 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3543 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3544 any expression without commas in the syntax (assignment
3545 expressions, not just conditional expressions); assignment
3546 expressions will be diagnosed as non-constant. */
3548 static tree
3549 c_parser_struct_declaration (c_parser *parser)
3551 struct c_declspecs *specs;
3552 tree prefix_attrs;
3553 tree all_prefix_attrs;
3554 tree decls;
3555 location_t decl_loc;
3556 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3558 int ext;
3559 tree decl;
3560 ext = disable_extension_diagnostics ();
3561 c_parser_consume_token (parser);
3562 decl = c_parser_struct_declaration (parser);
3563 restore_extension_diagnostics (ext);
3564 return decl;
3566 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3568 c_parser_static_assert_declaration_no_semi (parser);
3569 return NULL_TREE;
3571 specs = build_null_declspecs ();
3572 decl_loc = c_parser_peek_token (parser)->location;
3573 /* Strictly by the standard, we shouldn't allow _Alignas here,
3574 but it appears to have been intended to allow it there, so
3575 we're keeping it as it is until WG14 reaches a conclusion
3576 of N1731.
3577 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3578 c_parser_declspecs (parser, specs, false, true, true,
3579 true, false, true, true, cla_nonabstract_decl);
3580 if (parser->error)
3581 return NULL_TREE;
3582 if (!specs->declspecs_seen_p)
3584 c_parser_error (parser, "expected specifier-qualifier-list");
3585 return NULL_TREE;
3587 finish_declspecs (specs);
3588 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3589 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3591 tree ret;
3592 if (specs->typespec_kind == ctsk_none)
3594 pedwarn (decl_loc, OPT_Wpedantic,
3595 "ISO C forbids member declarations with no members");
3596 shadow_tag_warned (specs, pedantic);
3597 ret = NULL_TREE;
3599 else
3601 /* Support for unnamed structs or unions as members of
3602 structs or unions (which is [a] useful and [b] supports
3603 MS P-SDK). */
3604 tree attrs = NULL;
3606 ret = grokfield (c_parser_peek_token (parser)->location,
3607 build_id_declarator (NULL_TREE), specs,
3608 NULL_TREE, &attrs);
3609 if (ret)
3610 decl_attributes (&ret, attrs, 0);
3612 return ret;
3615 /* Provide better error recovery. Note that a type name here is valid,
3616 and will be treated as a field name. */
3617 if (specs->typespec_kind == ctsk_tagdef
3618 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3619 && c_parser_next_token_starts_declspecs (parser)
3620 && !c_parser_next_token_is (parser, CPP_NAME))
3622 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3623 parser->error = false;
3624 return NULL_TREE;
3627 pending_xref_error ();
3628 prefix_attrs = specs->attrs;
3629 all_prefix_attrs = prefix_attrs;
3630 specs->attrs = NULL_TREE;
3631 decls = NULL_TREE;
3632 while (true)
3634 /* Declaring one or more declarators or un-named bit-fields. */
3635 struct c_declarator *declarator;
3636 bool dummy = false;
3637 if (c_parser_next_token_is (parser, CPP_COLON))
3638 declarator = build_id_declarator (NULL_TREE);
3639 else
3640 declarator = c_parser_declarator (parser,
3641 specs->typespec_kind != ctsk_none,
3642 C_DTR_NORMAL, &dummy);
3643 if (declarator == NULL)
3645 c_parser_skip_to_end_of_block_or_statement (parser);
3646 break;
3648 if (c_parser_next_token_is (parser, CPP_COLON)
3649 || c_parser_next_token_is (parser, CPP_COMMA)
3650 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3651 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3652 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3654 tree postfix_attrs = NULL_TREE;
3655 tree width = NULL_TREE;
3656 tree d;
3657 if (c_parser_next_token_is (parser, CPP_COLON))
3659 c_parser_consume_token (parser);
3660 width = c_parser_expr_no_commas (parser, NULL).value;
3662 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3663 postfix_attrs = c_parser_gnu_attributes (parser);
3664 d = grokfield (c_parser_peek_token (parser)->location,
3665 declarator, specs, width, &all_prefix_attrs);
3666 decl_attributes (&d, chainon (postfix_attrs,
3667 all_prefix_attrs), 0);
3668 DECL_CHAIN (d) = decls;
3669 decls = d;
3670 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3671 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3672 prefix_attrs);
3673 else
3674 all_prefix_attrs = prefix_attrs;
3675 if (c_parser_next_token_is (parser, CPP_COMMA))
3676 c_parser_consume_token (parser);
3677 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3678 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3680 /* Semicolon consumed in caller. */
3681 break;
3683 else
3685 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3686 break;
3689 else
3691 c_parser_error (parser,
3692 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3693 "%<__attribute__%>");
3694 break;
3697 return decls;
3700 /* Parse a typeof specifier (a GNU extension).
3702 typeof-specifier:
3703 typeof ( expression )
3704 typeof ( type-name )
3707 static struct c_typespec
3708 c_parser_typeof_specifier (c_parser *parser)
3710 struct c_typespec ret;
3711 ret.kind = ctsk_typeof;
3712 ret.spec = error_mark_node;
3713 ret.expr = NULL_TREE;
3714 ret.expr_const_operands = true;
3715 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3716 c_parser_consume_token (parser);
3717 c_inhibit_evaluation_warnings++;
3718 in_typeof++;
3719 matching_parens parens;
3720 if (!parens.require_open (parser))
3722 c_inhibit_evaluation_warnings--;
3723 in_typeof--;
3724 return ret;
3726 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3728 struct c_type_name *type = c_parser_type_name (parser);
3729 c_inhibit_evaluation_warnings--;
3730 in_typeof--;
3731 if (type != NULL)
3733 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3734 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3737 else
3739 bool was_vm;
3740 location_t here = c_parser_peek_token (parser)->location;
3741 struct c_expr expr = c_parser_expression (parser);
3742 c_inhibit_evaluation_warnings--;
3743 in_typeof--;
3744 if (TREE_CODE (expr.value) == COMPONENT_REF
3745 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3746 error_at (here, "%<typeof%> applied to a bit-field");
3747 mark_exp_read (expr.value);
3748 ret.spec = TREE_TYPE (expr.value);
3749 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3750 /* This is returned with the type so that when the type is
3751 evaluated, this can be evaluated. */
3752 if (was_vm)
3753 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3754 pop_maybe_used (was_vm);
3756 parens.skip_until_found_close (parser);
3757 return ret;
3760 /* Parse an alignment-specifier.
3762 C11 6.7.5:
3764 alignment-specifier:
3765 _Alignas ( type-name )
3766 _Alignas ( constant-expression )
3769 static tree
3770 c_parser_alignas_specifier (c_parser * parser)
3772 tree ret = error_mark_node;
3773 location_t loc = c_parser_peek_token (parser)->location;
3774 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3775 c_parser_consume_token (parser);
3776 if (flag_isoc99)
3777 pedwarn_c99 (loc, OPT_Wpedantic,
3778 "ISO C99 does not support %<_Alignas%>");
3779 else
3780 pedwarn_c99 (loc, OPT_Wpedantic,
3781 "ISO C90 does not support %<_Alignas%>");
3782 matching_parens parens;
3783 if (!parens.require_open (parser))
3784 return ret;
3785 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3787 struct c_type_name *type = c_parser_type_name (parser);
3788 if (type != NULL)
3789 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3790 false, true, 1);
3792 else
3793 ret = c_parser_expr_no_commas (parser, NULL).value;
3794 parens.skip_until_found_close (parser);
3795 return ret;
3798 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3799 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3800 a typedef name may be redeclared; otherwise it may not. KIND
3801 indicates which kind of declarator is wanted. Returns a valid
3802 declarator except in the case of a syntax error in which case NULL is
3803 returned. *SEEN_ID is set to true if an identifier being declared is
3804 seen; this is used to diagnose bad forms of abstract array declarators
3805 and to determine whether an identifier list is syntactically permitted.
3807 declarator:
3808 pointer[opt] direct-declarator
3810 direct-declarator:
3811 identifier
3812 ( gnu-attributes[opt] declarator )
3813 direct-declarator array-declarator
3814 direct-declarator ( parameter-type-list )
3815 direct-declarator ( identifier-list[opt] )
3817 pointer:
3818 * type-qualifier-list[opt]
3819 * type-qualifier-list[opt] pointer
3821 type-qualifier-list:
3822 type-qualifier
3823 gnu-attributes
3824 type-qualifier-list type-qualifier
3825 type-qualifier-list gnu-attributes
3827 array-declarator:
3828 [ type-qualifier-list[opt] assignment-expression[opt] ]
3829 [ static type-qualifier-list[opt] assignment-expression ]
3830 [ type-qualifier-list static assignment-expression ]
3831 [ type-qualifier-list[opt] * ]
3833 parameter-type-list:
3834 parameter-list
3835 parameter-list , ...
3837 parameter-list:
3838 parameter-declaration
3839 parameter-list , parameter-declaration
3841 parameter-declaration:
3842 declaration-specifiers declarator gnu-attributes[opt]
3843 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3845 identifier-list:
3846 identifier
3847 identifier-list , identifier
3849 abstract-declarator:
3850 pointer
3851 pointer[opt] direct-abstract-declarator
3853 direct-abstract-declarator:
3854 ( gnu-attributes[opt] abstract-declarator )
3855 direct-abstract-declarator[opt] array-declarator
3856 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3858 GNU extensions:
3860 direct-declarator:
3861 direct-declarator ( parameter-forward-declarations
3862 parameter-type-list[opt] )
3864 direct-abstract-declarator:
3865 direct-abstract-declarator[opt] ( parameter-forward-declarations
3866 parameter-type-list[opt] )
3868 parameter-forward-declarations:
3869 parameter-list ;
3870 parameter-forward-declarations parameter-list ;
3872 The uses of gnu-attributes shown above are GNU extensions.
3874 Some forms of array declarator are not included in C99 in the
3875 syntax for abstract declarators; these are disallowed elsewhere.
3876 This may be a defect (DR#289).
3878 This function also accepts an omitted abstract declarator as being
3879 an abstract declarator, although not part of the formal syntax. */
3881 struct c_declarator *
3882 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3883 bool *seen_id)
3885 /* Parse any initial pointer part. */
3886 if (c_parser_next_token_is (parser, CPP_MULT))
3888 struct c_declspecs *quals_attrs = build_null_declspecs ();
3889 struct c_declarator *inner;
3890 c_parser_consume_token (parser);
3891 c_parser_declspecs (parser, quals_attrs, false, false, true,
3892 false, false, true, false, cla_prefer_id);
3893 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3894 if (inner == NULL)
3895 return NULL;
3896 else
3897 return make_pointer_declarator (quals_attrs, inner);
3899 /* Now we have a direct declarator, direct abstract declarator or
3900 nothing (which counts as a direct abstract declarator here). */
3901 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3904 /* Parse a direct declarator or direct abstract declarator; arguments
3905 as c_parser_declarator. */
3907 static struct c_declarator *
3908 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3909 bool *seen_id)
3911 /* The direct declarator must start with an identifier (possibly
3912 omitted) or a parenthesized declarator (possibly abstract). In
3913 an ordinary declarator, initial parentheses must start a
3914 parenthesized declarator. In an abstract declarator or parameter
3915 declarator, they could start a parenthesized declarator or a
3916 parameter list. To tell which, the open parenthesis and any
3917 following gnu-attributes must be read. If a declaration
3918 specifier or standard attributes follow, then it is a parameter
3919 list; if the specifier is a typedef name, there might be an
3920 ambiguity about redeclaring it, which is resolved in the
3921 direction of treating it as a typedef name. If a close
3922 parenthesis follows, it is also an empty parameter list, as the
3923 syntax does not permit empty abstract declarators. Otherwise, it
3924 is a parenthesized declarator (in which case the analysis may be
3925 repeated inside it, recursively).
3927 ??? There is an ambiguity in a parameter declaration "int
3928 (__attribute__((foo)) x)", where x is not a typedef name: it
3929 could be an abstract declarator for a function, or declare x with
3930 parentheses. The proper resolution of this ambiguity needs
3931 documenting. At present we follow an accident of the old
3932 parser's implementation, whereby the first parameter must have
3933 some declaration specifiers other than just gnu-attributes. Thus as
3934 a parameter declaration it is treated as a parenthesized
3935 parameter named x, and as an abstract declarator it is
3936 rejected.
3938 ??? Also following the old parser, gnu-attributes inside an empty
3939 parameter list are ignored, making it a list not yielding a
3940 prototype, rather than giving an error or making it have one
3941 parameter with implicit type int.
3943 ??? Also following the old parser, typedef names may be
3944 redeclared in declarators, but not Objective-C class names. */
3946 if (kind != C_DTR_ABSTRACT
3947 && c_parser_next_token_is (parser, CPP_NAME)
3948 && ((type_seen_p
3949 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3950 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3951 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3953 struct c_declarator *inner
3954 = build_id_declarator (c_parser_peek_token (parser)->value);
3955 *seen_id = true;
3956 inner->id_loc = c_parser_peek_token (parser)->location;
3957 c_parser_consume_token (parser);
3958 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3959 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3960 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3963 if (kind != C_DTR_NORMAL
3964 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3965 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3967 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3968 inner->id_loc = c_parser_peek_token (parser)->location;
3969 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3972 /* Either we are at the end of an abstract declarator, or we have
3973 parentheses. */
3975 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3977 tree attrs;
3978 struct c_declarator *inner;
3979 c_parser_consume_token (parser);
3980 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3981 RID_ATTRIBUTE);
3982 attrs = c_parser_gnu_attributes (parser);
3983 if (kind != C_DTR_NORMAL
3984 && (c_parser_next_token_starts_declspecs (parser)
3985 || (!have_gnu_attrs
3986 && c_parser_nth_token_starts_std_attributes (parser, 1))
3987 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3989 struct c_arg_info *args
3990 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3991 attrs, have_gnu_attrs);
3992 if (args == NULL)
3993 return NULL;
3994 else
3996 inner = build_id_declarator (NULL_TREE);
3997 if (!(args->types
3998 && args->types != error_mark_node
3999 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4000 && c_parser_nth_token_starts_std_attributes (parser, 1))
4002 tree std_attrs
4003 = c_parser_std_attribute_specifier_sequence (parser);
4004 if (std_attrs)
4005 inner = build_attrs_declarator (std_attrs, inner);
4007 inner = build_function_declarator (args, inner);
4008 return c_parser_direct_declarator_inner (parser, *seen_id,
4009 inner);
4012 /* A parenthesized declarator. */
4013 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4014 if (inner != NULL && attrs != NULL)
4015 inner = build_attrs_declarator (attrs, inner);
4016 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4018 c_parser_consume_token (parser);
4019 if (inner == NULL)
4020 return NULL;
4021 else
4022 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4024 else
4026 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4027 "expected %<)%>");
4028 return NULL;
4031 else
4033 if (kind == C_DTR_NORMAL)
4035 c_parser_error (parser, "expected identifier or %<(%>");
4036 return NULL;
4038 else
4039 return build_id_declarator (NULL_TREE);
4043 /* Parse part of a direct declarator or direct abstract declarator,
4044 given that some (in INNER) has already been parsed; ID_PRESENT is
4045 true if an identifier is present, false for an abstract
4046 declarator. */
4048 static struct c_declarator *
4049 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4050 struct c_declarator *inner)
4052 /* Parse a sequence of array declarators and parameter lists. */
4053 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4054 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4056 location_t brace_loc = c_parser_peek_token (parser)->location;
4057 struct c_declarator *declarator;
4058 struct c_declspecs *quals_attrs = build_null_declspecs ();
4059 bool static_seen;
4060 bool star_seen;
4061 struct c_expr dimen;
4062 dimen.value = NULL_TREE;
4063 dimen.original_code = ERROR_MARK;
4064 dimen.original_type = NULL_TREE;
4065 c_parser_consume_token (parser);
4066 c_parser_declspecs (parser, quals_attrs, false, false, true,
4067 false, false, false, false, cla_prefer_id);
4068 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4069 if (static_seen)
4070 c_parser_consume_token (parser);
4071 if (static_seen && !quals_attrs->declspecs_seen_p)
4072 c_parser_declspecs (parser, quals_attrs, false, false, true,
4073 false, false, false, false, cla_prefer_id);
4074 if (!quals_attrs->declspecs_seen_p)
4075 quals_attrs = NULL;
4076 /* If "static" is present, there must be an array dimension.
4077 Otherwise, there may be a dimension, "*", or no
4078 dimension. */
4079 if (static_seen)
4081 star_seen = false;
4082 dimen = c_parser_expr_no_commas (parser, NULL);
4084 else
4086 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4088 dimen.value = NULL_TREE;
4089 star_seen = false;
4091 else if (c_parser_next_token_is (parser, CPP_MULT))
4093 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4095 dimen.value = NULL_TREE;
4096 star_seen = true;
4097 c_parser_consume_token (parser);
4099 else
4101 star_seen = false;
4102 dimen = c_parser_expr_no_commas (parser, NULL);
4105 else
4107 star_seen = false;
4108 dimen = c_parser_expr_no_commas (parser, NULL);
4111 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4112 c_parser_consume_token (parser);
4113 else
4115 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4116 "expected %<]%>");
4117 return NULL;
4119 if (dimen.value)
4120 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4121 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4122 static_seen, star_seen);
4123 if (declarator == NULL)
4124 return NULL;
4125 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4127 tree std_attrs
4128 = c_parser_std_attribute_specifier_sequence (parser);
4129 if (std_attrs)
4130 inner = build_attrs_declarator (std_attrs, inner);
4132 inner = set_array_declarator_inner (declarator, inner);
4133 return c_parser_direct_declarator_inner (parser, id_present, inner);
4135 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4137 tree attrs;
4138 struct c_arg_info *args;
4139 c_parser_consume_token (parser);
4140 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4141 RID_ATTRIBUTE);
4142 attrs = c_parser_gnu_attributes (parser);
4143 args = c_parser_parms_declarator (parser, id_present, attrs,
4144 have_gnu_attrs);
4145 if (args == NULL)
4146 return NULL;
4147 else
4149 if (!(args->types
4150 && args->types != error_mark_node
4151 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4152 && c_parser_nth_token_starts_std_attributes (parser, 1))
4154 tree std_attrs
4155 = c_parser_std_attribute_specifier_sequence (parser);
4156 if (std_attrs)
4157 inner = build_attrs_declarator (std_attrs, inner);
4159 inner = build_function_declarator (args, inner);
4160 return c_parser_direct_declarator_inner (parser, id_present, inner);
4163 return inner;
4166 /* Parse a parameter list or identifier list, including the closing
4167 parenthesis but not the opening one. ATTRS are the gnu-attributes
4168 at the start of the list. ID_LIST_OK is true if an identifier list
4169 is acceptable; such a list must not have attributes at the start.
4170 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4171 attributes) were present (in which case standard attributes cannot
4172 occur). */
4174 static struct c_arg_info *
4175 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4176 bool have_gnu_attrs)
4178 push_scope ();
4179 declare_parm_level ();
4180 /* If the list starts with an identifier, it is an identifier list.
4181 Otherwise, it is either a prototype list or an empty list. */
4182 if (id_list_ok
4183 && !attrs
4184 && c_parser_next_token_is (parser, CPP_NAME)
4185 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4187 /* Look ahead to detect typos in type names. */
4188 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4189 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4190 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4191 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4192 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4194 tree list = NULL_TREE, *nextp = &list;
4195 while (c_parser_next_token_is (parser, CPP_NAME)
4196 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4198 *nextp = build_tree_list (NULL_TREE,
4199 c_parser_peek_token (parser)->value);
4200 nextp = & TREE_CHAIN (*nextp);
4201 c_parser_consume_token (parser);
4202 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4203 break;
4204 c_parser_consume_token (parser);
4205 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4207 c_parser_error (parser, "expected identifier");
4208 break;
4211 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4213 struct c_arg_info *ret = build_arg_info ();
4214 ret->types = list;
4215 c_parser_consume_token (parser);
4216 pop_scope ();
4217 return ret;
4219 else
4221 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4222 "expected %<)%>");
4223 pop_scope ();
4224 return NULL;
4227 else
4229 struct c_arg_info *ret
4230 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4231 pop_scope ();
4232 return ret;
4236 /* Parse a parameter list (possibly empty), including the closing
4237 parenthesis but not the opening one. ATTRS are the gnu-attributes
4238 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4239 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4240 which means standard attributes cannot start the list. EXPR is
4241 NULL or an expression that needs to be evaluated for the side
4242 effects of array size expressions in the parameters. */
4244 static struct c_arg_info *
4245 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4246 bool have_gnu_attrs)
4248 bool bad_parm = false;
4250 /* ??? Following the old parser, forward parameter declarations may
4251 use abstract declarators, and if no real parameter declarations
4252 follow the forward declarations then this is not diagnosed. Also
4253 note as above that gnu-attributes are ignored as the only contents of
4254 the parentheses, or as the only contents after forward
4255 declarations. */
4256 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4258 struct c_arg_info *ret = build_arg_info ();
4259 c_parser_consume_token (parser);
4260 return ret;
4262 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4264 struct c_arg_info *ret = build_arg_info ();
4266 if (flag_allow_parameterless_variadic_functions)
4268 /* F (...) is allowed. */
4269 ret->types = NULL_TREE;
4271 else
4273 /* Suppress -Wold-style-definition for this case. */
4274 ret->types = error_mark_node;
4275 error_at (c_parser_peek_token (parser)->location,
4276 "ISO C requires a named argument before %<...%>");
4278 c_parser_consume_token (parser);
4279 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4281 c_parser_consume_token (parser);
4282 return ret;
4284 else
4286 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4287 "expected %<)%>");
4288 return NULL;
4291 /* Nonempty list of parameters, either terminated with semicolon
4292 (forward declarations; recurse) or with close parenthesis (normal
4293 function) or with ", ... )" (variadic function). */
4294 while (true)
4296 /* Parse a parameter. */
4297 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4298 have_gnu_attrs);
4299 attrs = NULL_TREE;
4300 have_gnu_attrs = false;
4301 if (parm == NULL)
4302 bad_parm = true;
4303 else
4304 push_parm_decl (parm, &expr);
4305 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4307 tree new_attrs;
4308 c_parser_consume_token (parser);
4309 mark_forward_parm_decls ();
4310 bool new_have_gnu_attrs
4311 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4312 new_attrs = c_parser_gnu_attributes (parser);
4313 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4314 new_have_gnu_attrs);
4316 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4318 c_parser_consume_token (parser);
4319 if (bad_parm)
4320 return NULL;
4321 else
4322 return get_parm_info (false, expr);
4324 if (!c_parser_require (parser, CPP_COMMA,
4325 "expected %<;%>, %<,%> or %<)%>",
4326 UNKNOWN_LOCATION, false))
4328 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4329 return NULL;
4331 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4333 c_parser_consume_token (parser);
4334 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4336 c_parser_consume_token (parser);
4337 if (bad_parm)
4338 return NULL;
4339 else
4340 return get_parm_info (true, expr);
4342 else
4344 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4345 "expected %<)%>");
4346 return NULL;
4352 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4353 start of the declaration if it is the first parameter;
4354 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4355 empty) there. */
4357 static struct c_parm *
4358 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4359 bool have_gnu_attrs)
4361 struct c_declspecs *specs;
4362 struct c_declarator *declarator;
4363 tree prefix_attrs;
4364 tree postfix_attrs = NULL_TREE;
4365 bool dummy = false;
4367 /* Accept #pragmas between parameter declarations. */
4368 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4369 c_parser_pragma (parser, pragma_param, NULL);
4371 if (!c_parser_next_token_starts_declspecs (parser)
4372 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4374 c_token *token = c_parser_peek_token (parser);
4375 if (parser->error)
4376 return NULL;
4377 c_parser_set_source_position_from_token (token);
4378 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4380 auto_diagnostic_group d;
4381 name_hint hint = lookup_name_fuzzy (token->value,
4382 FUZZY_LOOKUP_TYPENAME,
4383 token->location);
4384 if (const char *suggestion = hint.suggestion ())
4386 gcc_rich_location richloc (token->location);
4387 richloc.add_fixit_replace (suggestion);
4388 error_at (&richloc,
4389 "unknown type name %qE; did you mean %qs?",
4390 token->value, suggestion);
4392 else
4393 error_at (token->location, "unknown type name %qE", token->value);
4394 parser->error = true;
4396 /* ??? In some Objective-C cases '...' isn't applicable so there
4397 should be a different message. */
4398 else
4399 c_parser_error (parser,
4400 "expected declaration specifiers or %<...%>");
4401 c_parser_skip_to_end_of_parameter (parser);
4402 return NULL;
4405 location_t start_loc = c_parser_peek_token (parser)->location;
4407 specs = build_null_declspecs ();
4408 if (attrs)
4410 declspecs_add_attrs (input_location, specs, attrs);
4411 attrs = NULL_TREE;
4413 c_parser_declspecs (parser, specs, true, true, true, true, false,
4414 !have_gnu_attrs, true, cla_nonabstract_decl);
4415 finish_declspecs (specs);
4416 pending_xref_error ();
4417 prefix_attrs = specs->attrs;
4418 specs->attrs = NULL_TREE;
4419 declarator = c_parser_declarator (parser,
4420 specs->typespec_kind != ctsk_none,
4421 C_DTR_PARM, &dummy);
4422 if (declarator == NULL)
4424 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4425 return NULL;
4427 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4428 postfix_attrs = c_parser_gnu_attributes (parser);
4430 /* Generate a location for the parameter, ranging from the start of the
4431 initial token to the end of the final token.
4433 If we have a identifier, then use it for the caret location, e.g.
4435 extern int callee (int one, int (*two)(int, int), float three);
4436 ~~~~~~^~~~~~~~~~~~~~
4438 otherwise, reuse the start location for the caret location e.g.:
4440 extern int callee (int one, int (*)(int, int), float three);
4441 ^~~~~~~~~~~~~~~~~
4443 location_t end_loc = parser->last_token_location;
4445 /* Find any cdk_id declarator; determine if we have an identifier. */
4446 c_declarator *id_declarator = declarator;
4447 while (id_declarator && id_declarator->kind != cdk_id)
4448 id_declarator = id_declarator->declarator;
4449 location_t caret_loc = (id_declarator->u.id.id
4450 ? id_declarator->id_loc
4451 : start_loc);
4452 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4454 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4455 declarator, param_loc);
4458 /* Parse a string literal in an asm expression. It should not be
4459 translated, and wide string literals are an error although
4460 permitted by the syntax. This is a GNU extension.
4462 asm-string-literal:
4463 string-literal
4466 static tree
4467 c_parser_asm_string_literal (c_parser *parser)
4469 tree str;
4470 int save_flag = warn_overlength_strings;
4471 warn_overlength_strings = 0;
4472 str = c_parser_string_literal (parser, false, false).value;
4473 warn_overlength_strings = save_flag;
4474 return str;
4477 /* Parse a simple asm expression. This is used in restricted
4478 contexts, where a full expression with inputs and outputs does not
4479 make sense. This is a GNU extension.
4481 simple-asm-expr:
4482 asm ( asm-string-literal )
4485 static tree
4486 c_parser_simple_asm_expr (c_parser *parser)
4488 tree str;
4489 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4490 c_parser_consume_token (parser);
4491 matching_parens parens;
4492 if (!parens.require_open (parser))
4493 return NULL_TREE;
4494 str = c_parser_asm_string_literal (parser);
4495 if (!parens.require_close (parser))
4497 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4498 return NULL_TREE;
4500 return str;
4503 static tree
4504 c_parser_gnu_attribute_any_word (c_parser *parser)
4506 tree attr_name = NULL_TREE;
4508 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4510 /* ??? See comment above about what keywords are accepted here. */
4511 bool ok;
4512 switch (c_parser_peek_token (parser)->keyword)
4514 case RID_STATIC:
4515 case RID_UNSIGNED:
4516 case RID_LONG:
4517 case RID_CONST:
4518 case RID_EXTERN:
4519 case RID_REGISTER:
4520 case RID_TYPEDEF:
4521 case RID_SHORT:
4522 case RID_INLINE:
4523 case RID_NORETURN:
4524 case RID_VOLATILE:
4525 case RID_SIGNED:
4526 case RID_AUTO:
4527 case RID_RESTRICT:
4528 case RID_COMPLEX:
4529 case RID_THREAD:
4530 case RID_INT:
4531 case RID_CHAR:
4532 case RID_FLOAT:
4533 case RID_DOUBLE:
4534 case RID_VOID:
4535 case RID_DFLOAT32:
4536 case RID_DFLOAT64:
4537 case RID_DFLOAT128:
4538 CASE_RID_FLOATN_NX:
4539 case RID_BOOL:
4540 case RID_FRACT:
4541 case RID_ACCUM:
4542 case RID_SAT:
4543 case RID_TRANSACTION_ATOMIC:
4544 case RID_TRANSACTION_CANCEL:
4545 case RID_ATOMIC:
4546 case RID_AUTO_TYPE:
4547 case RID_INT_N_0:
4548 case RID_INT_N_1:
4549 case RID_INT_N_2:
4550 case RID_INT_N_3:
4551 ok = true;
4552 break;
4553 default:
4554 ok = false;
4555 break;
4557 if (!ok)
4558 return NULL_TREE;
4560 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4561 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4563 else if (c_parser_next_token_is (parser, CPP_NAME))
4564 attr_name = c_parser_peek_token (parser)->value;
4566 return attr_name;
4569 /* Parse attribute arguments. This is a common form of syntax
4570 covering all currently valid GNU and standard attributes.
4572 gnu-attribute-arguments:
4573 identifier
4574 identifier , nonempty-expr-list
4575 expr-list
4577 where the "identifier" must not be declared as a type. ??? Why not
4578 allow identifiers declared as types to start the arguments? */
4580 static tree
4581 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4582 bool require_string, bool allow_empty_args)
4584 vec<tree, va_gc> *expr_list;
4585 tree attr_args;
4586 /* Parse the attribute contents. If they start with an
4587 identifier which is followed by a comma or close
4588 parenthesis, then the arguments start with that
4589 identifier; otherwise they are an expression list.
4590 In objective-c the identifier may be a classname. */
4591 if (c_parser_next_token_is (parser, CPP_NAME)
4592 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4593 || (c_dialect_objc ()
4594 && c_parser_peek_token (parser)->id_kind
4595 == C_ID_CLASSNAME))
4596 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4597 || (c_parser_peek_2nd_token (parser)->type
4598 == CPP_CLOSE_PAREN))
4599 && (takes_identifier
4600 || (c_dialect_objc ()
4601 && c_parser_peek_token (parser)->id_kind
4602 == C_ID_CLASSNAME)))
4604 tree arg1 = c_parser_peek_token (parser)->value;
4605 c_parser_consume_token (parser);
4606 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4607 attr_args = build_tree_list (NULL_TREE, arg1);
4608 else
4610 tree tree_list;
4611 c_parser_consume_token (parser);
4612 expr_list = c_parser_expr_list (parser, false, true,
4613 NULL, NULL, NULL, NULL);
4614 tree_list = build_tree_list_vec (expr_list);
4615 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4616 release_tree_vector (expr_list);
4619 else
4621 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4623 if (!allow_empty_args)
4624 error_at (c_parser_peek_token (parser)->location,
4625 "parentheses must be omitted if "
4626 "attribute argument list is empty");
4627 attr_args = NULL_TREE;
4629 else if (require_string)
4631 /* The only valid argument for this attribute is a string
4632 literal. Handle this specially here to avoid accepting
4633 string literals with excess parentheses. */
4634 tree string = c_parser_string_literal (parser, false, true).value;
4635 attr_args = build_tree_list (NULL_TREE, string);
4637 else
4639 expr_list = c_parser_expr_list (parser, false, true,
4640 NULL, NULL, NULL, NULL);
4641 attr_args = build_tree_list_vec (expr_list);
4642 release_tree_vector (expr_list);
4645 return attr_args;
4648 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4650 gnu-attributes:
4651 empty
4652 gnu-attributes gnu-attribute
4654 gnu-attribute:
4655 __attribute__ ( ( gnu-attribute-list ) )
4657 gnu-attribute-list:
4658 gnu-attrib
4659 gnu-attribute_list , gnu-attrib
4661 gnu-attrib:
4662 empty
4663 any-word
4664 any-word ( gnu-attribute-arguments )
4666 where "any-word" may be any identifier (including one declared as a
4667 type), a reserved word storage class specifier, type specifier or
4668 type qualifier. ??? This still leaves out most reserved keywords
4669 (following the old parser), shouldn't we include them?
4670 When EXPECT_COMMA is true, expect the attribute to be preceded
4671 by a comma and fail if it isn't.
4672 When EMPTY_OK is true, allow and consume any number of consecutive
4673 commas with no attributes in between. */
4675 static tree
4676 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4677 bool expect_comma = false, bool empty_ok = true)
4679 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4680 if (!comma_first
4681 && !c_parser_next_token_is (parser, CPP_NAME)
4682 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4683 return NULL_TREE;
4685 while (c_parser_next_token_is (parser, CPP_COMMA))
4687 c_parser_consume_token (parser);
4688 if (!empty_ok)
4689 return attrs;
4692 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4693 if (attr_name == NULL_TREE)
4694 return NULL_TREE;
4696 attr_name = canonicalize_attr_name (attr_name);
4697 c_parser_consume_token (parser);
4699 tree attr;
4700 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4702 if (expect_comma && !comma_first)
4704 /* A comma is missing between the last attribute on the chain
4705 and this one. */
4706 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4707 "expected %<)%>");
4708 return error_mark_node;
4710 attr = build_tree_list (attr_name, NULL_TREE);
4711 /* Add this attribute to the list. */
4712 attrs = chainon (attrs, attr);
4713 return attrs;
4715 c_parser_consume_token (parser);
4717 tree attr_args
4718 = c_parser_attribute_arguments (parser,
4719 attribute_takes_identifier_p (attr_name),
4720 false, true);
4722 attr = build_tree_list (attr_name, attr_args);
4723 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4724 c_parser_consume_token (parser);
4725 else
4727 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4728 "expected %<)%>");
4729 return error_mark_node;
4732 if (expect_comma && !comma_first)
4734 /* A comma is missing between the last attribute on the chain
4735 and this one. */
4736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4737 "expected %<)%>");
4738 return error_mark_node;
4741 /* Add this attribute to the list. */
4742 attrs = chainon (attrs, attr);
4743 return attrs;
4746 static tree
4747 c_parser_gnu_attributes (c_parser *parser)
4749 tree attrs = NULL_TREE;
4750 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4752 bool save_translate_strings_p = parser->translate_strings_p;
4753 parser->translate_strings_p = false;
4754 /* Consume the `__attribute__' keyword. */
4755 c_parser_consume_token (parser);
4756 /* Look for the two `(' tokens. */
4757 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4759 parser->translate_strings_p = save_translate_strings_p;
4760 return attrs;
4762 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4764 parser->translate_strings_p = save_translate_strings_p;
4765 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4766 return attrs;
4768 /* Parse the attribute list. Require a comma between successive
4769 (possibly empty) attributes. */
4770 for (bool expect_comma = false; ; expect_comma = true)
4772 /* Parse a single attribute. */
4773 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4774 if (attr == error_mark_node)
4775 return attrs;
4776 if (!attr)
4777 break;
4778 attrs = attr;
4781 /* Look for the two `)' tokens. */
4782 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4783 c_parser_consume_token (parser);
4784 else
4786 parser->translate_strings_p = save_translate_strings_p;
4787 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4788 "expected %<)%>");
4789 return attrs;
4791 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4792 c_parser_consume_token (parser);
4793 else
4795 parser->translate_strings_p = save_translate_strings_p;
4796 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4797 "expected %<)%>");
4798 return attrs;
4800 parser->translate_strings_p = save_translate_strings_p;
4803 return attrs;
4806 /* Parse an optional balanced token sequence.
4808 balanced-token-sequence:
4809 balanced-token
4810 balanced-token-sequence balanced-token
4812 balanced-token:
4813 ( balanced-token-sequence[opt] )
4814 [ balanced-token-sequence[opt] ]
4815 { balanced-token-sequence[opt] }
4816 any token other than ()[]{}
4819 static void
4820 c_parser_balanced_token_sequence (c_parser *parser)
4822 while (true)
4824 c_token *token = c_parser_peek_token (parser);
4825 switch (token->type)
4827 case CPP_OPEN_BRACE:
4829 matching_braces braces;
4830 braces.consume_open (parser);
4831 c_parser_balanced_token_sequence (parser);
4832 braces.require_close (parser);
4833 break;
4836 case CPP_OPEN_PAREN:
4838 matching_parens parens;
4839 parens.consume_open (parser);
4840 c_parser_balanced_token_sequence (parser);
4841 parens.require_close (parser);
4842 break;
4845 case CPP_OPEN_SQUARE:
4846 c_parser_consume_token (parser);
4847 c_parser_balanced_token_sequence (parser);
4848 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4849 break;
4851 case CPP_CLOSE_BRACE:
4852 case CPP_CLOSE_PAREN:
4853 case CPP_CLOSE_SQUARE:
4854 case CPP_EOF:
4855 return;
4857 case CPP_PRAGMA:
4858 c_parser_consume_pragma (parser);
4859 c_parser_skip_to_pragma_eol (parser, false);
4860 break;
4862 default:
4863 c_parser_consume_token (parser);
4864 break;
4869 /* Parse standard (C2X) attributes (including GNU attributes in the
4870 gnu:: namespace).
4872 attribute-specifier-sequence:
4873 attribute-specifier-sequence[opt] attribute-specifier
4875 attribute-specifier:
4876 [ [ attribute-list ] ]
4878 attribute-list:
4879 attribute[opt]
4880 attribute-list, attribute[opt]
4882 attribute:
4883 attribute-token attribute-argument-clause[opt]
4885 attribute-token:
4886 standard-attribute
4887 attribute-prefixed-token
4889 standard-attribute:
4890 identifier
4892 attribute-prefixed-token:
4893 attribute-prefix :: identifier
4895 attribute-prefix:
4896 identifier
4898 attribute-argument-clause:
4899 ( balanced-token-sequence[opt] )
4901 Keywords are accepted as identifiers for this purpose.
4904 static tree
4905 c_parser_std_attribute (c_parser *parser, bool for_tm)
4907 c_token *token = c_parser_peek_token (parser);
4908 tree ns, name, attribute;
4910 /* Parse the attribute-token. */
4911 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4913 c_parser_error (parser, "expected identifier");
4914 return error_mark_node;
4916 name = canonicalize_attr_name (token->value);
4917 c_parser_consume_token (parser);
4918 if (c_parser_next_token_is (parser, CPP_SCOPE))
4920 ns = name;
4921 c_parser_consume_token (parser);
4922 token = c_parser_peek_token (parser);
4923 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4925 c_parser_error (parser, "expected identifier");
4926 return error_mark_node;
4928 name = canonicalize_attr_name (token->value);
4929 c_parser_consume_token (parser);
4931 else
4932 ns = NULL_TREE;
4933 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4935 /* Parse the arguments, if any. */
4936 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4937 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4938 goto out;
4940 location_t open_loc = c_parser_peek_token (parser)->location;
4941 matching_parens parens;
4942 parens.consume_open (parser);
4943 if ((as && as->max_length == 0)
4944 /* Special-case the transactional-memory attribute "outer",
4945 which is specially handled but not registered as an
4946 attribute, to avoid allowing arbitrary balanced token
4947 sequences as arguments. */
4948 || is_attribute_p ("outer", name))
4950 error_at (open_loc, "%qE attribute does not take any arguments", name);
4951 parens.skip_until_found_close (parser);
4952 return error_mark_node;
4954 /* If this is a fake attribute created to handle -Wno-attributes,
4955 we must skip parsing the arguments. */
4956 if (as && !attribute_ignored_p (as))
4958 bool takes_identifier
4959 = (ns != NULL_TREE
4960 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4961 && attribute_takes_identifier_p (name));
4962 bool require_string
4963 = (ns == NULL_TREE
4964 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4965 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4966 TREE_VALUE (attribute)
4967 = c_parser_attribute_arguments (parser, takes_identifier,
4968 require_string, false);
4970 else
4971 c_parser_balanced_token_sequence (parser);
4972 parens.require_close (parser);
4974 out:
4975 if (ns == NULL_TREE && !for_tm && !as)
4977 /* An attribute with standard syntax and no namespace specified
4978 is a constraint violation if it is not one of the known
4979 standard attributes. Diagnose it here with a pedwarn and
4980 then discard it to prevent a duplicate warning later. */
4981 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4982 name);
4983 return error_mark_node;
4985 return attribute;
4988 static tree
4989 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4991 location_t loc = c_parser_peek_token (parser)->location;
4992 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4993 return NULL_TREE;
4994 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4996 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4997 return NULL_TREE;
4999 if (!for_tm)
5000 pedwarn_c11 (loc, OPT_Wpedantic,
5001 "ISO C does not support %<[[]]%> attributes before C2X");
5002 tree attributes = NULL_TREE;
5003 while (true)
5005 c_token *token = c_parser_peek_token (parser);
5006 if (token->type == CPP_CLOSE_SQUARE)
5007 break;
5008 if (token->type == CPP_COMMA)
5010 c_parser_consume_token (parser);
5011 continue;
5013 tree attribute = c_parser_std_attribute (parser, for_tm);
5014 if (attribute != error_mark_node)
5016 TREE_CHAIN (attribute) = attributes;
5017 attributes = attribute;
5019 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5020 break;
5022 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5023 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5024 return nreverse (attributes);
5027 /* Look past an optional balanced token sequence of raw look-ahead
5028 tokens starting with the *Nth token. *N is updated to point to the
5029 following token. Return true if such a sequence was found, false
5030 if the tokens parsed were not balanced. */
5032 static bool
5033 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5035 while (true)
5037 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5038 switch (token->type)
5040 case CPP_OPEN_BRACE:
5042 ++*n;
5043 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5045 token = c_parser_peek_nth_token_raw (parser, *n);
5046 if (token->type == CPP_CLOSE_BRACE)
5047 ++*n;
5048 else
5049 return false;
5051 else
5052 return false;
5053 break;
5056 case CPP_OPEN_PAREN:
5058 ++*n;
5059 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5061 token = c_parser_peek_nth_token_raw (parser, *n);
5062 if (token->type == CPP_CLOSE_PAREN)
5063 ++*n;
5064 else
5065 return false;
5067 else
5068 return false;
5069 break;
5072 case CPP_OPEN_SQUARE:
5074 ++*n;
5075 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5077 token = c_parser_peek_nth_token_raw (parser, *n);
5078 if (token->type == CPP_CLOSE_SQUARE)
5079 ++*n;
5080 else
5081 return false;
5083 else
5084 return false;
5085 break;
5088 case CPP_CLOSE_BRACE:
5089 case CPP_CLOSE_PAREN:
5090 case CPP_CLOSE_SQUARE:
5091 case CPP_EOF:
5092 return true;
5094 default:
5095 ++*n;
5096 break;
5101 /* Return whether standard attributes start with the Nth token. */
5103 static bool
5104 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5106 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5107 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5108 return false;
5109 /* In C, '[[' must start attributes. In Objective-C, we need to
5110 check whether '[[' is matched by ']]'. */
5111 if (!c_dialect_objc ())
5112 return true;
5113 n += 2;
5114 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5115 return false;
5116 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5117 if (token->type != CPP_CLOSE_SQUARE)
5118 return false;
5119 token = c_parser_peek_nth_token_raw (parser, n + 1);
5120 return token->type == CPP_CLOSE_SQUARE;
5123 static tree
5124 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5126 tree attributes = NULL_TREE;
5129 tree attrs = c_parser_std_attribute_specifier (parser, false);
5130 attributes = chainon (attributes, attrs);
5132 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5133 return attributes;
5136 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5137 says whether alignment specifiers are OK (only in cases that might
5138 be the type name of a compound literal).
5140 type-name:
5141 specifier-qualifier-list abstract-declarator[opt]
5144 struct c_type_name *
5145 c_parser_type_name (c_parser *parser, bool alignas_ok)
5147 struct c_declspecs *specs = build_null_declspecs ();
5148 struct c_declarator *declarator;
5149 struct c_type_name *ret;
5150 bool dummy = false;
5151 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5152 false, true, cla_prefer_type);
5153 if (!specs->declspecs_seen_p)
5155 c_parser_error (parser, "expected specifier-qualifier-list");
5156 return NULL;
5158 if (specs->type != error_mark_node)
5160 pending_xref_error ();
5161 finish_declspecs (specs);
5163 declarator = c_parser_declarator (parser,
5164 specs->typespec_kind != ctsk_none,
5165 C_DTR_ABSTRACT, &dummy);
5166 if (declarator == NULL)
5167 return NULL;
5168 ret = XOBNEW (&parser_obstack, struct c_type_name);
5169 ret->specs = specs;
5170 ret->declarator = declarator;
5171 return ret;
5174 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5176 initializer:
5177 assignment-expression
5178 { initializer-list }
5179 { initializer-list , }
5181 initializer-list:
5182 designation[opt] initializer
5183 initializer-list , designation[opt] initializer
5185 designation:
5186 designator-list =
5188 designator-list:
5189 designator
5190 designator-list designator
5192 designator:
5193 array-designator
5194 . identifier
5196 array-designator:
5197 [ constant-expression ]
5199 GNU extensions:
5201 initializer:
5204 designation:
5205 array-designator
5206 identifier :
5208 array-designator:
5209 [ constant-expression ... constant-expression ]
5211 Any expression without commas is accepted in the syntax for the
5212 constant-expressions, with non-constant expressions rejected later.
5214 This function is only used for top-level initializers; for nested
5215 ones, see c_parser_initval. */
5217 static struct c_expr
5218 c_parser_initializer (c_parser *parser)
5220 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5221 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5222 else
5224 struct c_expr ret;
5225 location_t loc = c_parser_peek_token (parser)->location;
5226 ret = c_parser_expr_no_commas (parser, NULL);
5227 if (TREE_CODE (ret.value) != STRING_CST
5228 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5229 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5230 return ret;
5234 /* The location of the last comma within the current initializer list,
5235 or UNKNOWN_LOCATION if not within one. */
5237 location_t last_init_list_comma;
5239 /* Parse a braced initializer list. TYPE is the type specified for a
5240 compound literal, and NULL_TREE for other initializers and for
5241 nested braced lists. NESTED_P is true for nested braced lists,
5242 false for the list of a compound literal or the list that is the
5243 top-level initializer in a declaration. */
5245 static struct c_expr
5246 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5247 struct obstack *outer_obstack)
5249 struct c_expr ret;
5250 struct obstack braced_init_obstack;
5251 location_t brace_loc = c_parser_peek_token (parser)->location;
5252 gcc_obstack_init (&braced_init_obstack);
5253 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5254 matching_braces braces;
5255 braces.consume_open (parser);
5256 if (nested_p)
5258 finish_implicit_inits (brace_loc, outer_obstack);
5259 push_init_level (brace_loc, 0, &braced_init_obstack);
5261 else
5262 really_start_incremental_init (type);
5263 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5265 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5267 else
5269 /* Parse a non-empty initializer list, possibly with a trailing
5270 comma. */
5271 while (true)
5273 c_parser_initelt (parser, &braced_init_obstack);
5274 if (parser->error)
5275 break;
5276 if (c_parser_next_token_is (parser, CPP_COMMA))
5278 last_init_list_comma = c_parser_peek_token (parser)->location;
5279 c_parser_consume_token (parser);
5281 else
5282 break;
5283 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5284 break;
5287 c_token *next_tok = c_parser_peek_token (parser);
5288 if (next_tok->type != CPP_CLOSE_BRACE)
5290 ret.set_error ();
5291 ret.original_code = ERROR_MARK;
5292 ret.original_type = NULL;
5293 braces.skip_until_found_close (parser);
5294 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5295 obstack_free (&braced_init_obstack, NULL);
5296 return ret;
5298 location_t close_loc = next_tok->location;
5299 c_parser_consume_token (parser);
5300 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5301 obstack_free (&braced_init_obstack, NULL);
5302 set_c_expr_source_range (&ret, brace_loc, close_loc);
5303 return ret;
5306 /* Parse a nested initializer, including designators. */
5308 static void
5309 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5311 /* Parse any designator or designator list. A single array
5312 designator may have the subsequent "=" omitted in GNU C, but a
5313 longer list or a structure member designator may not. */
5314 if (c_parser_next_token_is (parser, CPP_NAME)
5315 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5317 /* Old-style structure member designator. */
5318 set_init_label (c_parser_peek_token (parser)->location,
5319 c_parser_peek_token (parser)->value,
5320 c_parser_peek_token (parser)->location,
5321 braced_init_obstack);
5322 /* Use the colon as the error location. */
5323 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5324 "obsolete use of designated initializer with %<:%>");
5325 c_parser_consume_token (parser);
5326 c_parser_consume_token (parser);
5328 else
5330 /* des_seen is 0 if there have been no designators, 1 if there
5331 has been a single array designator and 2 otherwise. */
5332 int des_seen = 0;
5333 /* Location of a designator. */
5334 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5335 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5336 || c_parser_next_token_is (parser, CPP_DOT))
5338 int des_prev = des_seen;
5339 if (!des_seen)
5340 des_loc = c_parser_peek_token (parser)->location;
5341 if (des_seen < 2)
5342 des_seen++;
5343 if (c_parser_next_token_is (parser, CPP_DOT))
5345 des_seen = 2;
5346 c_parser_consume_token (parser);
5347 if (c_parser_next_token_is (parser, CPP_NAME))
5349 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5350 c_parser_peek_token (parser)->location,
5351 braced_init_obstack);
5352 c_parser_consume_token (parser);
5354 else
5356 struct c_expr init;
5357 init.set_error ();
5358 init.original_code = ERROR_MARK;
5359 init.original_type = NULL;
5360 c_parser_error (parser, "expected identifier");
5361 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5362 process_init_element (input_location, init, false,
5363 braced_init_obstack);
5364 return;
5367 else
5369 tree first, second;
5370 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5371 location_t array_index_loc = UNKNOWN_LOCATION;
5372 /* ??? Following the old parser, [ objc-receiver
5373 objc-message-args ] is accepted as an initializer,
5374 being distinguished from a designator by what follows
5375 the first assignment expression inside the square
5376 brackets, but after a first array designator a
5377 subsequent square bracket is for Objective-C taken to
5378 start an expression, using the obsolete form of
5379 designated initializer without '=', rather than
5380 possibly being a second level of designation: in LALR
5381 terms, the '[' is shifted rather than reducing
5382 designator to designator-list. */
5383 if (des_prev == 1 && c_dialect_objc ())
5385 des_seen = des_prev;
5386 break;
5388 if (des_prev == 0 && c_dialect_objc ())
5390 /* This might be an array designator or an
5391 Objective-C message expression. If the former,
5392 continue parsing here; if the latter, parse the
5393 remainder of the initializer given the starting
5394 primary-expression. ??? It might make sense to
5395 distinguish when des_prev == 1 as well; see
5396 previous comment. */
5397 tree rec, args;
5398 struct c_expr mexpr;
5399 c_parser_consume_token (parser);
5400 if (c_parser_peek_token (parser)->type == CPP_NAME
5401 && ((c_parser_peek_token (parser)->id_kind
5402 == C_ID_TYPENAME)
5403 || (c_parser_peek_token (parser)->id_kind
5404 == C_ID_CLASSNAME)))
5406 /* Type name receiver. */
5407 tree id = c_parser_peek_token (parser)->value;
5408 c_parser_consume_token (parser);
5409 rec = objc_get_class_reference (id);
5410 goto parse_message_args;
5412 first = c_parser_expr_no_commas (parser, NULL).value;
5413 mark_exp_read (first);
5414 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5415 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5416 goto array_desig_after_first;
5417 /* Expression receiver. So far only one part
5418 without commas has been parsed; there might be
5419 more of the expression. */
5420 rec = first;
5421 while (c_parser_next_token_is (parser, CPP_COMMA))
5423 struct c_expr next;
5424 location_t comma_loc, exp_loc;
5425 comma_loc = c_parser_peek_token (parser)->location;
5426 c_parser_consume_token (parser);
5427 exp_loc = c_parser_peek_token (parser)->location;
5428 next = c_parser_expr_no_commas (parser, NULL);
5429 next = convert_lvalue_to_rvalue (exp_loc, next,
5430 true, true);
5431 rec = build_compound_expr (comma_loc, rec, next.value);
5433 parse_message_args:
5434 /* Now parse the objc-message-args. */
5435 args = c_parser_objc_message_args (parser);
5436 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5437 "expected %<]%>");
5438 mexpr.value
5439 = objc_build_message_expr (rec, args);
5440 mexpr.original_code = ERROR_MARK;
5441 mexpr.original_type = NULL;
5442 /* Now parse and process the remainder of the
5443 initializer, starting with this message
5444 expression as a primary-expression. */
5445 c_parser_initval (parser, &mexpr, braced_init_obstack);
5446 return;
5448 c_parser_consume_token (parser);
5449 array_index_loc = c_parser_peek_token (parser)->location;
5450 first = c_parser_expr_no_commas (parser, NULL).value;
5451 mark_exp_read (first);
5452 array_desig_after_first:
5453 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5455 ellipsis_loc = c_parser_peek_token (parser)->location;
5456 c_parser_consume_token (parser);
5457 second = c_parser_expr_no_commas (parser, NULL).value;
5458 mark_exp_read (second);
5460 else
5461 second = NULL_TREE;
5462 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5464 c_parser_consume_token (parser);
5465 set_init_index (array_index_loc, first, second,
5466 braced_init_obstack);
5467 if (second)
5468 pedwarn (ellipsis_loc, OPT_Wpedantic,
5469 "ISO C forbids specifying range of elements to initialize");
5471 else
5472 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5473 "expected %<]%>");
5476 if (des_seen >= 1)
5478 if (c_parser_next_token_is (parser, CPP_EQ))
5480 pedwarn_c90 (des_loc, OPT_Wpedantic,
5481 "ISO C90 forbids specifying subobject "
5482 "to initialize");
5483 c_parser_consume_token (parser);
5485 else
5487 if (des_seen == 1)
5488 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5489 "obsolete use of designated initializer without %<=%>");
5490 else
5492 struct c_expr init;
5493 init.set_error ();
5494 init.original_code = ERROR_MARK;
5495 init.original_type = NULL;
5496 c_parser_error (parser, "expected %<=%>");
5497 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5498 process_init_element (input_location, init, false,
5499 braced_init_obstack);
5500 return;
5505 c_parser_initval (parser, NULL, braced_init_obstack);
5508 /* Parse a nested initializer; as c_parser_initializer but parses
5509 initializers within braced lists, after any designators have been
5510 applied. If AFTER is not NULL then it is an Objective-C message
5511 expression which is the primary-expression starting the
5512 initializer. */
5514 static void
5515 c_parser_initval (c_parser *parser, struct c_expr *after,
5516 struct obstack * braced_init_obstack)
5518 struct c_expr init;
5519 gcc_assert (!after || c_dialect_objc ());
5520 location_t loc = c_parser_peek_token (parser)->location;
5522 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5523 init = c_parser_braced_init (parser, NULL_TREE, true,
5524 braced_init_obstack);
5525 else
5527 init = c_parser_expr_no_commas (parser, after);
5528 if (init.value != NULL_TREE
5529 && TREE_CODE (init.value) != STRING_CST
5530 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5531 init = convert_lvalue_to_rvalue (loc, init, true, true);
5533 process_init_element (loc, init, false, braced_init_obstack);
5536 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5537 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5539 compound-statement:
5540 { block-item-list[opt] }
5541 { label-declarations block-item-list }
5543 block-item-list:
5544 block-item
5545 block-item-list block-item
5547 block-item:
5548 label
5549 nested-declaration
5550 statement
5552 nested-declaration:
5553 declaration
5555 GNU extensions:
5557 compound-statement:
5558 { label-declarations block-item-list }
5560 nested-declaration:
5561 __extension__ nested-declaration
5562 nested-function-definition
5564 label-declarations:
5565 label-declaration
5566 label-declarations label-declaration
5568 label-declaration:
5569 __label__ identifier-list ;
5571 Allowing the mixing of declarations and code is new in C99. The
5572 GNU syntax also permits (not shown above) labels at the end of
5573 compound statements, which yield an error. We don't allow labels
5574 on declarations; this might seem like a natural extension, but
5575 there would be a conflict between gnu-attributes on the label and
5576 prefix gnu-attributes on the declaration. ??? The syntax follows the
5577 old parser in requiring something after label declarations.
5578 Although they are erroneous if the labels declared aren't defined,
5579 is it useful for the syntax to be this way?
5581 OpenACC:
5583 block-item:
5584 openacc-directive
5586 openacc-directive:
5587 update-directive
5589 OpenMP:
5591 block-item:
5592 openmp-directive
5594 openmp-directive:
5595 barrier-directive
5596 flush-directive
5597 taskwait-directive
5598 taskyield-directive
5599 cancel-directive
5600 cancellation-point-directive */
5602 static tree
5603 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5605 tree stmt;
5606 location_t brace_loc;
5607 brace_loc = c_parser_peek_token (parser)->location;
5608 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5610 /* Ensure a scope is entered and left anyway to avoid confusion
5611 if we have just prepared to enter a function body. */
5612 stmt = c_begin_compound_stmt (true);
5613 c_end_compound_stmt (brace_loc, stmt, true);
5614 return error_mark_node;
5616 stmt = c_begin_compound_stmt (true);
5617 location_t end_loc = c_parser_compound_statement_nostart (parser);
5618 if (endlocp)
5619 *endlocp = end_loc;
5621 return c_end_compound_stmt (brace_loc, stmt, true);
5624 /* Parse a compound statement except for the opening brace. This is
5625 used for parsing both compound statements and statement expressions
5626 (which follow different paths to handling the opening). */
5628 static location_t
5629 c_parser_compound_statement_nostart (c_parser *parser)
5631 bool last_stmt = false;
5632 bool last_label = false;
5633 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5634 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5635 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5637 location_t endloc = c_parser_peek_token (parser)->location;
5638 add_debug_begin_stmt (endloc);
5639 c_parser_consume_token (parser);
5640 return endloc;
5642 mark_valid_location_for_stdc_pragma (true);
5643 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5645 /* Read zero or more forward-declarations for labels that nested
5646 functions can jump to. */
5647 mark_valid_location_for_stdc_pragma (false);
5648 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5650 label_loc = c_parser_peek_token (parser)->location;
5651 c_parser_consume_token (parser);
5652 /* Any identifiers, including those declared as type names,
5653 are OK here. */
5654 while (true)
5656 tree label;
5657 if (c_parser_next_token_is_not (parser, CPP_NAME))
5659 c_parser_error (parser, "expected identifier");
5660 break;
5662 label
5663 = declare_label (c_parser_peek_token (parser)->value);
5664 C_DECLARED_LABEL_FLAG (label) = 1;
5665 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5666 c_parser_consume_token (parser);
5667 if (c_parser_next_token_is (parser, CPP_COMMA))
5668 c_parser_consume_token (parser);
5669 else
5670 break;
5672 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5674 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5676 /* We must now have at least one statement, label or declaration. */
5677 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5679 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5680 c_parser_error (parser, "expected declaration or statement");
5681 location_t endloc = c_parser_peek_token (parser)->location;
5682 c_parser_consume_token (parser);
5683 return endloc;
5685 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5687 location_t loc = c_parser_peek_token (parser)->location;
5688 loc = expansion_point_location_if_in_system_header (loc);
5689 /* Standard attributes may start a label, statement or declaration. */
5690 bool have_std_attrs
5691 = c_parser_nth_token_starts_std_attributes (parser, 1);
5692 tree std_attrs = NULL_TREE;
5693 if (have_std_attrs)
5694 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5695 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5696 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5697 || (c_parser_next_token_is (parser, CPP_NAME)
5698 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5700 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5701 label_loc = c_parser_peek_2nd_token (parser)->location;
5702 else
5703 label_loc = c_parser_peek_token (parser)->location;
5704 last_label = true;
5705 last_stmt = false;
5706 mark_valid_location_for_stdc_pragma (false);
5707 c_parser_label (parser, std_attrs);
5709 else if (c_parser_next_tokens_start_declaration (parser)
5710 || (have_std_attrs
5711 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5713 if (last_label)
5714 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5715 "a label can only be part of a statement and "
5716 "a declaration is not a statement");
5718 mark_valid_location_for_stdc_pragma (false);
5719 bool fallthru_attr_p = false;
5720 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5721 true, true, true, NULL,
5722 NULL, have_std_attrs, std_attrs,
5723 NULL, &fallthru_attr_p);
5725 if (last_stmt && !fallthru_attr_p)
5726 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5727 "ISO C90 forbids mixed declarations and code");
5728 last_stmt = fallthru_attr_p;
5729 last_label = false;
5731 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5733 /* __extension__ can start a declaration, but is also an
5734 unary operator that can start an expression. Consume all
5735 but the last of a possible series of __extension__ to
5736 determine which. If standard attributes have already
5737 been seen, it must start a statement, not a declaration,
5738 but standard attributes starting a declaration may appear
5739 after __extension__. */
5740 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5741 && (c_parser_peek_2nd_token (parser)->keyword
5742 == RID_EXTENSION))
5743 c_parser_consume_token (parser);
5744 if (!have_std_attrs
5745 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5746 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5748 int ext;
5749 ext = disable_extension_diagnostics ();
5750 c_parser_consume_token (parser);
5751 last_label = false;
5752 mark_valid_location_for_stdc_pragma (false);
5753 c_parser_declaration_or_fndef (parser, true, true, true, true,
5754 true);
5755 /* Following the old parser, __extension__ does not
5756 disable this diagnostic. */
5757 restore_extension_diagnostics (ext);
5758 if (last_stmt)
5759 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5760 "ISO C90 forbids mixed declarations and code");
5761 last_stmt = false;
5763 else
5764 goto statement;
5766 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5768 if (have_std_attrs)
5769 c_parser_error (parser, "expected declaration or statement");
5770 /* External pragmas, and some omp pragmas, are not associated
5771 with regular c code, and so are not to be considered statements
5772 syntactically. This ensures that the user doesn't put them
5773 places that would turn into syntax errors if the directive
5774 were ignored. */
5775 if (c_parser_pragma (parser,
5776 last_label ? pragma_stmt : pragma_compound,
5777 NULL))
5778 last_label = false, last_stmt = true;
5780 else if (c_parser_next_token_is (parser, CPP_EOF))
5782 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5783 c_parser_error (parser, "expected declaration or statement");
5784 return c_parser_peek_token (parser)->location;
5786 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5788 if (parser->in_if_block)
5790 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5791 error_at (loc, "expected %<}%> before %<else%>");
5792 return c_parser_peek_token (parser)->location;
5794 else
5796 error_at (loc, "%<else%> without a previous %<if%>");
5797 c_parser_consume_token (parser);
5798 continue;
5801 else
5803 statement:
5804 c_warn_unused_attributes (std_attrs);
5805 last_label = false;
5806 last_stmt = true;
5807 mark_valid_location_for_stdc_pragma (false);
5808 c_parser_statement_after_labels (parser, NULL);
5811 parser->error = false;
5813 if (last_label)
5814 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5815 location_t endloc = c_parser_peek_token (parser)->location;
5816 c_parser_consume_token (parser);
5817 /* Restore the value we started with. */
5818 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5819 return endloc;
5822 /* Parse all consecutive labels, possibly preceded by standard
5823 attributes. In this context, a statement is required, not a
5824 declaration, so attributes must be followed by a statement that is
5825 not just a semicolon. */
5827 static void
5828 c_parser_all_labels (c_parser *parser)
5830 tree std_attrs = NULL;
5831 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5833 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5834 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5835 c_parser_error (parser, "expected statement");
5837 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5838 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5839 || (c_parser_next_token_is (parser, CPP_NAME)
5840 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5842 c_parser_label (parser, std_attrs);
5843 std_attrs = NULL;
5844 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5846 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5847 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5848 c_parser_error (parser, "expected statement");
5851 if (std_attrs)
5852 c_warn_unused_attributes (std_attrs);
5855 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5857 label:
5858 identifier : gnu-attributes[opt]
5859 case constant-expression :
5860 default :
5862 GNU extensions:
5864 label:
5865 case constant-expression ... constant-expression :
5867 The use of gnu-attributes on labels is a GNU extension. The syntax in
5868 GNU C accepts any expressions without commas, non-constant
5869 expressions being rejected later. Any standard
5870 attribute-specifier-sequence before the first label has been parsed
5871 in the caller, to distinguish statements from declarations. Any
5872 attribute-specifier-sequence after the label is parsed in this
5873 function. */
5874 static void
5875 c_parser_label (c_parser *parser, tree std_attrs)
5877 location_t loc1 = c_parser_peek_token (parser)->location;
5878 tree label = NULL_TREE;
5880 /* Remember whether this case or a user-defined label is allowed to fall
5881 through to. */
5882 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5884 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5886 tree exp1, exp2;
5887 c_parser_consume_token (parser);
5888 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5889 if (c_parser_next_token_is (parser, CPP_COLON))
5891 c_parser_consume_token (parser);
5892 label = do_case (loc1, exp1, NULL_TREE);
5894 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5896 c_parser_consume_token (parser);
5897 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5898 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5899 label = do_case (loc1, exp1, exp2);
5901 else
5902 c_parser_error (parser, "expected %<:%> or %<...%>");
5904 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5906 c_parser_consume_token (parser);
5907 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5908 label = do_case (loc1, NULL_TREE, NULL_TREE);
5910 else
5912 tree name = c_parser_peek_token (parser)->value;
5913 tree tlab;
5914 tree attrs;
5915 location_t loc2 = c_parser_peek_token (parser)->location;
5916 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5917 c_parser_consume_token (parser);
5918 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5919 c_parser_consume_token (parser);
5920 attrs = c_parser_gnu_attributes (parser);
5921 tlab = define_label (loc2, name);
5922 if (tlab)
5924 decl_attributes (&tlab, attrs, 0);
5925 decl_attributes (&tlab, std_attrs, 0);
5926 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5928 if (attrs
5929 && c_parser_next_tokens_start_declaration (parser))
5930 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5931 " label and declaration appertains to the label");
5933 if (label)
5935 if (TREE_CODE (label) == LABEL_EXPR)
5936 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5937 else
5938 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5942 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5944 statement:
5945 labeled-statement
5946 attribute-specifier-sequence[opt] compound-statement
5947 expression-statement
5948 attribute-specifier-sequence[opt] selection-statement
5949 attribute-specifier-sequence[opt] iteration-statement
5950 attribute-specifier-sequence[opt] jump-statement
5952 labeled-statement:
5953 attribute-specifier-sequence[opt] label statement
5955 expression-statement:
5956 expression[opt] ;
5957 attribute-specifier-sequence expression ;
5959 selection-statement:
5960 if-statement
5961 switch-statement
5963 iteration-statement:
5964 while-statement
5965 do-statement
5966 for-statement
5968 jump-statement:
5969 goto identifier ;
5970 continue ;
5971 break ;
5972 return expression[opt] ;
5974 GNU extensions:
5976 statement:
5977 attribute-specifier-sequence[opt] asm-statement
5979 jump-statement:
5980 goto * expression ;
5982 expression-statement:
5983 gnu-attributes ;
5985 Objective-C:
5987 statement:
5988 attribute-specifier-sequence[opt] objc-throw-statement
5989 attribute-specifier-sequence[opt] objc-try-catch-statement
5990 attribute-specifier-sequence[opt] objc-synchronized-statement
5992 objc-throw-statement:
5993 @throw expression ;
5994 @throw ;
5996 OpenACC:
5998 statement:
5999 attribute-specifier-sequence[opt] openacc-construct
6001 openacc-construct:
6002 parallel-construct
6003 kernels-construct
6004 data-construct
6005 loop-construct
6007 parallel-construct:
6008 parallel-directive structured-block
6010 kernels-construct:
6011 kernels-directive structured-block
6013 data-construct:
6014 data-directive structured-block
6016 loop-construct:
6017 loop-directive structured-block
6019 OpenMP:
6021 statement:
6022 attribute-specifier-sequence[opt] openmp-construct
6024 openmp-construct:
6025 parallel-construct
6026 for-construct
6027 simd-construct
6028 for-simd-construct
6029 sections-construct
6030 single-construct
6031 parallel-for-construct
6032 parallel-for-simd-construct
6033 parallel-sections-construct
6034 master-construct
6035 critical-construct
6036 atomic-construct
6037 ordered-construct
6039 parallel-construct:
6040 parallel-directive structured-block
6042 for-construct:
6043 for-directive iteration-statement
6045 simd-construct:
6046 simd-directive iteration-statements
6048 for-simd-construct:
6049 for-simd-directive iteration-statements
6051 sections-construct:
6052 sections-directive section-scope
6054 single-construct:
6055 single-directive structured-block
6057 parallel-for-construct:
6058 parallel-for-directive iteration-statement
6060 parallel-for-simd-construct:
6061 parallel-for-simd-directive iteration-statement
6063 parallel-sections-construct:
6064 parallel-sections-directive section-scope
6066 master-construct:
6067 master-directive structured-block
6069 critical-construct:
6070 critical-directive structured-block
6072 atomic-construct:
6073 atomic-directive expression-statement
6075 ordered-construct:
6076 ordered-directive structured-block
6078 Transactional Memory:
6080 statement:
6081 attribute-specifier-sequence[opt] transaction-statement
6082 attribute-specifier-sequence[opt] transaction-cancel-statement
6084 IF_P is used to track whether there's a (possibly labeled) if statement
6085 which is not enclosed in braces and has an else clause. This is used to
6086 implement -Wparentheses. */
6088 static void
6089 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6091 c_parser_all_labels (parser);
6092 if (loc_after_labels)
6093 *loc_after_labels = c_parser_peek_token (parser)->location;
6094 c_parser_statement_after_labels (parser, if_p, NULL);
6097 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6098 of if-else-if conditions. All labels and standard attributes have
6099 been parsed in the caller.
6101 IF_P is used to track whether there's a (possibly labeled) if statement
6102 which is not enclosed in braces and has an else clause. This is used to
6103 implement -Wparentheses. */
6105 static void
6106 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6107 vec<tree> *chain)
6109 location_t loc = c_parser_peek_token (parser)->location;
6110 tree stmt = NULL_TREE;
6111 bool in_if_block = parser->in_if_block;
6112 parser->in_if_block = false;
6113 if (if_p != NULL)
6114 *if_p = false;
6116 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6117 add_debug_begin_stmt (loc);
6119 restart:
6120 switch (c_parser_peek_token (parser)->type)
6122 case CPP_OPEN_BRACE:
6123 add_stmt (c_parser_compound_statement (parser));
6124 break;
6125 case CPP_KEYWORD:
6126 switch (c_parser_peek_token (parser)->keyword)
6128 case RID_IF:
6129 c_parser_if_statement (parser, if_p, chain);
6130 break;
6131 case RID_SWITCH:
6132 c_parser_switch_statement (parser, if_p);
6133 break;
6134 case RID_WHILE:
6135 c_parser_while_statement (parser, false, 0, if_p);
6136 break;
6137 case RID_DO:
6138 c_parser_do_statement (parser, false, 0);
6139 break;
6140 case RID_FOR:
6141 c_parser_for_statement (parser, false, 0, if_p);
6142 break;
6143 case RID_GOTO:
6144 c_parser_consume_token (parser);
6145 if (c_parser_next_token_is (parser, CPP_NAME))
6147 stmt = c_finish_goto_label (loc,
6148 c_parser_peek_token (parser)->value);
6149 c_parser_consume_token (parser);
6151 else if (c_parser_next_token_is (parser, CPP_MULT))
6153 struct c_expr val;
6155 c_parser_consume_token (parser);
6156 val = c_parser_expression (parser);
6157 val = convert_lvalue_to_rvalue (loc, val, false, true);
6158 stmt = c_finish_goto_ptr (loc, val);
6160 else
6161 c_parser_error (parser, "expected identifier or %<*%>");
6162 goto expect_semicolon;
6163 case RID_CONTINUE:
6164 c_parser_consume_token (parser);
6165 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6166 goto expect_semicolon;
6167 case RID_BREAK:
6168 c_parser_consume_token (parser);
6169 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6170 goto expect_semicolon;
6171 case RID_RETURN:
6172 c_parser_consume_token (parser);
6173 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6175 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6176 c_parser_consume_token (parser);
6178 else
6180 location_t xloc = c_parser_peek_token (parser)->location;
6181 struct c_expr expr = c_parser_expression_conv (parser);
6182 mark_exp_read (expr.value);
6183 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6184 expr.value, expr.original_type);
6185 goto expect_semicolon;
6187 break;
6188 case RID_ASM:
6189 stmt = c_parser_asm_statement (parser);
6190 break;
6191 case RID_TRANSACTION_ATOMIC:
6192 case RID_TRANSACTION_RELAXED:
6193 stmt = c_parser_transaction (parser,
6194 c_parser_peek_token (parser)->keyword);
6195 break;
6196 case RID_TRANSACTION_CANCEL:
6197 stmt = c_parser_transaction_cancel (parser);
6198 goto expect_semicolon;
6199 case RID_AT_THROW:
6200 gcc_assert (c_dialect_objc ());
6201 c_parser_consume_token (parser);
6202 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6204 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6205 c_parser_consume_token (parser);
6207 else
6209 struct c_expr expr = c_parser_expression (parser);
6210 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6211 expr.value = c_fully_fold (expr.value, false, NULL);
6212 stmt = objc_build_throw_stmt (loc, expr.value);
6213 goto expect_semicolon;
6215 break;
6216 case RID_AT_TRY:
6217 gcc_assert (c_dialect_objc ());
6218 c_parser_objc_try_catch_finally_statement (parser);
6219 break;
6220 case RID_AT_SYNCHRONIZED:
6221 gcc_assert (c_dialect_objc ());
6222 c_parser_objc_synchronized_statement (parser);
6223 break;
6224 case RID_ATTRIBUTE:
6226 /* Allow '__attribute__((fallthrough));'. */
6227 tree attrs = c_parser_gnu_attributes (parser);
6228 if (attribute_fallthrough_p (attrs))
6230 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6232 tree fn = build_call_expr_internal_loc (loc,
6233 IFN_FALLTHROUGH,
6234 void_type_node, 0);
6235 add_stmt (fn);
6236 /* Eat the ';'. */
6237 c_parser_consume_token (parser);
6239 else
6240 warning_at (loc, OPT_Wattributes,
6241 "%<fallthrough%> attribute not followed "
6242 "by %<;%>");
6244 else if (attrs != NULL_TREE)
6245 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6246 " can be applied to a null statement");
6247 break;
6249 default:
6250 goto expr_stmt;
6252 break;
6253 case CPP_SEMICOLON:
6254 c_parser_consume_token (parser);
6255 break;
6256 case CPP_CLOSE_PAREN:
6257 case CPP_CLOSE_SQUARE:
6258 /* Avoid infinite loop in error recovery:
6259 c_parser_skip_until_found stops at a closing nesting
6260 delimiter without consuming it, but here we need to consume
6261 it to proceed further. */
6262 c_parser_error (parser, "expected statement");
6263 c_parser_consume_token (parser);
6264 break;
6265 case CPP_PRAGMA:
6266 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6267 goto restart;
6268 break;
6269 default:
6270 expr_stmt:
6271 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6272 expect_semicolon:
6273 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6274 break;
6276 /* Two cases cannot and do not have line numbers associated: If stmt
6277 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6278 cannot hold line numbers. But that's OK because the statement
6279 will either be changed to a MODIFY_EXPR during gimplification of
6280 the statement expr, or discarded. If stmt was compound, but
6281 without new variables, we will have skipped the creation of a
6282 BIND and will have a bare STATEMENT_LIST. But that's OK because
6283 (recursively) all of the component statements should already have
6284 line numbers assigned. ??? Can we discard no-op statements
6285 earlier? */
6286 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6287 protected_set_expr_location (stmt, loc);
6289 parser->in_if_block = in_if_block;
6292 /* Parse the condition from an if, do, while or for statements. */
6294 static tree
6295 c_parser_condition (c_parser *parser)
6297 location_t loc = c_parser_peek_token (parser)->location;
6298 tree cond;
6299 cond = c_parser_expression_conv (parser).value;
6300 cond = c_objc_common_truthvalue_conversion (loc, cond);
6301 cond = c_fully_fold (cond, false, NULL);
6302 if (warn_sequence_point)
6303 verify_sequence_points (cond);
6304 return cond;
6307 /* Parse a parenthesized condition from an if, do or while statement.
6309 condition:
6310 ( expression )
6312 static tree
6313 c_parser_paren_condition (c_parser *parser)
6315 tree cond;
6316 matching_parens parens;
6317 if (!parens.require_open (parser))
6318 return error_mark_node;
6319 cond = c_parser_condition (parser);
6320 parens.skip_until_found_close (parser);
6321 return cond;
6324 /* Parse a statement which is a block in C99.
6326 IF_P is used to track whether there's a (possibly labeled) if statement
6327 which is not enclosed in braces and has an else clause. This is used to
6328 implement -Wparentheses. */
6330 static tree
6331 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6332 location_t *loc_after_labels)
6334 tree block = c_begin_compound_stmt (flag_isoc99);
6335 location_t loc = c_parser_peek_token (parser)->location;
6336 c_parser_statement (parser, if_p, loc_after_labels);
6337 return c_end_compound_stmt (loc, block, flag_isoc99);
6340 /* Parse the body of an if statement. This is just parsing a
6341 statement but (a) it is a block in C99, (b) we track whether the
6342 body is an if statement for the sake of -Wparentheses warnings, (c)
6343 we handle an empty body specially for the sake of -Wempty-body
6344 warnings, and (d) we call parser_compound_statement directly
6345 because c_parser_statement_after_labels resets
6346 parser->in_if_block.
6348 IF_P is used to track whether there's a (possibly labeled) if statement
6349 which is not enclosed in braces and has an else clause. This is used to
6350 implement -Wparentheses. */
6352 static tree
6353 c_parser_if_body (c_parser *parser, bool *if_p,
6354 const token_indent_info &if_tinfo)
6356 tree block = c_begin_compound_stmt (flag_isoc99);
6357 location_t body_loc = c_parser_peek_token (parser)->location;
6358 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6359 token_indent_info body_tinfo
6360 = get_token_indent_info (c_parser_peek_token (parser));
6362 c_parser_all_labels (parser);
6363 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6365 location_t loc = c_parser_peek_token (parser)->location;
6366 add_stmt (build_empty_stmt (loc));
6367 c_parser_consume_token (parser);
6368 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6369 warning_at (loc, OPT_Wempty_body,
6370 "suggest braces around empty body in an %<if%> statement");
6372 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6373 add_stmt (c_parser_compound_statement (parser));
6374 else
6376 body_loc_after_labels = c_parser_peek_token (parser)->location;
6377 c_parser_statement_after_labels (parser, if_p);
6380 token_indent_info next_tinfo
6381 = get_token_indent_info (c_parser_peek_token (parser));
6382 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6383 if (body_loc_after_labels != UNKNOWN_LOCATION
6384 && next_tinfo.type != CPP_SEMICOLON)
6385 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6386 if_tinfo.location, RID_IF);
6388 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6391 /* Parse the else body of an if statement. This is just parsing a
6392 statement but (a) it is a block in C99, (b) we handle an empty body
6393 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6394 of if-else-if conditions. */
6396 static tree
6397 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6398 vec<tree> *chain)
6400 location_t body_loc = c_parser_peek_token (parser)->location;
6401 tree block = c_begin_compound_stmt (flag_isoc99);
6402 token_indent_info body_tinfo
6403 = get_token_indent_info (c_parser_peek_token (parser));
6404 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6406 c_parser_all_labels (parser);
6407 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6409 location_t loc = c_parser_peek_token (parser)->location;
6410 warning_at (loc,
6411 OPT_Wempty_body,
6412 "suggest braces around empty body in an %<else%> statement");
6413 add_stmt (build_empty_stmt (loc));
6414 c_parser_consume_token (parser);
6416 else
6418 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6419 body_loc_after_labels = c_parser_peek_token (parser)->location;
6420 c_parser_statement_after_labels (parser, NULL, chain);
6423 token_indent_info next_tinfo
6424 = get_token_indent_info (c_parser_peek_token (parser));
6425 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6426 if (body_loc_after_labels != UNKNOWN_LOCATION
6427 && next_tinfo.type != CPP_SEMICOLON)
6428 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6429 else_tinfo.location, RID_ELSE);
6431 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6434 /* We might need to reclassify any previously-lexed identifier, e.g.
6435 when we've left a for loop with an if-statement without else in the
6436 body - we might have used a wrong scope for the token. See PR67784. */
6438 static void
6439 c_parser_maybe_reclassify_token (c_parser *parser)
6441 if (c_parser_next_token_is (parser, CPP_NAME))
6443 c_token *token = c_parser_peek_token (parser);
6445 if (token->id_kind != C_ID_CLASSNAME)
6447 tree decl = lookup_name (token->value);
6449 token->id_kind = C_ID_ID;
6450 if (decl)
6452 if (TREE_CODE (decl) == TYPE_DECL)
6453 token->id_kind = C_ID_TYPENAME;
6455 else if (c_dialect_objc ())
6457 tree objc_interface_decl = objc_is_class_name (token->value);
6458 /* Objective-C class names are in the same namespace as
6459 variables and typedefs, and hence are shadowed by local
6460 declarations. */
6461 if (objc_interface_decl)
6463 token->value = objc_interface_decl;
6464 token->id_kind = C_ID_CLASSNAME;
6471 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6473 if-statement:
6474 if ( expression ) statement
6475 if ( expression ) statement else statement
6477 CHAIN is a vector of if-else-if conditions.
6478 IF_P is used to track whether there's a (possibly labeled) if statement
6479 which is not enclosed in braces and has an else clause. This is used to
6480 implement -Wparentheses. */
6482 static void
6483 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6485 tree block;
6486 location_t loc;
6487 tree cond;
6488 bool nested_if = false;
6489 tree first_body, second_body;
6490 bool in_if_block;
6492 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6493 token_indent_info if_tinfo
6494 = get_token_indent_info (c_parser_peek_token (parser));
6495 c_parser_consume_token (parser);
6496 block = c_begin_compound_stmt (flag_isoc99);
6497 loc = c_parser_peek_token (parser)->location;
6498 cond = c_parser_paren_condition (parser);
6499 in_if_block = parser->in_if_block;
6500 parser->in_if_block = true;
6501 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6502 parser->in_if_block = in_if_block;
6504 if (warn_duplicated_cond)
6505 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6507 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6509 token_indent_info else_tinfo
6510 = get_token_indent_info (c_parser_peek_token (parser));
6511 c_parser_consume_token (parser);
6512 if (warn_duplicated_cond)
6514 if (c_parser_next_token_is_keyword (parser, RID_IF)
6515 && chain == NULL)
6517 /* We've got "if (COND) else if (COND2)". Start the
6518 condition chain and add COND as the first element. */
6519 chain = new vec<tree> ();
6520 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6521 chain->safe_push (cond);
6523 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6524 /* This is if-else without subsequent if. Zap the condition
6525 chain; we would have already warned at this point. */
6526 vec_free (chain);
6528 second_body = c_parser_else_body (parser, else_tinfo, chain);
6529 /* Set IF_P to true to indicate that this if statement has an
6530 else clause. This may trigger the Wparentheses warning
6531 below when we get back up to the parent if statement. */
6532 if (if_p != NULL)
6533 *if_p = true;
6535 else
6537 second_body = NULL_TREE;
6539 /* Diagnose an ambiguous else if if-then-else is nested inside
6540 if-then. */
6541 if (nested_if)
6542 warning_at (loc, OPT_Wdangling_else,
6543 "suggest explicit braces to avoid ambiguous %<else%>");
6545 if (warn_duplicated_cond)
6546 /* This if statement does not have an else clause. We don't
6547 need the condition chain anymore. */
6548 vec_free (chain);
6550 c_finish_if_stmt (loc, cond, first_body, second_body);
6551 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6553 c_parser_maybe_reclassify_token (parser);
6556 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6558 switch-statement:
6559 switch (expression) statement
6562 static void
6563 c_parser_switch_statement (c_parser *parser, bool *if_p)
6565 struct c_expr ce;
6566 tree block, expr, body;
6567 unsigned char save_in_statement;
6568 location_t switch_loc = c_parser_peek_token (parser)->location;
6569 location_t switch_cond_loc;
6570 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6571 c_parser_consume_token (parser);
6572 block = c_begin_compound_stmt (flag_isoc99);
6573 bool explicit_cast_p = false;
6574 matching_parens parens;
6575 if (parens.require_open (parser))
6577 switch_cond_loc = c_parser_peek_token (parser)->location;
6578 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6579 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6580 explicit_cast_p = true;
6581 ce = c_parser_expression (parser);
6582 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6583 expr = ce.value;
6584 /* ??? expr has no valid location? */
6585 parens.skip_until_found_close (parser);
6587 else
6589 switch_cond_loc = UNKNOWN_LOCATION;
6590 expr = error_mark_node;
6591 ce.original_type = error_mark_node;
6593 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6594 save_in_statement = in_statement;
6595 in_statement |= IN_SWITCH_STMT;
6596 location_t loc_after_labels;
6597 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6598 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6599 location_t next_loc = c_parser_peek_token (parser)->location;
6600 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6601 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6602 RID_SWITCH);
6603 c_finish_switch (body, ce.original_type);
6604 in_statement = save_in_statement;
6605 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6606 c_parser_maybe_reclassify_token (parser);
6609 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6611 while-statement:
6612 while (expression) statement
6614 IF_P is used to track whether there's a (possibly labeled) if statement
6615 which is not enclosed in braces and has an else clause. This is used to
6616 implement -Wparentheses. */
6618 static void
6619 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6620 bool *if_p)
6622 tree block, cond, body;
6623 unsigned char save_in_statement;
6624 location_t loc;
6625 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6626 token_indent_info while_tinfo
6627 = get_token_indent_info (c_parser_peek_token (parser));
6628 c_parser_consume_token (parser);
6629 block = c_begin_compound_stmt (flag_isoc99);
6630 loc = c_parser_peek_token (parser)->location;
6631 cond = c_parser_paren_condition (parser);
6632 if (ivdep && cond != error_mark_node)
6633 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6634 build_int_cst (integer_type_node,
6635 annot_expr_ivdep_kind),
6636 integer_zero_node);
6637 if (unroll && cond != error_mark_node)
6638 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6639 build_int_cst (integer_type_node,
6640 annot_expr_unroll_kind),
6641 build_int_cst (integer_type_node, unroll));
6642 save_in_statement = in_statement;
6643 in_statement = IN_ITERATION_STMT;
6645 token_indent_info body_tinfo
6646 = get_token_indent_info (c_parser_peek_token (parser));
6648 location_t loc_after_labels;
6649 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6650 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6651 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6652 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6653 c_parser_maybe_reclassify_token (parser);
6655 token_indent_info next_tinfo
6656 = get_token_indent_info (c_parser_peek_token (parser));
6657 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6659 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6660 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6661 while_tinfo.location, RID_WHILE);
6663 in_statement = save_in_statement;
6666 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6668 do-statement:
6669 do statement while ( expression ) ;
6672 static void
6673 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6675 tree block, cond, body;
6676 unsigned char save_in_statement;
6677 location_t loc;
6678 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6679 c_parser_consume_token (parser);
6680 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6681 warning_at (c_parser_peek_token (parser)->location,
6682 OPT_Wempty_body,
6683 "suggest braces around empty body in %<do%> statement");
6684 block = c_begin_compound_stmt (flag_isoc99);
6685 loc = c_parser_peek_token (parser)->location;
6686 save_in_statement = in_statement;
6687 in_statement = IN_ITERATION_STMT;
6688 body = c_parser_c99_block_statement (parser, NULL);
6689 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6690 in_statement = save_in_statement;
6691 cond = c_parser_paren_condition (parser);
6692 if (ivdep && cond != error_mark_node)
6693 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6694 build_int_cst (integer_type_node,
6695 annot_expr_ivdep_kind),
6696 integer_zero_node);
6697 if (unroll && cond != error_mark_node)
6698 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6699 build_int_cst (integer_type_node,
6700 annot_expr_unroll_kind),
6701 build_int_cst (integer_type_node, unroll));
6702 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6703 c_parser_skip_to_end_of_block_or_statement (parser);
6705 add_stmt (build_stmt (loc, DO_STMT, cond, body));
6706 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6709 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6711 for-statement:
6712 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6713 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6715 The form with a declaration is new in C99.
6717 ??? In accordance with the old parser, the declaration may be a
6718 nested function, which is then rejected in check_for_loop_decls,
6719 but does it make any sense for this to be included in the grammar?
6720 Note in particular that the nested function does not include a
6721 trailing ';', whereas the "declaration" production includes one.
6722 Also, can we reject bad declarations earlier and cheaper than
6723 check_for_loop_decls?
6725 In Objective-C, there are two additional variants:
6727 foreach-statement:
6728 for ( expression in expresssion ) statement
6729 for ( declaration in expression ) statement
6731 This is inconsistent with C, because the second variant is allowed
6732 even if c99 is not enabled.
6734 The rest of the comment documents these Objective-C foreach-statement.
6736 Here is the canonical example of the first variant:
6737 for (object in array) { do something with object }
6738 we call the first expression ("object") the "object_expression" and
6739 the second expression ("array") the "collection_expression".
6740 object_expression must be an lvalue of type "id" (a generic Objective-C
6741 object) because the loop works by assigning to object_expression the
6742 various objects from the collection_expression. collection_expression
6743 must evaluate to something of type "id" which responds to the method
6744 countByEnumeratingWithState:objects:count:.
6746 The canonical example of the second variant is:
6747 for (id object in array) { do something with object }
6748 which is completely equivalent to
6750 id object;
6751 for (object in array) { do something with object }
6753 Note that initizializing 'object' in some way (eg, "for ((object =
6754 xxx) in array) { do something with object }") is possibly
6755 technically valid, but completely pointless as 'object' will be
6756 assigned to something else as soon as the loop starts. We should
6757 most likely reject it (TODO).
6759 The beginning of the Objective-C foreach-statement looks exactly
6760 like the beginning of the for-statement, and we can tell it is a
6761 foreach-statement only because the initial declaration or
6762 expression is terminated by 'in' instead of ';'.
6764 IF_P is used to track whether there's a (possibly labeled) if statement
6765 which is not enclosed in braces and has an else clause. This is used to
6766 implement -Wparentheses. */
6768 static void
6769 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6770 bool *if_p)
6772 tree block, cond, incr, body;
6773 unsigned char save_in_statement;
6774 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6775 /* The following are only used when parsing an ObjC foreach statement. */
6776 tree object_expression;
6777 /* Silence the bogus uninitialized warning. */
6778 tree collection_expression = NULL;
6779 location_t loc = c_parser_peek_token (parser)->location;
6780 location_t for_loc = loc;
6781 bool is_foreach_statement = false;
6782 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6783 token_indent_info for_tinfo
6784 = get_token_indent_info (c_parser_peek_token (parser));
6785 c_parser_consume_token (parser);
6786 /* Open a compound statement in Objective-C as well, just in case this is
6787 as foreach expression. */
6788 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6789 cond = error_mark_node;
6790 incr = error_mark_node;
6791 matching_parens parens;
6792 if (parens.require_open (parser))
6794 /* Parse the initialization declaration or expression. */
6795 object_expression = error_mark_node;
6796 parser->objc_could_be_foreach_context = c_dialect_objc ();
6797 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6799 parser->objc_could_be_foreach_context = false;
6800 c_parser_consume_token (parser);
6801 c_finish_expr_stmt (loc, NULL_TREE);
6803 else if (c_parser_next_tokens_start_declaration (parser)
6804 || c_parser_nth_token_starts_std_attributes (parser, 1))
6806 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6807 &object_expression);
6808 parser->objc_could_be_foreach_context = false;
6810 if (c_parser_next_token_is_keyword (parser, RID_IN))
6812 c_parser_consume_token (parser);
6813 is_foreach_statement = true;
6814 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6815 c_parser_error (parser, "multiple iterating variables in "
6816 "fast enumeration");
6818 else
6819 check_for_loop_decls (for_loc, flag_isoc99);
6821 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6823 /* __extension__ can start a declaration, but is also an
6824 unary operator that can start an expression. Consume all
6825 but the last of a possible series of __extension__ to
6826 determine which. */
6827 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6828 && (c_parser_peek_2nd_token (parser)->keyword
6829 == RID_EXTENSION))
6830 c_parser_consume_token (parser);
6831 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6832 || c_parser_nth_token_starts_std_attributes (parser, 2))
6834 int ext;
6835 ext = disable_extension_diagnostics ();
6836 c_parser_consume_token (parser);
6837 c_parser_declaration_or_fndef (parser, true, true, true, true,
6838 true, &object_expression);
6839 parser->objc_could_be_foreach_context = false;
6841 restore_extension_diagnostics (ext);
6842 if (c_parser_next_token_is_keyword (parser, RID_IN))
6844 c_parser_consume_token (parser);
6845 is_foreach_statement = true;
6846 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6847 c_parser_error (parser, "multiple iterating variables in "
6848 "fast enumeration");
6850 else
6851 check_for_loop_decls (for_loc, flag_isoc99);
6853 else
6854 goto init_expr;
6856 else
6858 init_expr:
6860 struct c_expr ce;
6861 tree init_expression;
6862 ce = c_parser_expression (parser);
6863 init_expression = ce.value;
6864 parser->objc_could_be_foreach_context = false;
6865 if (c_parser_next_token_is_keyword (parser, RID_IN))
6867 c_parser_consume_token (parser);
6868 is_foreach_statement = true;
6869 if (! lvalue_p (init_expression))
6870 c_parser_error (parser, "invalid iterating variable in "
6871 "fast enumeration");
6872 object_expression
6873 = c_fully_fold (init_expression, false, NULL);
6875 else
6877 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6878 init_expression = ce.value;
6879 c_finish_expr_stmt (loc, init_expression);
6880 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6881 "expected %<;%>");
6885 /* Parse the loop condition. In the case of a foreach
6886 statement, there is no loop condition. */
6887 gcc_assert (!parser->objc_could_be_foreach_context);
6888 if (!is_foreach_statement)
6890 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6892 if (ivdep)
6894 c_parser_error (parser, "missing loop condition in loop "
6895 "with %<GCC ivdep%> pragma");
6896 cond = error_mark_node;
6898 else if (unroll)
6900 c_parser_error (parser, "missing loop condition in loop "
6901 "with %<GCC unroll%> pragma");
6902 cond = error_mark_node;
6904 else
6906 c_parser_consume_token (parser);
6907 cond = NULL_TREE;
6910 else
6912 cond = c_parser_condition (parser);
6913 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6914 "expected %<;%>");
6916 if (ivdep && cond != error_mark_node)
6917 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6918 build_int_cst (integer_type_node,
6919 annot_expr_ivdep_kind),
6920 integer_zero_node);
6921 if (unroll && cond != error_mark_node)
6922 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6923 build_int_cst (integer_type_node,
6924 annot_expr_unroll_kind),
6925 build_int_cst (integer_type_node, unroll));
6927 /* Parse the increment expression (the third expression in a
6928 for-statement). In the case of a foreach-statement, this is
6929 the expression that follows the 'in'. */
6930 loc = c_parser_peek_token (parser)->location;
6931 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6933 if (is_foreach_statement)
6935 c_parser_error (parser,
6936 "missing collection in fast enumeration");
6937 collection_expression = error_mark_node;
6939 else
6940 incr = c_process_expr_stmt (loc, NULL_TREE);
6942 else
6944 if (is_foreach_statement)
6945 collection_expression
6946 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6947 else
6949 struct c_expr ce = c_parser_expression (parser);
6950 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6951 incr = c_process_expr_stmt (loc, ce.value);
6954 parens.skip_until_found_close (parser);
6956 save_in_statement = in_statement;
6957 if (is_foreach_statement)
6959 in_statement = IN_OBJC_FOREACH;
6960 save_objc_foreach_break_label = objc_foreach_break_label;
6961 save_objc_foreach_continue_label = objc_foreach_continue_label;
6962 objc_foreach_break_label = create_artificial_label (loc);
6963 objc_foreach_continue_label = create_artificial_label (loc);
6965 else
6966 in_statement = IN_ITERATION_STMT;
6968 token_indent_info body_tinfo
6969 = get_token_indent_info (c_parser_peek_token (parser));
6971 location_t loc_after_labels;
6972 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6973 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6975 if (is_foreach_statement)
6976 objc_finish_foreach_loop (for_loc, object_expression,
6977 collection_expression, body,
6978 objc_foreach_break_label,
6979 objc_foreach_continue_label);
6980 else
6981 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
6982 body, NULL_TREE));
6983 add_stmt (c_end_compound_stmt (for_loc, block,
6984 flag_isoc99 || c_dialect_objc ()));
6985 c_parser_maybe_reclassify_token (parser);
6987 token_indent_info next_tinfo
6988 = get_token_indent_info (c_parser_peek_token (parser));
6989 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
6991 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6992 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6993 for_tinfo.location, RID_FOR);
6995 in_statement = save_in_statement;
6996 if (is_foreach_statement)
6998 objc_foreach_break_label = save_objc_foreach_break_label;
6999 objc_foreach_continue_label = save_objc_foreach_continue_label;
7003 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7004 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7005 tags allowed.
7007 asm-qualifier:
7008 volatile
7009 inline
7010 goto
7012 asm-qualifier-list:
7013 asm-qualifier-list asm-qualifier
7014 asm-qualifier
7016 asm-statement:
7017 asm asm-qualifier-list[opt] ( asm-argument ) ;
7019 asm-argument:
7020 asm-string-literal
7021 asm-string-literal : asm-operands[opt]
7022 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7023 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7024 : asm-clobbers[opt]
7025 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7026 : asm-goto-operands
7028 The form with asm-goto-operands is valid if and only if the
7029 asm-qualifier-list contains goto, and is the only allowed form in that case.
7030 Duplicate asm-qualifiers are not allowed.
7032 The :: token is considered equivalent to two consecutive : tokens. */
7034 static tree
7035 c_parser_asm_statement (c_parser *parser)
7037 tree str, outputs, inputs, clobbers, labels, ret;
7038 bool simple;
7039 location_t asm_loc = c_parser_peek_token (parser)->location;
7040 int section, nsections;
7042 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7043 c_parser_consume_token (parser);
7045 /* Handle the asm-qualifier-list. */
7046 location_t volatile_loc = UNKNOWN_LOCATION;
7047 location_t inline_loc = UNKNOWN_LOCATION;
7048 location_t goto_loc = UNKNOWN_LOCATION;
7049 for (;;)
7051 c_token *token = c_parser_peek_token (parser);
7052 location_t loc = token->location;
7053 switch (token->keyword)
7055 case RID_VOLATILE:
7056 if (volatile_loc)
7058 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7059 inform (volatile_loc, "first seen here");
7061 else
7062 volatile_loc = loc;
7063 c_parser_consume_token (parser);
7064 continue;
7066 case RID_INLINE:
7067 if (inline_loc)
7069 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7070 inform (inline_loc, "first seen here");
7072 else
7073 inline_loc = loc;
7074 c_parser_consume_token (parser);
7075 continue;
7077 case RID_GOTO:
7078 if (goto_loc)
7080 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7081 inform (goto_loc, "first seen here");
7083 else
7084 goto_loc = loc;
7085 c_parser_consume_token (parser);
7086 continue;
7088 case RID_CONST:
7089 case RID_RESTRICT:
7090 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7091 c_parser_consume_token (parser);
7092 continue;
7094 default:
7095 break;
7097 break;
7100 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7101 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7102 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7104 ret = NULL;
7106 matching_parens parens;
7107 if (!parens.require_open (parser))
7108 goto error;
7110 str = c_parser_asm_string_literal (parser);
7111 if (str == NULL_TREE)
7112 goto error_close_paren;
7114 simple = true;
7115 outputs = NULL_TREE;
7116 inputs = NULL_TREE;
7117 clobbers = NULL_TREE;
7118 labels = NULL_TREE;
7120 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7121 goto done_asm;
7123 /* Parse each colon-delimited section of operands. */
7124 nsections = 3 + is_goto;
7125 for (section = 0; section < nsections; ++section)
7127 if (c_parser_next_token_is (parser, CPP_SCOPE))
7129 ++section;
7130 if (section == nsections)
7132 c_parser_error (parser, "expected %<)%>");
7133 goto error_close_paren;
7135 c_parser_consume_token (parser);
7137 else if (!c_parser_require (parser, CPP_COLON,
7138 is_goto
7139 ? G_("expected %<:%>")
7140 : G_("expected %<:%> or %<)%>"),
7141 UNKNOWN_LOCATION, is_goto))
7142 goto error_close_paren;
7144 /* Once past any colon, we're no longer a simple asm. */
7145 simple = false;
7147 if ((!c_parser_next_token_is (parser, CPP_COLON)
7148 && !c_parser_next_token_is (parser, CPP_SCOPE)
7149 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7150 || section == 3)
7151 switch (section)
7153 case 0:
7154 outputs = c_parser_asm_operands (parser);
7155 break;
7156 case 1:
7157 inputs = c_parser_asm_operands (parser);
7158 break;
7159 case 2:
7160 clobbers = c_parser_asm_clobbers (parser);
7161 break;
7162 case 3:
7163 labels = c_parser_asm_goto_operands (parser);
7164 break;
7165 default:
7166 gcc_unreachable ();
7169 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7170 goto done_asm;
7173 done_asm:
7174 if (!parens.require_close (parser))
7176 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7177 goto error;
7180 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7181 c_parser_skip_to_end_of_block_or_statement (parser);
7183 ret = build_asm_stmt (is_volatile,
7184 build_asm_expr (asm_loc, str, outputs, inputs,
7185 clobbers, labels, simple, is_inline));
7187 error:
7188 return ret;
7190 error_close_paren:
7191 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7192 goto error;
7195 /* Parse asm operands, a GNU extension.
7197 asm-operands:
7198 asm-operand
7199 asm-operands , asm-operand
7201 asm-operand:
7202 asm-string-literal ( expression )
7203 [ identifier ] asm-string-literal ( expression )
7206 static tree
7207 c_parser_asm_operands (c_parser *parser)
7209 tree list = NULL_TREE;
7210 while (true)
7212 tree name, str;
7213 struct c_expr expr;
7214 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7216 c_parser_consume_token (parser);
7217 if (c_parser_next_token_is (parser, CPP_NAME))
7219 tree id = c_parser_peek_token (parser)->value;
7220 c_parser_consume_token (parser);
7221 name = build_string (IDENTIFIER_LENGTH (id),
7222 IDENTIFIER_POINTER (id));
7224 else
7226 c_parser_error (parser, "expected identifier");
7227 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7228 return NULL_TREE;
7230 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7231 "expected %<]%>");
7233 else
7234 name = NULL_TREE;
7235 str = c_parser_asm_string_literal (parser);
7236 if (str == NULL_TREE)
7237 return NULL_TREE;
7238 matching_parens parens;
7239 if (!parens.require_open (parser))
7240 return NULL_TREE;
7241 expr = c_parser_expression (parser);
7242 mark_exp_read (expr.value);
7243 if (!parens.require_close (parser))
7245 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7246 return NULL_TREE;
7248 list = chainon (list, build_tree_list (build_tree_list (name, str),
7249 expr.value));
7250 if (c_parser_next_token_is (parser, CPP_COMMA))
7251 c_parser_consume_token (parser);
7252 else
7253 break;
7255 return list;
7258 /* Parse asm clobbers, a GNU extension.
7260 asm-clobbers:
7261 asm-string-literal
7262 asm-clobbers , asm-string-literal
7265 static tree
7266 c_parser_asm_clobbers (c_parser *parser)
7268 tree list = NULL_TREE;
7269 while (true)
7271 tree str = c_parser_asm_string_literal (parser);
7272 if (str)
7273 list = tree_cons (NULL_TREE, str, list);
7274 else
7275 return NULL_TREE;
7276 if (c_parser_next_token_is (parser, CPP_COMMA))
7277 c_parser_consume_token (parser);
7278 else
7279 break;
7281 return list;
7284 /* Parse asm goto labels, a GNU extension.
7286 asm-goto-operands:
7287 identifier
7288 asm-goto-operands , identifier
7291 static tree
7292 c_parser_asm_goto_operands (c_parser *parser)
7294 tree list = NULL_TREE;
7295 while (true)
7297 tree name, label;
7299 if (c_parser_next_token_is (parser, CPP_NAME))
7301 c_token *tok = c_parser_peek_token (parser);
7302 name = tok->value;
7303 label = lookup_label_for_goto (tok->location, name);
7304 c_parser_consume_token (parser);
7305 TREE_USED (label) = 1;
7307 else
7309 c_parser_error (parser, "expected identifier");
7310 return NULL_TREE;
7313 name = build_string (IDENTIFIER_LENGTH (name),
7314 IDENTIFIER_POINTER (name));
7315 list = tree_cons (name, label, list);
7316 if (c_parser_next_token_is (parser, CPP_COMMA))
7317 c_parser_consume_token (parser);
7318 else
7319 return nreverse (list);
7323 /* Parse a possibly concatenated sequence of string literals.
7324 TRANSLATE says whether to translate them to the execution character
7325 set; WIDE_OK says whether any kind of prefixed string literal is
7326 permitted in this context. This code is based on that in
7327 lex_string. */
7329 struct c_expr
7330 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7332 struct c_expr ret;
7333 size_t count;
7334 struct obstack str_ob;
7335 struct obstack loc_ob;
7336 cpp_string str, istr, *strs;
7337 c_token *tok;
7338 location_t loc, last_tok_loc;
7339 enum cpp_ttype type;
7340 tree value, string_tree;
7342 tok = c_parser_peek_token (parser);
7343 loc = tok->location;
7344 last_tok_loc = linemap_resolve_location (line_table, loc,
7345 LRK_MACRO_DEFINITION_LOCATION,
7346 NULL);
7347 type = tok->type;
7348 switch (type)
7350 case CPP_STRING:
7351 case CPP_WSTRING:
7352 case CPP_STRING16:
7353 case CPP_STRING32:
7354 case CPP_UTF8STRING:
7355 string_tree = tok->value;
7356 break;
7358 default:
7359 c_parser_error (parser, "expected string literal");
7360 ret.set_error ();
7361 ret.value = NULL_TREE;
7362 ret.original_code = ERROR_MARK;
7363 ret.original_type = NULL_TREE;
7364 return ret;
7367 /* Try to avoid the overhead of creating and destroying an obstack
7368 for the common case of just one string. */
7369 switch (c_parser_peek_2nd_token (parser)->type)
7371 default:
7372 c_parser_consume_token (parser);
7373 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7374 str.len = TREE_STRING_LENGTH (string_tree);
7375 count = 1;
7376 strs = &str;
7377 break;
7379 case CPP_STRING:
7380 case CPP_WSTRING:
7381 case CPP_STRING16:
7382 case CPP_STRING32:
7383 case CPP_UTF8STRING:
7384 gcc_obstack_init (&str_ob);
7385 gcc_obstack_init (&loc_ob);
7386 count = 0;
7389 c_parser_consume_token (parser);
7390 count++;
7391 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7392 str.len = TREE_STRING_LENGTH (string_tree);
7393 if (type != tok->type)
7395 if (type == CPP_STRING)
7396 type = tok->type;
7397 else if (tok->type != CPP_STRING)
7398 error ("unsupported non-standard concatenation "
7399 "of string literals");
7401 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7402 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7403 tok = c_parser_peek_token (parser);
7404 string_tree = tok->value;
7405 last_tok_loc
7406 = linemap_resolve_location (line_table, tok->location,
7407 LRK_MACRO_DEFINITION_LOCATION, NULL);
7409 while (tok->type == CPP_STRING
7410 || tok->type == CPP_WSTRING
7411 || tok->type == CPP_STRING16
7412 || tok->type == CPP_STRING32
7413 || tok->type == CPP_UTF8STRING);
7414 strs = (cpp_string *) obstack_finish (&str_ob);
7417 if (count > 1 && !in_system_header_at (input_location))
7418 warning (OPT_Wtraditional,
7419 "traditional C rejects string constant concatenation");
7421 if ((type == CPP_STRING || wide_ok)
7422 && ((translate
7423 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7424 (parse_in, strs, count, &istr, type)))
7426 value = build_string (istr.len, (const char *) istr.text);
7427 free (CONST_CAST (unsigned char *, istr.text));
7428 if (count > 1)
7430 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7431 gcc_assert (g_string_concat_db);
7432 g_string_concat_db->record_string_concatenation (count, locs);
7435 else
7437 if (type != CPP_STRING && !wide_ok)
7439 error_at (loc, "a wide string is invalid in this context");
7440 type = CPP_STRING;
7442 /* Callers cannot generally handle error_mark_node in this
7443 context, so return the empty string instead. An error has
7444 been issued, either above or from cpp_interpret_string. */
7445 switch (type)
7447 default:
7448 case CPP_STRING:
7449 case CPP_UTF8STRING:
7450 value = build_string (1, "");
7451 break;
7452 case CPP_STRING16:
7453 value = build_string (TYPE_PRECISION (char16_type_node)
7454 / TYPE_PRECISION (char_type_node),
7455 "\0"); /* char16_t is 16 bits */
7456 break;
7457 case CPP_STRING32:
7458 value = build_string (TYPE_PRECISION (char32_type_node)
7459 / TYPE_PRECISION (char_type_node),
7460 "\0\0\0"); /* char32_t is 32 bits */
7461 break;
7462 case CPP_WSTRING:
7463 value = build_string (TYPE_PRECISION (wchar_type_node)
7464 / TYPE_PRECISION (char_type_node),
7465 "\0\0\0"); /* widest supported wchar_t
7466 is 32 bits */
7467 break;
7471 switch (type)
7473 default:
7474 case CPP_STRING:
7475 case CPP_UTF8STRING:
7476 TREE_TYPE (value) = char_array_type_node;
7477 break;
7478 case CPP_STRING16:
7479 TREE_TYPE (value) = char16_array_type_node;
7480 break;
7481 case CPP_STRING32:
7482 TREE_TYPE (value) = char32_array_type_node;
7483 break;
7484 case CPP_WSTRING:
7485 TREE_TYPE (value) = wchar_array_type_node;
7487 value = fix_string_type (value);
7489 if (count > 1)
7491 obstack_free (&str_ob, 0);
7492 obstack_free (&loc_ob, 0);
7495 ret.value = value;
7496 ret.original_code = STRING_CST;
7497 ret.original_type = NULL_TREE;
7498 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7499 parser->seen_string_literal = true;
7500 return ret;
7503 /* Parse an expression other than a compound expression; that is, an
7504 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7505 AFTER is not NULL then it is an Objective-C message expression which
7506 is the primary-expression starting the expression as an initializer.
7508 assignment-expression:
7509 conditional-expression
7510 unary-expression assignment-operator assignment-expression
7512 assignment-operator: one of
7513 = *= /= %= += -= <<= >>= &= ^= |=
7515 In GNU C we accept any conditional expression on the LHS and
7516 diagnose the invalid lvalue rather than producing a syntax
7517 error. */
7519 static struct c_expr
7520 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7521 tree omp_atomic_lhs)
7523 struct c_expr lhs, rhs, ret;
7524 enum tree_code code;
7525 location_t op_location, exp_location;
7526 bool save_in_omp_for = c_in_omp_for;
7527 c_in_omp_for = false;
7528 gcc_assert (!after || c_dialect_objc ());
7529 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7530 op_location = c_parser_peek_token (parser)->location;
7531 switch (c_parser_peek_token (parser)->type)
7533 case CPP_EQ:
7534 code = NOP_EXPR;
7535 break;
7536 case CPP_MULT_EQ:
7537 code = MULT_EXPR;
7538 break;
7539 case CPP_DIV_EQ:
7540 code = TRUNC_DIV_EXPR;
7541 break;
7542 case CPP_MOD_EQ:
7543 code = TRUNC_MOD_EXPR;
7544 break;
7545 case CPP_PLUS_EQ:
7546 code = PLUS_EXPR;
7547 break;
7548 case CPP_MINUS_EQ:
7549 code = MINUS_EXPR;
7550 break;
7551 case CPP_LSHIFT_EQ:
7552 code = LSHIFT_EXPR;
7553 break;
7554 case CPP_RSHIFT_EQ:
7555 code = RSHIFT_EXPR;
7556 break;
7557 case CPP_AND_EQ:
7558 code = BIT_AND_EXPR;
7559 break;
7560 case CPP_XOR_EQ:
7561 code = BIT_XOR_EXPR;
7562 break;
7563 case CPP_OR_EQ:
7564 code = BIT_IOR_EXPR;
7565 break;
7566 default:
7567 c_in_omp_for = save_in_omp_for;
7568 return lhs;
7570 c_parser_consume_token (parser);
7571 exp_location = c_parser_peek_token (parser)->location;
7572 rhs = c_parser_expr_no_commas (parser, NULL);
7573 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7575 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7576 code, exp_location, rhs.value,
7577 rhs.original_type);
7578 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7579 if (code == NOP_EXPR)
7580 ret.original_code = MODIFY_EXPR;
7581 else
7583 suppress_warning (ret.value, OPT_Wparentheses);
7584 ret.original_code = ERROR_MARK;
7586 ret.original_type = NULL;
7587 c_in_omp_for = save_in_omp_for;
7588 return ret;
7591 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7592 AFTER is not NULL then it is an Objective-C message expression which is
7593 the primary-expression starting the expression as an initializer.
7595 conditional-expression:
7596 logical-OR-expression
7597 logical-OR-expression ? expression : conditional-expression
7599 GNU extensions:
7601 conditional-expression:
7602 logical-OR-expression ? : conditional-expression
7605 static struct c_expr
7606 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7607 tree omp_atomic_lhs)
7609 struct c_expr cond, exp1, exp2, ret;
7610 location_t start, cond_loc, colon_loc;
7612 gcc_assert (!after || c_dialect_objc ());
7614 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7616 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7617 return cond;
7618 if (cond.value != error_mark_node)
7619 start = cond.get_start ();
7620 else
7621 start = UNKNOWN_LOCATION;
7622 cond_loc = c_parser_peek_token (parser)->location;
7623 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7624 c_parser_consume_token (parser);
7625 if (c_parser_next_token_is (parser, CPP_COLON))
7627 tree eptype = NULL_TREE;
7629 location_t middle_loc = c_parser_peek_token (parser)->location;
7630 pedwarn (middle_loc, OPT_Wpedantic,
7631 "ISO C forbids omitting the middle term of a %<?:%> expression");
7632 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7634 eptype = TREE_TYPE (cond.value);
7635 cond.value = TREE_OPERAND (cond.value, 0);
7637 tree e = cond.value;
7638 while (TREE_CODE (e) == COMPOUND_EXPR)
7639 e = TREE_OPERAND (e, 1);
7640 warn_for_omitted_condop (middle_loc, e);
7641 /* Make sure first operand is calculated only once. */
7642 exp1.value = save_expr (default_conversion (cond.value));
7643 if (eptype)
7644 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7645 exp1.original_type = NULL;
7646 exp1.src_range = cond.src_range;
7647 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7648 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7650 else
7652 cond.value
7653 = c_objc_common_truthvalue_conversion
7654 (cond_loc, default_conversion (cond.value));
7655 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7656 exp1 = c_parser_expression_conv (parser);
7657 mark_exp_read (exp1.value);
7658 c_inhibit_evaluation_warnings +=
7659 ((cond.value == truthvalue_true_node)
7660 - (cond.value == truthvalue_false_node));
7663 colon_loc = c_parser_peek_token (parser)->location;
7664 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7666 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7667 ret.set_error ();
7668 ret.original_code = ERROR_MARK;
7669 ret.original_type = NULL;
7670 return ret;
7673 location_t exp2_loc = c_parser_peek_token (parser)->location;
7674 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7675 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7677 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7678 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7679 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7680 if (UNLIKELY (omp_atomic_lhs != NULL)
7681 && (TREE_CODE (cond.value) == GT_EXPR
7682 || TREE_CODE (cond.value) == LT_EXPR
7683 || TREE_CODE (cond.value) == EQ_EXPR)
7684 && c_tree_equal (exp2.value, omp_atomic_lhs)
7685 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
7686 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
7687 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
7688 cond.value, exp1.value, exp2.value);
7689 else
7690 ret.value
7691 = build_conditional_expr (colon_loc, cond.value,
7692 cond.original_code == C_MAYBE_CONST_EXPR,
7693 exp1.value, exp1.original_type, loc1,
7694 exp2.value, exp2.original_type, loc2);
7695 ret.original_code = ERROR_MARK;
7696 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7697 ret.original_type = NULL;
7698 else
7700 tree t1, t2;
7702 /* If both sides are enum type, the default conversion will have
7703 made the type of the result be an integer type. We want to
7704 remember the enum types we started with. */
7705 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7706 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7707 ret.original_type = ((t1 != error_mark_node
7708 && t2 != error_mark_node
7709 && (TYPE_MAIN_VARIANT (t1)
7710 == TYPE_MAIN_VARIANT (t2)))
7711 ? t1
7712 : NULL);
7714 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7715 return ret;
7718 /* Parse a binary expression; that is, a logical-OR-expression (C90
7719 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7720 NULL then it is an Objective-C message expression which is the
7721 primary-expression starting the expression as an initializer.
7723 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7724 when it should be the unfolded lhs. In a valid OpenMP source,
7725 one of the operands of the toplevel binary expression must be equal
7726 to it. In that case, just return a build2 created binary operation
7727 rather than result of parser_build_binary_op.
7729 multiplicative-expression:
7730 cast-expression
7731 multiplicative-expression * cast-expression
7732 multiplicative-expression / cast-expression
7733 multiplicative-expression % cast-expression
7735 additive-expression:
7736 multiplicative-expression
7737 additive-expression + multiplicative-expression
7738 additive-expression - multiplicative-expression
7740 shift-expression:
7741 additive-expression
7742 shift-expression << additive-expression
7743 shift-expression >> additive-expression
7745 relational-expression:
7746 shift-expression
7747 relational-expression < shift-expression
7748 relational-expression > shift-expression
7749 relational-expression <= shift-expression
7750 relational-expression >= shift-expression
7752 equality-expression:
7753 relational-expression
7754 equality-expression == relational-expression
7755 equality-expression != relational-expression
7757 AND-expression:
7758 equality-expression
7759 AND-expression & equality-expression
7761 exclusive-OR-expression:
7762 AND-expression
7763 exclusive-OR-expression ^ AND-expression
7765 inclusive-OR-expression:
7766 exclusive-OR-expression
7767 inclusive-OR-expression | exclusive-OR-expression
7769 logical-AND-expression:
7770 inclusive-OR-expression
7771 logical-AND-expression && inclusive-OR-expression
7773 logical-OR-expression:
7774 logical-AND-expression
7775 logical-OR-expression || logical-AND-expression
7778 static struct c_expr
7779 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7780 tree omp_atomic_lhs)
7782 /* A binary expression is parsed using operator-precedence parsing,
7783 with the operands being cast expressions. All the binary
7784 operators are left-associative. Thus a binary expression is of
7785 form:
7787 E0 op1 E1 op2 E2 ...
7789 which we represent on a stack. On the stack, the precedence
7790 levels are strictly increasing. When a new operator is
7791 encountered of higher precedence than that at the top of the
7792 stack, it is pushed; its LHS is the top expression, and its RHS
7793 is everything parsed until it is popped. When a new operator is
7794 encountered with precedence less than or equal to that at the top
7795 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7796 by the result of the operation until the operator at the top of
7797 the stack has lower precedence than the new operator or there is
7798 only one element on the stack; then the top expression is the LHS
7799 of the new operator. In the case of logical AND and OR
7800 expressions, we also need to adjust c_inhibit_evaluation_warnings
7801 as appropriate when the operators are pushed and popped. */
7803 struct {
7804 /* The expression at this stack level. */
7805 struct c_expr expr;
7806 /* The precedence of the operator on its left, PREC_NONE at the
7807 bottom of the stack. */
7808 enum c_parser_prec prec;
7809 /* The operation on its left. */
7810 enum tree_code op;
7811 /* The source location of this operation. */
7812 location_t loc;
7813 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7814 tree sizeof_arg;
7815 } stack[NUM_PRECS];
7816 int sp;
7817 /* Location of the binary operator. */
7818 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7819 #define POP \
7820 do { \
7821 switch (stack[sp].op) \
7823 case TRUTH_ANDIF_EXPR: \
7824 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7825 == truthvalue_false_node); \
7826 break; \
7827 case TRUTH_ORIF_EXPR: \
7828 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7829 == truthvalue_true_node); \
7830 break; \
7831 case TRUNC_DIV_EXPR: \
7832 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7833 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7834 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7835 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7837 tree type0 = stack[sp - 1].sizeof_arg; \
7838 tree type1 = stack[sp].sizeof_arg; \
7839 tree first_arg = type0; \
7840 if (!TYPE_P (type0)) \
7841 type0 = TREE_TYPE (type0); \
7842 if (!TYPE_P (type1)) \
7843 type1 = TREE_TYPE (type1); \
7844 if (POINTER_TYPE_P (type0) \
7845 && comptypes (TREE_TYPE (type0), type1) \
7846 && !(TREE_CODE (first_arg) == PARM_DECL \
7847 && C_ARRAY_PARAMETER (first_arg) \
7848 && warn_sizeof_array_argument)) \
7850 auto_diagnostic_group d; \
7851 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7852 "division %<sizeof (%T) / sizeof (%T)%> " \
7853 "does not compute the number of array " \
7854 "elements", \
7855 type0, type1)) \
7856 if (DECL_P (first_arg)) \
7857 inform (DECL_SOURCE_LOCATION (first_arg), \
7858 "first %<sizeof%> operand was declared here"); \
7860 else if (TREE_CODE (type0) == ARRAY_TYPE \
7861 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7862 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7863 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7864 stack[sp].sizeof_arg, type1); \
7866 break; \
7867 default: \
7868 break; \
7870 stack[sp - 1].expr \
7871 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7872 stack[sp - 1].expr, true, true); \
7873 stack[sp].expr \
7874 = convert_lvalue_to_rvalue (stack[sp].loc, \
7875 stack[sp].expr, true, true); \
7876 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
7877 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
7878 && ((1 << stack[sp].prec) \
7879 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
7880 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
7881 | (1 << PREC_ADD) | (1 << PREC_MULT) \
7882 | (1 << PREC_EQ)))) \
7883 || ((c_parser_next_token_is (parser, CPP_QUERY) \
7884 || (omp_atomic_lhs == void_list_node \
7885 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
7886 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7887 && stack[sp].op != TRUNC_MOD_EXPR \
7888 && stack[sp].op != GE_EXPR \
7889 && stack[sp].op != LE_EXPR \
7890 && stack[sp].op != NE_EXPR \
7891 && stack[0].expr.value != error_mark_node \
7892 && stack[1].expr.value != error_mark_node \
7893 && (omp_atomic_lhs == void_list_node \
7894 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7895 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
7896 || (stack[sp].op == EQ_EXPR \
7897 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
7899 tree t = make_node (stack[1].op); \
7900 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7901 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7902 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7903 stack[0].expr.value = t; \
7905 else \
7906 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7907 stack[sp].op, \
7908 stack[sp - 1].expr, \
7909 stack[sp].expr); \
7910 sp--; \
7911 } while (0)
7912 gcc_assert (!after || c_dialect_objc ());
7913 stack[0].loc = c_parser_peek_token (parser)->location;
7914 stack[0].expr = c_parser_cast_expression (parser, after);
7915 stack[0].prec = PREC_NONE;
7916 stack[0].sizeof_arg = c_last_sizeof_arg;
7917 sp = 0;
7918 while (true)
7920 enum c_parser_prec oprec;
7921 enum tree_code ocode;
7922 source_range src_range;
7923 if (parser->error)
7924 goto out;
7925 switch (c_parser_peek_token (parser)->type)
7927 case CPP_MULT:
7928 oprec = PREC_MULT;
7929 ocode = MULT_EXPR;
7930 break;
7931 case CPP_DIV:
7932 oprec = PREC_MULT;
7933 ocode = TRUNC_DIV_EXPR;
7934 break;
7935 case CPP_MOD:
7936 oprec = PREC_MULT;
7937 ocode = TRUNC_MOD_EXPR;
7938 break;
7939 case CPP_PLUS:
7940 oprec = PREC_ADD;
7941 ocode = PLUS_EXPR;
7942 break;
7943 case CPP_MINUS:
7944 oprec = PREC_ADD;
7945 ocode = MINUS_EXPR;
7946 break;
7947 case CPP_LSHIFT:
7948 oprec = PREC_SHIFT;
7949 ocode = LSHIFT_EXPR;
7950 break;
7951 case CPP_RSHIFT:
7952 oprec = PREC_SHIFT;
7953 ocode = RSHIFT_EXPR;
7954 break;
7955 case CPP_LESS:
7956 oprec = PREC_REL;
7957 ocode = LT_EXPR;
7958 break;
7959 case CPP_GREATER:
7960 oprec = PREC_REL;
7961 ocode = GT_EXPR;
7962 break;
7963 case CPP_LESS_EQ:
7964 oprec = PREC_REL;
7965 ocode = LE_EXPR;
7966 break;
7967 case CPP_GREATER_EQ:
7968 oprec = PREC_REL;
7969 ocode = GE_EXPR;
7970 break;
7971 case CPP_EQ_EQ:
7972 oprec = PREC_EQ;
7973 ocode = EQ_EXPR;
7974 break;
7975 case CPP_NOT_EQ:
7976 oprec = PREC_EQ;
7977 ocode = NE_EXPR;
7978 break;
7979 case CPP_AND:
7980 oprec = PREC_BITAND;
7981 ocode = BIT_AND_EXPR;
7982 break;
7983 case CPP_XOR:
7984 oprec = PREC_BITXOR;
7985 ocode = BIT_XOR_EXPR;
7986 break;
7987 case CPP_OR:
7988 oprec = PREC_BITOR;
7989 ocode = BIT_IOR_EXPR;
7990 break;
7991 case CPP_AND_AND:
7992 oprec = PREC_LOGAND;
7993 ocode = TRUTH_ANDIF_EXPR;
7994 break;
7995 case CPP_OR_OR:
7996 oprec = PREC_LOGOR;
7997 ocode = TRUTH_ORIF_EXPR;
7998 break;
7999 default:
8000 /* Not a binary operator, so end of the binary
8001 expression. */
8002 goto out;
8004 binary_loc = c_parser_peek_token (parser)->location;
8005 while (oprec <= stack[sp].prec)
8006 POP;
8007 c_parser_consume_token (parser);
8008 switch (ocode)
8010 case TRUTH_ANDIF_EXPR:
8011 src_range = stack[sp].expr.src_range;
8012 stack[sp].expr
8013 = convert_lvalue_to_rvalue (stack[sp].loc,
8014 stack[sp].expr, true, true);
8015 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8016 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8017 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8018 == truthvalue_false_node);
8019 set_c_expr_source_range (&stack[sp].expr, src_range);
8020 break;
8021 case TRUTH_ORIF_EXPR:
8022 src_range = stack[sp].expr.src_range;
8023 stack[sp].expr
8024 = convert_lvalue_to_rvalue (stack[sp].loc,
8025 stack[sp].expr, true, true);
8026 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8027 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8028 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8029 == truthvalue_true_node);
8030 set_c_expr_source_range (&stack[sp].expr, src_range);
8031 break;
8032 default:
8033 break;
8035 sp++;
8036 stack[sp].loc = binary_loc;
8037 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8038 stack[sp].prec = oprec;
8039 stack[sp].op = ocode;
8040 stack[sp].sizeof_arg = c_last_sizeof_arg;
8042 out:
8043 while (sp > 0)
8044 POP;
8045 return stack[0].expr;
8046 #undef POP
8049 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8050 is not NULL then it is an Objective-C message expression which is the
8051 primary-expression starting the expression as an initializer.
8053 cast-expression:
8054 unary-expression
8055 ( type-name ) unary-expression
8058 static struct c_expr
8059 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8061 location_t cast_loc = c_parser_peek_token (parser)->location;
8062 gcc_assert (!after || c_dialect_objc ());
8063 if (after)
8064 return c_parser_postfix_expression_after_primary (parser,
8065 cast_loc, *after);
8066 /* If the expression begins with a parenthesized type name, it may
8067 be either a cast or a compound literal; we need to see whether
8068 the next character is '{' to tell the difference. If not, it is
8069 an unary expression. Full detection of unknown typenames here
8070 would require a 3-token lookahead. */
8071 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8072 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8074 struct c_type_name *type_name;
8075 struct c_expr ret;
8076 struct c_expr expr;
8077 matching_parens parens;
8078 parens.consume_open (parser);
8079 type_name = c_parser_type_name (parser, true);
8080 parens.skip_until_found_close (parser);
8081 if (type_name == NULL)
8083 ret.set_error ();
8084 ret.original_code = ERROR_MARK;
8085 ret.original_type = NULL;
8086 return ret;
8089 /* Save casted types in the function's used types hash table. */
8090 used_types_insert (type_name->specs->type);
8092 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8093 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8094 cast_loc);
8095 if (type_name->specs->alignas_p)
8096 error_at (type_name->specs->locations[cdw_alignas],
8097 "alignment specified for type name in cast");
8099 location_t expr_loc = c_parser_peek_token (parser)->location;
8100 expr = c_parser_cast_expression (parser, NULL);
8101 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8103 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8104 if (ret.value && expr.value)
8105 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8106 ret.original_code = ERROR_MARK;
8107 ret.original_type = NULL;
8108 return ret;
8110 else
8111 return c_parser_unary_expression (parser);
8114 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8116 unary-expression:
8117 postfix-expression
8118 ++ unary-expression
8119 -- unary-expression
8120 unary-operator cast-expression
8121 sizeof unary-expression
8122 sizeof ( type-name )
8124 unary-operator: one of
8125 & * + - ~ !
8127 GNU extensions:
8129 unary-expression:
8130 __alignof__ unary-expression
8131 __alignof__ ( type-name )
8132 && identifier
8134 (C11 permits _Alignof with type names only.)
8136 unary-operator: one of
8137 __extension__ __real__ __imag__
8139 Transactional Memory:
8141 unary-expression:
8142 transaction-expression
8144 In addition, the GNU syntax treats ++ and -- as unary operators, so
8145 they may be applied to cast expressions with errors for non-lvalues
8146 given later. */
8148 static struct c_expr
8149 c_parser_unary_expression (c_parser *parser)
8151 int ext;
8152 struct c_expr ret, op;
8153 location_t op_loc = c_parser_peek_token (parser)->location;
8154 location_t exp_loc;
8155 location_t finish;
8156 ret.original_code = ERROR_MARK;
8157 ret.original_type = NULL;
8158 switch (c_parser_peek_token (parser)->type)
8160 case CPP_PLUS_PLUS:
8161 c_parser_consume_token (parser);
8162 exp_loc = c_parser_peek_token (parser)->location;
8163 op = c_parser_cast_expression (parser, NULL);
8165 op = default_function_array_read_conversion (exp_loc, op);
8166 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8167 case CPP_MINUS_MINUS:
8168 c_parser_consume_token (parser);
8169 exp_loc = c_parser_peek_token (parser)->location;
8170 op = c_parser_cast_expression (parser, NULL);
8172 op = default_function_array_read_conversion (exp_loc, op);
8173 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8174 case CPP_AND:
8175 c_parser_consume_token (parser);
8176 op = c_parser_cast_expression (parser, NULL);
8177 mark_exp_read (op.value);
8178 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8179 case CPP_MULT:
8181 c_parser_consume_token (parser);
8182 exp_loc = c_parser_peek_token (parser)->location;
8183 op = c_parser_cast_expression (parser, NULL);
8184 finish = op.get_finish ();
8185 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8186 location_t combined_loc = make_location (op_loc, op_loc, finish);
8187 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8188 ret.src_range.m_start = op_loc;
8189 ret.src_range.m_finish = finish;
8190 return ret;
8192 case CPP_PLUS:
8193 if (!c_dialect_objc () && !in_system_header_at (input_location))
8194 warning_at (op_loc,
8195 OPT_Wtraditional,
8196 "traditional C rejects the unary plus operator");
8197 c_parser_consume_token (parser);
8198 exp_loc = c_parser_peek_token (parser)->location;
8199 op = c_parser_cast_expression (parser, NULL);
8200 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8201 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8202 case CPP_MINUS:
8203 c_parser_consume_token (parser);
8204 exp_loc = c_parser_peek_token (parser)->location;
8205 op = c_parser_cast_expression (parser, NULL);
8206 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8207 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8208 case CPP_COMPL:
8209 c_parser_consume_token (parser);
8210 exp_loc = c_parser_peek_token (parser)->location;
8211 op = c_parser_cast_expression (parser, NULL);
8212 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8213 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8214 case CPP_NOT:
8215 c_parser_consume_token (parser);
8216 exp_loc = c_parser_peek_token (parser)->location;
8217 op = c_parser_cast_expression (parser, NULL);
8218 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8219 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8220 case CPP_AND_AND:
8221 /* Refer to the address of a label as a pointer. */
8222 c_parser_consume_token (parser);
8223 if (c_parser_next_token_is (parser, CPP_NAME))
8225 ret.value = finish_label_address_expr
8226 (c_parser_peek_token (parser)->value, op_loc);
8227 set_c_expr_source_range (&ret, op_loc,
8228 c_parser_peek_token (parser)->get_finish ());
8229 c_parser_consume_token (parser);
8231 else
8233 c_parser_error (parser, "expected identifier");
8234 ret.set_error ();
8236 return ret;
8237 case CPP_KEYWORD:
8238 switch (c_parser_peek_token (parser)->keyword)
8240 case RID_SIZEOF:
8241 return c_parser_sizeof_expression (parser);
8242 case RID_ALIGNOF:
8243 return c_parser_alignof_expression (parser);
8244 case RID_BUILTIN_HAS_ATTRIBUTE:
8245 return c_parser_has_attribute_expression (parser);
8246 case RID_EXTENSION:
8247 c_parser_consume_token (parser);
8248 ext = disable_extension_diagnostics ();
8249 ret = c_parser_cast_expression (parser, NULL);
8250 restore_extension_diagnostics (ext);
8251 return ret;
8252 case RID_REALPART:
8253 c_parser_consume_token (parser);
8254 exp_loc = c_parser_peek_token (parser)->location;
8255 op = c_parser_cast_expression (parser, NULL);
8256 op = default_function_array_conversion (exp_loc, op);
8257 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8258 case RID_IMAGPART:
8259 c_parser_consume_token (parser);
8260 exp_loc = c_parser_peek_token (parser)->location;
8261 op = c_parser_cast_expression (parser, NULL);
8262 op = default_function_array_conversion (exp_loc, op);
8263 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8264 case RID_TRANSACTION_ATOMIC:
8265 case RID_TRANSACTION_RELAXED:
8266 return c_parser_transaction_expression (parser,
8267 c_parser_peek_token (parser)->keyword);
8268 default:
8269 return c_parser_postfix_expression (parser);
8271 default:
8272 return c_parser_postfix_expression (parser);
8276 /* Parse a sizeof expression. */
8278 static struct c_expr
8279 c_parser_sizeof_expression (c_parser *parser)
8281 struct c_expr expr;
8282 struct c_expr result;
8283 location_t expr_loc;
8284 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8286 location_t start;
8287 location_t finish = UNKNOWN_LOCATION;
8289 start = c_parser_peek_token (parser)->location;
8291 c_parser_consume_token (parser);
8292 c_inhibit_evaluation_warnings++;
8293 in_sizeof++;
8294 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8295 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8297 /* Either sizeof ( type-name ) or sizeof unary-expression
8298 starting with a compound literal. */
8299 struct c_type_name *type_name;
8300 matching_parens parens;
8301 parens.consume_open (parser);
8302 expr_loc = c_parser_peek_token (parser)->location;
8303 type_name = c_parser_type_name (parser, true);
8304 parens.skip_until_found_close (parser);
8305 finish = parser->tokens_buf[0].location;
8306 if (type_name == NULL)
8308 struct c_expr ret;
8309 c_inhibit_evaluation_warnings--;
8310 in_sizeof--;
8311 ret.set_error ();
8312 ret.original_code = ERROR_MARK;
8313 ret.original_type = NULL;
8314 return ret;
8316 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8318 expr = c_parser_postfix_expression_after_paren_type (parser,
8319 type_name,
8320 expr_loc);
8321 finish = expr.get_finish ();
8322 goto sizeof_expr;
8324 /* sizeof ( type-name ). */
8325 if (type_name->specs->alignas_p)
8326 error_at (type_name->specs->locations[cdw_alignas],
8327 "alignment specified for type name in %<sizeof%>");
8328 c_inhibit_evaluation_warnings--;
8329 in_sizeof--;
8330 result = c_expr_sizeof_type (expr_loc, type_name);
8332 else
8334 expr_loc = c_parser_peek_token (parser)->location;
8335 expr = c_parser_unary_expression (parser);
8336 finish = expr.get_finish ();
8337 sizeof_expr:
8338 c_inhibit_evaluation_warnings--;
8339 in_sizeof--;
8340 mark_exp_read (expr.value);
8341 if (TREE_CODE (expr.value) == COMPONENT_REF
8342 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8343 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8344 result = c_expr_sizeof_expr (expr_loc, expr);
8346 if (finish == UNKNOWN_LOCATION)
8347 finish = start;
8348 set_c_expr_source_range (&result, start, finish);
8349 return result;
8352 /* Parse an alignof expression. */
8354 static struct c_expr
8355 c_parser_alignof_expression (c_parser *parser)
8357 struct c_expr expr;
8358 location_t start_loc = c_parser_peek_token (parser)->location;
8359 location_t end_loc;
8360 tree alignof_spelling = c_parser_peek_token (parser)->value;
8361 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8362 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8363 "_Alignof") == 0;
8364 /* A diagnostic is not required for the use of this identifier in
8365 the implementation namespace; only diagnose it for the C11
8366 spelling because of existing code using the other spellings. */
8367 if (is_c11_alignof)
8369 if (flag_isoc99)
8370 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8371 alignof_spelling);
8372 else
8373 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8374 alignof_spelling);
8376 c_parser_consume_token (parser);
8377 c_inhibit_evaluation_warnings++;
8378 in_alignof++;
8379 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8380 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8382 /* Either __alignof__ ( type-name ) or __alignof__
8383 unary-expression starting with a compound literal. */
8384 location_t loc;
8385 struct c_type_name *type_name;
8386 struct c_expr ret;
8387 matching_parens parens;
8388 parens.consume_open (parser);
8389 loc = c_parser_peek_token (parser)->location;
8390 type_name = c_parser_type_name (parser, true);
8391 end_loc = c_parser_peek_token (parser)->location;
8392 parens.skip_until_found_close (parser);
8393 if (type_name == NULL)
8395 struct c_expr ret;
8396 c_inhibit_evaluation_warnings--;
8397 in_alignof--;
8398 ret.set_error ();
8399 ret.original_code = ERROR_MARK;
8400 ret.original_type = NULL;
8401 return ret;
8403 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8405 expr = c_parser_postfix_expression_after_paren_type (parser,
8406 type_name,
8407 loc);
8408 goto alignof_expr;
8410 /* alignof ( type-name ). */
8411 if (type_name->specs->alignas_p)
8412 error_at (type_name->specs->locations[cdw_alignas],
8413 "alignment specified for type name in %qE",
8414 alignof_spelling);
8415 c_inhibit_evaluation_warnings--;
8416 in_alignof--;
8417 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8418 NULL, NULL),
8419 false, is_c11_alignof, 1);
8420 ret.original_code = ERROR_MARK;
8421 ret.original_type = NULL;
8422 set_c_expr_source_range (&ret, start_loc, end_loc);
8423 return ret;
8425 else
8427 struct c_expr ret;
8428 expr = c_parser_unary_expression (parser);
8429 end_loc = expr.src_range.m_finish;
8430 alignof_expr:
8431 mark_exp_read (expr.value);
8432 c_inhibit_evaluation_warnings--;
8433 in_alignof--;
8434 if (is_c11_alignof)
8435 pedwarn (start_loc,
8436 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8437 alignof_spelling);
8438 ret.value = c_alignof_expr (start_loc, expr.value);
8439 ret.original_code = ERROR_MARK;
8440 ret.original_type = NULL;
8441 set_c_expr_source_range (&ret, start_loc, end_loc);
8442 return ret;
8446 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8447 expression. */
8449 static struct c_expr
8450 c_parser_has_attribute_expression (c_parser *parser)
8452 gcc_assert (c_parser_next_token_is_keyword (parser,
8453 RID_BUILTIN_HAS_ATTRIBUTE));
8454 location_t start = c_parser_peek_token (parser)->location;
8455 c_parser_consume_token (parser);
8457 c_inhibit_evaluation_warnings++;
8459 matching_parens parens;
8460 if (!parens.require_open (parser))
8462 c_inhibit_evaluation_warnings--;
8463 in_typeof--;
8465 struct c_expr result;
8466 result.set_error ();
8467 result.original_code = ERROR_MARK;
8468 result.original_type = NULL;
8469 return result;
8472 /* Treat the type argument the same way as in typeof for the purposes
8473 of warnings. FIXME: Generalize this so the warning refers to
8474 __builtin_has_attribute rather than typeof. */
8475 in_typeof++;
8477 /* The first operand: one of DECL, EXPR, or TYPE. */
8478 tree oper = NULL_TREE;
8479 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8481 struct c_type_name *tname = c_parser_type_name (parser);
8482 in_typeof--;
8483 if (tname)
8485 oper = groktypename (tname, NULL, NULL);
8486 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8489 else
8491 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8492 c_inhibit_evaluation_warnings--;
8493 in_typeof--;
8494 if (cexpr.value != error_mark_node)
8496 mark_exp_read (cexpr.value);
8497 oper = cexpr.value;
8498 tree etype = TREE_TYPE (oper);
8499 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8500 /* This is returned with the type so that when the type is
8501 evaluated, this can be evaluated. */
8502 if (was_vm)
8503 oper = c_fully_fold (oper, false, NULL);
8504 pop_maybe_used (was_vm);
8508 struct c_expr result;
8509 result.original_code = ERROR_MARK;
8510 result.original_type = NULL;
8512 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8514 /* Consume the closing parenthesis if that's the next token
8515 in the likely case the built-in was invoked with fewer
8516 than two arguments. */
8517 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8518 c_parser_consume_token (parser);
8519 c_inhibit_evaluation_warnings--;
8520 result.set_error ();
8521 return result;
8524 bool save_translate_strings_p = parser->translate_strings_p;
8526 location_t atloc = c_parser_peek_token (parser)->location;
8527 /* Parse a single attribute. Require no leading comma and do not
8528 allow empty attributes. */
8529 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8531 parser->translate_strings_p = save_translate_strings_p;
8533 location_t finish = c_parser_peek_token (parser)->location;
8534 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8535 c_parser_consume_token (parser);
8536 else
8538 c_parser_error (parser, "expected identifier");
8539 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8541 result.set_error ();
8542 return result;
8545 if (!attr)
8547 error_at (atloc, "expected identifier");
8548 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8549 "expected %<)%>");
8550 result.set_error ();
8551 return result;
8554 result.original_code = INTEGER_CST;
8555 result.original_type = boolean_type_node;
8557 if (has_attribute (atloc, oper, attr, default_conversion))
8558 result.value = boolean_true_node;
8559 else
8560 result.value = boolean_false_node;
8562 set_c_expr_source_range (&result, start, finish);
8563 return result;
8566 /* Helper function to read arguments of builtins which are interfaces
8567 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8568 others. The name of the builtin is passed using BNAME parameter.
8569 Function returns true if there were no errors while parsing and
8570 stores the arguments in CEXPR_LIST. If it returns true,
8571 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8572 parenthesis. */
8573 static bool
8574 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8575 vec<c_expr_t, va_gc> **ret_cexpr_list,
8576 bool choose_expr_p,
8577 location_t *out_close_paren_loc)
8579 location_t loc = c_parser_peek_token (parser)->location;
8580 vec<c_expr_t, va_gc> *cexpr_list;
8581 c_expr_t expr;
8582 bool saved_force_folding_builtin_constant_p;
8584 *ret_cexpr_list = NULL;
8585 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8587 error_at (loc, "cannot take address of %qs", bname);
8588 return false;
8591 c_parser_consume_token (parser);
8593 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8595 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8596 c_parser_consume_token (parser);
8597 return true;
8600 saved_force_folding_builtin_constant_p
8601 = force_folding_builtin_constant_p;
8602 force_folding_builtin_constant_p |= choose_expr_p;
8603 expr = c_parser_expr_no_commas (parser, NULL);
8604 force_folding_builtin_constant_p
8605 = saved_force_folding_builtin_constant_p;
8606 vec_alloc (cexpr_list, 1);
8607 vec_safe_push (cexpr_list, expr);
8608 while (c_parser_next_token_is (parser, CPP_COMMA))
8610 c_parser_consume_token (parser);
8611 expr = c_parser_expr_no_commas (parser, NULL);
8612 vec_safe_push (cexpr_list, expr);
8615 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8616 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8617 return false;
8619 *ret_cexpr_list = cexpr_list;
8620 return true;
8623 /* This represents a single generic-association. */
8625 struct c_generic_association
8627 /* The location of the starting token of the type. */
8628 location_t type_location;
8629 /* The association's type, or NULL_TREE for 'default'. */
8630 tree type;
8631 /* The association's expression. */
8632 struct c_expr expression;
8635 /* Parse a generic-selection. (C11 6.5.1.1).
8637 generic-selection:
8638 _Generic ( assignment-expression , generic-assoc-list )
8640 generic-assoc-list:
8641 generic-association
8642 generic-assoc-list , generic-association
8644 generic-association:
8645 type-name : assignment-expression
8646 default : assignment-expression
8649 static struct c_expr
8650 c_parser_generic_selection (c_parser *parser)
8652 struct c_expr selector, error_expr;
8653 tree selector_type;
8654 struct c_generic_association matched_assoc;
8655 int match_found = -1;
8656 location_t generic_loc, selector_loc;
8658 error_expr.original_code = ERROR_MARK;
8659 error_expr.original_type = NULL;
8660 error_expr.set_error ();
8661 matched_assoc.type_location = UNKNOWN_LOCATION;
8662 matched_assoc.type = NULL_TREE;
8663 matched_assoc.expression = error_expr;
8665 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8666 generic_loc = c_parser_peek_token (parser)->location;
8667 c_parser_consume_token (parser);
8668 if (flag_isoc99)
8669 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8670 "ISO C99 does not support %<_Generic%>");
8671 else
8672 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8673 "ISO C90 does not support %<_Generic%>");
8675 matching_parens parens;
8676 if (!parens.require_open (parser))
8677 return error_expr;
8679 c_inhibit_evaluation_warnings++;
8680 selector_loc = c_parser_peek_token (parser)->location;
8681 selector = c_parser_expr_no_commas (parser, NULL);
8682 selector = default_function_array_conversion (selector_loc, selector);
8683 c_inhibit_evaluation_warnings--;
8685 if (selector.value == error_mark_node)
8687 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8688 return selector;
8690 mark_exp_read (selector.value);
8691 selector_type = TREE_TYPE (selector.value);
8692 /* In ISO C terms, rvalues (including the controlling expression of
8693 _Generic) do not have qualified types. */
8694 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8695 selector_type = TYPE_MAIN_VARIANT (selector_type);
8696 /* In ISO C terms, _Noreturn is not part of the type of expressions
8697 such as &abort, but in GCC it is represented internally as a type
8698 qualifier. */
8699 if (FUNCTION_POINTER_TYPE_P (selector_type)
8700 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8701 selector_type
8702 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8704 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8706 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8707 return error_expr;
8710 auto_vec<c_generic_association> associations;
8711 while (1)
8713 struct c_generic_association assoc, *iter;
8714 unsigned int ix;
8715 c_token *token = c_parser_peek_token (parser);
8717 assoc.type_location = token->location;
8718 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8720 c_parser_consume_token (parser);
8721 assoc.type = NULL_TREE;
8723 else
8725 struct c_type_name *type_name;
8727 type_name = c_parser_type_name (parser);
8728 if (type_name == NULL)
8730 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8731 return error_expr;
8733 assoc.type = groktypename (type_name, NULL, NULL);
8734 if (assoc.type == error_mark_node)
8736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8737 return error_expr;
8740 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8741 error_at (assoc.type_location,
8742 "%<_Generic%> association has function type");
8743 else if (!COMPLETE_TYPE_P (assoc.type))
8744 error_at (assoc.type_location,
8745 "%<_Generic%> association has incomplete type");
8747 if (variably_modified_type_p (assoc.type, NULL_TREE))
8748 error_at (assoc.type_location,
8749 "%<_Generic%> association has "
8750 "variable length type");
8753 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8755 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8756 return error_expr;
8759 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8760 if (assoc.expression.value == error_mark_node)
8762 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8763 return error_expr;
8766 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8768 if (assoc.type == NULL_TREE)
8770 if (iter->type == NULL_TREE)
8772 error_at (assoc.type_location,
8773 "duplicate %<default%> case in %<_Generic%>");
8774 inform (iter->type_location, "original %<default%> is here");
8777 else if (iter->type != NULL_TREE)
8779 if (comptypes (assoc.type, iter->type))
8781 error_at (assoc.type_location,
8782 "%<_Generic%> specifies two compatible types");
8783 inform (iter->type_location, "compatible type is here");
8788 if (assoc.type == NULL_TREE)
8790 if (match_found < 0)
8792 matched_assoc = assoc;
8793 match_found = associations.length ();
8796 else if (comptypes (assoc.type, selector_type))
8798 if (match_found < 0 || matched_assoc.type == NULL_TREE)
8800 matched_assoc = assoc;
8801 match_found = associations.length ();
8803 else
8805 error_at (assoc.type_location,
8806 "%<_Generic%> selector matches multiple associations");
8807 inform (matched_assoc.type_location,
8808 "other match is here");
8812 associations.safe_push (assoc);
8814 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8815 break;
8816 c_parser_consume_token (parser);
8819 unsigned int ix;
8820 struct c_generic_association *iter;
8821 FOR_EACH_VEC_ELT (associations, ix, iter)
8822 if (ix != (unsigned) match_found)
8823 mark_exp_read (iter->expression.value);
8825 if (!parens.require_close (parser))
8827 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8828 return error_expr;
8831 if (match_found < 0)
8833 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8834 "compatible with any association",
8835 selector_type);
8836 return error_expr;
8839 return matched_assoc.expression;
8842 /* Check the validity of a function pointer argument *EXPR (argument
8843 position POS) to __builtin_tgmath. Return the number of function
8844 arguments if possibly valid; return 0 having reported an error if
8845 not valid. */
8847 static unsigned int
8848 check_tgmath_function (c_expr *expr, unsigned int pos)
8850 tree type = TREE_TYPE (expr->value);
8851 if (!FUNCTION_POINTER_TYPE_P (type))
8853 error_at (expr->get_location (),
8854 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8855 pos);
8856 return 0;
8858 type = TREE_TYPE (type);
8859 if (!prototype_p (type))
8861 error_at (expr->get_location (),
8862 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8863 return 0;
8865 if (stdarg_p (type))
8867 error_at (expr->get_location (),
8868 "argument %u of %<__builtin_tgmath%> has variable arguments",
8869 pos);
8870 return 0;
8872 unsigned int nargs = 0;
8873 function_args_iterator iter;
8874 tree t;
8875 FOREACH_FUNCTION_ARGS (type, t, iter)
8877 if (t == void_type_node)
8878 break;
8879 nargs++;
8881 if (nargs == 0)
8883 error_at (expr->get_location (),
8884 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8885 return 0;
8887 return nargs;
8890 /* Ways in which a parameter or return value of a type-generic macro
8891 may vary between the different functions the macro may call. */
8892 enum tgmath_parm_kind
8894 tgmath_fixed, tgmath_real, tgmath_complex
8897 /* Helper function for c_parser_postfix_expression. Parse predefined
8898 identifiers. */
8900 static struct c_expr
8901 c_parser_predefined_identifier (c_parser *parser)
8903 location_t loc = c_parser_peek_token (parser)->location;
8904 switch (c_parser_peek_token (parser)->keyword)
8906 case RID_FUNCTION_NAME:
8907 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8908 "identifier", "__FUNCTION__");
8909 break;
8910 case RID_PRETTY_FUNCTION_NAME:
8911 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8912 "identifier", "__PRETTY_FUNCTION__");
8913 break;
8914 case RID_C99_FUNCTION_NAME:
8915 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8916 "%<__func__%> predefined identifier");
8917 break;
8918 default:
8919 gcc_unreachable ();
8922 struct c_expr expr;
8923 expr.original_code = ERROR_MARK;
8924 expr.original_type = NULL;
8925 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8926 c_parser_peek_token (parser)->value);
8927 set_c_expr_source_range (&expr, loc, loc);
8928 c_parser_consume_token (parser);
8929 return expr;
8932 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8933 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8934 call c_parser_postfix_expression_after_paren_type on encountering them.
8936 postfix-expression:
8937 primary-expression
8938 postfix-expression [ expression ]
8939 postfix-expression ( argument-expression-list[opt] )
8940 postfix-expression . identifier
8941 postfix-expression -> identifier
8942 postfix-expression ++
8943 postfix-expression --
8944 ( type-name ) { initializer-list }
8945 ( type-name ) { initializer-list , }
8947 argument-expression-list:
8948 argument-expression
8949 argument-expression-list , argument-expression
8951 primary-expression:
8952 identifier
8953 constant
8954 string-literal
8955 ( expression )
8956 generic-selection
8958 GNU extensions:
8960 primary-expression:
8961 __func__
8962 (treated as a keyword in GNU C)
8963 __FUNCTION__
8964 __PRETTY_FUNCTION__
8965 ( compound-statement )
8966 __builtin_va_arg ( assignment-expression , type-name )
8967 __builtin_offsetof ( type-name , offsetof-member-designator )
8968 __builtin_choose_expr ( assignment-expression ,
8969 assignment-expression ,
8970 assignment-expression )
8971 __builtin_types_compatible_p ( type-name , type-name )
8972 __builtin_tgmath ( expr-list )
8973 __builtin_complex ( assignment-expression , assignment-expression )
8974 __builtin_shuffle ( assignment-expression , assignment-expression )
8975 __builtin_shuffle ( assignment-expression ,
8976 assignment-expression ,
8977 assignment-expression, )
8978 __builtin_convertvector ( assignment-expression , type-name )
8979 __builtin_assoc_barrier ( assignment-expression )
8981 offsetof-member-designator:
8982 identifier
8983 offsetof-member-designator . identifier
8984 offsetof-member-designator [ expression ]
8986 Objective-C:
8988 primary-expression:
8989 [ objc-receiver objc-message-args ]
8990 @selector ( objc-selector-arg )
8991 @protocol ( identifier )
8992 @encode ( type-name )
8993 objc-string-literal
8994 Classname . identifier
8997 static struct c_expr
8998 c_parser_postfix_expression (c_parser *parser)
9000 struct c_expr expr, e1;
9001 struct c_type_name *t1, *t2;
9002 location_t loc = c_parser_peek_token (parser)->location;
9003 source_range tok_range = c_parser_peek_token (parser)->get_range ();
9004 expr.original_code = ERROR_MARK;
9005 expr.original_type = NULL;
9006 switch (c_parser_peek_token (parser)->type)
9008 case CPP_NUMBER:
9009 expr.value = c_parser_peek_token (parser)->value;
9010 set_c_expr_source_range (&expr, tok_range);
9011 loc = c_parser_peek_token (parser)->location;
9012 c_parser_consume_token (parser);
9013 if (TREE_CODE (expr.value) == FIXED_CST
9014 && !targetm.fixed_point_supported_p ())
9016 error_at (loc, "fixed-point types not supported for this target");
9017 expr.set_error ();
9019 break;
9020 case CPP_CHAR:
9021 case CPP_CHAR16:
9022 case CPP_CHAR32:
9023 case CPP_UTF8CHAR:
9024 case CPP_WCHAR:
9025 expr.value = c_parser_peek_token (parser)->value;
9026 /* For the purpose of warning when a pointer is compared with
9027 a zero character constant. */
9028 expr.original_type = char_type_node;
9029 set_c_expr_source_range (&expr, tok_range);
9030 c_parser_consume_token (parser);
9031 break;
9032 case CPP_STRING:
9033 case CPP_STRING16:
9034 case CPP_STRING32:
9035 case CPP_WSTRING:
9036 case CPP_UTF8STRING:
9037 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9038 true);
9039 break;
9040 case CPP_OBJC_STRING:
9041 gcc_assert (c_dialect_objc ());
9042 expr.value
9043 = objc_build_string_object (c_parser_peek_token (parser)->value);
9044 set_c_expr_source_range (&expr, tok_range);
9045 c_parser_consume_token (parser);
9046 break;
9047 case CPP_NAME:
9048 switch (c_parser_peek_token (parser)->id_kind)
9050 case C_ID_ID:
9052 tree id = c_parser_peek_token (parser)->value;
9053 c_parser_consume_token (parser);
9054 expr.value = build_external_ref (loc, id,
9055 (c_parser_peek_token (parser)->type
9056 == CPP_OPEN_PAREN),
9057 &expr.original_type);
9058 set_c_expr_source_range (&expr, tok_range);
9059 break;
9061 case C_ID_CLASSNAME:
9063 /* Here we parse the Objective-C 2.0 Class.name dot
9064 syntax. */
9065 tree class_name = c_parser_peek_token (parser)->value;
9066 tree component;
9067 c_parser_consume_token (parser);
9068 gcc_assert (c_dialect_objc ());
9069 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9071 expr.set_error ();
9072 break;
9074 if (c_parser_next_token_is_not (parser, CPP_NAME))
9076 c_parser_error (parser, "expected identifier");
9077 expr.set_error ();
9078 break;
9080 c_token *component_tok = c_parser_peek_token (parser);
9081 component = component_tok->value;
9082 location_t end_loc = component_tok->get_finish ();
9083 c_parser_consume_token (parser);
9084 expr.value = objc_build_class_component_ref (class_name,
9085 component);
9086 set_c_expr_source_range (&expr, loc, end_loc);
9087 break;
9089 default:
9090 c_parser_error (parser, "expected expression");
9091 expr.set_error ();
9092 break;
9094 break;
9095 case CPP_OPEN_PAREN:
9096 /* A parenthesized expression, statement expression or compound
9097 literal. */
9098 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9100 /* A statement expression. */
9101 tree stmt;
9102 location_t brace_loc;
9103 c_parser_consume_token (parser);
9104 brace_loc = c_parser_peek_token (parser)->location;
9105 c_parser_consume_token (parser);
9106 /* If we've not yet started the current function's statement list,
9107 or we're in the parameter scope of an old-style function
9108 declaration, statement expressions are not allowed. */
9109 if (!building_stmt_list_p () || old_style_parameter_scope ())
9111 error_at (loc, "braced-group within expression allowed "
9112 "only inside a function");
9113 parser->error = true;
9114 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9115 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9116 expr.set_error ();
9117 break;
9119 stmt = c_begin_stmt_expr ();
9120 c_parser_compound_statement_nostart (parser);
9121 location_t close_loc = c_parser_peek_token (parser)->location;
9122 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9123 "expected %<)%>");
9124 pedwarn (loc, OPT_Wpedantic,
9125 "ISO C forbids braced-groups within expressions");
9126 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9127 set_c_expr_source_range (&expr, loc, close_loc);
9128 mark_exp_read (expr.value);
9130 else
9132 /* A parenthesized expression. */
9133 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9134 c_parser_consume_token (parser);
9135 expr = c_parser_expression (parser);
9136 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9137 suppress_warning (expr.value, OPT_Wparentheses);
9138 if (expr.original_code != C_MAYBE_CONST_EXPR
9139 && expr.original_code != SIZEOF_EXPR)
9140 expr.original_code = ERROR_MARK;
9141 /* Remember that we saw ( ) around the sizeof. */
9142 if (expr.original_code == SIZEOF_EXPR)
9143 expr.original_code = PAREN_SIZEOF_EXPR;
9144 /* Don't change EXPR.ORIGINAL_TYPE. */
9145 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9146 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9147 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9148 "expected %<)%>", loc_open_paren);
9150 break;
9151 case CPP_KEYWORD:
9152 switch (c_parser_peek_token (parser)->keyword)
9154 case RID_FUNCTION_NAME:
9155 case RID_PRETTY_FUNCTION_NAME:
9156 case RID_C99_FUNCTION_NAME:
9157 expr = c_parser_predefined_identifier (parser);
9158 break;
9159 case RID_VA_ARG:
9161 location_t start_loc = loc;
9162 c_parser_consume_token (parser);
9163 matching_parens parens;
9164 if (!parens.require_open (parser))
9166 expr.set_error ();
9167 break;
9169 e1 = c_parser_expr_no_commas (parser, NULL);
9170 mark_exp_read (e1.value);
9171 e1.value = c_fully_fold (e1.value, false, NULL);
9172 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9174 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9175 expr.set_error ();
9176 break;
9178 loc = c_parser_peek_token (parser)->location;
9179 t1 = c_parser_type_name (parser);
9180 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9181 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9182 "expected %<)%>");
9183 if (t1 == NULL)
9185 expr.set_error ();
9187 else
9189 tree type_expr = NULL_TREE;
9190 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9191 groktypename (t1, &type_expr, NULL));
9192 if (type_expr)
9194 expr.value = build2 (C_MAYBE_CONST_EXPR,
9195 TREE_TYPE (expr.value), type_expr,
9196 expr.value);
9197 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9199 set_c_expr_source_range (&expr, start_loc, end_loc);
9202 break;
9203 case RID_OFFSETOF:
9205 c_parser_consume_token (parser);
9206 matching_parens parens;
9207 if (!parens.require_open (parser))
9209 expr.set_error ();
9210 break;
9212 t1 = c_parser_type_name (parser);
9213 if (t1 == NULL)
9214 parser->error = true;
9215 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9216 gcc_assert (parser->error);
9217 if (parser->error)
9219 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9220 expr.set_error ();
9221 break;
9223 tree type = groktypename (t1, NULL, NULL);
9224 tree offsetof_ref;
9225 if (type == error_mark_node)
9226 offsetof_ref = error_mark_node;
9227 else
9229 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9230 SET_EXPR_LOCATION (offsetof_ref, loc);
9232 /* Parse the second argument to __builtin_offsetof. We
9233 must have one identifier, and beyond that we want to
9234 accept sub structure and sub array references. */
9235 if (c_parser_next_token_is (parser, CPP_NAME))
9237 c_token *comp_tok = c_parser_peek_token (parser);
9238 offsetof_ref
9239 = build_component_ref (loc, offsetof_ref, comp_tok->value,
9240 comp_tok->location, UNKNOWN_LOCATION);
9241 c_parser_consume_token (parser);
9242 while (c_parser_next_token_is (parser, CPP_DOT)
9243 || c_parser_next_token_is (parser,
9244 CPP_OPEN_SQUARE)
9245 || c_parser_next_token_is (parser,
9246 CPP_DEREF))
9248 if (c_parser_next_token_is (parser, CPP_DEREF))
9250 loc = c_parser_peek_token (parser)->location;
9251 offsetof_ref = build_array_ref (loc,
9252 offsetof_ref,
9253 integer_zero_node);
9254 goto do_dot;
9256 else if (c_parser_next_token_is (parser, CPP_DOT))
9258 do_dot:
9259 c_parser_consume_token (parser);
9260 if (c_parser_next_token_is_not (parser,
9261 CPP_NAME))
9263 c_parser_error (parser, "expected identifier");
9264 break;
9266 c_token *comp_tok = c_parser_peek_token (parser);
9267 offsetof_ref
9268 = build_component_ref (loc, offsetof_ref,
9269 comp_tok->value,
9270 comp_tok->location,
9271 UNKNOWN_LOCATION);
9272 c_parser_consume_token (parser);
9274 else
9276 struct c_expr ce;
9277 tree idx;
9278 loc = c_parser_peek_token (parser)->location;
9279 c_parser_consume_token (parser);
9280 ce = c_parser_expression (parser);
9281 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9282 idx = ce.value;
9283 idx = c_fully_fold (idx, false, NULL);
9284 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9285 "expected %<]%>");
9286 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9290 else
9291 c_parser_error (parser, "expected identifier");
9292 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9293 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9294 "expected %<)%>");
9295 expr.value = fold_offsetof (offsetof_ref);
9296 set_c_expr_source_range (&expr, loc, end_loc);
9298 break;
9299 case RID_CHOOSE_EXPR:
9301 vec<c_expr_t, va_gc> *cexpr_list;
9302 c_expr_t *e1_p, *e2_p, *e3_p;
9303 tree c;
9304 location_t close_paren_loc;
9306 c_parser_consume_token (parser);
9307 if (!c_parser_get_builtin_args (parser,
9308 "__builtin_choose_expr",
9309 &cexpr_list, true,
9310 &close_paren_loc))
9312 expr.set_error ();
9313 break;
9316 if (vec_safe_length (cexpr_list) != 3)
9318 error_at (loc, "wrong number of arguments to "
9319 "%<__builtin_choose_expr%>");
9320 expr.set_error ();
9321 break;
9324 e1_p = &(*cexpr_list)[0];
9325 e2_p = &(*cexpr_list)[1];
9326 e3_p = &(*cexpr_list)[2];
9328 c = e1_p->value;
9329 mark_exp_read (e2_p->value);
9330 mark_exp_read (e3_p->value);
9331 if (TREE_CODE (c) != INTEGER_CST
9332 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9333 error_at (loc,
9334 "first argument to %<__builtin_choose_expr%> not"
9335 " a constant");
9336 constant_expression_warning (c);
9337 expr = integer_zerop (c) ? *e3_p : *e2_p;
9338 set_c_expr_source_range (&expr, loc, close_paren_loc);
9339 break;
9341 case RID_TYPES_COMPATIBLE_P:
9343 c_parser_consume_token (parser);
9344 matching_parens parens;
9345 if (!parens.require_open (parser))
9347 expr.set_error ();
9348 break;
9350 t1 = c_parser_type_name (parser);
9351 if (t1 == NULL)
9353 expr.set_error ();
9354 break;
9356 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9358 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9359 expr.set_error ();
9360 break;
9362 t2 = c_parser_type_name (parser);
9363 if (t2 == NULL)
9365 expr.set_error ();
9366 break;
9368 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9369 parens.skip_until_found_close (parser);
9370 tree e1, e2;
9371 e1 = groktypename (t1, NULL, NULL);
9372 e2 = groktypename (t2, NULL, NULL);
9373 if (e1 == error_mark_node || e2 == error_mark_node)
9375 expr.set_error ();
9376 break;
9379 e1 = TYPE_MAIN_VARIANT (e1);
9380 e2 = TYPE_MAIN_VARIANT (e2);
9382 expr.value
9383 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9384 set_c_expr_source_range (&expr, loc, close_paren_loc);
9386 break;
9387 case RID_BUILTIN_TGMATH:
9389 vec<c_expr_t, va_gc> *cexpr_list;
9390 location_t close_paren_loc;
9392 c_parser_consume_token (parser);
9393 if (!c_parser_get_builtin_args (parser,
9394 "__builtin_tgmath",
9395 &cexpr_list, false,
9396 &close_paren_loc))
9398 expr.set_error ();
9399 break;
9402 if (vec_safe_length (cexpr_list) < 3)
9404 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9405 expr.set_error ();
9406 break;
9409 unsigned int i;
9410 c_expr_t *p;
9411 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9412 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9413 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9414 if (nargs == 0)
9416 expr.set_error ();
9417 break;
9419 if (vec_safe_length (cexpr_list) < nargs)
9421 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9422 expr.set_error ();
9423 break;
9425 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9426 if (num_functions < 2)
9428 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9429 expr.set_error ();
9430 break;
9433 /* The first NUM_FUNCTIONS expressions are the function
9434 pointers. The remaining NARGS expressions are the
9435 arguments that are to be passed to one of those
9436 functions, chosen following <tgmath.h> rules. */
9437 for (unsigned int j = 1; j < num_functions; j++)
9439 unsigned int this_nargs
9440 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9441 if (this_nargs == 0)
9443 expr.set_error ();
9444 goto out;
9446 if (this_nargs != nargs)
9448 error_at ((*cexpr_list)[j].get_location (),
9449 "argument %u of %<__builtin_tgmath%> has "
9450 "wrong number of arguments", j + 1);
9451 expr.set_error ();
9452 goto out;
9456 /* The functions all have the same number of arguments.
9457 Determine whether arguments and return types vary in
9458 ways permitted for <tgmath.h> functions. */
9459 /* The first entry in each of these vectors is for the
9460 return type, subsequent entries for parameter
9461 types. */
9462 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9463 auto_vec<tree> parm_first (nargs + 1);
9464 auto_vec<bool> parm_complex (nargs + 1);
9465 auto_vec<bool> parm_varies (nargs + 1);
9466 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9467 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9468 parm_first.quick_push (first_ret);
9469 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9470 parm_varies.quick_push (false);
9471 function_args_iterator iter;
9472 tree t;
9473 unsigned int argpos;
9474 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9476 if (t == void_type_node)
9477 break;
9478 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9479 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9480 parm_varies.quick_push (false);
9482 for (unsigned int j = 1; j < num_functions; j++)
9484 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9485 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9486 if (ret != parm_first[0])
9488 parm_varies[0] = true;
9489 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9490 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9492 error_at ((*cexpr_list)[0].get_location (),
9493 "invalid type-generic return type for "
9494 "argument %u of %<__builtin_tgmath%>",
9496 expr.set_error ();
9497 goto out;
9499 if (!SCALAR_FLOAT_TYPE_P (ret)
9500 && !COMPLEX_FLOAT_TYPE_P (ret))
9502 error_at ((*cexpr_list)[j].get_location (),
9503 "invalid type-generic return type for "
9504 "argument %u of %<__builtin_tgmath%>",
9505 j + 1);
9506 expr.set_error ();
9507 goto out;
9510 if (TREE_CODE (ret) == COMPLEX_TYPE)
9511 parm_complex[0] = true;
9512 argpos = 1;
9513 FOREACH_FUNCTION_ARGS (type, t, iter)
9515 if (t == void_type_node)
9516 break;
9517 t = TYPE_MAIN_VARIANT (t);
9518 if (t != parm_first[argpos])
9520 parm_varies[argpos] = true;
9521 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9522 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9524 error_at ((*cexpr_list)[0].get_location (),
9525 "invalid type-generic type for "
9526 "argument %u of argument %u of "
9527 "%<__builtin_tgmath%>", argpos, 1);
9528 expr.set_error ();
9529 goto out;
9531 if (!SCALAR_FLOAT_TYPE_P (t)
9532 && !COMPLEX_FLOAT_TYPE_P (t))
9534 error_at ((*cexpr_list)[j].get_location (),
9535 "invalid type-generic type for "
9536 "argument %u of argument %u of "
9537 "%<__builtin_tgmath%>", argpos, j + 1);
9538 expr.set_error ();
9539 goto out;
9542 if (TREE_CODE (t) == COMPLEX_TYPE)
9543 parm_complex[argpos] = true;
9544 argpos++;
9547 enum tgmath_parm_kind max_variation = tgmath_fixed;
9548 for (unsigned int j = 0; j <= nargs; j++)
9550 enum tgmath_parm_kind this_kind;
9551 if (parm_varies[j])
9553 if (parm_complex[j])
9554 max_variation = this_kind = tgmath_complex;
9555 else
9557 this_kind = tgmath_real;
9558 if (max_variation != tgmath_complex)
9559 max_variation = tgmath_real;
9562 else
9563 this_kind = tgmath_fixed;
9564 parm_kind.quick_push (this_kind);
9566 if (max_variation == tgmath_fixed)
9568 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9569 "all have the same type");
9570 expr.set_error ();
9571 break;
9574 /* Identify a parameter (not the return type) that varies,
9575 including with complex types if any variation includes
9576 complex types; there must be at least one such
9577 parameter. */
9578 unsigned int tgarg = 0;
9579 for (unsigned int j = 1; j <= nargs; j++)
9580 if (parm_kind[j] == max_variation)
9582 tgarg = j;
9583 break;
9585 if (tgarg == 0)
9587 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9588 "lack type-generic parameter");
9589 expr.set_error ();
9590 break;
9593 /* Determine the type of the relevant parameter for each
9594 function. */
9595 auto_vec<tree> tg_type (num_functions);
9596 for (unsigned int j = 0; j < num_functions; j++)
9598 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9599 argpos = 1;
9600 FOREACH_FUNCTION_ARGS (type, t, iter)
9602 if (argpos == tgarg)
9604 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9605 break;
9607 argpos++;
9611 /* Verify that the corresponding types are different for
9612 all the listed functions. Also determine whether all
9613 the types are complex, whether all the types are
9614 standard or binary, and whether all the types are
9615 decimal. */
9616 bool all_complex = true;
9617 bool all_binary = true;
9618 bool all_decimal = true;
9619 hash_set<tree> tg_types;
9620 FOR_EACH_VEC_ELT (tg_type, i, t)
9622 if (TREE_CODE (t) == COMPLEX_TYPE)
9623 all_decimal = false;
9624 else
9626 all_complex = false;
9627 if (DECIMAL_FLOAT_TYPE_P (t))
9628 all_binary = false;
9629 else
9630 all_decimal = false;
9632 if (tg_types.add (t))
9634 error_at ((*cexpr_list)[i].get_location (),
9635 "duplicate type-generic parameter type for "
9636 "function argument %u of %<__builtin_tgmath%>",
9637 i + 1);
9638 expr.set_error ();
9639 goto out;
9643 /* Verify that other parameters and the return type whose
9644 types vary have their types varying in the correct
9645 way. */
9646 for (unsigned int j = 0; j < num_functions; j++)
9648 tree exp_type = tg_type[j];
9649 tree exp_real_type = exp_type;
9650 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9651 exp_real_type = TREE_TYPE (exp_type);
9652 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9653 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9654 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9655 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9657 error_at ((*cexpr_list)[j].get_location (),
9658 "bad return type for function argument %u "
9659 "of %<__builtin_tgmath%>", j + 1);
9660 expr.set_error ();
9661 goto out;
9663 argpos = 1;
9664 FOREACH_FUNCTION_ARGS (type, t, iter)
9666 if (t == void_type_node)
9667 break;
9668 t = TYPE_MAIN_VARIANT (t);
9669 if ((parm_kind[argpos] == tgmath_complex
9670 && t != exp_type)
9671 || (parm_kind[argpos] == tgmath_real
9672 && t != exp_real_type))
9674 error_at ((*cexpr_list)[j].get_location (),
9675 "bad type for argument %u of "
9676 "function argument %u of "
9677 "%<__builtin_tgmath%>", argpos, j + 1);
9678 expr.set_error ();
9679 goto out;
9681 argpos++;
9685 /* The functions listed are a valid set of functions for a
9686 <tgmath.h> macro to select between. Identify the
9687 matching function, if any. First, the argument types
9688 must be combined following <tgmath.h> rules. Integer
9689 types are treated as _Decimal64 if any type-generic
9690 argument is decimal, or if the only alternatives for
9691 type-generic arguments are of decimal types, and are
9692 otherwise treated as double (or _Complex double for
9693 complex integer types, or _Float64 or _Complex _Float64
9694 if all the return types are the same _FloatN or
9695 _FloatNx type). After that adjustment, types are
9696 combined following the usual arithmetic conversions.
9697 If the function only accepts complex arguments, a
9698 complex type is produced. */
9699 bool arg_complex = all_complex;
9700 bool arg_binary = all_binary;
9701 bool arg_int_decimal = all_decimal;
9702 for (unsigned int j = 1; j <= nargs; j++)
9704 if (parm_kind[j] == tgmath_fixed)
9705 continue;
9706 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9707 tree type = TREE_TYPE (ce->value);
9708 if (!INTEGRAL_TYPE_P (type)
9709 && !SCALAR_FLOAT_TYPE_P (type)
9710 && TREE_CODE (type) != COMPLEX_TYPE)
9712 error_at (ce->get_location (),
9713 "invalid type of argument %u of type-generic "
9714 "function", j);
9715 expr.set_error ();
9716 goto out;
9718 if (DECIMAL_FLOAT_TYPE_P (type))
9720 arg_int_decimal = true;
9721 if (all_complex)
9723 error_at (ce->get_location (),
9724 "decimal floating-point argument %u to "
9725 "complex-only type-generic function", j);
9726 expr.set_error ();
9727 goto out;
9729 else if (all_binary)
9731 error_at (ce->get_location (),
9732 "decimal floating-point argument %u to "
9733 "binary-only type-generic function", j);
9734 expr.set_error ();
9735 goto out;
9737 else if (arg_complex)
9739 error_at (ce->get_location (),
9740 "both complex and decimal floating-point "
9741 "arguments to type-generic function");
9742 expr.set_error ();
9743 goto out;
9745 else if (arg_binary)
9747 error_at (ce->get_location (),
9748 "both binary and decimal floating-point "
9749 "arguments to type-generic function");
9750 expr.set_error ();
9751 goto out;
9754 else if (TREE_CODE (type) == COMPLEX_TYPE)
9756 arg_complex = true;
9757 if (COMPLEX_FLOAT_TYPE_P (type))
9758 arg_binary = true;
9759 if (all_decimal)
9761 error_at (ce->get_location (),
9762 "complex argument %u to "
9763 "decimal-only type-generic function", j);
9764 expr.set_error ();
9765 goto out;
9767 else if (arg_int_decimal)
9769 error_at (ce->get_location (),
9770 "both complex and decimal floating-point "
9771 "arguments to type-generic function");
9772 expr.set_error ();
9773 goto out;
9776 else if (SCALAR_FLOAT_TYPE_P (type))
9778 arg_binary = true;
9779 if (all_decimal)
9781 error_at (ce->get_location (),
9782 "binary argument %u to "
9783 "decimal-only type-generic function", j);
9784 expr.set_error ();
9785 goto out;
9787 else if (arg_int_decimal)
9789 error_at (ce->get_location (),
9790 "both binary and decimal floating-point "
9791 "arguments to type-generic function");
9792 expr.set_error ();
9793 goto out;
9797 /* For a macro rounding its result to a narrower type, map
9798 integer types to _Float64 not double if the return type
9799 is a _FloatN or _FloatNx type. */
9800 bool arg_int_float64 = false;
9801 if (parm_kind[0] == tgmath_fixed
9802 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9803 && float64_type_node != NULL_TREE)
9804 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9805 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9807 arg_int_float64 = true;
9808 break;
9810 tree arg_real = NULL_TREE;
9811 for (unsigned int j = 1; j <= nargs; j++)
9813 if (parm_kind[j] == tgmath_fixed)
9814 continue;
9815 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9816 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9817 if (TREE_CODE (type) == COMPLEX_TYPE)
9818 type = TREE_TYPE (type);
9819 if (INTEGRAL_TYPE_P (type))
9820 type = (arg_int_decimal
9821 ? dfloat64_type_node
9822 : arg_int_float64
9823 ? float64_type_node
9824 : double_type_node);
9825 if (arg_real == NULL_TREE)
9826 arg_real = type;
9827 else
9828 arg_real = common_type (arg_real, type);
9829 if (arg_real == error_mark_node)
9831 expr.set_error ();
9832 goto out;
9835 tree arg_type = (arg_complex
9836 ? build_complex_type (arg_real)
9837 : arg_real);
9839 /* Look for a function to call with type-generic parameter
9840 type ARG_TYPE. */
9841 c_expr_t *fn = NULL;
9842 for (unsigned int j = 0; j < num_functions; j++)
9844 if (tg_type[j] == arg_type)
9846 fn = &(*cexpr_list)[j];
9847 break;
9850 if (fn == NULL
9851 && parm_kind[0] == tgmath_fixed
9852 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9854 /* Presume this is a macro that rounds its result to a
9855 narrower type, and look for the first function with
9856 at least the range and precision of the argument
9857 type. */
9858 for (unsigned int j = 0; j < num_functions; j++)
9860 if (arg_complex
9861 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9862 continue;
9863 tree real_tg_type = (arg_complex
9864 ? TREE_TYPE (tg_type[j])
9865 : tg_type[j]);
9866 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9867 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9868 continue;
9869 scalar_float_mode arg_mode
9870 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9871 scalar_float_mode tg_mode
9872 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9873 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9874 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9875 if (arg_fmt->b == tg_fmt->b
9876 && arg_fmt->p <= tg_fmt->p
9877 && arg_fmt->emax <= tg_fmt->emax
9878 && (arg_fmt->emin - arg_fmt->p
9879 >= tg_fmt->emin - tg_fmt->p))
9881 fn = &(*cexpr_list)[j];
9882 break;
9886 if (fn == NULL)
9888 error_at (loc, "no matching function for type-generic call");
9889 expr.set_error ();
9890 break;
9893 /* Construct a call to FN. */
9894 vec<tree, va_gc> *args;
9895 vec_alloc (args, nargs);
9896 vec<tree, va_gc> *origtypes;
9897 vec_alloc (origtypes, nargs);
9898 auto_vec<location_t> arg_loc (nargs);
9899 for (unsigned int j = 0; j < nargs; j++)
9901 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9902 args->quick_push (ce->value);
9903 arg_loc.quick_push (ce->get_location ());
9904 origtypes->quick_push (ce->original_type);
9906 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9907 args, origtypes);
9908 set_c_expr_source_range (&expr, loc, close_paren_loc);
9909 break;
9911 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9913 vec<c_expr_t, va_gc> *cexpr_list;
9914 c_expr_t *e2_p;
9915 tree chain_value;
9916 location_t close_paren_loc;
9918 c_parser_consume_token (parser);
9919 if (!c_parser_get_builtin_args (parser,
9920 "__builtin_call_with_static_chain",
9921 &cexpr_list, false,
9922 &close_paren_loc))
9924 expr.set_error ();
9925 break;
9927 if (vec_safe_length (cexpr_list) != 2)
9929 error_at (loc, "wrong number of arguments to "
9930 "%<__builtin_call_with_static_chain%>");
9931 expr.set_error ();
9932 break;
9935 expr = (*cexpr_list)[0];
9936 e2_p = &(*cexpr_list)[1];
9937 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9938 chain_value = e2_p->value;
9939 mark_exp_read (chain_value);
9941 if (TREE_CODE (expr.value) != CALL_EXPR)
9942 error_at (loc, "first argument to "
9943 "%<__builtin_call_with_static_chain%> "
9944 "must be a call expression");
9945 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9946 error_at (loc, "second argument to "
9947 "%<__builtin_call_with_static_chain%> "
9948 "must be a pointer type");
9949 else
9950 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9951 set_c_expr_source_range (&expr, loc, close_paren_loc);
9952 break;
9954 case RID_BUILTIN_COMPLEX:
9956 vec<c_expr_t, va_gc> *cexpr_list;
9957 c_expr_t *e1_p, *e2_p;
9958 location_t close_paren_loc;
9960 c_parser_consume_token (parser);
9961 if (!c_parser_get_builtin_args (parser,
9962 "__builtin_complex",
9963 &cexpr_list, false,
9964 &close_paren_loc))
9966 expr.set_error ();
9967 break;
9970 if (vec_safe_length (cexpr_list) != 2)
9972 error_at (loc, "wrong number of arguments to "
9973 "%<__builtin_complex%>");
9974 expr.set_error ();
9975 break;
9978 e1_p = &(*cexpr_list)[0];
9979 e2_p = &(*cexpr_list)[1];
9981 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9982 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9983 e1_p->value = convert (TREE_TYPE (e1_p->value),
9984 TREE_OPERAND (e1_p->value, 0));
9985 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9986 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9987 e2_p->value = convert (TREE_TYPE (e2_p->value),
9988 TREE_OPERAND (e2_p->value, 0));
9989 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9990 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9991 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9992 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9994 error_at (loc, "%<__builtin_complex%> operand "
9995 "not of real binary floating-point type");
9996 expr.set_error ();
9997 break;
9999 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10000 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10002 error_at (loc,
10003 "%<__builtin_complex%> operands of different types");
10004 expr.set_error ();
10005 break;
10007 pedwarn_c90 (loc, OPT_Wpedantic,
10008 "ISO C90 does not support complex types");
10009 expr.value = build2_loc (loc, COMPLEX_EXPR,
10010 build_complex_type
10011 (TYPE_MAIN_VARIANT
10012 (TREE_TYPE (e1_p->value))),
10013 e1_p->value, e2_p->value);
10014 set_c_expr_source_range (&expr, loc, close_paren_loc);
10015 break;
10017 case RID_BUILTIN_SHUFFLE:
10019 vec<c_expr_t, va_gc> *cexpr_list;
10020 unsigned int i;
10021 c_expr_t *p;
10022 location_t close_paren_loc;
10024 c_parser_consume_token (parser);
10025 if (!c_parser_get_builtin_args (parser,
10026 "__builtin_shuffle",
10027 &cexpr_list, false,
10028 &close_paren_loc))
10030 expr.set_error ();
10031 break;
10034 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10035 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10037 if (vec_safe_length (cexpr_list) == 2)
10038 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10039 NULL_TREE,
10040 (*cexpr_list)[1].value);
10042 else if (vec_safe_length (cexpr_list) == 3)
10043 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10044 (*cexpr_list)[1].value,
10045 (*cexpr_list)[2].value);
10046 else
10048 error_at (loc, "wrong number of arguments to "
10049 "%<__builtin_shuffle%>");
10050 expr.set_error ();
10052 set_c_expr_source_range (&expr, loc, close_paren_loc);
10053 break;
10055 case RID_BUILTIN_SHUFFLEVECTOR:
10057 vec<c_expr_t, va_gc> *cexpr_list;
10058 unsigned int i;
10059 c_expr_t *p;
10060 location_t close_paren_loc;
10062 c_parser_consume_token (parser);
10063 if (!c_parser_get_builtin_args (parser,
10064 "__builtin_shufflevector",
10065 &cexpr_list, false,
10066 &close_paren_loc))
10068 expr.set_error ();
10069 break;
10072 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10073 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10075 if (vec_safe_length (cexpr_list) < 3)
10077 error_at (loc, "wrong number of arguments to "
10078 "%<__builtin_shuffle%>");
10079 expr.set_error ();
10081 else
10083 auto_vec<tree, 16> mask;
10084 for (i = 2; i < cexpr_list->length (); ++i)
10085 mask.safe_push ((*cexpr_list)[i].value);
10086 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10087 (*cexpr_list)[1].value,
10088 mask);
10090 set_c_expr_source_range (&expr, loc, close_paren_loc);
10091 break;
10093 case RID_BUILTIN_CONVERTVECTOR:
10095 location_t start_loc = loc;
10096 c_parser_consume_token (parser);
10097 matching_parens parens;
10098 if (!parens.require_open (parser))
10100 expr.set_error ();
10101 break;
10103 e1 = c_parser_expr_no_commas (parser, NULL);
10104 mark_exp_read (e1.value);
10105 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10107 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10108 expr.set_error ();
10109 break;
10111 loc = c_parser_peek_token (parser)->location;
10112 t1 = c_parser_type_name (parser);
10113 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10114 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10115 "expected %<)%>");
10116 if (t1 == NULL)
10117 expr.set_error ();
10118 else
10120 tree type_expr = NULL_TREE;
10121 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10122 groktypename (t1, &type_expr,
10123 NULL));
10124 set_c_expr_source_range (&expr, start_loc, end_loc);
10127 break;
10128 case RID_BUILTIN_ASSOC_BARRIER:
10130 location_t start_loc = loc;
10131 c_parser_consume_token (parser);
10132 matching_parens parens;
10133 if (!parens.require_open (parser))
10135 expr.set_error ();
10136 break;
10138 e1 = c_parser_expr_no_commas (parser, NULL);
10139 mark_exp_read (e1.value);
10140 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10141 parens.skip_until_found_close (parser);
10142 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10143 set_c_expr_source_range (&expr, start_loc, end_loc);
10145 break;
10146 case RID_AT_SELECTOR:
10148 gcc_assert (c_dialect_objc ());
10149 c_parser_consume_token (parser);
10150 matching_parens parens;
10151 if (!parens.require_open (parser))
10153 expr.set_error ();
10154 break;
10156 tree sel = c_parser_objc_selector_arg (parser);
10157 location_t close_loc = c_parser_peek_token (parser)->location;
10158 parens.skip_until_found_close (parser);
10159 expr.value = objc_build_selector_expr (loc, sel);
10160 set_c_expr_source_range (&expr, loc, close_loc);
10162 break;
10163 case RID_AT_PROTOCOL:
10165 gcc_assert (c_dialect_objc ());
10166 c_parser_consume_token (parser);
10167 matching_parens parens;
10168 if (!parens.require_open (parser))
10170 expr.set_error ();
10171 break;
10173 if (c_parser_next_token_is_not (parser, CPP_NAME))
10175 c_parser_error (parser, "expected identifier");
10176 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10177 expr.set_error ();
10178 break;
10180 tree id = c_parser_peek_token (parser)->value;
10181 c_parser_consume_token (parser);
10182 location_t close_loc = c_parser_peek_token (parser)->location;
10183 parens.skip_until_found_close (parser);
10184 expr.value = objc_build_protocol_expr (id);
10185 set_c_expr_source_range (&expr, loc, close_loc);
10187 break;
10188 case RID_AT_ENCODE:
10190 /* Extension to support C-structures in the archiver. */
10191 gcc_assert (c_dialect_objc ());
10192 c_parser_consume_token (parser);
10193 matching_parens parens;
10194 if (!parens.require_open (parser))
10196 expr.set_error ();
10197 break;
10199 t1 = c_parser_type_name (parser);
10200 if (t1 == NULL)
10202 expr.set_error ();
10203 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10204 break;
10206 location_t close_loc = c_parser_peek_token (parser)->location;
10207 parens.skip_until_found_close (parser);
10208 tree type = groktypename (t1, NULL, NULL);
10209 expr.value = objc_build_encode_expr (type);
10210 set_c_expr_source_range (&expr, loc, close_loc);
10212 break;
10213 case RID_GENERIC:
10214 expr = c_parser_generic_selection (parser);
10215 break;
10216 case RID_OMP_ALL_MEMORY:
10217 gcc_assert (flag_openmp);
10218 c_parser_consume_token (parser);
10219 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
10220 "%<depend%> clause");
10221 expr.set_error ();
10222 break;
10223 default:
10224 c_parser_error (parser, "expected expression");
10225 expr.set_error ();
10226 break;
10228 break;
10229 case CPP_OPEN_SQUARE:
10230 if (c_dialect_objc ())
10232 tree receiver, args;
10233 c_parser_consume_token (parser);
10234 receiver = c_parser_objc_receiver (parser);
10235 args = c_parser_objc_message_args (parser);
10236 location_t close_loc = c_parser_peek_token (parser)->location;
10237 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10238 "expected %<]%>");
10239 expr.value = objc_build_message_expr (receiver, args);
10240 set_c_expr_source_range (&expr, loc, close_loc);
10241 break;
10243 /* Else fall through to report error. */
10244 /* FALLTHRU */
10245 default:
10246 c_parser_error (parser, "expected expression");
10247 expr.set_error ();
10248 break;
10250 out:
10251 return c_parser_postfix_expression_after_primary
10252 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10255 /* Parse a postfix expression after a parenthesized type name: the
10256 brace-enclosed initializer of a compound literal, possibly followed
10257 by some postfix operators. This is separate because it is not
10258 possible to tell until after the type name whether a cast
10259 expression has a cast or a compound literal, or whether the operand
10260 of sizeof is a parenthesized type name or starts with a compound
10261 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10262 location of the first token after the parentheses around the type
10263 name. */
10265 static struct c_expr
10266 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10267 struct c_type_name *type_name,
10268 location_t type_loc)
10270 tree type;
10271 struct c_expr init;
10272 bool non_const;
10273 struct c_expr expr;
10274 location_t start_loc;
10275 tree type_expr = NULL_TREE;
10276 bool type_expr_const = true;
10277 check_compound_literal_type (type_loc, type_name);
10278 rich_location richloc (line_table, type_loc);
10279 start_init (NULL_TREE, NULL, 0, &richloc);
10280 type = groktypename (type_name, &type_expr, &type_expr_const);
10281 start_loc = c_parser_peek_token (parser)->location;
10282 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10284 error_at (type_loc, "compound literal has variable size");
10285 type = error_mark_node;
10287 init = c_parser_braced_init (parser, type, false, NULL);
10288 finish_init ();
10289 maybe_warn_string_init (type_loc, type, init);
10291 if (type != error_mark_node
10292 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10293 && current_function_decl)
10295 error ("compound literal qualified by address-space qualifier");
10296 type = error_mark_node;
10299 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10300 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10301 ? CONSTRUCTOR_NON_CONST (init.value)
10302 : init.original_code == C_MAYBE_CONST_EXPR);
10303 non_const |= !type_expr_const;
10304 unsigned int alignas_align = 0;
10305 if (type != error_mark_node
10306 && type_name->specs->align_log != -1)
10308 alignas_align = 1U << type_name->specs->align_log;
10309 if (alignas_align < min_align_of_type (type))
10311 error_at (type_name->specs->locations[cdw_alignas],
10312 "%<_Alignas%> specifiers cannot reduce "
10313 "alignment of compound literal");
10314 alignas_align = 0;
10317 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10318 alignas_align);
10319 set_c_expr_source_range (&expr, init.src_range);
10320 expr.original_code = ERROR_MARK;
10321 expr.original_type = NULL;
10322 if (type != error_mark_node
10323 && expr.value != error_mark_node
10324 && type_expr)
10326 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10328 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10329 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10331 else
10333 gcc_assert (!non_const);
10334 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10335 type_expr, expr.value);
10338 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10341 /* Callback function for sizeof_pointer_memaccess_warning to compare
10342 types. */
10344 static bool
10345 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10347 return comptypes (type1, type2) == 1;
10350 /* Warn for patterns where abs-like function appears to be used incorrectly,
10351 gracefully ignore any non-abs-like function. The warning location should
10352 be LOC. FNDECL is the declaration of called function, it must be a
10353 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10354 call. */
10356 static void
10357 warn_for_abs (location_t loc, tree fndecl, tree arg)
10359 /* Avoid warning in unreachable subexpressions. */
10360 if (c_inhibit_evaluation_warnings)
10361 return;
10363 tree atype = TREE_TYPE (arg);
10365 /* Casts from pointers (and thus arrays and fndecls) will generate
10366 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10367 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10368 types and possibly other exotic types. */
10369 if (!INTEGRAL_TYPE_P (atype)
10370 && !SCALAR_FLOAT_TYPE_P (atype)
10371 && TREE_CODE (atype) != COMPLEX_TYPE)
10372 return;
10374 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10376 switch (fcode)
10378 case BUILT_IN_ABS:
10379 case BUILT_IN_LABS:
10380 case BUILT_IN_LLABS:
10381 case BUILT_IN_IMAXABS:
10382 if (!INTEGRAL_TYPE_P (atype))
10384 if (SCALAR_FLOAT_TYPE_P (atype))
10385 warning_at (loc, OPT_Wabsolute_value,
10386 "using integer absolute value function %qD when "
10387 "argument is of floating-point type %qT",
10388 fndecl, atype);
10389 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10390 warning_at (loc, OPT_Wabsolute_value,
10391 "using integer absolute value function %qD when "
10392 "argument is of complex type %qT", fndecl, atype);
10393 else
10394 gcc_unreachable ();
10395 return;
10397 if (TYPE_UNSIGNED (atype))
10398 warning_at (loc, OPT_Wabsolute_value,
10399 "taking the absolute value of unsigned type %qT "
10400 "has no effect", atype);
10401 break;
10403 CASE_FLT_FN (BUILT_IN_FABS):
10404 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10405 if (!SCALAR_FLOAT_TYPE_P (atype)
10406 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10408 if (INTEGRAL_TYPE_P (atype))
10409 warning_at (loc, OPT_Wabsolute_value,
10410 "using floating-point absolute value function %qD "
10411 "when argument is of integer type %qT", fndecl, atype);
10412 else if (DECIMAL_FLOAT_TYPE_P (atype))
10413 warning_at (loc, OPT_Wabsolute_value,
10414 "using floating-point absolute value function %qD "
10415 "when argument is of decimal floating-point type %qT",
10416 fndecl, atype);
10417 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10418 warning_at (loc, OPT_Wabsolute_value,
10419 "using floating-point absolute value function %qD when "
10420 "argument is of complex type %qT", fndecl, atype);
10421 else
10422 gcc_unreachable ();
10423 return;
10425 break;
10427 CASE_FLT_FN (BUILT_IN_CABS):
10428 if (TREE_CODE (atype) != COMPLEX_TYPE)
10430 if (INTEGRAL_TYPE_P (atype))
10431 warning_at (loc, OPT_Wabsolute_value,
10432 "using complex absolute value function %qD when "
10433 "argument is of integer type %qT", fndecl, atype);
10434 else if (SCALAR_FLOAT_TYPE_P (atype))
10435 warning_at (loc, OPT_Wabsolute_value,
10436 "using complex absolute value function %qD when "
10437 "argument is of floating-point type %qT",
10438 fndecl, atype);
10439 else
10440 gcc_unreachable ();
10442 return;
10444 break;
10446 case BUILT_IN_FABSD32:
10447 case BUILT_IN_FABSD64:
10448 case BUILT_IN_FABSD128:
10449 if (!DECIMAL_FLOAT_TYPE_P (atype))
10451 if (INTEGRAL_TYPE_P (atype))
10452 warning_at (loc, OPT_Wabsolute_value,
10453 "using decimal floating-point absolute value "
10454 "function %qD when argument is of integer type %qT",
10455 fndecl, atype);
10456 else if (SCALAR_FLOAT_TYPE_P (atype))
10457 warning_at (loc, OPT_Wabsolute_value,
10458 "using decimal floating-point absolute value "
10459 "function %qD when argument is of floating-point "
10460 "type %qT", fndecl, atype);
10461 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10462 warning_at (loc, OPT_Wabsolute_value,
10463 "using decimal floating-point absolute value "
10464 "function %qD when argument is of complex type %qT",
10465 fndecl, atype);
10466 else
10467 gcc_unreachable ();
10468 return;
10470 break;
10472 default:
10473 return;
10476 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10477 return;
10479 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10480 if (TREE_CODE (atype) == COMPLEX_TYPE)
10482 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10483 atype = TREE_TYPE (atype);
10484 ftype = TREE_TYPE (ftype);
10487 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10488 warning_at (loc, OPT_Wabsolute_value,
10489 "absolute value function %qD given an argument of type %qT "
10490 "but has parameter of type %qT which may cause truncation "
10491 "of value", fndecl, atype, ftype);
10495 /* Parse a postfix expression after the initial primary or compound
10496 literal; that is, parse a series of postfix operators.
10498 EXPR_LOC is the location of the primary expression. */
10500 static struct c_expr
10501 c_parser_postfix_expression_after_primary (c_parser *parser,
10502 location_t expr_loc,
10503 struct c_expr expr)
10505 struct c_expr orig_expr;
10506 tree ident, idx;
10507 location_t sizeof_arg_loc[3], comp_loc;
10508 tree sizeof_arg[3];
10509 unsigned int literal_zero_mask;
10510 unsigned int i;
10511 vec<tree, va_gc> *exprlist;
10512 vec<tree, va_gc> *origtypes = NULL;
10513 vec<location_t> arg_loc = vNULL;
10514 location_t start;
10515 location_t finish;
10517 while (true)
10519 location_t op_loc = c_parser_peek_token (parser)->location;
10520 switch (c_parser_peek_token (parser)->type)
10522 case CPP_OPEN_SQUARE:
10523 /* Array reference. */
10524 c_parser_consume_token (parser);
10525 idx = c_parser_expression (parser).value;
10526 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10527 "expected %<]%>");
10528 start = expr.get_start ();
10529 finish = parser->tokens_buf[0].location;
10530 expr.value = build_array_ref (op_loc, expr.value, idx);
10531 set_c_expr_source_range (&expr, start, finish);
10532 expr.original_code = ERROR_MARK;
10533 expr.original_type = NULL;
10534 break;
10535 case CPP_OPEN_PAREN:
10536 /* Function call. */
10538 matching_parens parens;
10539 parens.consume_open (parser);
10540 for (i = 0; i < 3; i++)
10542 sizeof_arg[i] = NULL_TREE;
10543 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10545 literal_zero_mask = 0;
10546 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10547 exprlist = NULL;
10548 else
10549 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10550 sizeof_arg_loc, sizeof_arg,
10551 &arg_loc, &literal_zero_mask);
10552 parens.skip_until_found_close (parser);
10554 orig_expr = expr;
10555 mark_exp_read (expr.value);
10556 if (warn_sizeof_pointer_memaccess)
10557 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10558 expr.value, exprlist,
10559 sizeof_arg,
10560 sizeof_ptr_memacc_comptypes);
10561 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10563 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10564 && vec_safe_length (exprlist) == 3)
10566 tree arg0 = (*exprlist)[0];
10567 tree arg2 = (*exprlist)[2];
10568 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10570 if (warn_absolute_value
10571 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10572 && vec_safe_length (exprlist) == 1)
10573 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10576 start = expr.get_start ();
10577 finish = parser->tokens_buf[0].get_finish ();
10578 expr.value
10579 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10580 exprlist, origtypes);
10581 set_c_expr_source_range (&expr, start, finish);
10583 expr.original_code = ERROR_MARK;
10584 if (TREE_CODE (expr.value) == INTEGER_CST
10585 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10586 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10587 expr.original_code = C_MAYBE_CONST_EXPR;
10588 expr.original_type = NULL;
10589 if (exprlist)
10591 release_tree_vector (exprlist);
10592 release_tree_vector (origtypes);
10594 arg_loc.release ();
10595 break;
10596 case CPP_DOT:
10597 /* Structure element reference. */
10598 c_parser_consume_token (parser);
10599 expr = default_function_array_conversion (expr_loc, expr);
10600 if (c_parser_next_token_is (parser, CPP_NAME))
10602 c_token *comp_tok = c_parser_peek_token (parser);
10603 ident = comp_tok->value;
10604 comp_loc = comp_tok->location;
10606 else
10608 c_parser_error (parser, "expected identifier");
10609 expr.set_error ();
10610 expr.original_code = ERROR_MARK;
10611 expr.original_type = NULL;
10612 return expr;
10614 start = expr.get_start ();
10615 finish = c_parser_peek_token (parser)->get_finish ();
10616 c_parser_consume_token (parser);
10617 expr.value = build_component_ref (op_loc, expr.value, ident,
10618 comp_loc, UNKNOWN_LOCATION);
10619 set_c_expr_source_range (&expr, start, finish);
10620 expr.original_code = ERROR_MARK;
10621 if (TREE_CODE (expr.value) != COMPONENT_REF)
10622 expr.original_type = NULL;
10623 else
10625 /* Remember the original type of a bitfield. */
10626 tree field = TREE_OPERAND (expr.value, 1);
10627 if (TREE_CODE (field) != FIELD_DECL)
10628 expr.original_type = NULL;
10629 else
10630 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10632 break;
10633 case CPP_DEREF:
10634 /* Structure element reference. */
10635 c_parser_consume_token (parser);
10636 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10637 if (c_parser_next_token_is (parser, CPP_NAME))
10639 c_token *comp_tok = c_parser_peek_token (parser);
10640 ident = comp_tok->value;
10641 comp_loc = comp_tok->location;
10643 else
10645 c_parser_error (parser, "expected identifier");
10646 expr.set_error ();
10647 expr.original_code = ERROR_MARK;
10648 expr.original_type = NULL;
10649 return expr;
10651 start = expr.get_start ();
10652 finish = c_parser_peek_token (parser)->get_finish ();
10653 c_parser_consume_token (parser);
10654 expr.value = build_component_ref (op_loc,
10655 build_indirect_ref (op_loc,
10656 expr.value,
10657 RO_ARROW),
10658 ident, comp_loc,
10659 expr.get_location ());
10660 set_c_expr_source_range (&expr, start, finish);
10661 expr.original_code = ERROR_MARK;
10662 if (TREE_CODE (expr.value) != COMPONENT_REF)
10663 expr.original_type = NULL;
10664 else
10666 /* Remember the original type of a bitfield. */
10667 tree field = TREE_OPERAND (expr.value, 1);
10668 if (TREE_CODE (field) != FIELD_DECL)
10669 expr.original_type = NULL;
10670 else
10671 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10673 break;
10674 case CPP_PLUS_PLUS:
10675 /* Postincrement. */
10676 start = expr.get_start ();
10677 finish = c_parser_peek_token (parser)->get_finish ();
10678 c_parser_consume_token (parser);
10679 expr = default_function_array_read_conversion (expr_loc, expr);
10680 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10681 expr.value, false);
10682 set_c_expr_source_range (&expr, start, finish);
10683 expr.original_code = ERROR_MARK;
10684 expr.original_type = NULL;
10685 break;
10686 case CPP_MINUS_MINUS:
10687 /* Postdecrement. */
10688 start = expr.get_start ();
10689 finish = c_parser_peek_token (parser)->get_finish ();
10690 c_parser_consume_token (parser);
10691 expr = default_function_array_read_conversion (expr_loc, expr);
10692 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10693 expr.value, false);
10694 set_c_expr_source_range (&expr, start, finish);
10695 expr.original_code = ERROR_MARK;
10696 expr.original_type = NULL;
10697 break;
10698 default:
10699 return expr;
10704 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10706 expression:
10707 assignment-expression
10708 expression , assignment-expression
10711 static struct c_expr
10712 c_parser_expression (c_parser *parser)
10714 location_t tloc = c_parser_peek_token (parser)->location;
10715 struct c_expr expr;
10716 expr = c_parser_expr_no_commas (parser, NULL);
10717 if (c_parser_next_token_is (parser, CPP_COMMA))
10718 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10719 while (c_parser_next_token_is (parser, CPP_COMMA))
10721 struct c_expr next;
10722 tree lhsval;
10723 location_t loc = c_parser_peek_token (parser)->location;
10724 location_t expr_loc;
10725 c_parser_consume_token (parser);
10726 expr_loc = c_parser_peek_token (parser)->location;
10727 lhsval = expr.value;
10728 while (TREE_CODE (lhsval) == COMPOUND_EXPR
10729 || TREE_CODE (lhsval) == NOP_EXPR)
10731 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10732 lhsval = TREE_OPERAND (lhsval, 1);
10733 else
10734 lhsval = TREE_OPERAND (lhsval, 0);
10736 if (DECL_P (lhsval) || handled_component_p (lhsval))
10737 mark_exp_read (lhsval);
10738 next = c_parser_expr_no_commas (parser, NULL);
10739 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10740 expr.value = build_compound_expr (loc, expr.value, next.value);
10741 expr.original_code = COMPOUND_EXPR;
10742 expr.original_type = next.original_type;
10744 return expr;
10747 /* Parse an expression and convert functions or arrays to pointers and
10748 lvalues to rvalues. */
10750 static struct c_expr
10751 c_parser_expression_conv (c_parser *parser)
10753 struct c_expr expr;
10754 location_t loc = c_parser_peek_token (parser)->location;
10755 expr = c_parser_expression (parser);
10756 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10757 return expr;
10760 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10761 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10763 static inline void
10764 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10765 unsigned int idx)
10767 if (idx >= HOST_BITS_PER_INT)
10768 return;
10770 c_token *tok = c_parser_peek_token (parser);
10771 switch (tok->type)
10773 case CPP_NUMBER:
10774 case CPP_CHAR:
10775 case CPP_WCHAR:
10776 case CPP_CHAR16:
10777 case CPP_CHAR32:
10778 case CPP_UTF8CHAR:
10779 /* If a parameter is literal zero alone, remember it
10780 for -Wmemset-transposed-args warning. */
10781 if (integer_zerop (tok->value)
10782 && !TREE_OVERFLOW (tok->value)
10783 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10784 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10785 *literal_zero_mask |= 1U << idx;
10786 default:
10787 break;
10791 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10792 functions and arrays to pointers and lvalues to rvalues. If
10793 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10794 locations of function arguments into this vector.
10796 nonempty-expr-list:
10797 assignment-expression
10798 nonempty-expr-list , assignment-expression
10801 static vec<tree, va_gc> *
10802 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10803 vec<tree, va_gc> **p_orig_types,
10804 location_t *sizeof_arg_loc, tree *sizeof_arg,
10805 vec<location_t> *locations,
10806 unsigned int *literal_zero_mask)
10808 vec<tree, va_gc> *ret;
10809 vec<tree, va_gc> *orig_types;
10810 struct c_expr expr;
10811 unsigned int idx = 0;
10813 ret = make_tree_vector ();
10814 if (p_orig_types == NULL)
10815 orig_types = NULL;
10816 else
10817 orig_types = make_tree_vector ();
10819 if (literal_zero_mask)
10820 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10821 expr = c_parser_expr_no_commas (parser, NULL);
10822 if (convert_p)
10823 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10824 if (fold_p)
10825 expr.value = c_fully_fold (expr.value, false, NULL);
10826 ret->quick_push (expr.value);
10827 if (orig_types)
10828 orig_types->quick_push (expr.original_type);
10829 if (locations)
10830 locations->safe_push (expr.get_location ());
10831 if (sizeof_arg != NULL
10832 && (expr.original_code == SIZEOF_EXPR
10833 || expr.original_code == PAREN_SIZEOF_EXPR))
10835 sizeof_arg[0] = c_last_sizeof_arg;
10836 sizeof_arg_loc[0] = c_last_sizeof_loc;
10838 while (c_parser_next_token_is (parser, CPP_COMMA))
10840 c_parser_consume_token (parser);
10841 if (literal_zero_mask)
10842 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10843 expr = c_parser_expr_no_commas (parser, NULL);
10844 if (convert_p)
10845 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10846 true);
10847 if (fold_p)
10848 expr.value = c_fully_fold (expr.value, false, NULL);
10849 vec_safe_push (ret, expr.value);
10850 if (orig_types)
10851 vec_safe_push (orig_types, expr.original_type);
10852 if (locations)
10853 locations->safe_push (expr.get_location ());
10854 if (++idx < 3
10855 && sizeof_arg != NULL
10856 && (expr.original_code == SIZEOF_EXPR
10857 || expr.original_code == PAREN_SIZEOF_EXPR))
10859 sizeof_arg[idx] = c_last_sizeof_arg;
10860 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10863 if (orig_types)
10864 *p_orig_types = orig_types;
10865 return ret;
10868 /* Parse Objective-C-specific constructs. */
10870 /* Parse an objc-class-definition.
10872 objc-class-definition:
10873 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10874 objc-class-instance-variables[opt] objc-methodprotolist @end
10875 @implementation identifier objc-superclass[opt]
10876 objc-class-instance-variables[opt]
10877 @interface identifier ( identifier ) objc-protocol-refs[opt]
10878 objc-methodprotolist @end
10879 @interface identifier ( ) objc-protocol-refs[opt]
10880 objc-methodprotolist @end
10881 @implementation identifier ( identifier )
10883 objc-superclass:
10884 : identifier
10886 "@interface identifier (" must start "@interface identifier (
10887 identifier ) ...": objc-methodprotolist in the first production may
10888 not start with a parenthesized identifier as a declarator of a data
10889 definition with no declaration specifiers if the objc-superclass,
10890 objc-protocol-refs and objc-class-instance-variables are omitted. */
10892 static void
10893 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10895 bool iface_p;
10896 tree id1;
10897 tree superclass;
10898 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10899 iface_p = true;
10900 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10901 iface_p = false;
10902 else
10903 gcc_unreachable ();
10905 c_parser_consume_token (parser);
10906 if (c_parser_next_token_is_not (parser, CPP_NAME))
10908 c_parser_error (parser, "expected identifier");
10909 return;
10911 id1 = c_parser_peek_token (parser)->value;
10912 location_t loc1 = c_parser_peek_token (parser)->location;
10913 c_parser_consume_token (parser);
10914 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10916 /* We have a category or class extension. */
10917 tree id2;
10918 tree proto = NULL_TREE;
10919 matching_parens parens;
10920 parens.consume_open (parser);
10921 if (c_parser_next_token_is_not (parser, CPP_NAME))
10923 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10925 /* We have a class extension. */
10926 id2 = NULL_TREE;
10928 else
10930 c_parser_error (parser, "expected identifier or %<)%>");
10931 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10932 return;
10935 else
10937 id2 = c_parser_peek_token (parser)->value;
10938 c_parser_consume_token (parser);
10940 parens.skip_until_found_close (parser);
10941 if (!iface_p)
10943 objc_start_category_implementation (id1, id2);
10944 return;
10946 if (c_parser_next_token_is (parser, CPP_LESS))
10947 proto = c_parser_objc_protocol_refs (parser);
10948 objc_start_category_interface (id1, id2, proto, attributes);
10949 c_parser_objc_methodprotolist (parser);
10950 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10951 objc_finish_interface ();
10952 return;
10954 if (c_parser_next_token_is (parser, CPP_COLON))
10956 c_parser_consume_token (parser);
10957 if (c_parser_next_token_is_not (parser, CPP_NAME))
10959 c_parser_error (parser, "expected identifier");
10960 return;
10962 superclass = c_parser_peek_token (parser)->value;
10963 c_parser_consume_token (parser);
10965 else
10966 superclass = NULL_TREE;
10967 if (iface_p)
10969 tree proto = NULL_TREE;
10970 if (c_parser_next_token_is (parser, CPP_LESS))
10971 proto = c_parser_objc_protocol_refs (parser);
10972 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
10974 else
10975 objc_start_class_implementation (id1, superclass);
10976 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10977 c_parser_objc_class_instance_variables (parser);
10978 if (iface_p)
10980 objc_continue_interface ();
10981 c_parser_objc_methodprotolist (parser);
10982 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10983 objc_finish_interface ();
10985 else
10987 objc_continue_implementation ();
10988 return;
10992 /* Parse objc-class-instance-variables.
10994 objc-class-instance-variables:
10995 { objc-instance-variable-decl-list[opt] }
10997 objc-instance-variable-decl-list:
10998 objc-visibility-spec
10999 objc-instance-variable-decl ;
11001 objc-instance-variable-decl-list objc-visibility-spec
11002 objc-instance-variable-decl-list objc-instance-variable-decl ;
11003 objc-instance-variable-decl-list ;
11005 objc-visibility-spec:
11006 @private
11007 @protected
11008 @public
11010 objc-instance-variable-decl:
11011 struct-declaration
11014 static void
11015 c_parser_objc_class_instance_variables (c_parser *parser)
11017 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
11018 c_parser_consume_token (parser);
11019 while (c_parser_next_token_is_not (parser, CPP_EOF))
11021 tree decls;
11022 /* Parse any stray semicolon. */
11023 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11025 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11026 "extra semicolon");
11027 c_parser_consume_token (parser);
11028 continue;
11030 /* Stop if at the end of the instance variables. */
11031 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11033 c_parser_consume_token (parser);
11034 break;
11036 /* Parse any objc-visibility-spec. */
11037 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11039 c_parser_consume_token (parser);
11040 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11041 continue;
11043 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11045 c_parser_consume_token (parser);
11046 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11047 continue;
11049 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11051 c_parser_consume_token (parser);
11052 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11053 continue;
11055 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11057 c_parser_consume_token (parser);
11058 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11059 continue;
11061 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11063 c_parser_pragma (parser, pragma_external, NULL);
11064 continue;
11067 /* Parse some comma-separated declarations. */
11068 decls = c_parser_struct_declaration (parser);
11069 if (decls == NULL)
11071 /* There is a syntax error. We want to skip the offending
11072 tokens up to the next ';' (included) or '}'
11073 (excluded). */
11075 /* First, skip manually a ')' or ']'. This is because they
11076 reduce the nesting level, so c_parser_skip_until_found()
11077 wouldn't be able to skip past them. */
11078 c_token *token = c_parser_peek_token (parser);
11079 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11080 c_parser_consume_token (parser);
11082 /* Then, do the standard skipping. */
11083 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11085 /* We hopefully recovered. Start normal parsing again. */
11086 parser->error = false;
11087 continue;
11089 else
11091 /* Comma-separated instance variables are chained together
11092 in reverse order; add them one by one. */
11093 tree ivar = nreverse (decls);
11094 for (; ivar; ivar = DECL_CHAIN (ivar))
11095 objc_add_instance_variable (copy_node (ivar));
11097 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11101 /* Parse an objc-class-declaration.
11103 objc-class-declaration:
11104 @class identifier-list ;
11107 static void
11108 c_parser_objc_class_declaration (c_parser *parser)
11110 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11111 c_parser_consume_token (parser);
11112 /* Any identifiers, including those declared as type names, are OK
11113 here. */
11114 while (true)
11116 tree id;
11117 if (c_parser_next_token_is_not (parser, CPP_NAME))
11119 c_parser_error (parser, "expected identifier");
11120 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11121 parser->error = false;
11122 return;
11124 id = c_parser_peek_token (parser)->value;
11125 objc_declare_class (id);
11126 c_parser_consume_token (parser);
11127 if (c_parser_next_token_is (parser, CPP_COMMA))
11128 c_parser_consume_token (parser);
11129 else
11130 break;
11132 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11135 /* Parse an objc-alias-declaration.
11137 objc-alias-declaration:
11138 @compatibility_alias identifier identifier ;
11141 static void
11142 c_parser_objc_alias_declaration (c_parser *parser)
11144 tree id1, id2;
11145 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11146 c_parser_consume_token (parser);
11147 if (c_parser_next_token_is_not (parser, CPP_NAME))
11149 c_parser_error (parser, "expected identifier");
11150 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11151 return;
11153 id1 = c_parser_peek_token (parser)->value;
11154 c_parser_consume_token (parser);
11155 if (c_parser_next_token_is_not (parser, CPP_NAME))
11157 c_parser_error (parser, "expected identifier");
11158 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11159 return;
11161 id2 = c_parser_peek_token (parser)->value;
11162 c_parser_consume_token (parser);
11163 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11164 objc_declare_alias (id1, id2);
11167 /* Parse an objc-protocol-definition.
11169 objc-protocol-definition:
11170 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11171 @protocol identifier-list ;
11173 "@protocol identifier ;" should be resolved as "@protocol
11174 identifier-list ;": objc-methodprotolist may not start with a
11175 semicolon in the first alternative if objc-protocol-refs are
11176 omitted. */
11178 static void
11179 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11181 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11183 c_parser_consume_token (parser);
11184 if (c_parser_next_token_is_not (parser, CPP_NAME))
11186 c_parser_error (parser, "expected identifier");
11187 return;
11189 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11190 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11192 /* Any identifiers, including those declared as type names, are
11193 OK here. */
11194 while (true)
11196 tree id;
11197 if (c_parser_next_token_is_not (parser, CPP_NAME))
11199 c_parser_error (parser, "expected identifier");
11200 break;
11202 id = c_parser_peek_token (parser)->value;
11203 objc_declare_protocol (id, attributes);
11204 c_parser_consume_token (parser);
11205 if (c_parser_next_token_is (parser, CPP_COMMA))
11206 c_parser_consume_token (parser);
11207 else
11208 break;
11210 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11212 else
11214 tree id = c_parser_peek_token (parser)->value;
11215 tree proto = NULL_TREE;
11216 c_parser_consume_token (parser);
11217 if (c_parser_next_token_is (parser, CPP_LESS))
11218 proto = c_parser_objc_protocol_refs (parser);
11219 parser->objc_pq_context = true;
11220 objc_start_protocol (id, proto, attributes);
11221 c_parser_objc_methodprotolist (parser);
11222 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11223 parser->objc_pq_context = false;
11224 objc_finish_interface ();
11228 /* Parse an objc-method-type.
11230 objc-method-type:
11234 Return true if it is a class method (+) and false if it is
11235 an instance method (-).
11237 static inline bool
11238 c_parser_objc_method_type (c_parser *parser)
11240 switch (c_parser_peek_token (parser)->type)
11242 case CPP_PLUS:
11243 c_parser_consume_token (parser);
11244 return true;
11245 case CPP_MINUS:
11246 c_parser_consume_token (parser);
11247 return false;
11248 default:
11249 gcc_unreachable ();
11253 /* Parse an objc-method-definition.
11255 objc-method-definition:
11256 objc-method-type objc-method-decl ;[opt] compound-statement
11259 static void
11260 c_parser_objc_method_definition (c_parser *parser)
11262 bool is_class_method = c_parser_objc_method_type (parser);
11263 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11264 parser->objc_pq_context = true;
11265 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11266 &expr);
11267 if (decl == error_mark_node)
11268 return; /* Bail here. */
11270 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11272 c_parser_consume_token (parser);
11273 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11274 "extra semicolon in method definition specified");
11277 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11279 c_parser_error (parser, "expected %<{%>");
11280 return;
11283 parser->objc_pq_context = false;
11284 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11286 add_stmt (c_parser_compound_statement (parser));
11287 objc_finish_method_definition (current_function_decl);
11289 else
11291 /* This code is executed when we find a method definition
11292 outside of an @implementation context (or invalid for other
11293 reasons). Parse the method (to keep going) but do not emit
11294 any code.
11296 c_parser_compound_statement (parser);
11300 /* Parse an objc-methodprotolist.
11302 objc-methodprotolist:
11303 empty
11304 objc-methodprotolist objc-methodproto
11305 objc-methodprotolist declaration
11306 objc-methodprotolist ;
11307 @optional
11308 @required
11310 The declaration is a data definition, which may be missing
11311 declaration specifiers under the same rules and diagnostics as
11312 other data definitions outside functions, and the stray semicolon
11313 is diagnosed the same way as a stray semicolon outside a
11314 function. */
11316 static void
11317 c_parser_objc_methodprotolist (c_parser *parser)
11319 while (true)
11321 /* The list is terminated by @end. */
11322 switch (c_parser_peek_token (parser)->type)
11324 case CPP_SEMICOLON:
11325 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11326 "ISO C does not allow extra %<;%> outside of a function");
11327 c_parser_consume_token (parser);
11328 break;
11329 case CPP_PLUS:
11330 case CPP_MINUS:
11331 c_parser_objc_methodproto (parser);
11332 break;
11333 case CPP_PRAGMA:
11334 c_parser_pragma (parser, pragma_external, NULL);
11335 break;
11336 case CPP_EOF:
11337 return;
11338 default:
11339 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11340 return;
11341 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11342 c_parser_objc_at_property_declaration (parser);
11343 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11345 objc_set_method_opt (true);
11346 c_parser_consume_token (parser);
11348 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11350 objc_set_method_opt (false);
11351 c_parser_consume_token (parser);
11353 else
11354 c_parser_declaration_or_fndef (parser, false, false, true,
11355 false, true);
11356 break;
11361 /* Parse an objc-methodproto.
11363 objc-methodproto:
11364 objc-method-type objc-method-decl ;
11367 static void
11368 c_parser_objc_methodproto (c_parser *parser)
11370 bool is_class_method = c_parser_objc_method_type (parser);
11371 tree decl, attributes = NULL_TREE;
11373 /* Remember protocol qualifiers in prototypes. */
11374 parser->objc_pq_context = true;
11375 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11376 NULL);
11377 /* Forget protocol qualifiers now. */
11378 parser->objc_pq_context = false;
11380 /* Do not allow the presence of attributes to hide an erroneous
11381 method implementation in the interface section. */
11382 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11384 c_parser_error (parser, "expected %<;%>");
11385 return;
11388 if (decl != error_mark_node)
11389 objc_add_method_declaration (is_class_method, decl, attributes);
11391 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11394 /* If we are at a position that method attributes may be present, check that
11395 there are not any parsed already (a syntax error) and then collect any
11396 specified at the current location. Finally, if new attributes were present,
11397 check that the next token is legal ( ';' for decls and '{' for defs). */
11399 static bool
11400 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11402 bool bad = false;
11403 if (*attributes)
11405 c_parser_error (parser,
11406 "method attributes must be specified at the end only");
11407 *attributes = NULL_TREE;
11408 bad = true;
11411 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11412 *attributes = c_parser_gnu_attributes (parser);
11414 /* If there were no attributes here, just report any earlier error. */
11415 if (*attributes == NULL_TREE || bad)
11416 return bad;
11418 /* If the attributes are followed by a ; or {, then just report any earlier
11419 error. */
11420 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11421 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11422 return bad;
11424 /* We've got attributes, but not at the end. */
11425 c_parser_error (parser,
11426 "expected %<;%> or %<{%> after method attribute definition");
11427 return true;
11430 /* Parse an objc-method-decl.
11432 objc-method-decl:
11433 ( objc-type-name ) objc-selector
11434 objc-selector
11435 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11436 objc-keyword-selector objc-optparmlist
11437 gnu-attributes
11439 objc-keyword-selector:
11440 objc-keyword-decl
11441 objc-keyword-selector objc-keyword-decl
11443 objc-keyword-decl:
11444 objc-selector : ( objc-type-name ) identifier
11445 objc-selector : identifier
11446 : ( objc-type-name ) identifier
11447 : identifier
11449 objc-optparmlist:
11450 objc-optparms objc-optellipsis
11452 objc-optparms:
11453 empty
11454 objc-opt-parms , parameter-declaration
11456 objc-optellipsis:
11457 empty
11458 , ...
11461 static tree
11462 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11463 tree *attributes, tree *expr)
11465 tree type = NULL_TREE;
11466 tree sel;
11467 tree parms = NULL_TREE;
11468 bool ellipsis = false;
11469 bool attr_err = false;
11471 *attributes = NULL_TREE;
11472 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11474 matching_parens parens;
11475 parens.consume_open (parser);
11476 type = c_parser_objc_type_name (parser);
11477 parens.skip_until_found_close (parser);
11479 sel = c_parser_objc_selector (parser);
11480 /* If there is no selector, or a colon follows, we have an
11481 objc-keyword-selector. If there is a selector, and a colon does
11482 not follow, that selector ends the objc-method-decl. */
11483 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11485 tree tsel = sel;
11486 tree list = NULL_TREE;
11487 while (true)
11489 tree atype = NULL_TREE, id, keyworddecl;
11490 tree param_attr = NULL_TREE;
11491 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11492 break;
11493 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11495 c_parser_consume_token (parser);
11496 atype = c_parser_objc_type_name (parser);
11497 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11498 "expected %<)%>");
11500 /* New ObjC allows attributes on method parameters. */
11501 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11502 param_attr = c_parser_gnu_attributes (parser);
11503 if (c_parser_next_token_is_not (parser, CPP_NAME))
11505 c_parser_error (parser, "expected identifier");
11506 return error_mark_node;
11508 id = c_parser_peek_token (parser)->value;
11509 c_parser_consume_token (parser);
11510 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11511 list = chainon (list, keyworddecl);
11512 tsel = c_parser_objc_selector (parser);
11513 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11514 break;
11517 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11519 /* Parse the optional parameter list. Optional Objective-C
11520 method parameters follow the C syntax, and may include '...'
11521 to denote a variable number of arguments. */
11522 parms = make_node (TREE_LIST);
11523 while (c_parser_next_token_is (parser, CPP_COMMA))
11525 struct c_parm *parm;
11526 c_parser_consume_token (parser);
11527 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11529 ellipsis = true;
11530 c_parser_consume_token (parser);
11531 attr_err |= c_parser_objc_maybe_method_attributes
11532 (parser, attributes) ;
11533 break;
11535 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11536 if (parm == NULL)
11537 break;
11538 parms = chainon (parms,
11539 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11541 sel = list;
11543 else
11544 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11546 if (sel == NULL)
11548 c_parser_error (parser, "objective-c method declaration is expected");
11549 return error_mark_node;
11552 if (attr_err)
11553 return error_mark_node;
11555 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11558 /* Parse an objc-type-name.
11560 objc-type-name:
11561 objc-type-qualifiers[opt] type-name
11562 objc-type-qualifiers[opt]
11564 objc-type-qualifiers:
11565 objc-type-qualifier
11566 objc-type-qualifiers objc-type-qualifier
11568 objc-type-qualifier: one of
11569 in out inout bycopy byref oneway
11572 static tree
11573 c_parser_objc_type_name (c_parser *parser)
11575 tree quals = NULL_TREE;
11576 struct c_type_name *type_name = NULL;
11577 tree type = NULL_TREE;
11578 while (true)
11580 c_token *token = c_parser_peek_token (parser);
11581 if (token->type == CPP_KEYWORD
11582 && (token->keyword == RID_IN
11583 || token->keyword == RID_OUT
11584 || token->keyword == RID_INOUT
11585 || token->keyword == RID_BYCOPY
11586 || token->keyword == RID_BYREF
11587 || token->keyword == RID_ONEWAY))
11589 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11590 c_parser_consume_token (parser);
11592 else
11593 break;
11595 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11596 type_name = c_parser_type_name (parser);
11597 if (type_name)
11598 type = groktypename (type_name, NULL, NULL);
11600 /* If the type is unknown, and error has already been produced and
11601 we need to recover from the error. In that case, use NULL_TREE
11602 for the type, as if no type had been specified; this will use the
11603 default type ('id') which is good for error recovery. */
11604 if (type == error_mark_node)
11605 type = NULL_TREE;
11607 return build_tree_list (quals, type);
11610 /* Parse objc-protocol-refs.
11612 objc-protocol-refs:
11613 < identifier-list >
11616 static tree
11617 c_parser_objc_protocol_refs (c_parser *parser)
11619 tree list = NULL_TREE;
11620 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11621 c_parser_consume_token (parser);
11622 /* Any identifiers, including those declared as type names, are OK
11623 here. */
11624 while (true)
11626 tree id;
11627 if (c_parser_next_token_is_not (parser, CPP_NAME))
11629 c_parser_error (parser, "expected identifier");
11630 break;
11632 id = c_parser_peek_token (parser)->value;
11633 list = chainon (list, build_tree_list (NULL_TREE, id));
11634 c_parser_consume_token (parser);
11635 if (c_parser_next_token_is (parser, CPP_COMMA))
11636 c_parser_consume_token (parser);
11637 else
11638 break;
11640 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11641 return list;
11644 /* Parse an objc-try-catch-finally-statement.
11646 objc-try-catch-finally-statement:
11647 @try compound-statement objc-catch-list[opt]
11648 @try compound-statement objc-catch-list[opt] @finally compound-statement
11650 objc-catch-list:
11651 @catch ( objc-catch-parameter-declaration ) compound-statement
11652 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11654 objc-catch-parameter-declaration:
11655 parameter-declaration
11656 '...'
11658 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11660 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11661 for C++. Keep them in sync. */
11663 static void
11664 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11666 location_t location;
11667 tree stmt;
11669 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11670 c_parser_consume_token (parser);
11671 location = c_parser_peek_token (parser)->location;
11672 objc_maybe_warn_exceptions (location);
11673 stmt = c_parser_compound_statement (parser);
11674 objc_begin_try_stmt (location, stmt);
11676 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11678 struct c_parm *parm;
11679 tree parameter_declaration = error_mark_node;
11680 bool seen_open_paren = false;
11682 c_parser_consume_token (parser);
11683 matching_parens parens;
11684 if (!parens.require_open (parser))
11685 seen_open_paren = true;
11686 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11688 /* We have "@catch (...)" (where the '...' are literally
11689 what is in the code). Skip the '...'.
11690 parameter_declaration is set to NULL_TREE, and
11691 objc_being_catch_clauses() knows that that means
11692 '...'. */
11693 c_parser_consume_token (parser);
11694 parameter_declaration = NULL_TREE;
11696 else
11698 /* We have "@catch (NSException *exception)" or something
11699 like that. Parse the parameter declaration. */
11700 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11701 if (parm == NULL)
11702 parameter_declaration = error_mark_node;
11703 else
11704 parameter_declaration = grokparm (parm, NULL);
11706 if (seen_open_paren)
11707 parens.require_close (parser);
11708 else
11710 /* If there was no open parenthesis, we are recovering from
11711 an error, and we are trying to figure out what mistake
11712 the user has made. */
11714 /* If there is an immediate closing parenthesis, the user
11715 probably forgot the opening one (ie, they typed "@catch
11716 NSException *e)". Parse the closing parenthesis and keep
11717 going. */
11718 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11719 c_parser_consume_token (parser);
11721 /* If these is no immediate closing parenthesis, the user
11722 probably doesn't know that parenthesis are required at
11723 all (ie, they typed "@catch NSException *e"). So, just
11724 forget about the closing parenthesis and keep going. */
11726 objc_begin_catch_clause (parameter_declaration);
11727 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11728 c_parser_compound_statement_nostart (parser);
11729 objc_finish_catch_clause ();
11731 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11733 c_parser_consume_token (parser);
11734 location = c_parser_peek_token (parser)->location;
11735 stmt = c_parser_compound_statement (parser);
11736 objc_build_finally_clause (location, stmt);
11738 objc_finish_try_stmt ();
11741 /* Parse an objc-synchronized-statement.
11743 objc-synchronized-statement:
11744 @synchronized ( expression ) compound-statement
11747 static void
11748 c_parser_objc_synchronized_statement (c_parser *parser)
11750 location_t loc;
11751 tree expr, stmt;
11752 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11753 c_parser_consume_token (parser);
11754 loc = c_parser_peek_token (parser)->location;
11755 objc_maybe_warn_exceptions (loc);
11756 matching_parens parens;
11757 if (parens.require_open (parser))
11759 struct c_expr ce = c_parser_expression (parser);
11760 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11761 expr = ce.value;
11762 expr = c_fully_fold (expr, false, NULL);
11763 parens.skip_until_found_close (parser);
11765 else
11766 expr = error_mark_node;
11767 stmt = c_parser_compound_statement (parser);
11768 objc_build_synchronized (loc, expr, stmt);
11771 /* Parse an objc-selector; return NULL_TREE without an error if the
11772 next token is not an objc-selector.
11774 objc-selector:
11775 identifier
11776 one of
11777 enum struct union if else while do for switch case default
11778 break continue return goto asm sizeof typeof __alignof
11779 unsigned long const short volatile signed restrict _Complex
11780 in out inout bycopy byref oneway int char float double void _Bool
11781 _Atomic
11783 ??? Why this selection of keywords but not, for example, storage
11784 class specifiers? */
11786 static tree
11787 c_parser_objc_selector (c_parser *parser)
11789 c_token *token = c_parser_peek_token (parser);
11790 tree value = token->value;
11791 if (token->type == CPP_NAME)
11793 c_parser_consume_token (parser);
11794 return value;
11796 if (token->type != CPP_KEYWORD)
11797 return NULL_TREE;
11798 switch (token->keyword)
11800 case RID_ENUM:
11801 case RID_STRUCT:
11802 case RID_UNION:
11803 case RID_IF:
11804 case RID_ELSE:
11805 case RID_WHILE:
11806 case RID_DO:
11807 case RID_FOR:
11808 case RID_SWITCH:
11809 case RID_CASE:
11810 case RID_DEFAULT:
11811 case RID_BREAK:
11812 case RID_CONTINUE:
11813 case RID_RETURN:
11814 case RID_GOTO:
11815 case RID_ASM:
11816 case RID_SIZEOF:
11817 case RID_TYPEOF:
11818 case RID_ALIGNOF:
11819 case RID_UNSIGNED:
11820 case RID_LONG:
11821 case RID_CONST:
11822 case RID_SHORT:
11823 case RID_VOLATILE:
11824 case RID_SIGNED:
11825 case RID_RESTRICT:
11826 case RID_COMPLEX:
11827 case RID_IN:
11828 case RID_OUT:
11829 case RID_INOUT:
11830 case RID_BYCOPY:
11831 case RID_BYREF:
11832 case RID_ONEWAY:
11833 case RID_INT:
11834 case RID_CHAR:
11835 case RID_FLOAT:
11836 case RID_DOUBLE:
11837 CASE_RID_FLOATN_NX:
11838 case RID_VOID:
11839 case RID_BOOL:
11840 case RID_ATOMIC:
11841 case RID_AUTO_TYPE:
11842 case RID_INT_N_0:
11843 case RID_INT_N_1:
11844 case RID_INT_N_2:
11845 case RID_INT_N_3:
11846 c_parser_consume_token (parser);
11847 return value;
11848 default:
11849 return NULL_TREE;
11853 /* Parse an objc-selector-arg.
11855 objc-selector-arg:
11856 objc-selector
11857 objc-keywordname-list
11859 objc-keywordname-list:
11860 objc-keywordname
11861 objc-keywordname-list objc-keywordname
11863 objc-keywordname:
11864 objc-selector :
11868 static tree
11869 c_parser_objc_selector_arg (c_parser *parser)
11871 tree sel = c_parser_objc_selector (parser);
11872 tree list = NULL_TREE;
11873 if (sel
11874 && c_parser_next_token_is_not (parser, CPP_COLON)
11875 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11876 return sel;
11877 while (true)
11879 if (c_parser_next_token_is (parser, CPP_SCOPE))
11881 c_parser_consume_token (parser);
11882 list = chainon (list, build_tree_list (sel, NULL_TREE));
11883 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11885 else
11887 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11888 return list;
11889 list = chainon (list, build_tree_list (sel, NULL_TREE));
11891 sel = c_parser_objc_selector (parser);
11892 if (!sel
11893 && c_parser_next_token_is_not (parser, CPP_COLON)
11894 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11895 break;
11897 return list;
11900 /* Parse an objc-receiver.
11902 objc-receiver:
11903 expression
11904 class-name
11905 type-name
11908 static tree
11909 c_parser_objc_receiver (c_parser *parser)
11911 location_t loc = c_parser_peek_token (parser)->location;
11913 if (c_parser_peek_token (parser)->type == CPP_NAME
11914 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11915 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11917 tree id = c_parser_peek_token (parser)->value;
11918 c_parser_consume_token (parser);
11919 return objc_get_class_reference (id);
11921 struct c_expr ce = c_parser_expression (parser);
11922 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11923 return c_fully_fold (ce.value, false, NULL);
11926 /* Parse objc-message-args.
11928 objc-message-args:
11929 objc-selector
11930 objc-keywordarg-list
11932 objc-keywordarg-list:
11933 objc-keywordarg
11934 objc-keywordarg-list objc-keywordarg
11936 objc-keywordarg:
11937 objc-selector : objc-keywordexpr
11938 : objc-keywordexpr
11941 static tree
11942 c_parser_objc_message_args (c_parser *parser)
11944 tree sel = c_parser_objc_selector (parser);
11945 tree list = NULL_TREE;
11946 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11947 return sel;
11948 while (true)
11950 tree keywordexpr;
11951 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11952 return error_mark_node;
11953 keywordexpr = c_parser_objc_keywordexpr (parser);
11954 list = chainon (list, build_tree_list (sel, keywordexpr));
11955 sel = c_parser_objc_selector (parser);
11956 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11957 break;
11959 return list;
11962 /* Parse an objc-keywordexpr.
11964 objc-keywordexpr:
11965 nonempty-expr-list
11968 static tree
11969 c_parser_objc_keywordexpr (c_parser *parser)
11971 tree ret;
11972 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11973 NULL, NULL, NULL, NULL);
11974 if (vec_safe_length (expr_list) == 1)
11976 /* Just return the expression, remove a level of
11977 indirection. */
11978 ret = (*expr_list)[0];
11980 else
11982 /* We have a comma expression, we will collapse later. */
11983 ret = build_tree_list_vec (expr_list);
11985 release_tree_vector (expr_list);
11986 return ret;
11989 /* A check, needed in several places, that ObjC interface, implementation or
11990 method definitions are not prefixed by incorrect items. */
11991 static bool
11992 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11993 struct c_declspecs *specs)
11995 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11996 || specs->typespec_kind != ctsk_none)
11998 c_parser_error (parser,
11999 "no type or storage class may be specified here,");
12000 c_parser_skip_to_end_of_block_or_statement (parser);
12001 return true;
12003 return false;
12006 /* Parse an Objective-C @property declaration. The syntax is:
12008 objc-property-declaration:
12009 '@property' objc-property-attributes[opt] struct-declaration ;
12011 objc-property-attributes:
12012 '(' objc-property-attribute-list ')'
12014 objc-property-attribute-list:
12015 objc-property-attribute
12016 objc-property-attribute-list, objc-property-attribute
12018 objc-property-attribute
12019 'getter' = identifier
12020 'setter' = identifier
12021 'readonly'
12022 'readwrite'
12023 'assign'
12024 'retain'
12025 'copy'
12026 'nonatomic'
12028 For example:
12029 @property NSString *name;
12030 @property (readonly) id object;
12031 @property (retain, nonatomic, getter=getTheName) id name;
12032 @property int a, b, c;
12034 PS: This function is identical to cp_parser_objc_at_propery_declaration
12035 for C++. Keep them in sync. */
12036 static void
12037 c_parser_objc_at_property_declaration (c_parser *parser)
12039 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12040 location_t loc = c_parser_peek_token (parser)->location;
12041 c_parser_consume_token (parser); /* Eat '@property'. */
12043 /* Parse the optional attribute list.
12045 A list of parsed, but not verified, attributes. */
12046 vec<property_attribute_info *> prop_attr_list = vNULL;
12048 bool syntax_error = false;
12049 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12051 matching_parens parens;
12053 location_t attr_start = c_parser_peek_token (parser)->location;
12054 /* Eat the '(' */
12055 parens.consume_open (parser);
12057 /* Property attribute keywords are valid now. */
12058 parser->objc_property_attr_context = true;
12060 /* Allow @property (), with a warning. */
12061 location_t attr_end = c_parser_peek_token (parser)->location;
12063 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12065 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12066 warning_at (attr_comb, OPT_Wattributes,
12067 "empty property attribute list");
12069 else
12070 while (true)
12072 c_token *token = c_parser_peek_token (parser);
12073 attr_start = token->location;
12074 attr_end = get_finish (token->location);
12075 location_t attr_comb = make_location (attr_start, attr_start,
12076 attr_end);
12078 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12080 warning_at (attr_comb, OPT_Wattributes,
12081 "missing property attribute");
12082 if (token->type == CPP_CLOSE_PAREN)
12083 break;
12084 c_parser_consume_token (parser);
12085 continue;
12088 tree attr_name = NULL_TREE;
12089 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12090 bool add_at = false;
12091 if (token->type == CPP_KEYWORD)
12093 keyword = token->keyword;
12094 if (OBJC_IS_AT_KEYWORD (keyword))
12096 /* For '@' keywords the token value has the keyword,
12097 prepend the '@' for diagnostics. */
12098 attr_name = token->value;
12099 add_at = true;
12101 else
12102 attr_name = ridpointers[(int)keyword];
12104 else if (token->type == CPP_NAME)
12105 attr_name = token->value;
12106 c_parser_consume_token (parser);
12108 enum objc_property_attribute_kind prop_kind
12109 = objc_prop_attr_kind_for_rid (keyword);
12110 property_attribute_info *prop
12111 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12112 prop_attr_list.safe_push (prop);
12114 tree meth_name;
12115 switch (prop->prop_kind)
12117 default: break;
12118 case OBJC_PROPERTY_ATTR_UNKNOWN:
12119 if (attr_name)
12120 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12121 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12122 else
12123 error_at (attr_comb, "unknown property attribute");
12124 prop->parse_error = syntax_error = true;
12125 break;
12127 case OBJC_PROPERTY_ATTR_GETTER:
12128 case OBJC_PROPERTY_ATTR_SETTER:
12129 if (c_parser_next_token_is_not (parser, CPP_EQ))
12131 attr_comb = make_location (attr_end, attr_start, attr_end);
12132 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12133 attr_name);
12134 prop->parse_error = syntax_error = true;
12135 break;
12137 token = c_parser_peek_token (parser);
12138 attr_end = token->location;
12139 c_parser_consume_token (parser); /* eat the = */
12140 if (c_parser_next_token_is_not (parser, CPP_NAME))
12142 attr_comb = make_location (attr_end, attr_start, attr_end);
12143 error_at (attr_comb, "expected %qE selector name",
12144 attr_name);
12145 prop->parse_error = syntax_error = true;
12146 break;
12148 /* Get the end of the method name, and consume the name. */
12149 token = c_parser_peek_token (parser);
12150 attr_end = get_finish (token->location);
12151 meth_name = token->value;
12152 c_parser_consume_token (parser);
12153 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12155 if (c_parser_next_token_is_not (parser, CPP_COLON))
12157 attr_comb = make_location (attr_end, attr_start,
12158 attr_end);
12159 error_at (attr_comb, "setter method names must"
12160 " terminate with %<:%>");
12161 prop->parse_error = syntax_error = true;
12163 else
12165 attr_end = get_finish (c_parser_peek_token
12166 (parser)->location);
12167 c_parser_consume_token (parser);
12169 attr_comb = make_location (attr_start, attr_start,
12170 attr_end);
12172 else
12173 attr_comb = make_location (attr_start, attr_start,
12174 attr_end);
12175 prop->ident = meth_name;
12176 /* Updated location including all that was successfully
12177 parsed. */
12178 prop->prop_loc = attr_comb;
12179 break;
12182 /* If we see a comma here, then keep going - even if we already
12183 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12184 this makes a more useful output and avoid spurious warnings about
12185 missing attributes that are, in fact, specified after the one with
12186 the syntax error. */
12187 if (c_parser_next_token_is (parser, CPP_COMMA))
12188 c_parser_consume_token (parser);
12189 else
12190 break;
12192 parser->objc_property_attr_context = false;
12194 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12195 /* We don't really want to chew the whole of the file looking for a
12196 matching closing parenthesis, so we will try to read the decl and
12197 let the error handling for that close out the statement. */
12199 else
12200 syntax_error = false, parens.skip_until_found_close (parser);
12203 /* 'properties' is the list of properties that we read. Usually a
12204 single one, but maybe more (eg, in "@property int a, b, c;" there
12205 are three). */
12206 tree properties = c_parser_struct_declaration (parser);
12208 if (properties == error_mark_node)
12209 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12210 else
12212 if (properties == NULL_TREE)
12213 c_parser_error (parser, "expected identifier");
12214 else
12216 /* Comma-separated properties are chained together in reverse order;
12217 add them one by one. */
12218 properties = nreverse (properties);
12219 for (; properties; properties = TREE_CHAIN (properties))
12220 objc_add_property_declaration (loc, copy_node (properties),
12221 prop_attr_list);
12223 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12226 while (!prop_attr_list.is_empty())
12227 delete prop_attr_list.pop ();
12228 prop_attr_list.release ();
12229 parser->error = false;
12232 /* Parse an Objective-C @synthesize declaration. The syntax is:
12234 objc-synthesize-declaration:
12235 @synthesize objc-synthesize-identifier-list ;
12237 objc-synthesize-identifier-list:
12238 objc-synthesize-identifier
12239 objc-synthesize-identifier-list, objc-synthesize-identifier
12241 objc-synthesize-identifier
12242 identifier
12243 identifier = identifier
12245 For example:
12246 @synthesize MyProperty;
12247 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12249 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12250 for C++. Keep them in sync.
12252 static void
12253 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12255 tree list = NULL_TREE;
12256 location_t loc;
12257 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12258 loc = c_parser_peek_token (parser)->location;
12260 c_parser_consume_token (parser);
12261 while (true)
12263 tree property, ivar;
12264 if (c_parser_next_token_is_not (parser, CPP_NAME))
12266 c_parser_error (parser, "expected identifier");
12267 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12268 /* Once we find the semicolon, we can resume normal parsing.
12269 We have to reset parser->error manually because
12270 c_parser_skip_until_found() won't reset it for us if the
12271 next token is precisely a semicolon. */
12272 parser->error = false;
12273 return;
12275 property = c_parser_peek_token (parser)->value;
12276 c_parser_consume_token (parser);
12277 if (c_parser_next_token_is (parser, CPP_EQ))
12279 c_parser_consume_token (parser);
12280 if (c_parser_next_token_is_not (parser, CPP_NAME))
12282 c_parser_error (parser, "expected identifier");
12283 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12284 parser->error = false;
12285 return;
12287 ivar = c_parser_peek_token (parser)->value;
12288 c_parser_consume_token (parser);
12290 else
12291 ivar = NULL_TREE;
12292 list = chainon (list, build_tree_list (ivar, property));
12293 if (c_parser_next_token_is (parser, CPP_COMMA))
12294 c_parser_consume_token (parser);
12295 else
12296 break;
12298 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12299 objc_add_synthesize_declaration (loc, list);
12302 /* Parse an Objective-C @dynamic declaration. The syntax is:
12304 objc-dynamic-declaration:
12305 @dynamic identifier-list ;
12307 For example:
12308 @dynamic MyProperty;
12309 @dynamic MyProperty, AnotherProperty;
12311 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12312 for C++. Keep them in sync.
12314 static void
12315 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12317 tree list = NULL_TREE;
12318 location_t loc;
12319 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12320 loc = c_parser_peek_token (parser)->location;
12322 c_parser_consume_token (parser);
12323 while (true)
12325 tree property;
12326 if (c_parser_next_token_is_not (parser, CPP_NAME))
12328 c_parser_error (parser, "expected identifier");
12329 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12330 parser->error = false;
12331 return;
12333 property = c_parser_peek_token (parser)->value;
12334 list = chainon (list, build_tree_list (NULL_TREE, property));
12335 c_parser_consume_token (parser);
12336 if (c_parser_next_token_is (parser, CPP_COMMA))
12337 c_parser_consume_token (parser);
12338 else
12339 break;
12341 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12342 objc_add_dynamic_declaration (loc, list);
12346 /* Parse a pragma GCC ivdep. */
12348 static bool
12349 c_parse_pragma_ivdep (c_parser *parser)
12351 c_parser_consume_pragma (parser);
12352 c_parser_skip_to_pragma_eol (parser);
12353 return true;
12356 /* Parse a pragma GCC unroll. */
12358 static unsigned short
12359 c_parser_pragma_unroll (c_parser *parser)
12361 unsigned short unroll;
12362 c_parser_consume_pragma (parser);
12363 location_t location = c_parser_peek_token (parser)->location;
12364 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12365 mark_exp_read (expr);
12366 expr = c_fully_fold (expr, false, NULL);
12367 HOST_WIDE_INT lunroll = 0;
12368 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12369 || TREE_CODE (expr) != INTEGER_CST
12370 || (lunroll = tree_to_shwi (expr)) < 0
12371 || lunroll >= USHRT_MAX)
12373 error_at (location, "%<#pragma GCC unroll%> requires an"
12374 " assignment-expression that evaluates to a non-negative"
12375 " integral constant less than %u", USHRT_MAX);
12376 unroll = 0;
12378 else
12380 unroll = (unsigned short)lunroll;
12381 if (unroll == 0)
12382 unroll = 1;
12385 c_parser_skip_to_pragma_eol (parser);
12386 return unroll;
12389 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12390 should be considered, statements. ALLOW_STMT is true if we're within
12391 the context of a function and such pragmas are to be allowed. Returns
12392 true if we actually parsed such a pragma. */
12394 static bool
12395 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12397 unsigned int id;
12398 const char *construct = NULL;
12400 input_location = c_parser_peek_token (parser)->location;
12401 id = c_parser_peek_token (parser)->pragma_kind;
12402 gcc_assert (id != PRAGMA_NONE);
12404 switch (id)
12406 case PRAGMA_OACC_DECLARE:
12407 c_parser_oacc_declare (parser);
12408 return false;
12410 case PRAGMA_OACC_ENTER_DATA:
12411 if (context != pragma_compound)
12413 construct = "acc enter data";
12414 in_compound:
12415 if (context == pragma_stmt)
12417 error_at (c_parser_peek_token (parser)->location,
12418 "%<#pragma %s%> may only be used in compound "
12419 "statements", construct);
12420 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12421 return true;
12423 goto bad_stmt;
12425 c_parser_oacc_enter_exit_data (parser, true);
12426 return false;
12428 case PRAGMA_OACC_EXIT_DATA:
12429 if (context != pragma_compound)
12431 construct = "acc exit data";
12432 goto in_compound;
12434 c_parser_oacc_enter_exit_data (parser, false);
12435 return false;
12437 case PRAGMA_OACC_ROUTINE:
12438 if (context != pragma_external)
12440 error_at (c_parser_peek_token (parser)->location,
12441 "%<#pragma acc routine%> must be at file scope");
12442 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12443 return false;
12445 c_parser_oacc_routine (parser, context);
12446 return false;
12448 case PRAGMA_OACC_UPDATE:
12449 if (context != pragma_compound)
12451 construct = "acc update";
12452 goto in_compound;
12454 c_parser_oacc_update (parser);
12455 return false;
12457 case PRAGMA_OMP_BARRIER:
12458 if (context != pragma_compound)
12460 construct = "omp barrier";
12461 goto in_compound;
12463 c_parser_omp_barrier (parser);
12464 return false;
12466 case PRAGMA_OMP_DEPOBJ:
12467 if (context != pragma_compound)
12469 construct = "omp depobj";
12470 goto in_compound;
12472 c_parser_omp_depobj (parser);
12473 return false;
12475 case PRAGMA_OMP_FLUSH:
12476 if (context != pragma_compound)
12478 construct = "omp flush";
12479 goto in_compound;
12481 c_parser_omp_flush (parser);
12482 return false;
12484 case PRAGMA_OMP_TASKWAIT:
12485 if (context != pragma_compound)
12487 construct = "omp taskwait";
12488 goto in_compound;
12490 c_parser_omp_taskwait (parser);
12491 return false;
12493 case PRAGMA_OMP_TASKYIELD:
12494 if (context != pragma_compound)
12496 construct = "omp taskyield";
12497 goto in_compound;
12499 c_parser_omp_taskyield (parser);
12500 return false;
12502 case PRAGMA_OMP_CANCEL:
12503 if (context != pragma_compound)
12505 construct = "omp cancel";
12506 goto in_compound;
12508 c_parser_omp_cancel (parser);
12509 return false;
12511 case PRAGMA_OMP_CANCELLATION_POINT:
12512 return c_parser_omp_cancellation_point (parser, context);
12514 case PRAGMA_OMP_THREADPRIVATE:
12515 c_parser_omp_threadprivate (parser);
12516 return false;
12518 case PRAGMA_OMP_TARGET:
12519 return c_parser_omp_target (parser, context, if_p);
12521 case PRAGMA_OMP_END_DECLARE_TARGET:
12522 c_parser_omp_end_declare_target (parser);
12523 return false;
12525 case PRAGMA_OMP_SCAN:
12526 error_at (c_parser_peek_token (parser)->location,
12527 "%<#pragma omp scan%> may only be used in "
12528 "a loop construct with %<inscan%> %<reduction%> clause");
12529 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12530 return false;
12532 case PRAGMA_OMP_SECTION:
12533 error_at (c_parser_peek_token (parser)->location,
12534 "%<#pragma omp section%> may only be used in "
12535 "%<#pragma omp sections%> construct");
12536 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12537 return false;
12539 case PRAGMA_OMP_DECLARE:
12540 return c_parser_omp_declare (parser, context);
12542 case PRAGMA_OMP_REQUIRES:
12543 if (context != pragma_external)
12545 error_at (c_parser_peek_token (parser)->location,
12546 "%<#pragma omp requires%> may only be used at file scope");
12547 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12548 return false;
12550 c_parser_omp_requires (parser);
12551 return false;
12553 case PRAGMA_OMP_NOTHING:
12554 c_parser_omp_nothing (parser);
12555 return false;
12557 case PRAGMA_OMP_ERROR:
12558 return c_parser_omp_error (parser, context);
12560 case PRAGMA_OMP_ORDERED:
12561 return c_parser_omp_ordered (parser, context, if_p);
12563 case PRAGMA_IVDEP:
12565 const bool ivdep = c_parse_pragma_ivdep (parser);
12566 unsigned short unroll;
12567 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12568 unroll = c_parser_pragma_unroll (parser);
12569 else
12570 unroll = 0;
12571 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12572 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12573 && !c_parser_next_token_is_keyword (parser, RID_DO))
12575 c_parser_error (parser, "for, while or do statement expected");
12576 return false;
12578 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12579 c_parser_for_statement (parser, ivdep, unroll, if_p);
12580 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12581 c_parser_while_statement (parser, ivdep, unroll, if_p);
12582 else
12583 c_parser_do_statement (parser, ivdep, unroll);
12585 return true;
12587 case PRAGMA_UNROLL:
12589 unsigned short unroll = c_parser_pragma_unroll (parser);
12590 bool ivdep;
12591 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12592 ivdep = c_parse_pragma_ivdep (parser);
12593 else
12594 ivdep = false;
12595 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12596 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12597 && !c_parser_next_token_is_keyword (parser, RID_DO))
12599 c_parser_error (parser, "for, while or do statement expected");
12600 return false;
12602 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12603 c_parser_for_statement (parser, ivdep, unroll, if_p);
12604 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12605 c_parser_while_statement (parser, ivdep, unroll, if_p);
12606 else
12607 c_parser_do_statement (parser, ivdep, unroll);
12609 return true;
12611 case PRAGMA_GCC_PCH_PREPROCESS:
12612 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12613 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12614 return false;
12616 case PRAGMA_OACC_WAIT:
12617 if (context != pragma_compound)
12619 construct = "acc wait";
12620 goto in_compound;
12622 /* FALL THROUGH. */
12624 default:
12625 if (id < PRAGMA_FIRST_EXTERNAL)
12627 if (context != pragma_stmt && context != pragma_compound)
12629 bad_stmt:
12630 c_parser_error (parser, "expected declaration specifiers");
12631 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12632 return false;
12634 c_parser_omp_construct (parser, if_p);
12635 return true;
12637 break;
12640 c_parser_consume_pragma (parser);
12641 c_invoke_pragma_handler (id);
12643 /* Skip to EOL, but suppress any error message. Those will have been
12644 generated by the handler routine through calling error, as opposed
12645 to calling c_parser_error. */
12646 parser->error = true;
12647 c_parser_skip_to_pragma_eol (parser);
12649 return false;
12652 /* The interface the pragma parsers have to the lexer. */
12654 enum cpp_ttype
12655 pragma_lex (tree *value, location_t *loc)
12657 c_token *tok = c_parser_peek_token (the_parser);
12658 enum cpp_ttype ret = tok->type;
12660 *value = tok->value;
12661 if (loc)
12662 *loc = tok->location;
12664 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12665 ret = CPP_EOF;
12666 else if (ret == CPP_STRING)
12667 *value = c_parser_string_literal (the_parser, false, false).value;
12668 else
12670 if (ret == CPP_KEYWORD)
12671 ret = CPP_NAME;
12672 c_parser_consume_token (the_parser);
12675 return ret;
12678 static void
12679 c_parser_pragma_pch_preprocess (c_parser *parser)
12681 tree name = NULL;
12683 parser->lex_joined_string = true;
12684 c_parser_consume_pragma (parser);
12685 if (c_parser_next_token_is (parser, CPP_STRING))
12687 name = c_parser_peek_token (parser)->value;
12688 c_parser_consume_token (parser);
12690 else
12691 c_parser_error (parser, "expected string literal");
12692 c_parser_skip_to_pragma_eol (parser);
12693 parser->lex_joined_string = false;
12695 if (name)
12696 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12699 /* OpenACC and OpenMP parsing routines. */
12701 /* Returns name of the next clause.
12702 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12703 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12704 returned and the token is consumed. */
12706 static pragma_omp_clause
12707 c_parser_omp_clause_name (c_parser *parser)
12709 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12711 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12712 result = PRAGMA_OACC_CLAUSE_AUTO;
12713 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12714 result = PRAGMA_OMP_CLAUSE_IF;
12715 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12716 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12717 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12718 result = PRAGMA_OMP_CLAUSE_FOR;
12719 else if (c_parser_next_token_is (parser, CPP_NAME))
12721 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12723 switch (p[0])
12725 case 'a':
12726 if (!strcmp ("affinity", p))
12727 result = PRAGMA_OMP_CLAUSE_AFFINITY;
12728 else if (!strcmp ("aligned", p))
12729 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12730 else if (!strcmp ("allocate", p))
12731 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12732 else if (!strcmp ("async", p))
12733 result = PRAGMA_OACC_CLAUSE_ASYNC;
12734 else if (!strcmp ("attach", p))
12735 result = PRAGMA_OACC_CLAUSE_ATTACH;
12736 break;
12737 case 'b':
12738 if (!strcmp ("bind", p))
12739 result = PRAGMA_OMP_CLAUSE_BIND;
12740 break;
12741 case 'c':
12742 if (!strcmp ("collapse", p))
12743 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12744 else if (!strcmp ("copy", p))
12745 result = PRAGMA_OACC_CLAUSE_COPY;
12746 else if (!strcmp ("copyin", p))
12747 result = PRAGMA_OMP_CLAUSE_COPYIN;
12748 else if (!strcmp ("copyout", p))
12749 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12750 else if (!strcmp ("copyprivate", p))
12751 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12752 else if (!strcmp ("create", p))
12753 result = PRAGMA_OACC_CLAUSE_CREATE;
12754 break;
12755 case 'd':
12756 if (!strcmp ("defaultmap", p))
12757 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12758 else if (!strcmp ("delete", p))
12759 result = PRAGMA_OACC_CLAUSE_DELETE;
12760 else if (!strcmp ("depend", p))
12761 result = PRAGMA_OMP_CLAUSE_DEPEND;
12762 else if (!strcmp ("detach", p))
12763 result = PRAGMA_OACC_CLAUSE_DETACH;
12764 else if (!strcmp ("device", p))
12765 result = PRAGMA_OMP_CLAUSE_DEVICE;
12766 else if (!strcmp ("deviceptr", p))
12767 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12768 else if (!strcmp ("device_resident", p))
12769 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12770 else if (!strcmp ("device_type", p))
12771 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12772 else if (!strcmp ("dist_schedule", p))
12773 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12774 break;
12775 case 'e':
12776 if (!strcmp ("enter", p))
12777 result = PRAGMA_OMP_CLAUSE_ENTER;
12778 break;
12779 case 'f':
12780 if (!strcmp ("filter", p))
12781 result = PRAGMA_OMP_CLAUSE_FILTER;
12782 else if (!strcmp ("final", p))
12783 result = PRAGMA_OMP_CLAUSE_FINAL;
12784 else if (!strcmp ("finalize", p))
12785 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12786 else if (!strcmp ("firstprivate", p))
12787 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12788 else if (!strcmp ("from", p))
12789 result = PRAGMA_OMP_CLAUSE_FROM;
12790 break;
12791 case 'g':
12792 if (!strcmp ("gang", p))
12793 result = PRAGMA_OACC_CLAUSE_GANG;
12794 else if (!strcmp ("grainsize", p))
12795 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12796 break;
12797 case 'h':
12798 if (!strcmp ("has_device_addr", p))
12799 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
12800 else if (!strcmp ("hint", p))
12801 result = PRAGMA_OMP_CLAUSE_HINT;
12802 else if (!strcmp ("host", p))
12803 result = PRAGMA_OACC_CLAUSE_HOST;
12804 break;
12805 case 'i':
12806 if (!strcmp ("if_present", p))
12807 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12808 else if (!strcmp ("in_reduction", p))
12809 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12810 else if (!strcmp ("inbranch", p))
12811 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12812 else if (!strcmp ("independent", p))
12813 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12814 else if (!strcmp ("is_device_ptr", p))
12815 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12816 break;
12817 case 'l':
12818 if (!strcmp ("lastprivate", p))
12819 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12820 else if (!strcmp ("linear", p))
12821 result = PRAGMA_OMP_CLAUSE_LINEAR;
12822 else if (!strcmp ("link", p))
12823 result = PRAGMA_OMP_CLAUSE_LINK;
12824 break;
12825 case 'm':
12826 if (!strcmp ("map", p))
12827 result = PRAGMA_OMP_CLAUSE_MAP;
12828 else if (!strcmp ("mergeable", p))
12829 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12830 break;
12831 case 'n':
12832 if (!strcmp ("no_create", p))
12833 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12834 else if (!strcmp ("nogroup", p))
12835 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12836 else if (!strcmp ("nohost", p))
12837 result = PRAGMA_OACC_CLAUSE_NOHOST;
12838 else if (!strcmp ("nontemporal", p))
12839 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12840 else if (!strcmp ("notinbranch", p))
12841 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12842 else if (!strcmp ("nowait", p))
12843 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12844 else if (!strcmp ("num_gangs", p))
12845 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12846 else if (!strcmp ("num_tasks", p))
12847 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12848 else if (!strcmp ("num_teams", p))
12849 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12850 else if (!strcmp ("num_threads", p))
12851 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12852 else if (!strcmp ("num_workers", p))
12853 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12854 break;
12855 case 'o':
12856 if (!strcmp ("ordered", p))
12857 result = PRAGMA_OMP_CLAUSE_ORDERED;
12858 else if (!strcmp ("order", p))
12859 result = PRAGMA_OMP_CLAUSE_ORDER;
12860 break;
12861 case 'p':
12862 if (!strcmp ("parallel", p))
12863 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12864 else if (!strcmp ("present", p))
12865 result = PRAGMA_OACC_CLAUSE_PRESENT;
12866 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12867 clauses. */
12868 else if (!strcmp ("present_or_copy", p)
12869 || !strcmp ("pcopy", p))
12870 result = PRAGMA_OACC_CLAUSE_COPY;
12871 else if (!strcmp ("present_or_copyin", p)
12872 || !strcmp ("pcopyin", p))
12873 result = PRAGMA_OACC_CLAUSE_COPYIN;
12874 else if (!strcmp ("present_or_copyout", p)
12875 || !strcmp ("pcopyout", p))
12876 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12877 else if (!strcmp ("present_or_create", p)
12878 || !strcmp ("pcreate", p))
12879 result = PRAGMA_OACC_CLAUSE_CREATE;
12880 else if (!strcmp ("priority", p))
12881 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12882 else if (!strcmp ("private", p))
12883 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12884 else if (!strcmp ("proc_bind", p))
12885 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12886 break;
12887 case 'r':
12888 if (!strcmp ("reduction", p))
12889 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12890 break;
12891 case 's':
12892 if (!strcmp ("safelen", p))
12893 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12894 else if (!strcmp ("schedule", p))
12895 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12896 else if (!strcmp ("sections", p))
12897 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12898 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12899 result = PRAGMA_OACC_CLAUSE_HOST;
12900 else if (!strcmp ("seq", p))
12901 result = PRAGMA_OACC_CLAUSE_SEQ;
12902 else if (!strcmp ("shared", p))
12903 result = PRAGMA_OMP_CLAUSE_SHARED;
12904 else if (!strcmp ("simd", p))
12905 result = PRAGMA_OMP_CLAUSE_SIMD;
12906 else if (!strcmp ("simdlen", p))
12907 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12908 break;
12909 case 't':
12910 if (!strcmp ("task_reduction", p))
12911 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12912 else if (!strcmp ("taskgroup", p))
12913 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12914 else if (!strcmp ("thread_limit", p))
12915 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12916 else if (!strcmp ("threads", p))
12917 result = PRAGMA_OMP_CLAUSE_THREADS;
12918 else if (!strcmp ("tile", p))
12919 result = PRAGMA_OACC_CLAUSE_TILE;
12920 else if (!strcmp ("to", p))
12921 result = PRAGMA_OMP_CLAUSE_TO;
12922 break;
12923 case 'u':
12924 if (!strcmp ("uniform", p))
12925 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12926 else if (!strcmp ("untied", p))
12927 result = PRAGMA_OMP_CLAUSE_UNTIED;
12928 else if (!strcmp ("use_device", p))
12929 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12930 else if (!strcmp ("use_device_addr", p))
12931 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12932 else if (!strcmp ("use_device_ptr", p))
12933 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12934 break;
12935 case 'v':
12936 if (!strcmp ("vector", p))
12937 result = PRAGMA_OACC_CLAUSE_VECTOR;
12938 else if (!strcmp ("vector_length", p))
12939 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12940 break;
12941 case 'w':
12942 if (!strcmp ("wait", p))
12943 result = PRAGMA_OACC_CLAUSE_WAIT;
12944 else if (!strcmp ("worker", p))
12945 result = PRAGMA_OACC_CLAUSE_WORKER;
12946 break;
12950 if (result != PRAGMA_OMP_CLAUSE_NONE)
12951 c_parser_consume_token (parser);
12953 return result;
12956 /* Validate that a clause of the given type does not already exist. */
12958 static void
12959 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12960 const char *name)
12962 if (tree c = omp_find_clause (clauses, code))
12963 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12966 /* OpenACC 2.0
12967 Parse wait clause or wait directive parameters. */
12969 static tree
12970 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12972 vec<tree, va_gc> *args;
12973 tree t, args_tree;
12975 matching_parens parens;
12976 if (!parens.require_open (parser))
12977 return list;
12979 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12980 args_tree = build_tree_list_vec (args);
12982 for (t = args_tree; t; t = TREE_CHAIN (t))
12984 tree targ = TREE_VALUE (t);
12986 if (targ != error_mark_node)
12988 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12990 c_parser_error (parser, "expression must be integral");
12991 targ = error_mark_node;
12993 else
12995 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12997 OMP_CLAUSE_DECL (c) = targ;
12998 OMP_CLAUSE_CHAIN (c) = list;
12999 list = c;
13004 release_tree_vector (args);
13005 parens.require_close (parser);
13006 return list;
13009 /* OpenACC 2.0, OpenMP 2.5:
13010 variable-list:
13011 identifier
13012 variable-list , identifier
13014 If KIND is nonzero, create the appropriate node and install the
13015 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13016 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13018 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13019 return the list created.
13021 The optional ALLOW_DEREF argument is true if list items can use the deref
13022 (->) operator. */
13024 struct omp_dim
13026 tree low_bound, length;
13027 location_t loc;
13028 bool no_colon;
13029 omp_dim (tree lb, tree len, location_t lo, bool nc)
13030 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13033 static tree
13034 c_parser_omp_variable_list (c_parser *parser,
13035 location_t clause_loc,
13036 enum omp_clause_code kind, tree list,
13037 bool allow_deref = false)
13039 auto_vec<omp_dim> dims;
13040 bool array_section_p;
13041 auto_vec<c_token> tokens;
13042 unsigned int tokens_avail = 0;
13043 bool first = true;
13045 while (1)
13047 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13049 if (c_parser_next_token_is_not (parser, CPP_NAME)
13050 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13052 struct c_expr expr;
13053 if (kind == OMP_CLAUSE_DEPEND
13054 && c_parser_next_token_is_keyword (parser,
13055 RID_OMP_ALL_MEMORY)
13056 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13057 || (c_parser_peek_2nd_token (parser)->type
13058 == CPP_CLOSE_PAREN)))
13060 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
13061 c_parser_consume_token (parser);
13063 else
13064 expr = c_parser_expr_no_commas (parser, NULL);
13065 if (expr.value != error_mark_node)
13067 tree u = build_omp_clause (clause_loc, kind);
13068 OMP_CLAUSE_DECL (u) = expr.value;
13069 OMP_CLAUSE_CHAIN (u) = list;
13070 list = u;
13073 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13074 break;
13076 c_parser_consume_token (parser);
13077 first = false;
13078 continue;
13081 tokens.truncate (0);
13082 unsigned int nesting_depth = 0;
13083 while (1)
13085 c_token *token = c_parser_peek_token (parser);
13086 switch (token->type)
13088 case CPP_EOF:
13089 case CPP_PRAGMA_EOL:
13090 break;
13091 case CPP_OPEN_BRACE:
13092 case CPP_OPEN_PAREN:
13093 case CPP_OPEN_SQUARE:
13094 ++nesting_depth;
13095 goto add;
13096 case CPP_CLOSE_BRACE:
13097 case CPP_CLOSE_PAREN:
13098 case CPP_CLOSE_SQUARE:
13099 if (nesting_depth-- == 0)
13100 break;
13101 goto add;
13102 case CPP_COMMA:
13103 if (nesting_depth == 0)
13104 break;
13105 goto add;
13106 default:
13107 add:
13108 tokens.safe_push (*token);
13109 c_parser_consume_token (parser);
13110 continue;
13112 break;
13115 /* Make sure nothing tries to read past the end of the tokens. */
13116 c_token eof_token;
13117 memset (&eof_token, 0, sizeof (eof_token));
13118 eof_token.type = CPP_EOF;
13119 tokens.safe_push (eof_token);
13120 tokens.safe_push (eof_token);
13122 tokens_avail = parser->tokens_avail;
13123 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13124 parser->tokens = tokens.address ();
13125 parser->tokens_avail = tokens.length ();
13128 tree t = NULL_TREE;
13130 if (c_parser_next_token_is (parser, CPP_NAME)
13131 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13133 t = lookup_name (c_parser_peek_token (parser)->value);
13135 if (t == NULL_TREE)
13137 undeclared_variable (c_parser_peek_token (parser)->location,
13138 c_parser_peek_token (parser)->value);
13139 t = error_mark_node;
13142 c_parser_consume_token (parser);
13144 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13145 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13146 || (c_parser_peek_token (parser)->keyword
13147 == RID_PRETTY_FUNCTION_NAME)
13148 || (c_parser_peek_token (parser)->keyword
13149 == RID_C99_FUNCTION_NAME)))
13150 t = c_parser_predefined_identifier (parser).value;
13151 else
13153 if (first)
13154 c_parser_error (parser, "expected identifier");
13155 break;
13158 if (t == error_mark_node)
13160 else if (kind != 0)
13162 switch (kind)
13164 case OMP_CLAUSE__CACHE_:
13165 /* The OpenACC cache directive explicitly only allows "array
13166 elements or subarrays". */
13167 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13169 c_parser_error (parser, "expected %<[%>");
13170 t = error_mark_node;
13171 break;
13173 /* FALLTHROUGH */
13174 case OMP_CLAUSE_MAP:
13175 case OMP_CLAUSE_FROM:
13176 case OMP_CLAUSE_TO:
13177 start_component_ref:
13178 while (c_parser_next_token_is (parser, CPP_DOT)
13179 || (allow_deref
13180 && c_parser_next_token_is (parser, CPP_DEREF)))
13182 location_t op_loc = c_parser_peek_token (parser)->location;
13183 location_t arrow_loc = UNKNOWN_LOCATION;
13184 if (c_parser_next_token_is (parser, CPP_DEREF))
13186 c_expr t_expr;
13187 t_expr.value = t;
13188 t_expr.original_code = ERROR_MARK;
13189 t_expr.original_type = NULL;
13190 set_c_expr_source_range (&t_expr, op_loc, op_loc);
13191 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13192 true, false);
13193 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13194 arrow_loc = t_expr.get_location ();
13196 c_parser_consume_token (parser);
13197 if (!c_parser_next_token_is (parser, CPP_NAME))
13199 c_parser_error (parser, "expected identifier");
13200 t = error_mark_node;
13201 break;
13204 c_token *comp_tok = c_parser_peek_token (parser);
13205 tree ident = comp_tok->value;
13206 location_t comp_loc = comp_tok->location;
13207 c_parser_consume_token (parser);
13208 t = build_component_ref (op_loc, t, ident, comp_loc,
13209 arrow_loc);
13211 /* FALLTHROUGH */
13212 case OMP_CLAUSE_AFFINITY:
13213 case OMP_CLAUSE_DEPEND:
13214 case OMP_CLAUSE_REDUCTION:
13215 case OMP_CLAUSE_IN_REDUCTION:
13216 case OMP_CLAUSE_TASK_REDUCTION:
13217 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13218 array_section_p = false;
13219 dims.truncate (0);
13220 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13222 location_t loc = UNKNOWN_LOCATION;
13223 tree low_bound = NULL_TREE, length = NULL_TREE;
13224 bool no_colon = false;
13226 c_parser_consume_token (parser);
13227 if (!c_parser_next_token_is (parser, CPP_COLON))
13229 location_t expr_loc
13230 = c_parser_peek_token (parser)->location;
13231 c_expr expr = c_parser_expression (parser);
13232 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13233 false, true);
13234 low_bound = expr.value;
13235 loc = expr_loc;
13237 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13239 length = integer_one_node;
13240 no_colon = true;
13242 else
13244 /* Look for `:'. */
13245 if (!c_parser_require (parser, CPP_COLON,
13246 "expected %<:%>"))
13248 t = error_mark_node;
13249 break;
13251 array_section_p = true;
13252 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13254 location_t expr_loc
13255 = c_parser_peek_token (parser)->location;
13256 c_expr expr = c_parser_expression (parser);
13257 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13258 false, true);
13259 length = expr.value;
13262 /* Look for the closing `]'. */
13263 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13264 "expected %<]%>"))
13266 t = error_mark_node;
13267 break;
13270 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13273 if (t != error_mark_node)
13275 if ((kind == OMP_CLAUSE_MAP
13276 || kind == OMP_CLAUSE_FROM
13277 || kind == OMP_CLAUSE_TO)
13278 && !array_section_p
13279 && (c_parser_next_token_is (parser, CPP_DOT)
13280 || (allow_deref
13281 && c_parser_next_token_is (parser,
13282 CPP_DEREF))))
13284 for (unsigned i = 0; i < dims.length (); i++)
13286 gcc_assert (dims[i].length == integer_one_node);
13287 t = build_array_ref (dims[i].loc,
13288 t, dims[i].low_bound);
13290 goto start_component_ref;
13292 else
13293 for (unsigned i = 0; i < dims.length (); i++)
13294 t = tree_cons (dims[i].low_bound, dims[i].length, t);
13297 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13298 && t != error_mark_node
13299 && parser->tokens_avail != 2)
13301 if (array_section_p)
13303 error_at (c_parser_peek_token (parser)->location,
13304 "expected %<)%> or %<,%>");
13305 t = error_mark_node;
13307 else
13309 parser->tokens = tokens.address ();
13310 parser->tokens_avail = tokens.length ();
13312 t = c_parser_expr_no_commas (parser, NULL).value;
13313 if (t != error_mark_node && parser->tokens_avail != 2)
13315 error_at (c_parser_peek_token (parser)->location,
13316 "expected %<)%> or %<,%>");
13317 t = error_mark_node;
13321 break;
13322 default:
13323 break;
13326 if (t != error_mark_node)
13328 tree u = build_omp_clause (clause_loc, kind);
13329 OMP_CLAUSE_DECL (u) = t;
13330 OMP_CLAUSE_CHAIN (u) = list;
13331 list = u;
13334 else
13335 list = tree_cons (t, NULL_TREE, list);
13337 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13339 parser->tokens = &parser->tokens_buf[0];
13340 parser->tokens_avail = tokens_avail;
13342 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13343 break;
13345 c_parser_consume_token (parser);
13346 first = false;
13349 return list;
13352 /* Similarly, but expect leading and trailing parenthesis. This is a very
13353 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13354 argument is true if list items can use the deref (->) operator. */
13356 static tree
13357 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13358 tree list, bool allow_deref = false)
13360 /* The clauses location. */
13361 location_t loc = c_parser_peek_token (parser)->location;
13363 matching_parens parens;
13364 if (parens.require_open (parser))
13366 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13367 parens.skip_until_found_close (parser);
13369 return list;
13372 /* OpenACC 2.0:
13373 copy ( variable-list )
13374 copyin ( variable-list )
13375 copyout ( variable-list )
13376 create ( variable-list )
13377 delete ( variable-list )
13378 present ( variable-list )
13380 OpenACC 2.6:
13381 no_create ( variable-list )
13382 attach ( variable-list )
13383 detach ( variable-list ) */
13385 static tree
13386 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13387 tree list)
13389 enum gomp_map_kind kind;
13390 switch (c_kind)
13392 case PRAGMA_OACC_CLAUSE_ATTACH:
13393 kind = GOMP_MAP_ATTACH;
13394 break;
13395 case PRAGMA_OACC_CLAUSE_COPY:
13396 kind = GOMP_MAP_TOFROM;
13397 break;
13398 case PRAGMA_OACC_CLAUSE_COPYIN:
13399 kind = GOMP_MAP_TO;
13400 break;
13401 case PRAGMA_OACC_CLAUSE_COPYOUT:
13402 kind = GOMP_MAP_FROM;
13403 break;
13404 case PRAGMA_OACC_CLAUSE_CREATE:
13405 kind = GOMP_MAP_ALLOC;
13406 break;
13407 case PRAGMA_OACC_CLAUSE_DELETE:
13408 kind = GOMP_MAP_RELEASE;
13409 break;
13410 case PRAGMA_OACC_CLAUSE_DETACH:
13411 kind = GOMP_MAP_DETACH;
13412 break;
13413 case PRAGMA_OACC_CLAUSE_DEVICE:
13414 kind = GOMP_MAP_FORCE_TO;
13415 break;
13416 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13417 kind = GOMP_MAP_DEVICE_RESIDENT;
13418 break;
13419 case PRAGMA_OACC_CLAUSE_HOST:
13420 kind = GOMP_MAP_FORCE_FROM;
13421 break;
13422 case PRAGMA_OACC_CLAUSE_LINK:
13423 kind = GOMP_MAP_LINK;
13424 break;
13425 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13426 kind = GOMP_MAP_IF_PRESENT;
13427 break;
13428 case PRAGMA_OACC_CLAUSE_PRESENT:
13429 kind = GOMP_MAP_FORCE_PRESENT;
13430 break;
13431 default:
13432 gcc_unreachable ();
13434 tree nl, c;
13435 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13437 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13438 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13440 return nl;
13443 /* OpenACC 2.0:
13444 deviceptr ( variable-list ) */
13446 static tree
13447 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13449 location_t loc = c_parser_peek_token (parser)->location;
13450 tree vars, t;
13452 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13453 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13454 variable-list must only allow for pointer variables. */
13455 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13456 for (t = vars; t && t; t = TREE_CHAIN (t))
13458 tree v = TREE_PURPOSE (t);
13460 /* FIXME diagnostics: Ideally we should keep individual
13461 locations for all the variables in the var list to make the
13462 following errors more precise. Perhaps
13463 c_parser_omp_var_list_parens() should construct a list of
13464 locations to go along with the var list. */
13466 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13467 error_at (loc, "%qD is not a variable", v);
13468 else if (TREE_TYPE (v) == error_mark_node)
13470 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13471 error_at (loc, "%qD is not a pointer variable", v);
13473 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13474 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13475 OMP_CLAUSE_DECL (u) = v;
13476 OMP_CLAUSE_CHAIN (u) = list;
13477 list = u;
13480 return list;
13483 /* OpenACC 2.0, OpenMP 3.0:
13484 collapse ( constant-expression ) */
13486 static tree
13487 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13489 tree c, num = error_mark_node;
13490 HOST_WIDE_INT n;
13491 location_t loc;
13493 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13494 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13496 loc = c_parser_peek_token (parser)->location;
13497 matching_parens parens;
13498 if (parens.require_open (parser))
13500 num = c_parser_expr_no_commas (parser, NULL).value;
13501 parens.skip_until_found_close (parser);
13503 if (num == error_mark_node)
13504 return list;
13505 mark_exp_read (num);
13506 num = c_fully_fold (num, false, NULL);
13507 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13508 || !tree_fits_shwi_p (num)
13509 || (n = tree_to_shwi (num)) <= 0
13510 || (int) n != n)
13512 error_at (loc,
13513 "collapse argument needs positive constant integer expression");
13514 return list;
13516 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13517 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13518 OMP_CLAUSE_CHAIN (c) = list;
13519 return c;
13522 /* OpenMP 2.5:
13523 copyin ( variable-list ) */
13525 static tree
13526 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13528 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13531 /* OpenMP 2.5:
13532 copyprivate ( variable-list ) */
13534 static tree
13535 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13537 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13540 /* OpenMP 2.5:
13541 default ( none | shared )
13543 OpenMP 5.1:
13544 default ( private | firstprivate )
13546 OpenACC:
13547 default ( none | present ) */
13549 static tree
13550 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13552 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13553 location_t loc = c_parser_peek_token (parser)->location;
13554 tree c;
13556 matching_parens parens;
13557 if (!parens.require_open (parser))
13558 return list;
13559 if (c_parser_next_token_is (parser, CPP_NAME))
13561 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13563 switch (p[0])
13565 case 'n':
13566 if (strcmp ("none", p) != 0)
13567 goto invalid_kind;
13568 kind = OMP_CLAUSE_DEFAULT_NONE;
13569 break;
13571 case 'p':
13572 if (is_oacc)
13574 if (strcmp ("present", p) != 0)
13575 goto invalid_kind;
13576 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13578 else
13580 if (strcmp ("private", p) != 0)
13581 goto invalid_kind;
13582 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
13584 break;
13586 case 'f':
13587 if (strcmp ("firstprivate", p) != 0 || is_oacc)
13588 goto invalid_kind;
13589 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13590 break;
13592 case 's':
13593 if (strcmp ("shared", p) != 0 || is_oacc)
13594 goto invalid_kind;
13595 kind = OMP_CLAUSE_DEFAULT_SHARED;
13596 break;
13598 default:
13599 goto invalid_kind;
13602 c_parser_consume_token (parser);
13604 else
13606 invalid_kind:
13607 if (is_oacc)
13608 c_parser_error (parser, "expected %<none%> or %<present%>");
13609 else
13610 c_parser_error (parser, "expected %<none%>, %<shared%>, "
13611 "%<private%> or %<firstprivate%>");
13613 parens.skip_until_found_close (parser);
13615 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13616 return list;
13618 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13619 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13620 OMP_CLAUSE_CHAIN (c) = list;
13621 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13623 return c;
13626 /* OpenMP 2.5:
13627 firstprivate ( variable-list ) */
13629 static tree
13630 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13632 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13635 /* OpenMP 3.1:
13636 final ( expression ) */
13638 static tree
13639 c_parser_omp_clause_final (c_parser *parser, tree list)
13641 location_t loc = c_parser_peek_token (parser)->location;
13642 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13644 matching_parens parens;
13645 tree t, c;
13646 if (!parens.require_open (parser))
13647 t = error_mark_node;
13648 else
13650 location_t eloc = c_parser_peek_token (parser)->location;
13651 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13652 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13653 t = c_objc_common_truthvalue_conversion (eloc, t);
13654 t = c_fully_fold (t, false, NULL);
13655 parens.skip_until_found_close (parser);
13658 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13660 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13661 OMP_CLAUSE_FINAL_EXPR (c) = t;
13662 OMP_CLAUSE_CHAIN (c) = list;
13663 list = c;
13665 else
13666 c_parser_error (parser, "expected %<(%>");
13668 return list;
13671 /* OpenACC, OpenMP 2.5:
13672 if ( expression )
13674 OpenMP 4.5:
13675 if ( directive-name-modifier : expression )
13677 directive-name-modifier:
13678 parallel | task | taskloop | target data | target | target update
13679 | target enter data | target exit data
13681 OpenMP 5.0:
13682 directive-name-modifier:
13683 ... | simd | cancel */
13685 static tree
13686 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13688 location_t location = c_parser_peek_token (parser)->location;
13689 enum tree_code if_modifier = ERROR_MARK;
13691 matching_parens parens;
13692 if (!parens.require_open (parser))
13693 return list;
13695 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13697 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13698 int n = 2;
13699 if (strcmp (p, "cancel") == 0)
13700 if_modifier = VOID_CST;
13701 else if (strcmp (p, "parallel") == 0)
13702 if_modifier = OMP_PARALLEL;
13703 else if (strcmp (p, "simd") == 0)
13704 if_modifier = OMP_SIMD;
13705 else if (strcmp (p, "task") == 0)
13706 if_modifier = OMP_TASK;
13707 else if (strcmp (p, "taskloop") == 0)
13708 if_modifier = OMP_TASKLOOP;
13709 else if (strcmp (p, "target") == 0)
13711 if_modifier = OMP_TARGET;
13712 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13714 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13715 if (strcmp ("data", p) == 0)
13716 if_modifier = OMP_TARGET_DATA;
13717 else if (strcmp ("update", p) == 0)
13718 if_modifier = OMP_TARGET_UPDATE;
13719 else if (strcmp ("enter", p) == 0)
13720 if_modifier = OMP_TARGET_ENTER_DATA;
13721 else if (strcmp ("exit", p) == 0)
13722 if_modifier = OMP_TARGET_EXIT_DATA;
13723 if (if_modifier != OMP_TARGET)
13725 n = 3;
13726 c_parser_consume_token (parser);
13728 else
13730 location_t loc = c_parser_peek_2nd_token (parser)->location;
13731 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13732 "or %<exit%>");
13733 if_modifier = ERROR_MARK;
13735 if (if_modifier == OMP_TARGET_ENTER_DATA
13736 || if_modifier == OMP_TARGET_EXIT_DATA)
13738 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13740 p = IDENTIFIER_POINTER
13741 (c_parser_peek_2nd_token (parser)->value);
13742 if (strcmp ("data", p) == 0)
13743 n = 4;
13745 if (n == 4)
13746 c_parser_consume_token (parser);
13747 else
13749 location_t loc
13750 = c_parser_peek_2nd_token (parser)->location;
13751 error_at (loc, "expected %<data%>");
13752 if_modifier = ERROR_MARK;
13757 if (if_modifier != ERROR_MARK)
13759 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13761 c_parser_consume_token (parser);
13762 c_parser_consume_token (parser);
13764 else
13766 if (n > 2)
13768 location_t loc = c_parser_peek_2nd_token (parser)->location;
13769 error_at (loc, "expected %<:%>");
13771 if_modifier = ERROR_MARK;
13776 location_t loc = c_parser_peek_token (parser)->location;
13777 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13778 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13779 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13780 t = c_fully_fold (t, false, NULL);
13781 parens.skip_until_found_close (parser);
13783 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13784 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13786 if (if_modifier != ERROR_MARK
13787 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13789 const char *p = NULL;
13790 switch (if_modifier)
13792 case VOID_CST: p = "cancel"; break;
13793 case OMP_PARALLEL: p = "parallel"; break;
13794 case OMP_SIMD: p = "simd"; break;
13795 case OMP_TASK: p = "task"; break;
13796 case OMP_TASKLOOP: p = "taskloop"; break;
13797 case OMP_TARGET_DATA: p = "target data"; break;
13798 case OMP_TARGET: p = "target"; break;
13799 case OMP_TARGET_UPDATE: p = "target update"; break;
13800 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13801 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13802 default: gcc_unreachable ();
13804 error_at (location, "too many %<if%> clauses with %qs modifier",
13806 return list;
13808 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13810 if (!is_omp)
13811 error_at (location, "too many %<if%> clauses");
13812 else
13813 error_at (location, "too many %<if%> clauses without modifier");
13814 return list;
13816 else if (if_modifier == ERROR_MARK
13817 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13819 error_at (location, "if any %<if%> clause has modifier, then all "
13820 "%<if%> clauses have to use modifier");
13821 return list;
13825 c = build_omp_clause (location, OMP_CLAUSE_IF);
13826 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13827 OMP_CLAUSE_IF_EXPR (c) = t;
13828 OMP_CLAUSE_CHAIN (c) = list;
13829 return c;
13832 /* OpenMP 2.5:
13833 lastprivate ( variable-list )
13835 OpenMP 5.0:
13836 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13838 static tree
13839 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13841 /* The clauses location. */
13842 location_t loc = c_parser_peek_token (parser)->location;
13844 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13846 bool conditional = false;
13847 if (c_parser_next_token_is (parser, CPP_NAME)
13848 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13850 const char *p
13851 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13852 if (strcmp (p, "conditional") == 0)
13854 conditional = true;
13855 c_parser_consume_token (parser);
13856 c_parser_consume_token (parser);
13859 tree nlist = c_parser_omp_variable_list (parser, loc,
13860 OMP_CLAUSE_LASTPRIVATE, list);
13861 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13862 if (conditional)
13863 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13864 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13865 return nlist;
13867 return list;
13870 /* OpenMP 3.1:
13871 mergeable */
13873 static tree
13874 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13876 tree c;
13878 /* FIXME: Should we allow duplicates? */
13879 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13881 c = build_omp_clause (c_parser_peek_token (parser)->location,
13882 OMP_CLAUSE_MERGEABLE);
13883 OMP_CLAUSE_CHAIN (c) = list;
13885 return c;
13888 /* OpenMP 2.5:
13889 nowait */
13891 static tree
13892 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13894 tree c;
13895 location_t loc = c_parser_peek_token (parser)->location;
13897 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13899 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13900 OMP_CLAUSE_CHAIN (c) = list;
13901 return c;
13904 /* OpenMP 2.5:
13905 num_threads ( expression ) */
13907 static tree
13908 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13910 location_t num_threads_loc = c_parser_peek_token (parser)->location;
13911 matching_parens parens;
13912 if (parens.require_open (parser))
13914 location_t expr_loc = c_parser_peek_token (parser)->location;
13915 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13916 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13917 tree c, t = expr.value;
13918 t = c_fully_fold (t, false, NULL);
13920 parens.skip_until_found_close (parser);
13922 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13924 c_parser_error (parser, "expected integer expression");
13925 return list;
13928 /* Attempt to statically determine when the number isn't positive. */
13929 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13930 build_int_cst (TREE_TYPE (t), 0));
13931 protected_set_expr_location (c, expr_loc);
13932 if (c == boolean_true_node)
13934 warning_at (expr_loc, 0,
13935 "%<num_threads%> value must be positive");
13936 t = integer_one_node;
13939 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13941 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13942 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13943 OMP_CLAUSE_CHAIN (c) = list;
13944 list = c;
13947 return list;
13950 /* OpenMP 4.5:
13951 num_tasks ( expression )
13953 OpenMP 5.1:
13954 num_tasks ( strict : expression ) */
13956 static tree
13957 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13959 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13960 matching_parens parens;
13961 if (parens.require_open (parser))
13963 bool strict = false;
13964 if (c_parser_next_token_is (parser, CPP_NAME)
13965 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
13966 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
13967 "strict") == 0)
13969 strict = true;
13970 c_parser_consume_token (parser);
13971 c_parser_consume_token (parser);
13974 location_t expr_loc = c_parser_peek_token (parser)->location;
13975 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13976 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13977 tree c, t = expr.value;
13978 t = c_fully_fold (t, false, NULL);
13980 parens.skip_until_found_close (parser);
13982 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13984 c_parser_error (parser, "expected integer expression");
13985 return list;
13988 /* Attempt to statically determine when the number isn't positive. */
13989 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13990 build_int_cst (TREE_TYPE (t), 0));
13991 if (CAN_HAVE_LOCATION_P (c))
13992 SET_EXPR_LOCATION (c, expr_loc);
13993 if (c == boolean_true_node)
13995 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13996 t = integer_one_node;
13999 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
14001 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
14002 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
14003 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
14004 OMP_CLAUSE_CHAIN (c) = list;
14005 list = c;
14008 return list;
14011 /* OpenMP 4.5:
14012 grainsize ( expression )
14014 OpenMP 5.1:
14015 grainsize ( strict : expression ) */
14017 static tree
14018 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
14020 location_t grainsize_loc = c_parser_peek_token (parser)->location;
14021 matching_parens parens;
14022 if (parens.require_open (parser))
14024 bool strict = false;
14025 if (c_parser_next_token_is (parser, CPP_NAME)
14026 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14027 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14028 "strict") == 0)
14030 strict = true;
14031 c_parser_consume_token (parser);
14032 c_parser_consume_token (parser);
14035 location_t expr_loc = c_parser_peek_token (parser)->location;
14036 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14037 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14038 tree c, t = expr.value;
14039 t = c_fully_fold (t, false, NULL);
14041 parens.skip_until_found_close (parser);
14043 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14045 c_parser_error (parser, "expected integer expression");
14046 return list;
14049 /* Attempt to statically determine when the number isn't positive. */
14050 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14051 build_int_cst (TREE_TYPE (t), 0));
14052 if (CAN_HAVE_LOCATION_P (c))
14053 SET_EXPR_LOCATION (c, expr_loc);
14054 if (c == boolean_true_node)
14056 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14057 t = integer_one_node;
14060 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14062 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14063 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14064 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14065 OMP_CLAUSE_CHAIN (c) = list;
14066 list = c;
14069 return list;
14072 /* OpenMP 4.5:
14073 priority ( expression ) */
14075 static tree
14076 c_parser_omp_clause_priority (c_parser *parser, tree list)
14078 location_t priority_loc = c_parser_peek_token (parser)->location;
14079 matching_parens parens;
14080 if (parens.require_open (parser))
14082 location_t expr_loc = c_parser_peek_token (parser)->location;
14083 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14084 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14085 tree c, t = expr.value;
14086 t = c_fully_fold (t, false, NULL);
14088 parens.skip_until_found_close (parser);
14090 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14092 c_parser_error (parser, "expected integer expression");
14093 return list;
14096 /* Attempt to statically determine when the number isn't
14097 non-negative. */
14098 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14099 build_int_cst (TREE_TYPE (t), 0));
14100 if (CAN_HAVE_LOCATION_P (c))
14101 SET_EXPR_LOCATION (c, expr_loc);
14102 if (c == boolean_true_node)
14104 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14105 t = integer_one_node;
14108 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14110 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14111 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14112 OMP_CLAUSE_CHAIN (c) = list;
14113 list = c;
14116 return list;
14119 /* OpenMP 4.5:
14120 hint ( expression ) */
14122 static tree
14123 c_parser_omp_clause_hint (c_parser *parser, tree list)
14125 location_t hint_loc = c_parser_peek_token (parser)->location;
14126 matching_parens parens;
14127 if (parens.require_open (parser))
14129 location_t expr_loc = c_parser_peek_token (parser)->location;
14130 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14131 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14132 tree c, t = expr.value;
14133 t = c_fully_fold (t, false, NULL);
14134 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14135 || TREE_CODE (t) != INTEGER_CST
14136 || tree_int_cst_sgn (t) == -1)
14138 c_parser_error (parser, "expected constant integer expression "
14139 "with valid sync-hint value");
14140 return list;
14142 parens.skip_until_found_close (parser);
14143 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14145 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14146 OMP_CLAUSE_HINT_EXPR (c) = t;
14147 OMP_CLAUSE_CHAIN (c) = list;
14148 list = c;
14151 return list;
14154 /* OpenMP 5.1:
14155 filter ( integer-expression ) */
14157 static tree
14158 c_parser_omp_clause_filter (c_parser *parser, tree list)
14160 location_t hint_loc = c_parser_peek_token (parser)->location;
14161 matching_parens parens;
14162 if (parens.require_open (parser))
14164 location_t expr_loc = c_parser_peek_token (parser)->location;
14165 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14166 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14167 tree c, t = expr.value;
14168 t = c_fully_fold (t, false, NULL);
14169 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14171 c_parser_error (parser, "expected integer expression");
14172 return list;
14174 parens.skip_until_found_close (parser);
14175 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14177 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14178 OMP_CLAUSE_FILTER_EXPR (c) = t;
14179 OMP_CLAUSE_CHAIN (c) = list;
14180 list = c;
14183 return list;
14186 /* OpenMP 4.5:
14187 defaultmap ( tofrom : scalar )
14189 OpenMP 5.0:
14190 defaultmap ( implicit-behavior [ : variable-category ] ) */
14192 static tree
14193 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14195 location_t loc = c_parser_peek_token (parser)->location;
14196 tree c;
14197 const char *p;
14198 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14199 enum omp_clause_defaultmap_kind category
14200 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14202 matching_parens parens;
14203 if (!parens.require_open (parser))
14204 return list;
14205 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14206 p = "default";
14207 else if (!c_parser_next_token_is (parser, CPP_NAME))
14209 invalid_behavior:
14210 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14211 "%<tofrom%>, %<firstprivate%>, %<none%> "
14212 "or %<default%>");
14213 goto out_err;
14215 else
14216 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14218 switch (p[0])
14220 case 'a':
14221 if (strcmp ("alloc", p) == 0)
14222 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14223 else
14224 goto invalid_behavior;
14225 break;
14227 case 'd':
14228 if (strcmp ("default", p) == 0)
14229 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14230 else
14231 goto invalid_behavior;
14232 break;
14234 case 'f':
14235 if (strcmp ("firstprivate", p) == 0)
14236 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14237 else if (strcmp ("from", p) == 0)
14238 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14239 else
14240 goto invalid_behavior;
14241 break;
14243 case 'n':
14244 if (strcmp ("none", p) == 0)
14245 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14246 else
14247 goto invalid_behavior;
14248 break;
14250 case 't':
14251 if (strcmp ("tofrom", p) == 0)
14252 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14253 else if (strcmp ("to", p) == 0)
14254 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14255 else
14256 goto invalid_behavior;
14257 break;
14259 default:
14260 goto invalid_behavior;
14262 c_parser_consume_token (parser);
14264 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14266 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14267 goto out_err;
14268 if (!c_parser_next_token_is (parser, CPP_NAME))
14270 invalid_category:
14271 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14272 "%<pointer%>");
14273 goto out_err;
14275 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14276 switch (p[0])
14278 case 'a':
14279 if (strcmp ("aggregate", p) == 0)
14280 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14281 else
14282 goto invalid_category;
14283 break;
14285 case 'p':
14286 if (strcmp ("pointer", p) == 0)
14287 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14288 else
14289 goto invalid_category;
14290 break;
14292 case 's':
14293 if (strcmp ("scalar", p) == 0)
14294 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14295 else
14296 goto invalid_category;
14297 break;
14299 default:
14300 goto invalid_category;
14303 c_parser_consume_token (parser);
14305 parens.skip_until_found_close (parser);
14307 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14308 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14309 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14310 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14311 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14312 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14314 enum omp_clause_defaultmap_kind cat = category;
14315 location_t loc = OMP_CLAUSE_LOCATION (c);
14316 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14317 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14318 p = NULL;
14319 switch (cat)
14321 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14322 p = NULL;
14323 break;
14324 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14325 p = "aggregate";
14326 break;
14327 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14328 p = "pointer";
14329 break;
14330 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14331 p = "scalar";
14332 break;
14333 default:
14334 gcc_unreachable ();
14336 if (p)
14337 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14339 else
14340 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14341 "category");
14342 break;
14345 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14346 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14347 OMP_CLAUSE_CHAIN (c) = list;
14348 return c;
14350 out_err:
14351 parens.skip_until_found_close (parser);
14352 return list;
14355 /* OpenACC 2.0:
14356 use_device ( variable-list )
14358 OpenMP 4.5:
14359 use_device_ptr ( variable-list ) */
14361 static tree
14362 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14364 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14365 list);
14368 /* OpenMP 5.0:
14369 use_device_addr ( variable-list ) */
14371 static tree
14372 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14374 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14375 list);
14378 /* OpenMP 5.1:
14379 has_device_addr ( variable-list ) */
14381 static tree
14382 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
14384 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
14385 list);
14388 /* OpenMP 4.5:
14389 is_device_ptr ( variable-list ) */
14391 static tree
14392 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14394 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14397 /* OpenACC:
14398 num_gangs ( expression )
14399 num_workers ( expression )
14400 vector_length ( expression ) */
14402 static tree
14403 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14404 tree list)
14406 location_t loc = c_parser_peek_token (parser)->location;
14408 matching_parens parens;
14409 if (!parens.require_open (parser))
14410 return list;
14412 location_t expr_loc = c_parser_peek_token (parser)->location;
14413 c_expr expr = c_parser_expression (parser);
14414 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14415 tree c, t = expr.value;
14416 t = c_fully_fold (t, false, NULL);
14418 parens.skip_until_found_close (parser);
14420 if (t == error_mark_node)
14421 return list;
14422 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14424 error_at (expr_loc, "%qs expression must be integral",
14425 omp_clause_code_name[code]);
14426 return list;
14429 /* Attempt to statically determine when the number isn't positive. */
14430 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14431 build_int_cst (TREE_TYPE (t), 0));
14432 protected_set_expr_location (c, expr_loc);
14433 if (c == boolean_true_node)
14435 warning_at (expr_loc, 0,
14436 "%qs value must be positive",
14437 omp_clause_code_name[code]);
14438 t = integer_one_node;
14441 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14443 c = build_omp_clause (loc, code);
14444 OMP_CLAUSE_OPERAND (c, 0) = t;
14445 OMP_CLAUSE_CHAIN (c) = list;
14446 return c;
14449 /* OpenACC:
14451 gang [( gang-arg-list )]
14452 worker [( [num:] int-expr )]
14453 vector [( [length:] int-expr )]
14455 where gang-arg is one of:
14457 [num:] int-expr
14458 static: size-expr
14460 and size-expr may be:
14463 int-expr
14466 static tree
14467 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14468 omp_clause_code kind,
14469 const char *str, tree list)
14471 const char *id = "num";
14472 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14474 if (kind == OMP_CLAUSE_VECTOR)
14475 id = "length";
14477 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14479 c_parser_consume_token (parser);
14483 c_token *next = c_parser_peek_token (parser);
14484 int idx = 0;
14486 /* Gang static argument. */
14487 if (kind == OMP_CLAUSE_GANG
14488 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14490 c_parser_consume_token (parser);
14492 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14493 goto cleanup_error;
14495 idx = 1;
14496 if (ops[idx] != NULL_TREE)
14498 c_parser_error (parser, "too many %<static%> arguments");
14499 goto cleanup_error;
14502 /* Check for the '*' argument. */
14503 if (c_parser_next_token_is (parser, CPP_MULT)
14504 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14505 || c_parser_peek_2nd_token (parser)->type
14506 == CPP_CLOSE_PAREN))
14508 c_parser_consume_token (parser);
14509 ops[idx] = integer_minus_one_node;
14511 if (c_parser_next_token_is (parser, CPP_COMMA))
14513 c_parser_consume_token (parser);
14514 continue;
14516 else
14517 break;
14520 /* Worker num: argument and vector length: arguments. */
14521 else if (c_parser_next_token_is (parser, CPP_NAME)
14522 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14523 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14525 c_parser_consume_token (parser); /* id */
14526 c_parser_consume_token (parser); /* ':' */
14529 /* Now collect the actual argument. */
14530 if (ops[idx] != NULL_TREE)
14532 c_parser_error (parser, "unexpected argument");
14533 goto cleanup_error;
14536 location_t expr_loc = c_parser_peek_token (parser)->location;
14537 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14538 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14539 tree expr = cexpr.value;
14540 if (expr == error_mark_node)
14541 goto cleanup_error;
14543 expr = c_fully_fold (expr, false, NULL);
14545 /* Attempt to statically determine when the number isn't a
14546 positive integer. */
14548 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14550 c_parser_error (parser, "expected integer expression");
14551 return list;
14554 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14555 build_int_cst (TREE_TYPE (expr), 0));
14556 if (c == boolean_true_node)
14558 warning_at (loc, 0,
14559 "%qs value must be positive", str);
14560 expr = integer_one_node;
14563 ops[idx] = expr;
14565 if (kind == OMP_CLAUSE_GANG
14566 && c_parser_next_token_is (parser, CPP_COMMA))
14568 c_parser_consume_token (parser);
14569 continue;
14571 break;
14573 while (1);
14575 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14576 goto cleanup_error;
14579 check_no_duplicate_clause (list, kind, str);
14581 c = build_omp_clause (loc, kind);
14583 if (ops[1])
14584 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14586 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14587 OMP_CLAUSE_CHAIN (c) = list;
14589 return c;
14591 cleanup_error:
14592 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14593 return list;
14596 /* OpenACC 2.5:
14597 auto
14598 finalize
14599 independent
14600 nohost
14601 seq */
14603 static tree
14604 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14605 tree list)
14607 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14609 tree c = build_omp_clause (loc, code);
14610 OMP_CLAUSE_CHAIN (c) = list;
14612 return c;
14615 /* OpenACC:
14616 async [( int-expr )] */
14618 static tree
14619 c_parser_oacc_clause_async (c_parser *parser, tree list)
14621 tree c, t;
14622 location_t loc = c_parser_peek_token (parser)->location;
14624 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14626 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14628 c_parser_consume_token (parser);
14630 t = c_parser_expr_no_commas (parser, NULL).value;
14631 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14632 c_parser_error (parser, "expected integer expression");
14633 else if (t == error_mark_node
14634 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14635 return list;
14637 else
14638 t = c_fully_fold (t, false, NULL);
14640 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14642 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14643 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14644 OMP_CLAUSE_CHAIN (c) = list;
14645 list = c;
14647 return list;
14650 /* OpenACC 2.0:
14651 tile ( size-expr-list ) */
14653 static tree
14654 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14656 tree c, expr = error_mark_node;
14657 location_t loc;
14658 tree tile = NULL_TREE;
14660 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14661 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14663 loc = c_parser_peek_token (parser)->location;
14664 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14665 return list;
14669 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14670 return list;
14672 if (c_parser_next_token_is (parser, CPP_MULT)
14673 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14674 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14676 c_parser_consume_token (parser);
14677 expr = integer_zero_node;
14679 else
14681 location_t expr_loc = c_parser_peek_token (parser)->location;
14682 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14683 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14684 expr = cexpr.value;
14686 if (expr == error_mark_node)
14688 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14689 "expected %<)%>");
14690 return list;
14693 expr = c_fully_fold (expr, false, NULL);
14695 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14696 || !tree_fits_shwi_p (expr)
14697 || tree_to_shwi (expr) <= 0)
14699 error_at (expr_loc, "%<tile%> argument needs positive"
14700 " integral constant");
14701 expr = integer_zero_node;
14705 tile = tree_cons (NULL_TREE, expr, tile);
14707 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14709 /* Consume the trailing ')'. */
14710 c_parser_consume_token (parser);
14712 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14713 tile = nreverse (tile);
14714 OMP_CLAUSE_TILE_LIST (c) = tile;
14715 OMP_CLAUSE_CHAIN (c) = list;
14716 return c;
14719 /* OpenACC:
14720 wait [( int-expr-list )] */
14722 static tree
14723 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14725 location_t clause_loc = c_parser_peek_token (parser)->location;
14727 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14728 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14729 else
14731 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14733 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14734 OMP_CLAUSE_CHAIN (c) = list;
14735 list = c;
14738 return list;
14742 /* OpenMP 5.0:
14743 order ( concurrent )
14745 OpenMP 5.1:
14746 order ( order-modifier : concurrent )
14748 order-modifier:
14749 reproducible
14750 unconstrained */
14752 static tree
14753 c_parser_omp_clause_order (c_parser *parser, tree list)
14755 location_t loc = c_parser_peek_token (parser)->location;
14756 tree c;
14757 const char *p;
14758 bool unconstrained = false;
14759 bool reproducible = false;
14761 matching_parens parens;
14762 if (!parens.require_open (parser))
14763 return list;
14764 if (c_parser_next_token_is (parser, CPP_NAME)
14765 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14767 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14768 if (strcmp (p, "unconstrained") == 0)
14769 unconstrained = true;
14770 else if (strcmp (p, "reproducible") == 0)
14771 reproducible = true;
14772 else
14774 c_parser_error (parser, "expected %<reproducible%> or "
14775 "%<unconstrained%>");
14776 goto out_err;
14778 c_parser_consume_token (parser);
14779 c_parser_consume_token (parser);
14781 if (!c_parser_next_token_is (parser, CPP_NAME))
14783 c_parser_error (parser, "expected %<concurrent%>");
14784 goto out_err;
14786 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14787 if (strcmp (p, "concurrent") != 0)
14789 c_parser_error (parser, "expected %<concurrent%>");
14790 goto out_err;
14792 c_parser_consume_token (parser);
14793 parens.skip_until_found_close (parser);
14794 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
14795 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14796 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
14797 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
14798 OMP_CLAUSE_CHAIN (c) = list;
14799 return c;
14801 out_err:
14802 parens.skip_until_found_close (parser);
14803 return list;
14807 /* OpenMP 5.0:
14808 bind ( teams | parallel | thread ) */
14810 static tree
14811 c_parser_omp_clause_bind (c_parser *parser, tree list)
14813 location_t loc = c_parser_peek_token (parser)->location;
14814 tree c;
14815 const char *p;
14816 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14818 matching_parens parens;
14819 if (!parens.require_open (parser))
14820 return list;
14821 if (!c_parser_next_token_is (parser, CPP_NAME))
14823 invalid:
14824 c_parser_error (parser,
14825 "expected %<teams%>, %<parallel%> or %<thread%>");
14826 parens.skip_until_found_close (parser);
14827 return list;
14829 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14830 if (strcmp (p, "teams") == 0)
14831 kind = OMP_CLAUSE_BIND_TEAMS;
14832 else if (strcmp (p, "parallel") == 0)
14833 kind = OMP_CLAUSE_BIND_PARALLEL;
14834 else if (strcmp (p, "thread") != 0)
14835 goto invalid;
14836 c_parser_consume_token (parser);
14837 parens.skip_until_found_close (parser);
14838 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14839 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14840 OMP_CLAUSE_BIND_KIND (c) = kind;
14841 OMP_CLAUSE_CHAIN (c) = list;
14842 return c;
14846 /* OpenMP 2.5:
14847 ordered
14849 OpenMP 4.5:
14850 ordered ( constant-expression ) */
14852 static tree
14853 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14855 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14857 tree c, num = NULL_TREE;
14858 HOST_WIDE_INT n;
14859 location_t loc = c_parser_peek_token (parser)->location;
14860 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14862 matching_parens parens;
14863 parens.consume_open (parser);
14864 num = c_parser_expr_no_commas (parser, NULL).value;
14865 parens.skip_until_found_close (parser);
14867 if (num == error_mark_node)
14868 return list;
14869 if (num)
14871 mark_exp_read (num);
14872 num = c_fully_fold (num, false, NULL);
14873 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14874 || !tree_fits_shwi_p (num)
14875 || (n = tree_to_shwi (num)) <= 0
14876 || (int) n != n)
14878 error_at (loc, "ordered argument needs positive "
14879 "constant integer expression");
14880 return list;
14883 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14884 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14885 OMP_CLAUSE_CHAIN (c) = list;
14886 return c;
14889 /* OpenMP 2.5:
14890 private ( variable-list ) */
14892 static tree
14893 c_parser_omp_clause_private (c_parser *parser, tree list)
14895 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14898 /* OpenMP 2.5:
14899 reduction ( reduction-operator : variable-list )
14901 reduction-operator:
14902 One of: + * - & ^ | && ||
14904 OpenMP 3.1:
14906 reduction-operator:
14907 One of: + * - & ^ | && || max min
14909 OpenMP 4.0:
14911 reduction-operator:
14912 One of: + * - & ^ | && ||
14913 identifier
14915 OpenMP 5.0:
14916 reduction ( reduction-modifier, reduction-operator : variable-list )
14917 in_reduction ( reduction-operator : variable-list )
14918 task_reduction ( reduction-operator : variable-list ) */
14920 static tree
14921 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14922 bool is_omp, tree list)
14924 location_t clause_loc = c_parser_peek_token (parser)->location;
14925 matching_parens parens;
14926 if (parens.require_open (parser))
14928 bool task = false;
14929 bool inscan = false;
14930 enum tree_code code = ERROR_MARK;
14931 tree reduc_id = NULL_TREE;
14933 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14935 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14936 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14938 c_parser_consume_token (parser);
14939 c_parser_consume_token (parser);
14941 else if (c_parser_next_token_is (parser, CPP_NAME)
14942 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14944 const char *p
14945 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14946 if (strcmp (p, "task") == 0)
14947 task = true;
14948 else if (strcmp (p, "inscan") == 0)
14949 inscan = true;
14950 if (task || inscan)
14952 c_parser_consume_token (parser);
14953 c_parser_consume_token (parser);
14958 switch (c_parser_peek_token (parser)->type)
14960 case CPP_PLUS:
14961 code = PLUS_EXPR;
14962 break;
14963 case CPP_MULT:
14964 code = MULT_EXPR;
14965 break;
14966 case CPP_MINUS:
14967 code = MINUS_EXPR;
14968 break;
14969 case CPP_AND:
14970 code = BIT_AND_EXPR;
14971 break;
14972 case CPP_XOR:
14973 code = BIT_XOR_EXPR;
14974 break;
14975 case CPP_OR:
14976 code = BIT_IOR_EXPR;
14977 break;
14978 case CPP_AND_AND:
14979 code = TRUTH_ANDIF_EXPR;
14980 break;
14981 case CPP_OR_OR:
14982 code = TRUTH_ORIF_EXPR;
14983 break;
14984 case CPP_NAME:
14986 const char *p
14987 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14988 if (strcmp (p, "min") == 0)
14990 code = MIN_EXPR;
14991 break;
14993 if (strcmp (p, "max") == 0)
14995 code = MAX_EXPR;
14996 break;
14998 reduc_id = c_parser_peek_token (parser)->value;
14999 break;
15001 default:
15002 c_parser_error (parser,
15003 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15004 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15005 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15006 return list;
15008 c_parser_consume_token (parser);
15009 reduc_id = c_omp_reduction_id (code, reduc_id);
15010 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15012 tree nl, c;
15014 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
15015 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15017 tree d = OMP_CLAUSE_DECL (c), type;
15018 if (TREE_CODE (d) != TREE_LIST)
15019 type = TREE_TYPE (d);
15020 else
15022 int cnt = 0;
15023 tree t;
15024 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
15025 cnt++;
15026 type = TREE_TYPE (t);
15027 while (cnt > 0)
15029 if (TREE_CODE (type) != POINTER_TYPE
15030 && TREE_CODE (type) != ARRAY_TYPE)
15031 break;
15032 type = TREE_TYPE (type);
15033 cnt--;
15036 while (TREE_CODE (type) == ARRAY_TYPE)
15037 type = TREE_TYPE (type);
15038 OMP_CLAUSE_REDUCTION_CODE (c) = code;
15039 if (task)
15040 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15041 else if (inscan)
15042 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15043 if (code == ERROR_MARK
15044 || !(INTEGRAL_TYPE_P (type)
15045 || TREE_CODE (type) == REAL_TYPE
15046 || TREE_CODE (type) == COMPLEX_TYPE))
15047 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15048 = c_omp_reduction_lookup (reduc_id,
15049 TYPE_MAIN_VARIANT (type));
15052 list = nl;
15054 parens.skip_until_found_close (parser);
15056 return list;
15059 /* OpenMP 2.5:
15060 schedule ( schedule-kind )
15061 schedule ( schedule-kind , expression )
15063 schedule-kind:
15064 static | dynamic | guided | runtime | auto
15066 OpenMP 4.5:
15067 schedule ( schedule-modifier : schedule-kind )
15068 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15070 schedule-modifier:
15071 simd
15072 monotonic
15073 nonmonotonic */
15075 static tree
15076 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15078 tree c, t;
15079 location_t loc = c_parser_peek_token (parser)->location;
15080 int modifiers = 0, nmodifiers = 0;
15082 matching_parens parens;
15083 if (!parens.require_open (parser))
15084 return list;
15086 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15088 location_t comma = UNKNOWN_LOCATION;
15089 while (c_parser_next_token_is (parser, CPP_NAME))
15091 tree kind = c_parser_peek_token (parser)->value;
15092 const char *p = IDENTIFIER_POINTER (kind);
15093 if (strcmp ("simd", p) == 0)
15094 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15095 else if (strcmp ("monotonic", p) == 0)
15096 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15097 else if (strcmp ("nonmonotonic", p) == 0)
15098 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15099 else
15100 break;
15101 comma = UNKNOWN_LOCATION;
15102 c_parser_consume_token (parser);
15103 if (nmodifiers++ == 0
15104 && c_parser_next_token_is (parser, CPP_COMMA))
15106 comma = c_parser_peek_token (parser)->location;
15107 c_parser_consume_token (parser);
15109 else
15111 c_parser_require (parser, CPP_COLON, "expected %<:%>");
15112 break;
15115 if (comma != UNKNOWN_LOCATION)
15116 error_at (comma, "expected %<:%>");
15118 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15119 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15120 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15121 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15123 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15124 "specified");
15125 modifiers = 0;
15128 if (c_parser_next_token_is (parser, CPP_NAME))
15130 tree kind = c_parser_peek_token (parser)->value;
15131 const char *p = IDENTIFIER_POINTER (kind);
15133 switch (p[0])
15135 case 'd':
15136 if (strcmp ("dynamic", p) != 0)
15137 goto invalid_kind;
15138 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15139 break;
15141 case 'g':
15142 if (strcmp ("guided", p) != 0)
15143 goto invalid_kind;
15144 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15145 break;
15147 case 'r':
15148 if (strcmp ("runtime", p) != 0)
15149 goto invalid_kind;
15150 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15151 break;
15153 default:
15154 goto invalid_kind;
15157 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15158 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15159 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15160 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15161 else
15162 goto invalid_kind;
15164 c_parser_consume_token (parser);
15165 if (c_parser_next_token_is (parser, CPP_COMMA))
15167 location_t here;
15168 c_parser_consume_token (parser);
15170 here = c_parser_peek_token (parser)->location;
15171 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15172 expr = convert_lvalue_to_rvalue (here, expr, false, true);
15173 t = expr.value;
15174 t = c_fully_fold (t, false, NULL);
15176 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15177 error_at (here, "schedule %<runtime%> does not take "
15178 "a %<chunk_size%> parameter");
15179 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15180 error_at (here,
15181 "schedule %<auto%> does not take "
15182 "a %<chunk_size%> parameter");
15183 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15185 /* Attempt to statically determine when the number isn't
15186 positive. */
15187 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15188 build_int_cst (TREE_TYPE (t), 0));
15189 protected_set_expr_location (s, loc);
15190 if (s == boolean_true_node)
15192 warning_at (loc, 0,
15193 "chunk size value must be positive");
15194 t = integer_one_node;
15196 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15198 else
15199 c_parser_error (parser, "expected integer expression");
15201 parens.skip_until_found_close (parser);
15203 else
15204 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15205 "expected %<,%> or %<)%>");
15207 OMP_CLAUSE_SCHEDULE_KIND (c)
15208 = (enum omp_clause_schedule_kind)
15209 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15211 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15212 OMP_CLAUSE_CHAIN (c) = list;
15213 return c;
15215 invalid_kind:
15216 c_parser_error (parser, "invalid schedule kind");
15217 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15218 return list;
15221 /* OpenMP 2.5:
15222 shared ( variable-list ) */
15224 static tree
15225 c_parser_omp_clause_shared (c_parser *parser, tree list)
15227 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15230 /* OpenMP 3.0:
15231 untied */
15233 static tree
15234 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15236 tree c;
15238 /* FIXME: Should we allow duplicates? */
15239 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15241 c = build_omp_clause (c_parser_peek_token (parser)->location,
15242 OMP_CLAUSE_UNTIED);
15243 OMP_CLAUSE_CHAIN (c) = list;
15245 return c;
15248 /* OpenMP 4.0:
15249 inbranch
15250 notinbranch */
15252 static tree
15253 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15254 enum omp_clause_code code, tree list)
15256 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15258 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15259 OMP_CLAUSE_CHAIN (c) = list;
15261 return c;
15264 /* OpenMP 4.0:
15265 parallel
15267 sections
15268 taskgroup */
15270 static tree
15271 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15272 enum omp_clause_code code, tree list)
15274 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15275 OMP_CLAUSE_CHAIN (c) = list;
15277 return c;
15280 /* OpenMP 4.5:
15281 nogroup */
15283 static tree
15284 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15286 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15287 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15288 OMP_CLAUSE_NOGROUP);
15289 OMP_CLAUSE_CHAIN (c) = list;
15290 return c;
15293 /* OpenMP 4.5:
15294 simd
15295 threads */
15297 static tree
15298 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15299 enum omp_clause_code code, tree list)
15301 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15302 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15303 OMP_CLAUSE_CHAIN (c) = list;
15304 return c;
15307 /* OpenMP 4.0:
15308 num_teams ( expression )
15310 OpenMP 5.1:
15311 num_teams ( expression : expression ) */
15313 static tree
15314 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15316 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15317 matching_parens parens;
15318 if (parens.require_open (parser))
15320 location_t upper_loc = c_parser_peek_token (parser)->location;
15321 location_t lower_loc = UNKNOWN_LOCATION;
15322 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15323 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15324 tree c, upper = expr.value, lower = NULL_TREE;
15325 upper = c_fully_fold (upper, false, NULL);
15327 if (c_parser_next_token_is (parser, CPP_COLON))
15329 c_parser_consume_token (parser);
15330 lower_loc = upper_loc;
15331 lower = upper;
15332 upper_loc = c_parser_peek_token (parser)->location;
15333 expr = c_parser_expr_no_commas (parser, NULL);
15334 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15335 upper = expr.value;
15336 upper = c_fully_fold (upper, false, NULL);
15339 parens.skip_until_found_close (parser);
15341 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
15342 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
15344 c_parser_error (parser, "expected integer expression");
15345 return list;
15348 /* Attempt to statically determine when the number isn't positive. */
15349 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
15350 build_int_cst (TREE_TYPE (upper), 0));
15351 protected_set_expr_location (c, upper_loc);
15352 if (c == boolean_true_node)
15354 warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
15355 upper = integer_one_node;
15357 if (lower)
15359 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
15360 build_int_cst (TREE_TYPE (lower), 0));
15361 protected_set_expr_location (c, lower_loc);
15362 if (c == boolean_true_node)
15364 warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
15365 lower = NULL_TREE;
15367 else if (TREE_CODE (lower) == INTEGER_CST
15368 && TREE_CODE (upper) == INTEGER_CST
15369 && tree_int_cst_lt (upper, lower))
15371 warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
15372 "than upper bound %qE", lower, upper);
15373 lower = NULL_TREE;
15377 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15379 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15380 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
15381 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
15382 OMP_CLAUSE_CHAIN (c) = list;
15383 list = c;
15386 return list;
15389 /* OpenMP 4.0:
15390 thread_limit ( expression ) */
15392 static tree
15393 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15395 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15396 matching_parens parens;
15397 if (parens.require_open (parser))
15399 location_t expr_loc = c_parser_peek_token (parser)->location;
15400 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15401 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15402 tree c, t = expr.value;
15403 t = c_fully_fold (t, false, NULL);
15405 parens.skip_until_found_close (parser);
15407 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15409 c_parser_error (parser, "expected integer expression");
15410 return list;
15413 /* Attempt to statically determine when the number isn't positive. */
15414 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15415 build_int_cst (TREE_TYPE (t), 0));
15416 protected_set_expr_location (c, expr_loc);
15417 if (c == boolean_true_node)
15419 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15420 t = integer_one_node;
15423 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15424 "thread_limit");
15426 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15427 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15428 OMP_CLAUSE_CHAIN (c) = list;
15429 list = c;
15432 return list;
15435 /* OpenMP 4.0:
15436 aligned ( variable-list )
15437 aligned ( variable-list : constant-expression ) */
15439 static tree
15440 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15442 location_t clause_loc = c_parser_peek_token (parser)->location;
15443 tree nl, c;
15445 matching_parens parens;
15446 if (!parens.require_open (parser))
15447 return list;
15449 nl = c_parser_omp_variable_list (parser, clause_loc,
15450 OMP_CLAUSE_ALIGNED, list);
15452 if (c_parser_next_token_is (parser, CPP_COLON))
15454 c_parser_consume_token (parser);
15455 location_t expr_loc = c_parser_peek_token (parser)->location;
15456 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15457 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15458 tree alignment = expr.value;
15459 alignment = c_fully_fold (alignment, false, NULL);
15460 if (TREE_CODE (alignment) != INTEGER_CST
15461 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15462 || tree_int_cst_sgn (alignment) != 1)
15464 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15465 "be positive constant integer expression");
15466 alignment = NULL_TREE;
15469 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15470 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15473 parens.skip_until_found_close (parser);
15474 return nl;
15477 /* OpenMP 5.0:
15478 allocate ( variable-list )
15479 allocate ( expression : variable-list )
15481 OpenMP 5.1:
15482 allocate ( allocator-modifier : variable-list )
15483 allocate ( allocator-modifier , allocator-modifier : variable-list )
15485 allocator-modifier:
15486 allocator ( expression )
15487 align ( expression ) */
15489 static tree
15490 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15492 location_t clause_loc = c_parser_peek_token (parser)->location;
15493 tree nl, c;
15494 tree allocator = NULL_TREE;
15495 tree align = NULL_TREE;
15497 matching_parens parens;
15498 if (!parens.require_open (parser))
15499 return list;
15501 if ((c_parser_next_token_is_not (parser, CPP_NAME)
15502 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15503 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15504 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15506 bool has_modifiers = false;
15507 tree orig_type = NULL_TREE;
15508 if (c_parser_next_token_is (parser, CPP_NAME)
15509 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15511 unsigned int n = 3;
15512 const char *p
15513 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15514 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
15515 && c_parser_check_balanced_raw_token_sequence (parser, &n)
15516 && (c_parser_peek_nth_token_raw (parser, n)->type
15517 == CPP_CLOSE_PAREN))
15519 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15520 == CPP_COLON)
15521 has_modifiers = true;
15522 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15523 == CPP_COMMA
15524 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
15525 == CPP_NAME)
15526 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
15527 == CPP_OPEN_PAREN))
15529 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
15530 const char *q = IDENTIFIER_POINTER (tok->value);
15531 n += 4;
15532 if ((strcmp (q, "allocator") == 0
15533 || strcmp (q, "align") == 0)
15534 && c_parser_check_balanced_raw_token_sequence (parser,
15536 && (c_parser_peek_nth_token_raw (parser, n)->type
15537 == CPP_CLOSE_PAREN)
15538 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15539 == CPP_COLON))
15540 has_modifiers = true;
15543 if (has_modifiers)
15545 c_parser_consume_token (parser);
15546 matching_parens parens2;;
15547 parens2.require_open (parser);
15548 location_t expr_loc = c_parser_peek_token (parser)->location;
15549 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15550 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15551 if (strcmp (p, "allocator") == 0)
15553 allocator = expr.value;
15554 allocator = c_fully_fold (allocator, false, NULL);
15555 orig_type = expr.original_type
15556 ? expr.original_type : TREE_TYPE (allocator);
15557 orig_type = TYPE_MAIN_VARIANT (orig_type);
15559 else
15561 align = expr.value;
15562 align = c_fully_fold (align, false, NULL);
15564 parens2.skip_until_found_close (parser);
15565 if (c_parser_next_token_is (parser, CPP_COMMA))
15567 c_parser_consume_token (parser);
15568 c_token *tok = c_parser_peek_token (parser);
15569 const char *q = "";
15570 if (c_parser_next_token_is (parser, CPP_NAME))
15571 q = IDENTIFIER_POINTER (tok->value);
15572 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
15574 c_parser_error (parser, "expected %<allocator%> or "
15575 "%<align%>");
15576 parens.skip_until_found_close (parser);
15577 return list;
15579 else if (strcmp (p, q) == 0)
15581 error_at (tok->location, "duplicate %qs modifier", p);
15582 parens.skip_until_found_close (parser);
15583 return list;
15585 c_parser_consume_token (parser);
15586 if (!parens2.require_open (parser))
15588 parens.skip_until_found_close (parser);
15589 return list;
15591 expr_loc = c_parser_peek_token (parser)->location;
15592 expr = c_parser_expr_no_commas (parser, NULL);
15593 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15594 true);
15595 if (strcmp (q, "allocator") == 0)
15597 allocator = expr.value;
15598 allocator = c_fully_fold (allocator, false, NULL);
15599 orig_type = expr.original_type
15600 ? expr.original_type : TREE_TYPE (allocator);
15601 orig_type = TYPE_MAIN_VARIANT (orig_type);
15603 else
15605 align = expr.value;
15606 align = c_fully_fold (align, false, NULL);
15608 parens2.skip_until_found_close (parser);
15612 if (!has_modifiers)
15614 location_t expr_loc = c_parser_peek_token (parser)->location;
15615 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15616 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15617 allocator = expr.value;
15618 allocator = c_fully_fold (allocator, false, NULL);
15619 orig_type = expr.original_type
15620 ? expr.original_type : TREE_TYPE (allocator);
15621 orig_type = TYPE_MAIN_VARIANT (orig_type);
15623 if (allocator
15624 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15625 || TREE_CODE (orig_type) != ENUMERAL_TYPE
15626 || (TYPE_NAME (orig_type)
15627 != get_identifier ("omp_allocator_handle_t"))))
15629 error_at (clause_loc, "%<allocate%> clause allocator expression "
15630 "has type %qT rather than "
15631 "%<omp_allocator_handle_t%>",
15632 TREE_TYPE (allocator));
15633 allocator = NULL_TREE;
15635 if (align
15636 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
15637 || !tree_fits_uhwi_p (align)
15638 || !integer_pow2p (align)))
15640 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
15641 "argument needs to be positive constant "
15642 "power of two integer expression");
15643 align = NULL_TREE;
15645 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15647 parens.skip_until_found_close (parser);
15648 return list;
15652 nl = c_parser_omp_variable_list (parser, clause_loc,
15653 OMP_CLAUSE_ALLOCATE, list);
15655 if (allocator || align)
15656 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15658 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15659 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
15662 parens.skip_until_found_close (parser);
15663 return nl;
15666 /* OpenMP 4.0:
15667 linear ( variable-list )
15668 linear ( variable-list : expression )
15670 OpenMP 4.5:
15671 linear ( modifier ( variable-list ) )
15672 linear ( modifier ( variable-list ) : expression )
15674 modifier:
15677 OpenMP 5.2:
15678 linear ( variable-list : modifiers-list )
15680 modifiers:
15682 step ( expression ) */
15684 static tree
15685 c_parser_omp_clause_linear (c_parser *parser, tree list)
15687 location_t clause_loc = c_parser_peek_token (parser)->location;
15688 tree nl, c, step;
15689 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15690 bool old_linear_modifier = false;
15692 matching_parens parens;
15693 if (!parens.require_open (parser))
15694 return list;
15696 if (c_parser_next_token_is (parser, CPP_NAME))
15698 c_token *tok = c_parser_peek_token (parser);
15699 const char *p = IDENTIFIER_POINTER (tok->value);
15700 if (strcmp ("val", p) == 0)
15701 kind = OMP_CLAUSE_LINEAR_VAL;
15702 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15703 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15704 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15706 old_linear_modifier = true;
15707 c_parser_consume_token (parser);
15708 c_parser_consume_token (parser);
15712 nl = c_parser_omp_variable_list (parser, clause_loc,
15713 OMP_CLAUSE_LINEAR, list);
15715 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15716 parens.skip_until_found_close (parser);
15718 if (c_parser_next_token_is (parser, CPP_COLON))
15720 c_parser_consume_token (parser);
15721 location_t expr_loc = c_parser_peek_token (parser)->location;
15722 bool has_modifiers = false;
15723 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
15724 && c_parser_next_token_is (parser, CPP_NAME))
15726 c_token *tok = c_parser_peek_token (parser);
15727 const char *p = IDENTIFIER_POINTER (tok->value);
15728 unsigned int pos = 0;
15729 if (strcmp ("val", p) == 0)
15730 pos = 2;
15731 else if (strcmp ("step", p) == 0
15732 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15734 pos = 3;
15735 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
15736 && (c_parser_peek_nth_token_raw (parser, pos)->type
15737 == CPP_CLOSE_PAREN))
15738 ++pos;
15739 else
15740 pos = 0;
15742 if (pos)
15744 tok = c_parser_peek_nth_token_raw (parser, pos);
15745 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
15746 has_modifiers = true;
15749 if (has_modifiers)
15751 step = NULL_TREE;
15752 while (c_parser_next_token_is (parser, CPP_NAME))
15754 c_token *tok = c_parser_peek_token (parser);
15755 const char *p = IDENTIFIER_POINTER (tok->value);
15756 if (strcmp ("val", p) == 0)
15758 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15759 error_at (tok->location, "multiple linear modifiers");
15760 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15761 c_parser_consume_token (parser);
15763 else if (strcmp ("step", p) == 0)
15765 c_parser_consume_token (parser);
15766 matching_parens parens2;
15767 if (parens2.require_open (parser))
15769 if (step)
15770 error_at (tok->location,
15771 "multiple %<step%> modifiers");
15772 expr_loc = c_parser_peek_token (parser)->location;
15773 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15774 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15775 true);
15776 step = c_fully_fold (expr.value, false, NULL);
15777 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15779 error_at (clause_loc, "%<linear%> clause step "
15780 "expression must be integral");
15781 step = integer_one_node;
15783 parens2.skip_until_found_close (parser);
15785 else
15786 break;
15788 else
15789 break;
15790 if (c_parser_next_token_is (parser, CPP_COMMA))
15792 c_parser_consume_token (parser);
15793 continue;
15795 break;
15797 if (!step)
15798 step = integer_one_node;
15800 else
15802 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15803 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15804 step = c_fully_fold (expr.value, false, NULL);
15805 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15807 error_at (clause_loc, "%<linear%> clause step expression must "
15808 "be integral");
15809 step = integer_one_node;
15814 else
15815 step = integer_one_node;
15817 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15819 OMP_CLAUSE_LINEAR_STEP (c) = step;
15820 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15821 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
15824 parens.skip_until_found_close (parser);
15825 return nl;
15828 /* OpenMP 5.0:
15829 nontemporal ( variable-list ) */
15831 static tree
15832 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15834 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15837 /* OpenMP 4.0:
15838 safelen ( constant-expression ) */
15840 static tree
15841 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15843 location_t clause_loc = c_parser_peek_token (parser)->location;
15844 tree c, t;
15846 matching_parens parens;
15847 if (!parens.require_open (parser))
15848 return list;
15850 location_t expr_loc = c_parser_peek_token (parser)->location;
15851 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15852 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15853 t = expr.value;
15854 t = c_fully_fold (t, false, NULL);
15855 if (TREE_CODE (t) != INTEGER_CST
15856 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15857 || tree_int_cst_sgn (t) != 1)
15859 error_at (clause_loc, "%<safelen%> clause expression must "
15860 "be positive constant integer expression");
15861 t = NULL_TREE;
15864 parens.skip_until_found_close (parser);
15865 if (t == NULL_TREE || t == error_mark_node)
15866 return list;
15868 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15870 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15871 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15872 OMP_CLAUSE_CHAIN (c) = list;
15873 return c;
15876 /* OpenMP 4.0:
15877 simdlen ( constant-expression ) */
15879 static tree
15880 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15882 location_t clause_loc = c_parser_peek_token (parser)->location;
15883 tree c, t;
15885 matching_parens parens;
15886 if (!parens.require_open (parser))
15887 return list;
15889 location_t expr_loc = c_parser_peek_token (parser)->location;
15890 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15891 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15892 t = expr.value;
15893 t = c_fully_fold (t, false, NULL);
15894 if (TREE_CODE (t) != INTEGER_CST
15895 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15896 || tree_int_cst_sgn (t) != 1)
15898 error_at (clause_loc, "%<simdlen%> clause expression must "
15899 "be positive constant integer expression");
15900 t = NULL_TREE;
15903 parens.skip_until_found_close (parser);
15904 if (t == NULL_TREE || t == error_mark_node)
15905 return list;
15907 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15909 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15910 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15911 OMP_CLAUSE_CHAIN (c) = list;
15912 return c;
15915 /* OpenMP 4.5:
15916 vec:
15917 identifier [+/- integer]
15918 vec , identifier [+/- integer]
15921 static tree
15922 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15923 tree list)
15925 tree vec = NULL;
15926 if (c_parser_next_token_is_not (parser, CPP_NAME)
15927 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15929 c_parser_error (parser, "expected identifier");
15930 return list;
15933 while (c_parser_next_token_is (parser, CPP_NAME)
15934 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15936 tree t = lookup_name (c_parser_peek_token (parser)->value);
15937 tree addend = NULL;
15939 if (t == NULL_TREE)
15941 undeclared_variable (c_parser_peek_token (parser)->location,
15942 c_parser_peek_token (parser)->value);
15943 t = error_mark_node;
15946 c_parser_consume_token (parser);
15948 bool neg = false;
15949 if (c_parser_next_token_is (parser, CPP_MINUS))
15950 neg = true;
15951 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15953 addend = integer_zero_node;
15954 neg = false;
15955 goto add_to_vector;
15957 c_parser_consume_token (parser);
15959 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15961 c_parser_error (parser, "expected integer");
15962 return list;
15965 addend = c_parser_peek_token (parser)->value;
15966 if (TREE_CODE (addend) != INTEGER_CST)
15968 c_parser_error (parser, "expected integer");
15969 return list;
15971 c_parser_consume_token (parser);
15973 add_to_vector:
15974 if (t != error_mark_node)
15976 vec = tree_cons (addend, t, vec);
15977 if (neg)
15978 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15981 if (c_parser_next_token_is_not (parser, CPP_COMMA)
15982 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
15983 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
15984 break;
15986 c_parser_consume_token (parser);
15989 if (vec == NULL_TREE)
15990 return list;
15992 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15993 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15994 OMP_CLAUSE_DECL (u) = nreverse (vec);
15995 OMP_CLAUSE_CHAIN (u) = list;
15996 return u;
15999 /* OpenMP 5.0:
16000 iterators ( iterators-definition )
16002 iterators-definition:
16003 iterator-specifier
16004 iterator-specifier , iterators-definition
16006 iterator-specifier:
16007 identifier = range-specification
16008 iterator-type identifier = range-specification
16010 range-specification:
16011 begin : end
16012 begin : end : step */
16014 static tree
16015 c_parser_omp_iterators (c_parser *parser)
16017 tree ret = NULL_TREE, *last = &ret;
16018 c_parser_consume_token (parser);
16020 push_scope ();
16022 matching_parens parens;
16023 if (!parens.require_open (parser))
16024 return error_mark_node;
16028 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
16029 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
16031 struct c_type_name *type = c_parser_type_name (parser);
16032 if (type != NULL)
16033 iter_type = groktypename (type, &type_expr, NULL);
16035 if (iter_type == NULL_TREE)
16036 iter_type = integer_type_node;
16038 location_t loc = c_parser_peek_token (parser)->location;
16039 if (!c_parser_next_token_is (parser, CPP_NAME))
16041 c_parser_error (parser, "expected identifier");
16042 break;
16045 tree id = c_parser_peek_token (parser)->value;
16046 c_parser_consume_token (parser);
16048 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16049 break;
16051 location_t eloc = c_parser_peek_token (parser)->location;
16052 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16053 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16054 tree begin = expr.value;
16056 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16057 break;
16059 eloc = c_parser_peek_token (parser)->location;
16060 expr = c_parser_expr_no_commas (parser, NULL);
16061 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16062 tree end = expr.value;
16064 tree step = integer_one_node;
16065 if (c_parser_next_token_is (parser, CPP_COLON))
16067 c_parser_consume_token (parser);
16068 eloc = c_parser_peek_token (parser)->location;
16069 expr = c_parser_expr_no_commas (parser, NULL);
16070 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16071 step = expr.value;
16074 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
16075 DECL_ARTIFICIAL (iter_var) = 1;
16076 DECL_CONTEXT (iter_var) = current_function_decl;
16077 pushdecl (iter_var);
16079 *last = make_tree_vec (6);
16080 TREE_VEC_ELT (*last, 0) = iter_var;
16081 TREE_VEC_ELT (*last, 1) = begin;
16082 TREE_VEC_ELT (*last, 2) = end;
16083 TREE_VEC_ELT (*last, 3) = step;
16084 last = &TREE_CHAIN (*last);
16086 if (c_parser_next_token_is (parser, CPP_COMMA))
16088 c_parser_consume_token (parser);
16089 continue;
16091 break;
16093 while (1);
16095 parens.skip_until_found_close (parser);
16096 return ret ? ret : error_mark_node;
16099 /* OpenMP 5.0:
16100 affinity ( [aff-modifier :] variable-list )
16101 aff-modifier:
16102 iterator ( iterators-definition ) */
16104 static tree
16105 c_parser_omp_clause_affinity (c_parser *parser, tree list)
16107 location_t clause_loc = c_parser_peek_token (parser)->location;
16108 tree nl, iterators = NULL_TREE;
16110 matching_parens parens;
16111 if (!parens.require_open (parser))
16112 return list;
16114 if (c_parser_next_token_is (parser, CPP_NAME))
16116 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16117 bool parse_iter = ((strcmp ("iterator", p) == 0)
16118 && (c_parser_peek_2nd_token (parser)->type
16119 == CPP_OPEN_PAREN));
16120 if (parse_iter)
16122 unsigned n = 3;
16123 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
16124 && (c_parser_peek_nth_token_raw (parser, n)->type
16125 == CPP_CLOSE_PAREN)
16126 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
16127 == CPP_COLON));
16129 if (parse_iter)
16131 iterators = c_parser_omp_iterators (parser);
16132 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16134 if (iterators)
16135 pop_scope ();
16136 parens.skip_until_found_close (parser);
16137 return list;
16141 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16142 list);
16143 if (iterators)
16145 tree block = pop_scope ();
16146 if (iterators != error_mark_node)
16148 TREE_VEC_ELT (iterators, 5) = block;
16149 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16150 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16151 OMP_CLAUSE_DECL (c));
16155 parens.skip_until_found_close (parser);
16156 return nl;
16160 /* OpenMP 4.0:
16161 depend ( depend-kind: variable-list )
16163 depend-kind:
16164 in | out | inout
16166 OpenMP 4.5:
16167 depend ( source )
16169 depend ( sink : vec )
16171 OpenMP 5.0:
16172 depend ( depend-modifier , depend-kind: variable-list )
16174 depend-kind:
16175 in | out | inout | mutexinoutset | depobj | inoutset
16177 depend-modifier:
16178 iterator ( iterators-definition ) */
16180 static tree
16181 c_parser_omp_clause_depend (c_parser *parser, tree list)
16183 location_t clause_loc = c_parser_peek_token (parser)->location;
16184 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16185 tree nl, c, iterators = NULL_TREE;
16187 matching_parens parens;
16188 if (!parens.require_open (parser))
16189 return list;
16193 if (c_parser_next_token_is_not (parser, CPP_NAME))
16194 goto invalid_kind;
16196 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16197 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16199 iterators = c_parser_omp_iterators (parser);
16200 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16201 continue;
16203 if (strcmp ("in", p) == 0)
16204 kind = OMP_CLAUSE_DEPEND_IN;
16205 else if (strcmp ("inout", p) == 0)
16206 kind = OMP_CLAUSE_DEPEND_INOUT;
16207 else if (strcmp ("inoutset", p) == 0)
16208 kind = OMP_CLAUSE_DEPEND_INOUTSET;
16209 else if (strcmp ("mutexinoutset", p) == 0)
16210 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16211 else if (strcmp ("out", p) == 0)
16212 kind = OMP_CLAUSE_DEPEND_OUT;
16213 else if (strcmp ("depobj", p) == 0)
16214 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16215 else if (strcmp ("sink", p) == 0)
16216 kind = OMP_CLAUSE_DEPEND_SINK;
16217 else if (strcmp ("source", p) == 0)
16218 kind = OMP_CLAUSE_DEPEND_SOURCE;
16219 else
16220 goto invalid_kind;
16221 break;
16223 while (1);
16225 c_parser_consume_token (parser);
16227 if (iterators
16228 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
16230 pop_scope ();
16231 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16232 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
16233 iterators = NULL_TREE;
16236 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
16238 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
16239 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16240 OMP_CLAUSE_DECL (c) = NULL_TREE;
16241 OMP_CLAUSE_CHAIN (c) = list;
16242 parens.skip_until_found_close (parser);
16243 return c;
16246 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16247 goto resync_fail;
16249 if (kind == OMP_CLAUSE_DEPEND_SINK)
16250 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
16251 else
16253 nl = c_parser_omp_variable_list (parser, clause_loc,
16254 OMP_CLAUSE_DEPEND, list);
16256 if (iterators)
16258 tree block = pop_scope ();
16259 if (iterators == error_mark_node)
16260 iterators = NULL_TREE;
16261 else
16262 TREE_VEC_ELT (iterators, 5) = block;
16265 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16267 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16268 if (iterators)
16269 OMP_CLAUSE_DECL (c)
16270 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16274 parens.skip_until_found_close (parser);
16275 return nl;
16277 invalid_kind:
16278 c_parser_error (parser, "invalid depend kind");
16279 resync_fail:
16280 parens.skip_until_found_close (parser);
16281 if (iterators)
16282 pop_scope ();
16283 return list;
16286 /* OpenMP 4.0:
16287 map ( map-kind: variable-list )
16288 map ( variable-list )
16290 map-kind:
16291 alloc | to | from | tofrom
16293 OpenMP 4.5:
16294 map-kind:
16295 alloc | to | from | tofrom | release | delete
16297 map ( always [,] map-kind: variable-list )
16299 OpenMP 5.0:
16300 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16302 map-type-modifier:
16303 always | close */
16305 static tree
16306 c_parser_omp_clause_map (c_parser *parser, tree list)
16308 location_t clause_loc = c_parser_peek_token (parser)->location;
16309 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
16310 tree nl, c;
16312 matching_parens parens;
16313 if (!parens.require_open (parser))
16314 return list;
16316 int pos = 1;
16317 int map_kind_pos = 0;
16318 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
16320 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
16322 map_kind_pos = pos;
16323 break;
16326 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
16327 pos++;
16328 pos++;
16331 int always_modifier = 0;
16332 int close_modifier = 0;
16333 for (int pos = 1; pos < map_kind_pos; ++pos)
16335 c_token *tok = c_parser_peek_token (parser);
16337 if (tok->type == CPP_COMMA)
16339 c_parser_consume_token (parser);
16340 continue;
16343 const char *p = IDENTIFIER_POINTER (tok->value);
16344 if (strcmp ("always", p) == 0)
16346 if (always_modifier)
16348 c_parser_error (parser, "too many %<always%> modifiers");
16349 parens.skip_until_found_close (parser);
16350 return list;
16352 always_modifier++;
16354 else if (strcmp ("close", p) == 0)
16356 if (close_modifier)
16358 c_parser_error (parser, "too many %<close%> modifiers");
16359 parens.skip_until_found_close (parser);
16360 return list;
16362 close_modifier++;
16364 else
16366 c_parser_error (parser, "%<#pragma omp target%> with "
16367 "modifier other than %<always%> or "
16368 "%<close%> on %<map%> clause");
16369 parens.skip_until_found_close (parser);
16370 return list;
16373 c_parser_consume_token (parser);
16376 if (c_parser_next_token_is (parser, CPP_NAME)
16377 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16379 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16380 if (strcmp ("alloc", p) == 0)
16381 kind = GOMP_MAP_ALLOC;
16382 else if (strcmp ("to", p) == 0)
16383 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
16384 else if (strcmp ("from", p) == 0)
16385 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
16386 else if (strcmp ("tofrom", p) == 0)
16387 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
16388 else if (strcmp ("release", p) == 0)
16389 kind = GOMP_MAP_RELEASE;
16390 else if (strcmp ("delete", p) == 0)
16391 kind = GOMP_MAP_DELETE;
16392 else
16394 c_parser_error (parser, "invalid map kind");
16395 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16396 "expected %<)%>");
16397 return list;
16399 c_parser_consume_token (parser);
16400 c_parser_consume_token (parser);
16403 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
16404 true);
16406 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16407 OMP_CLAUSE_SET_MAP_KIND (c, kind);
16409 parens.skip_until_found_close (parser);
16410 return nl;
16413 /* OpenMP 4.0:
16414 device ( expression )
16416 OpenMP 5.0:
16417 device ( [device-modifier :] integer-expression )
16419 device-modifier:
16420 ancestor | device_num */
16422 static tree
16423 c_parser_omp_clause_device (c_parser *parser, tree list)
16425 location_t clause_loc = c_parser_peek_token (parser)->location;
16426 location_t expr_loc;
16427 c_expr expr;
16428 tree c, t;
16429 bool ancestor = false;
16431 matching_parens parens;
16432 if (!parens.require_open (parser))
16433 return list;
16435 if (c_parser_next_token_is (parser, CPP_NAME)
16436 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16438 c_token *tok = c_parser_peek_token (parser);
16439 const char *p = IDENTIFIER_POINTER (tok->value);
16440 if (strcmp ("ancestor", p) == 0)
16442 /* A requires directive with the reverse_offload clause must be
16443 specified. */
16444 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
16446 error_at (tok->location, "%<ancestor%> device modifier not "
16447 "preceded by %<requires%> directive "
16448 "with %<reverse_offload%> clause");
16449 parens.skip_until_found_close (parser);
16450 return list;
16452 ancestor = true;
16454 else if (strcmp ("device_num", p) == 0)
16456 else
16458 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
16459 parens.skip_until_found_close (parser);
16460 return list;
16462 c_parser_consume_token (parser);
16463 c_parser_consume_token (parser);
16466 expr_loc = c_parser_peek_token (parser)->location;
16467 expr = c_parser_expr_no_commas (parser, NULL);
16468 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16469 t = expr.value;
16470 t = c_fully_fold (t, false, NULL);
16472 parens.skip_until_found_close (parser);
16474 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16476 c_parser_error (parser, "expected integer expression");
16477 return list;
16479 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
16481 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
16482 "%<1%>");
16483 return list;
16486 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
16488 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
16490 OMP_CLAUSE_DEVICE_ID (c) = t;
16491 OMP_CLAUSE_CHAIN (c) = list;
16492 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
16494 list = c;
16495 return list;
16498 /* OpenMP 4.0:
16499 dist_schedule ( static )
16500 dist_schedule ( static , expression ) */
16502 static tree
16503 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
16505 tree c, t = NULL_TREE;
16506 location_t loc = c_parser_peek_token (parser)->location;
16508 matching_parens parens;
16509 if (!parens.require_open (parser))
16510 return list;
16512 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
16514 c_parser_error (parser, "invalid dist_schedule kind");
16515 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16516 "expected %<)%>");
16517 return list;
16520 c_parser_consume_token (parser);
16521 if (c_parser_next_token_is (parser, CPP_COMMA))
16523 c_parser_consume_token (parser);
16525 location_t expr_loc = c_parser_peek_token (parser)->location;
16526 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16527 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16528 t = expr.value;
16529 t = c_fully_fold (t, false, NULL);
16530 parens.skip_until_found_close (parser);
16532 else
16533 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16534 "expected %<,%> or %<)%>");
16536 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16537 "dist_schedule"); */
16538 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
16539 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
16540 if (t == error_mark_node)
16541 return list;
16543 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
16544 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
16545 OMP_CLAUSE_CHAIN (c) = list;
16546 return c;
16549 /* OpenMP 4.0:
16550 proc_bind ( proc-bind-kind )
16552 proc-bind-kind:
16553 primary | master | close | spread
16554 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16556 static tree
16557 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16559 location_t clause_loc = c_parser_peek_token (parser)->location;
16560 enum omp_clause_proc_bind_kind kind;
16561 tree c;
16563 matching_parens parens;
16564 if (!parens.require_open (parser))
16565 return list;
16567 if (c_parser_next_token_is (parser, CPP_NAME))
16569 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16570 if (strcmp ("primary", p) == 0)
16571 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16572 else if (strcmp ("master", p) == 0)
16573 kind = OMP_CLAUSE_PROC_BIND_MASTER;
16574 else if (strcmp ("close", p) == 0)
16575 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16576 else if (strcmp ("spread", p) == 0)
16577 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16578 else
16579 goto invalid_kind;
16581 else
16582 goto invalid_kind;
16584 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16585 c_parser_consume_token (parser);
16586 parens.skip_until_found_close (parser);
16587 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16588 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16589 OMP_CLAUSE_CHAIN (c) = list;
16590 return c;
16592 invalid_kind:
16593 c_parser_error (parser, "invalid proc_bind kind");
16594 parens.skip_until_found_close (parser);
16595 return list;
16598 /* OpenMP 5.0:
16599 device_type ( host | nohost | any ) */
16601 static tree
16602 c_parser_omp_clause_device_type (c_parser *parser, tree list)
16604 location_t clause_loc = c_parser_peek_token (parser)->location;
16605 enum omp_clause_device_type_kind kind;
16606 tree c;
16608 matching_parens parens;
16609 if (!parens.require_open (parser))
16610 return list;
16612 if (c_parser_next_token_is (parser, CPP_NAME))
16614 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16615 if (strcmp ("host", p) == 0)
16616 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
16617 else if (strcmp ("nohost", p) == 0)
16618 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
16619 else if (strcmp ("any", p) == 0)
16620 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
16621 else
16622 goto invalid_kind;
16624 else
16625 goto invalid_kind;
16627 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16628 "device_type"); */
16629 c_parser_consume_token (parser);
16630 parens.skip_until_found_close (parser);
16631 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
16632 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
16633 OMP_CLAUSE_CHAIN (c) = list;
16634 return c;
16636 invalid_kind:
16637 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
16638 parens.skip_until_found_close (parser);
16639 return list;
16642 /* OpenMP 4.0:
16643 to ( variable-list ) */
16645 static tree
16646 c_parser_omp_clause_to (c_parser *parser, tree list)
16648 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
16651 /* OpenMP 4.0:
16652 from ( variable-list ) */
16654 static tree
16655 c_parser_omp_clause_from (c_parser *parser, tree list)
16657 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
16660 /* OpenMP 4.0:
16661 uniform ( variable-list ) */
16663 static tree
16664 c_parser_omp_clause_uniform (c_parser *parser, tree list)
16666 /* The clauses location. */
16667 location_t loc = c_parser_peek_token (parser)->location;
16669 matching_parens parens;
16670 if (parens.require_open (parser))
16672 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
16673 list);
16674 parens.skip_until_found_close (parser);
16676 return list;
16679 /* OpenMP 5.0:
16680 detach ( event-handle ) */
16682 static tree
16683 c_parser_omp_clause_detach (c_parser *parser, tree list)
16685 matching_parens parens;
16686 location_t clause_loc = c_parser_peek_token (parser)->location;
16688 if (!parens.require_open (parser))
16689 return list;
16691 if (c_parser_next_token_is_not (parser, CPP_NAME)
16692 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16694 c_parser_error (parser, "expected identifier");
16695 parens.skip_until_found_close (parser);
16696 return list;
16699 tree t = lookup_name (c_parser_peek_token (parser)->value);
16700 if (t == NULL_TREE)
16702 undeclared_variable (c_parser_peek_token (parser)->location,
16703 c_parser_peek_token (parser)->value);
16704 parens.skip_until_found_close (parser);
16705 return list;
16707 c_parser_consume_token (parser);
16709 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16710 if (!INTEGRAL_TYPE_P (type)
16711 || TREE_CODE (type) != ENUMERAL_TYPE
16712 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16714 error_at (clause_loc, "%<detach%> clause event handle "
16715 "has type %qT rather than "
16716 "%<omp_event_handle_t%>",
16717 type);
16718 parens.skip_until_found_close (parser);
16719 return list;
16722 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16723 OMP_CLAUSE_DECL (u) = t;
16724 OMP_CLAUSE_CHAIN (u) = list;
16725 parens.skip_until_found_close (parser);
16726 return u;
16729 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16730 is a bitmask in MASK. Return the list of clauses found. */
16732 static tree
16733 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16734 const char *where, bool finish_p = true)
16736 tree clauses = NULL;
16737 bool first = true;
16739 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16741 location_t here;
16742 pragma_omp_clause c_kind;
16743 const char *c_name;
16744 tree prev = clauses;
16746 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16747 c_parser_consume_token (parser);
16749 here = c_parser_peek_token (parser)->location;
16750 c_kind = c_parser_omp_clause_name (parser);
16752 switch (c_kind)
16754 case PRAGMA_OACC_CLAUSE_ASYNC:
16755 clauses = c_parser_oacc_clause_async (parser, clauses);
16756 c_name = "async";
16757 break;
16758 case PRAGMA_OACC_CLAUSE_AUTO:
16759 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16760 clauses);
16761 c_name = "auto";
16762 break;
16763 case PRAGMA_OACC_CLAUSE_ATTACH:
16764 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16765 c_name = "attach";
16766 break;
16767 case PRAGMA_OACC_CLAUSE_COLLAPSE:
16768 clauses = c_parser_omp_clause_collapse (parser, clauses);
16769 c_name = "collapse";
16770 break;
16771 case PRAGMA_OACC_CLAUSE_COPY:
16772 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16773 c_name = "copy";
16774 break;
16775 case PRAGMA_OACC_CLAUSE_COPYIN:
16776 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16777 c_name = "copyin";
16778 break;
16779 case PRAGMA_OACC_CLAUSE_COPYOUT:
16780 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16781 c_name = "copyout";
16782 break;
16783 case PRAGMA_OACC_CLAUSE_CREATE:
16784 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16785 c_name = "create";
16786 break;
16787 case PRAGMA_OACC_CLAUSE_DELETE:
16788 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16789 c_name = "delete";
16790 break;
16791 case PRAGMA_OMP_CLAUSE_DEFAULT:
16792 clauses = c_parser_omp_clause_default (parser, clauses, true);
16793 c_name = "default";
16794 break;
16795 case PRAGMA_OACC_CLAUSE_DETACH:
16796 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16797 c_name = "detach";
16798 break;
16799 case PRAGMA_OACC_CLAUSE_DEVICE:
16800 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16801 c_name = "device";
16802 break;
16803 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16804 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16805 c_name = "deviceptr";
16806 break;
16807 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16808 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16809 c_name = "device_resident";
16810 break;
16811 case PRAGMA_OACC_CLAUSE_FINALIZE:
16812 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16813 clauses);
16814 c_name = "finalize";
16815 break;
16816 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16817 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16818 c_name = "firstprivate";
16819 break;
16820 case PRAGMA_OACC_CLAUSE_GANG:
16821 c_name = "gang";
16822 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16823 c_name, clauses);
16824 break;
16825 case PRAGMA_OACC_CLAUSE_HOST:
16826 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16827 c_name = "host";
16828 break;
16829 case PRAGMA_OACC_CLAUSE_IF:
16830 clauses = c_parser_omp_clause_if (parser, clauses, false);
16831 c_name = "if";
16832 break;
16833 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16834 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16835 clauses);
16836 c_name = "if_present";
16837 break;
16838 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16839 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16840 clauses);
16841 c_name = "independent";
16842 break;
16843 case PRAGMA_OACC_CLAUSE_LINK:
16844 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16845 c_name = "link";
16846 break;
16847 case PRAGMA_OACC_CLAUSE_NO_CREATE:
16848 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16849 c_name = "no_create";
16850 break;
16851 case PRAGMA_OACC_CLAUSE_NOHOST:
16852 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
16853 clauses);
16854 c_name = "nohost";
16855 break;
16856 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16857 clauses = c_parser_oacc_single_int_clause (parser,
16858 OMP_CLAUSE_NUM_GANGS,
16859 clauses);
16860 c_name = "num_gangs";
16861 break;
16862 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16863 clauses = c_parser_oacc_single_int_clause (parser,
16864 OMP_CLAUSE_NUM_WORKERS,
16865 clauses);
16866 c_name = "num_workers";
16867 break;
16868 case PRAGMA_OACC_CLAUSE_PRESENT:
16869 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16870 c_name = "present";
16871 break;
16872 case PRAGMA_OACC_CLAUSE_PRIVATE:
16873 clauses = c_parser_omp_clause_private (parser, clauses);
16874 c_name = "private";
16875 break;
16876 case PRAGMA_OACC_CLAUSE_REDUCTION:
16877 clauses
16878 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16879 false, clauses);
16880 c_name = "reduction";
16881 break;
16882 case PRAGMA_OACC_CLAUSE_SEQ:
16883 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16884 clauses);
16885 c_name = "seq";
16886 break;
16887 case PRAGMA_OACC_CLAUSE_TILE:
16888 clauses = c_parser_oacc_clause_tile (parser, clauses);
16889 c_name = "tile";
16890 break;
16891 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16892 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16893 c_name = "use_device";
16894 break;
16895 case PRAGMA_OACC_CLAUSE_VECTOR:
16896 c_name = "vector";
16897 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16898 c_name, clauses);
16899 break;
16900 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16901 clauses = c_parser_oacc_single_int_clause (parser,
16902 OMP_CLAUSE_VECTOR_LENGTH,
16903 clauses);
16904 c_name = "vector_length";
16905 break;
16906 case PRAGMA_OACC_CLAUSE_WAIT:
16907 clauses = c_parser_oacc_clause_wait (parser, clauses);
16908 c_name = "wait";
16909 break;
16910 case PRAGMA_OACC_CLAUSE_WORKER:
16911 c_name = "worker";
16912 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16913 c_name, clauses);
16914 break;
16915 default:
16916 c_parser_error (parser, "expected %<#pragma acc%> clause");
16917 goto saw_error;
16920 first = false;
16922 if (((mask >> c_kind) & 1) == 0)
16924 /* Remove the invalid clause(s) from the list to avoid
16925 confusing the rest of the compiler. */
16926 clauses = prev;
16927 error_at (here, "%qs is not valid for %qs", c_name, where);
16931 saw_error:
16932 c_parser_skip_to_pragma_eol (parser);
16934 if (finish_p)
16935 return c_finish_omp_clauses (clauses, C_ORT_ACC);
16937 return clauses;
16940 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16941 is a bitmask in MASK. Return the list of clauses found.
16942 FINISH_P set if c_finish_omp_clauses should be called.
16943 NESTED non-zero if clauses should be terminated by closing paren instead
16944 of end of pragma. If it is 2, additionally commas are required in between
16945 the clauses. */
16947 static tree
16948 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16949 const char *where, bool finish_p = true,
16950 int nested = 0)
16952 tree clauses = NULL;
16953 bool first = true;
16955 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16957 location_t here;
16958 pragma_omp_clause c_kind;
16959 const char *c_name;
16960 tree prev = clauses;
16962 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16963 break;
16965 if (!first)
16967 if (c_parser_next_token_is (parser, CPP_COMMA))
16968 c_parser_consume_token (parser);
16969 else if (nested == 2)
16970 error_at (c_parser_peek_token (parser)->location,
16971 "clauses in %<simd%> trait should be separated "
16972 "by %<,%>");
16975 here = c_parser_peek_token (parser)->location;
16976 c_kind = c_parser_omp_clause_name (parser);
16978 switch (c_kind)
16980 case PRAGMA_OMP_CLAUSE_BIND:
16981 clauses = c_parser_omp_clause_bind (parser, clauses);
16982 c_name = "bind";
16983 break;
16984 case PRAGMA_OMP_CLAUSE_COLLAPSE:
16985 clauses = c_parser_omp_clause_collapse (parser, clauses);
16986 c_name = "collapse";
16987 break;
16988 case PRAGMA_OMP_CLAUSE_COPYIN:
16989 clauses = c_parser_omp_clause_copyin (parser, clauses);
16990 c_name = "copyin";
16991 break;
16992 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16993 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16994 c_name = "copyprivate";
16995 break;
16996 case PRAGMA_OMP_CLAUSE_DEFAULT:
16997 clauses = c_parser_omp_clause_default (parser, clauses, false);
16998 c_name = "default";
16999 break;
17000 case PRAGMA_OMP_CLAUSE_DETACH:
17001 clauses = c_parser_omp_clause_detach (parser, clauses);
17002 c_name = "detach";
17003 break;
17004 case PRAGMA_OMP_CLAUSE_FILTER:
17005 clauses = c_parser_omp_clause_filter (parser, clauses);
17006 c_name = "filter";
17007 break;
17008 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
17009 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
17010 c_name = "firstprivate";
17011 break;
17012 case PRAGMA_OMP_CLAUSE_FINAL:
17013 clauses = c_parser_omp_clause_final (parser, clauses);
17014 c_name = "final";
17015 break;
17016 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
17017 clauses = c_parser_omp_clause_grainsize (parser, clauses);
17018 c_name = "grainsize";
17019 break;
17020 case PRAGMA_OMP_CLAUSE_HINT:
17021 clauses = c_parser_omp_clause_hint (parser, clauses);
17022 c_name = "hint";
17023 break;
17024 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
17025 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
17026 c_name = "defaultmap";
17027 break;
17028 case PRAGMA_OMP_CLAUSE_IF:
17029 clauses = c_parser_omp_clause_if (parser, clauses, true);
17030 c_name = "if";
17031 break;
17032 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
17033 clauses
17034 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
17035 true, clauses);
17036 c_name = "in_reduction";
17037 break;
17038 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
17039 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
17040 c_name = "lastprivate";
17041 break;
17042 case PRAGMA_OMP_CLAUSE_MERGEABLE:
17043 clauses = c_parser_omp_clause_mergeable (parser, clauses);
17044 c_name = "mergeable";
17045 break;
17046 case PRAGMA_OMP_CLAUSE_NOWAIT:
17047 clauses = c_parser_omp_clause_nowait (parser, clauses);
17048 c_name = "nowait";
17049 break;
17050 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
17051 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
17052 c_name = "num_tasks";
17053 break;
17054 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
17055 clauses = c_parser_omp_clause_num_threads (parser, clauses);
17056 c_name = "num_threads";
17057 break;
17058 case PRAGMA_OMP_CLAUSE_ORDER:
17059 clauses = c_parser_omp_clause_order (parser, clauses);
17060 c_name = "order";
17061 break;
17062 case PRAGMA_OMP_CLAUSE_ORDERED:
17063 clauses = c_parser_omp_clause_ordered (parser, clauses);
17064 c_name = "ordered";
17065 break;
17066 case PRAGMA_OMP_CLAUSE_PRIORITY:
17067 clauses = c_parser_omp_clause_priority (parser, clauses);
17068 c_name = "priority";
17069 break;
17070 case PRAGMA_OMP_CLAUSE_PRIVATE:
17071 clauses = c_parser_omp_clause_private (parser, clauses);
17072 c_name = "private";
17073 break;
17074 case PRAGMA_OMP_CLAUSE_REDUCTION:
17075 clauses
17076 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17077 true, clauses);
17078 c_name = "reduction";
17079 break;
17080 case PRAGMA_OMP_CLAUSE_SCHEDULE:
17081 clauses = c_parser_omp_clause_schedule (parser, clauses);
17082 c_name = "schedule";
17083 break;
17084 case PRAGMA_OMP_CLAUSE_SHARED:
17085 clauses = c_parser_omp_clause_shared (parser, clauses);
17086 c_name = "shared";
17087 break;
17088 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
17089 clauses
17090 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
17091 true, clauses);
17092 c_name = "task_reduction";
17093 break;
17094 case PRAGMA_OMP_CLAUSE_UNTIED:
17095 clauses = c_parser_omp_clause_untied (parser, clauses);
17096 c_name = "untied";
17097 break;
17098 case PRAGMA_OMP_CLAUSE_INBRANCH:
17099 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
17100 clauses);
17101 c_name = "inbranch";
17102 break;
17103 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
17104 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
17105 c_name = "nontemporal";
17106 break;
17107 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
17108 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
17109 clauses);
17110 c_name = "notinbranch";
17111 break;
17112 case PRAGMA_OMP_CLAUSE_PARALLEL:
17113 clauses
17114 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
17115 clauses);
17116 c_name = "parallel";
17117 if (!first)
17119 clause_not_first:
17120 error_at (here, "%qs must be the first clause of %qs",
17121 c_name, where);
17122 clauses = prev;
17124 break;
17125 case PRAGMA_OMP_CLAUSE_FOR:
17126 clauses
17127 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
17128 clauses);
17129 c_name = "for";
17130 if (!first)
17131 goto clause_not_first;
17132 break;
17133 case PRAGMA_OMP_CLAUSE_SECTIONS:
17134 clauses
17135 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17136 clauses);
17137 c_name = "sections";
17138 if (!first)
17139 goto clause_not_first;
17140 break;
17141 case PRAGMA_OMP_CLAUSE_TASKGROUP:
17142 clauses
17143 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17144 clauses);
17145 c_name = "taskgroup";
17146 if (!first)
17147 goto clause_not_first;
17148 break;
17149 case PRAGMA_OMP_CLAUSE_LINK:
17150 clauses
17151 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17152 c_name = "link";
17153 break;
17154 case PRAGMA_OMP_CLAUSE_TO:
17155 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17157 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17158 clauses);
17159 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
17160 OMP_CLAUSE_ENTER_TO (c) = 1;
17161 clauses = nl;
17163 else
17164 clauses = c_parser_omp_clause_to (parser, clauses);
17165 c_name = "to";
17166 break;
17167 case PRAGMA_OMP_CLAUSE_FROM:
17168 clauses = c_parser_omp_clause_from (parser, clauses);
17169 c_name = "from";
17170 break;
17171 case PRAGMA_OMP_CLAUSE_UNIFORM:
17172 clauses = c_parser_omp_clause_uniform (parser, clauses);
17173 c_name = "uniform";
17174 break;
17175 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17176 clauses = c_parser_omp_clause_num_teams (parser, clauses);
17177 c_name = "num_teams";
17178 break;
17179 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17180 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17181 c_name = "thread_limit";
17182 break;
17183 case PRAGMA_OMP_CLAUSE_ALIGNED:
17184 clauses = c_parser_omp_clause_aligned (parser, clauses);
17185 c_name = "aligned";
17186 break;
17187 case PRAGMA_OMP_CLAUSE_ALLOCATE:
17188 clauses = c_parser_omp_clause_allocate (parser, clauses);
17189 c_name = "allocate";
17190 break;
17191 case PRAGMA_OMP_CLAUSE_LINEAR:
17192 clauses = c_parser_omp_clause_linear (parser, clauses);
17193 c_name = "linear";
17194 break;
17195 case PRAGMA_OMP_CLAUSE_AFFINITY:
17196 clauses = c_parser_omp_clause_affinity (parser, clauses);
17197 c_name = "affinity";
17198 break;
17199 case PRAGMA_OMP_CLAUSE_DEPEND:
17200 clauses = c_parser_omp_clause_depend (parser, clauses);
17201 c_name = "depend";
17202 break;
17203 case PRAGMA_OMP_CLAUSE_MAP:
17204 clauses = c_parser_omp_clause_map (parser, clauses);
17205 c_name = "map";
17206 break;
17207 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17208 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17209 c_name = "use_device_ptr";
17210 break;
17211 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17212 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17213 c_name = "use_device_addr";
17214 break;
17215 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17216 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17217 c_name = "has_device_addr";
17218 break;
17219 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17220 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17221 c_name = "is_device_ptr";
17222 break;
17223 case PRAGMA_OMP_CLAUSE_DEVICE:
17224 clauses = c_parser_omp_clause_device (parser, clauses);
17225 c_name = "device";
17226 break;
17227 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
17228 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
17229 c_name = "dist_schedule";
17230 break;
17231 case PRAGMA_OMP_CLAUSE_PROC_BIND:
17232 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
17233 c_name = "proc_bind";
17234 break;
17235 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
17236 clauses = c_parser_omp_clause_device_type (parser, clauses);
17237 c_name = "device_type";
17238 break;
17239 case PRAGMA_OMP_CLAUSE_SAFELEN:
17240 clauses = c_parser_omp_clause_safelen (parser, clauses);
17241 c_name = "safelen";
17242 break;
17243 case PRAGMA_OMP_CLAUSE_SIMDLEN:
17244 clauses = c_parser_omp_clause_simdlen (parser, clauses);
17245 c_name = "simdlen";
17246 break;
17247 case PRAGMA_OMP_CLAUSE_NOGROUP:
17248 clauses = c_parser_omp_clause_nogroup (parser, clauses);
17249 c_name = "nogroup";
17250 break;
17251 case PRAGMA_OMP_CLAUSE_THREADS:
17252 clauses
17253 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
17254 clauses);
17255 c_name = "threads";
17256 break;
17257 case PRAGMA_OMP_CLAUSE_SIMD:
17258 clauses
17259 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
17260 clauses);
17261 c_name = "simd";
17262 break;
17263 case PRAGMA_OMP_CLAUSE_ENTER:
17264 clauses
17265 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17266 clauses);
17267 c_name = "enter";
17268 break;
17269 default:
17270 c_parser_error (parser, "expected %<#pragma omp%> clause");
17271 goto saw_error;
17274 first = false;
17276 if (((mask >> c_kind) & 1) == 0)
17278 /* Remove the invalid clause(s) from the list to avoid
17279 confusing the rest of the compiler. */
17280 clauses = prev;
17281 error_at (here, "%qs is not valid for %qs", c_name, where);
17285 saw_error:
17286 if (!nested)
17287 c_parser_skip_to_pragma_eol (parser);
17289 if (finish_p)
17291 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
17292 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
17293 return c_finish_omp_clauses (clauses, C_ORT_OMP);
17296 return clauses;
17299 /* OpenACC 2.0, OpenMP 2.5:
17300 structured-block:
17301 statement
17303 In practice, we're also interested in adding the statement to an
17304 outer node. So it is convenient if we work around the fact that
17305 c_parser_statement calls add_stmt. */
17307 static tree
17308 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
17310 tree stmt = push_stmt_list ();
17311 c_parser_statement (parser, if_p);
17312 return pop_stmt_list (stmt);
17315 /* OpenACC 2.0:
17316 # pragma acc cache (variable-list) new-line
17318 LOC is the location of the #pragma token.
17321 static tree
17322 c_parser_oacc_cache (location_t loc, c_parser *parser)
17324 tree stmt, clauses;
17326 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
17327 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17329 c_parser_skip_to_pragma_eol (parser);
17331 stmt = make_node (OACC_CACHE);
17332 TREE_TYPE (stmt) = void_type_node;
17333 OACC_CACHE_CLAUSES (stmt) = clauses;
17334 SET_EXPR_LOCATION (stmt, loc);
17335 add_stmt (stmt);
17337 return stmt;
17340 /* OpenACC 2.0:
17341 # pragma acc data oacc-data-clause[optseq] new-line
17342 structured-block
17344 LOC is the location of the #pragma token.
17347 #define OACC_DATA_CLAUSE_MASK \
17348 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17356 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17358 static tree
17359 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
17361 tree stmt, clauses, block;
17363 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
17364 "#pragma acc data");
17366 block = c_begin_omp_parallel ();
17367 add_stmt (c_parser_omp_structured_block (parser, if_p));
17369 stmt = c_finish_oacc_data (loc, clauses, block);
17371 return stmt;
17374 /* OpenACC 2.0:
17375 # pragma acc declare oacc-data-clause[optseq] new-line
17378 #define OACC_DECLARE_CLAUSE_MASK \
17379 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17381 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17383 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17384 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17388 static void
17389 c_parser_oacc_declare (c_parser *parser)
17391 location_t pragma_loc = c_parser_peek_token (parser)->location;
17392 tree clauses, stmt, t, decl;
17394 bool error = false;
17396 c_parser_consume_pragma (parser);
17398 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
17399 "#pragma acc declare");
17400 if (!clauses)
17402 error_at (pragma_loc,
17403 "no valid clauses specified in %<#pragma acc declare%>");
17404 return;
17407 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
17409 location_t loc = OMP_CLAUSE_LOCATION (t);
17410 decl = OMP_CLAUSE_DECL (t);
17411 if (!DECL_P (decl))
17413 error_at (loc, "array section in %<#pragma acc declare%>");
17414 error = true;
17415 continue;
17418 switch (OMP_CLAUSE_MAP_KIND (t))
17420 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17421 case GOMP_MAP_ALLOC:
17422 case GOMP_MAP_TO:
17423 case GOMP_MAP_FORCE_DEVICEPTR:
17424 case GOMP_MAP_DEVICE_RESIDENT:
17425 break;
17427 case GOMP_MAP_LINK:
17428 if (!global_bindings_p ()
17429 && (TREE_STATIC (decl)
17430 || !DECL_EXTERNAL (decl)))
17432 error_at (loc,
17433 "%qD must be a global variable in "
17434 "%<#pragma acc declare link%>",
17435 decl);
17436 error = true;
17437 continue;
17439 break;
17441 default:
17442 if (global_bindings_p ())
17444 error_at (loc, "invalid OpenACC clause at file scope");
17445 error = true;
17446 continue;
17448 if (DECL_EXTERNAL (decl))
17450 error_at (loc,
17451 "invalid use of %<extern%> variable %qD "
17452 "in %<#pragma acc declare%>", decl);
17453 error = true;
17454 continue;
17456 else if (TREE_PUBLIC (decl))
17458 error_at (loc,
17459 "invalid use of %<global%> variable %qD "
17460 "in %<#pragma acc declare%>", decl);
17461 error = true;
17462 continue;
17464 break;
17467 if (!c_check_in_current_scope (decl))
17469 error_at (loc,
17470 "%qD must be a variable declared in the same scope as "
17471 "%<#pragma acc declare%>", decl);
17472 error = true;
17473 continue;
17476 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
17477 || lookup_attribute ("omp declare target link",
17478 DECL_ATTRIBUTES (decl)))
17480 error_at (loc, "variable %qD used more than once with "
17481 "%<#pragma acc declare%>", decl);
17482 error = true;
17483 continue;
17486 if (!error)
17488 tree id;
17490 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
17491 id = get_identifier ("omp declare target link");
17492 else
17493 id = get_identifier ("omp declare target");
17495 DECL_ATTRIBUTES (decl)
17496 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
17498 if (global_bindings_p ())
17500 symtab_node *node = symtab_node::get (decl);
17501 if (node != NULL)
17503 node->offloadable = 1;
17504 if (ENABLE_OFFLOADING)
17506 g->have_offload = true;
17507 if (is_a <varpool_node *> (node))
17508 vec_safe_push (offload_vars, decl);
17515 if (error || global_bindings_p ())
17516 return;
17518 stmt = make_node (OACC_DECLARE);
17519 TREE_TYPE (stmt) = void_type_node;
17520 OACC_DECLARE_CLAUSES (stmt) = clauses;
17521 SET_EXPR_LOCATION (stmt, pragma_loc);
17523 add_stmt (stmt);
17525 return;
17528 /* OpenACC 2.0:
17529 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17533 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17536 LOC is the location of the #pragma token.
17539 #define OACC_ENTER_DATA_CLAUSE_MASK \
17540 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17547 #define OACC_EXIT_DATA_CLAUSE_MASK \
17548 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17556 static void
17557 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
17559 location_t loc = c_parser_peek_token (parser)->location;
17560 tree clauses, stmt;
17561 const char *p = "";
17563 c_parser_consume_pragma (parser);
17565 if (c_parser_next_token_is (parser, CPP_NAME))
17567 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17568 c_parser_consume_token (parser);
17571 if (strcmp (p, "data") != 0)
17573 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17574 enter ? "enter" : "exit");
17575 parser->error = true;
17576 c_parser_skip_to_pragma_eol (parser);
17577 return;
17580 if (enter)
17581 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17582 "#pragma acc enter data");
17583 else
17584 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17585 "#pragma acc exit data");
17587 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17589 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17590 enter ? "enter" : "exit");
17591 return;
17594 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
17595 TREE_TYPE (stmt) = void_type_node;
17596 OMP_STANDALONE_CLAUSES (stmt) = clauses;
17597 SET_EXPR_LOCATION (stmt, loc);
17598 add_stmt (stmt);
17602 /* OpenACC 2.0:
17603 # pragma acc host_data oacc-data-clause[optseq] new-line
17604 structured-block
17607 #define OACC_HOST_DATA_CLAUSE_MASK \
17608 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17610 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17612 static tree
17613 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
17615 tree stmt, clauses, block;
17617 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
17618 "#pragma acc host_data");
17620 block = c_begin_omp_parallel ();
17621 add_stmt (c_parser_omp_structured_block (parser, if_p));
17622 stmt = c_finish_oacc_host_data (loc, clauses, block);
17623 return stmt;
17627 /* OpenACC 2.0:
17629 # pragma acc loop oacc-loop-clause[optseq] new-line
17630 structured-block
17632 LOC is the location of the #pragma token.
17635 #define OACC_LOOP_CLAUSE_MASK \
17636 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17645 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17646 static tree
17647 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
17648 omp_clause_mask mask, tree *cclauses, bool *if_p)
17650 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
17652 strcat (p_name, " loop");
17653 mask |= OACC_LOOP_CLAUSE_MASK;
17655 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
17656 cclauses == NULL);
17657 if (cclauses)
17659 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
17660 if (*cclauses)
17661 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
17662 if (clauses)
17663 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17666 tree block = c_begin_compound_stmt (true);
17667 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
17668 if_p);
17669 block = c_end_compound_stmt (loc, block, true);
17670 add_stmt (block);
17672 return stmt;
17675 /* OpenACC 2.0:
17676 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17677 structured-block
17681 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17682 structured-block
17684 OpenACC 2.6:
17686 # pragma acc serial oacc-serial-clause[optseq] new-line
17687 structured-block
17689 LOC is the location of the #pragma token.
17692 #define OACC_KERNELS_CLAUSE_MASK \
17693 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17694 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17695 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17696 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17697 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17698 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17699 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17705 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17706 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17707 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17709 #define OACC_PARALLEL_CLAUSE_MASK \
17710 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17715 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17729 #define OACC_SERIAL_CLAUSE_MASK \
17730 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17731 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17732 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17746 static tree
17747 c_parser_oacc_compute (location_t loc, c_parser *parser,
17748 enum pragma_kind p_kind, char *p_name, bool *if_p)
17750 omp_clause_mask mask;
17751 enum tree_code code;
17752 switch (p_kind)
17754 case PRAGMA_OACC_KERNELS:
17755 strcat (p_name, " kernels");
17756 mask = OACC_KERNELS_CLAUSE_MASK;
17757 code = OACC_KERNELS;
17758 break;
17759 case PRAGMA_OACC_PARALLEL:
17760 strcat (p_name, " parallel");
17761 mask = OACC_PARALLEL_CLAUSE_MASK;
17762 code = OACC_PARALLEL;
17763 break;
17764 case PRAGMA_OACC_SERIAL:
17765 strcat (p_name, " serial");
17766 mask = OACC_SERIAL_CLAUSE_MASK;
17767 code = OACC_SERIAL;
17768 break;
17769 default:
17770 gcc_unreachable ();
17773 if (c_parser_next_token_is (parser, CPP_NAME))
17775 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17776 if (strcmp (p, "loop") == 0)
17778 c_parser_consume_token (parser);
17779 tree block = c_begin_omp_parallel ();
17780 tree clauses;
17781 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17782 return c_finish_omp_construct (loc, code, block, clauses);
17786 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17788 tree block = c_begin_omp_parallel ();
17789 add_stmt (c_parser_omp_structured_block (parser, if_p));
17791 return c_finish_omp_construct (loc, code, block, clauses);
17794 /* OpenACC 2.0:
17795 # pragma acc routine oacc-routine-clause[optseq] new-line
17796 function-definition
17798 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17801 #define OACC_ROUTINE_CLAUSE_MASK \
17802 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17808 /* Parse an OpenACC routine directive. For named directives, we apply
17809 immediately to the named function. For unnamed ones we then parse
17810 a declaration or definition, which must be for a function. */
17812 static void
17813 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17815 gcc_checking_assert (context == pragma_external);
17817 oacc_routine_data data;
17818 data.error_seen = false;
17819 data.fndecl_seen = false;
17820 data.loc = c_parser_peek_token (parser)->location;
17822 c_parser_consume_pragma (parser);
17824 /* Look for optional '( name )'. */
17825 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17827 c_parser_consume_token (parser); /* '(' */
17829 tree decl = NULL_TREE;
17830 c_token *name_token = c_parser_peek_token (parser);
17831 location_t name_loc = name_token->location;
17832 if (name_token->type == CPP_NAME
17833 && (name_token->id_kind == C_ID_ID
17834 || name_token->id_kind == C_ID_TYPENAME))
17836 decl = lookup_name (name_token->value);
17837 if (!decl)
17838 error_at (name_loc,
17839 "%qE has not been declared", name_token->value);
17840 c_parser_consume_token (parser);
17842 else
17843 c_parser_error (parser, "expected function name");
17845 if (!decl
17846 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17848 c_parser_skip_to_pragma_eol (parser, false);
17849 return;
17852 data.clauses
17853 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17854 "#pragma acc routine");
17855 /* The clauses are in reverse order; fix that to make later diagnostic
17856 emission easier. */
17857 data.clauses = nreverse (data.clauses);
17859 if (TREE_CODE (decl) != FUNCTION_DECL)
17861 error_at (name_loc, "%qD does not refer to a function", decl);
17862 return;
17865 c_finish_oacc_routine (&data, decl, false);
17867 else /* No optional '( name )'. */
17869 data.clauses
17870 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17871 "#pragma acc routine");
17872 /* The clauses are in reverse order; fix that to make later diagnostic
17873 emission easier. */
17874 data.clauses = nreverse (data.clauses);
17876 /* Emit a helpful diagnostic if there's another pragma following this
17877 one. Also don't allow a static assertion declaration, as in the
17878 following we'll just parse a *single* "declaration or function
17879 definition", and the static assertion counts an one. */
17880 if (c_parser_next_token_is (parser, CPP_PRAGMA)
17881 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17883 error_at (data.loc,
17884 "%<#pragma acc routine%> not immediately followed by"
17885 " function declaration or definition");
17886 /* ..., and then just keep going. */
17887 return;
17890 /* We only have to consider the pragma_external case here. */
17891 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17892 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17894 int ext = disable_extension_diagnostics ();
17896 c_parser_consume_token (parser);
17897 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17898 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17899 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17900 NULL, NULL, false, NULL, &data);
17901 restore_extension_diagnostics (ext);
17903 else
17904 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17905 NULL, NULL, false, NULL, &data);
17909 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17910 IS_DEFN is true if we're applying it to the definition. */
17912 static void
17913 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17914 bool is_defn)
17916 /* Keep going if we're in error reporting mode. */
17917 if (data->error_seen
17918 || fndecl == error_mark_node)
17919 return;
17921 if (data->fndecl_seen)
17923 error_at (data->loc,
17924 "%<#pragma acc routine%> not immediately followed by"
17925 " a single function declaration or definition");
17926 data->error_seen = true;
17927 return;
17929 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17931 error_at (data->loc,
17932 "%<#pragma acc routine%> not immediately followed by"
17933 " function declaration or definition");
17934 data->error_seen = true;
17935 return;
17938 int compatible
17939 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17940 "#pragma acc routine");
17941 if (compatible < 0)
17943 data->error_seen = true;
17944 return;
17946 if (compatible > 0)
17949 else
17951 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17953 error_at (data->loc,
17954 TREE_USED (fndecl)
17955 ? G_("%<#pragma acc routine%> must be applied before use")
17956 : G_("%<#pragma acc routine%> must be applied before"
17957 " definition"));
17958 data->error_seen = true;
17959 return;
17962 /* Set the routine's level of parallelism. */
17963 tree dims = oacc_build_routine_dims (data->clauses);
17964 oacc_replace_fn_attrib (fndecl, dims);
17966 /* Add an "omp declare target" attribute. */
17967 DECL_ATTRIBUTES (fndecl)
17968 = tree_cons (get_identifier ("omp declare target"),
17969 data->clauses, DECL_ATTRIBUTES (fndecl));
17972 /* Remember that we've used this "#pragma acc routine". */
17973 data->fndecl_seen = true;
17976 /* OpenACC 2.0:
17977 # pragma acc update oacc-update-clause[optseq] new-line
17980 #define OACC_UPDATE_CLAUSE_MASK \
17981 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17986 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17988 static void
17989 c_parser_oacc_update (c_parser *parser)
17991 location_t loc = c_parser_peek_token (parser)->location;
17993 c_parser_consume_pragma (parser);
17995 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17996 "#pragma acc update");
17997 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17999 error_at (loc,
18000 "%<#pragma acc update%> must contain at least one "
18001 "%<device%> or %<host%> or %<self%> clause");
18002 return;
18005 if (parser->error)
18006 return;
18008 tree stmt = make_node (OACC_UPDATE);
18009 TREE_TYPE (stmt) = void_type_node;
18010 OACC_UPDATE_CLAUSES (stmt) = clauses;
18011 SET_EXPR_LOCATION (stmt, loc);
18012 add_stmt (stmt);
18015 /* OpenACC 2.0:
18016 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18018 LOC is the location of the #pragma token.
18021 #define OACC_WAIT_CLAUSE_MASK \
18022 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18024 static tree
18025 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
18027 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
18029 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
18030 list = c_parser_oacc_wait_list (parser, loc, list);
18032 strcpy (p_name, " wait");
18033 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
18034 stmt = c_finish_oacc_wait (loc, list, clauses);
18035 add_stmt (stmt);
18037 return stmt;
18040 /* OpenMP 5.0:
18041 # pragma omp allocate (list) [allocator(allocator)] */
18043 static void
18044 c_parser_omp_allocate (location_t loc, c_parser *parser)
18046 tree allocator = NULL_TREE;
18047 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
18048 if (c_parser_next_token_is (parser, CPP_NAME))
18050 matching_parens parens;
18051 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18052 c_parser_consume_token (parser);
18053 if (strcmp ("allocator", p) != 0)
18054 error_at (c_parser_peek_token (parser)->location,
18055 "expected %<allocator%>");
18056 else if (parens.require_open (parser))
18058 location_t expr_loc = c_parser_peek_token (parser)->location;
18059 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18060 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18061 allocator = expr.value;
18062 allocator = c_fully_fold (allocator, false, NULL);
18063 tree orig_type
18064 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
18065 orig_type = TYPE_MAIN_VARIANT (orig_type);
18066 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
18067 || TREE_CODE (orig_type) != ENUMERAL_TYPE
18068 || TYPE_NAME (orig_type)
18069 != get_identifier ("omp_allocator_handle_t"))
18071 error_at (expr_loc, "%<allocator%> clause allocator expression "
18072 "has type %qT rather than "
18073 "%<omp_allocator_handle_t%>",
18074 TREE_TYPE (allocator));
18075 allocator = NULL_TREE;
18077 parens.skip_until_found_close (parser);
18080 c_parser_skip_to_pragma_eol (parser);
18082 if (allocator)
18083 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
18084 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18086 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
18089 /* OpenMP 2.5:
18090 # pragma omp atomic new-line
18091 expression-stmt
18093 expression-stmt:
18094 x binop= expr | x++ | ++x | x-- | --x
18095 binop:
18096 +, *, -, /, &, ^, |, <<, >>
18098 where x is an lvalue expression with scalar type.
18100 OpenMP 3.1:
18101 # pragma omp atomic new-line
18102 update-stmt
18104 # pragma omp atomic read new-line
18105 read-stmt
18107 # pragma omp atomic write new-line
18108 write-stmt
18110 # pragma omp atomic update new-line
18111 update-stmt
18113 # pragma omp atomic capture new-line
18114 capture-stmt
18116 # pragma omp atomic capture new-line
18117 capture-block
18119 read-stmt:
18120 v = x
18121 write-stmt:
18122 x = expr
18123 update-stmt:
18124 expression-stmt | x = x binop expr
18125 capture-stmt:
18126 v = expression-stmt
18127 capture-block:
18128 { v = x; update-stmt; } | { update-stmt; v = x; }
18130 OpenMP 4.0:
18131 update-stmt:
18132 expression-stmt | x = x binop expr | x = expr binop x
18133 capture-stmt:
18134 v = update-stmt
18135 capture-block:
18136 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18138 OpenMP 5.1:
18139 # pragma omp atomic compare new-line
18140 conditional-update-atomic
18142 # pragma omp atomic compare capture new-line
18143 conditional-update-capture-atomic
18145 conditional-update-atomic:
18146 cond-expr-stmt | cond-update-stmt
18147 cond-expr-stmt:
18148 x = expr ordop x ? expr : x;
18149 x = x ordop expr ? expr : x;
18150 x = x == e ? d : x;
18151 cond-update-stmt:
18152 if (expr ordop x) { x = expr; }
18153 if (x ordop expr) { x = expr; }
18154 if (x == e) { x = d; }
18155 ordop:
18156 <, >
18157 conditional-update-capture-atomic:
18158 v = cond-expr-stmt
18159 { v = x; cond-expr-stmt }
18160 { cond-expr-stmt v = x; }
18161 { v = x; cond-update-stmt }
18162 { cond-update-stmt v = x; }
18163 if (x == e) { x = d; } else { v = x; }
18164 { r = x == e; if (r) { x = d; } }
18165 { r = x == e; if (r) { x = d; } else { v = x; } }
18167 where x, r and v are lvalue expressions with scalar type,
18168 expr, e and d are expressions with scalar type and e might be
18169 the same as v.
18171 LOC is the location of the #pragma token. */
18173 static void
18174 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18176 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18177 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18178 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
18179 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
18180 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
18181 struct c_expr expr;
18182 location_t eloc;
18183 bool structured_block = false;
18184 bool swapped = false;
18185 bool non_lvalue_p;
18186 bool first = true;
18187 tree clauses = NULL_TREE;
18188 bool capture = false;
18189 bool compare = false;
18190 bool weak = false;
18191 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18192 bool no_semicolon = false;
18193 bool extra_scope = false;
18195 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18197 if (!first
18198 && c_parser_next_token_is (parser, CPP_COMMA)
18199 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18200 c_parser_consume_token (parser);
18202 first = false;
18204 if (c_parser_next_token_is (parser, CPP_NAME))
18206 const char *p
18207 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18208 location_t cloc = c_parser_peek_token (parser)->location;
18209 enum tree_code new_code = ERROR_MARK;
18210 enum omp_memory_order new_memory_order
18211 = OMP_MEMORY_ORDER_UNSPECIFIED;
18212 bool new_capture = false;
18213 bool new_compare = false;
18214 bool new_weak = false;
18215 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18217 if (!strcmp (p, "read"))
18218 new_code = OMP_ATOMIC_READ;
18219 else if (!strcmp (p, "write"))
18220 new_code = NOP_EXPR;
18221 else if (!strcmp (p, "update"))
18222 new_code = OMP_ATOMIC;
18223 else if (openacc && !strcmp (p, "capture"))
18224 new_code = OMP_ATOMIC_CAPTURE_NEW;
18225 else if (openacc)
18227 p = NULL;
18228 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18229 "or %<capture%> clause");
18231 else if (!strcmp (p, "capture"))
18232 new_capture = true;
18233 else if (!strcmp (p, "compare"))
18234 new_compare = true;
18235 else if (!strcmp (p, "weak"))
18236 new_weak = true;
18237 else if (!strcmp (p, "fail"))
18239 matching_parens parens;
18241 c_parser_consume_token (parser);
18242 if (!parens.require_open (parser))
18243 continue;
18245 if (c_parser_next_token_is (parser, CPP_NAME))
18247 const char *q
18248 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18250 if (!strcmp (q, "seq_cst"))
18251 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
18252 else if (!strcmp (q, "acquire"))
18253 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
18254 else if (!strcmp (q, "relaxed"))
18255 new_fail = OMP_MEMORY_ORDER_RELAXED;
18258 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18260 c_parser_consume_token (parser);
18261 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18262 error_at (cloc, "too many %qs clauses", "fail");
18263 else
18264 fail = new_fail;
18266 else
18267 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
18268 "or %<relaxed%>");
18269 parens.skip_until_found_close (parser);
18270 continue;
18272 else if (!strcmp (p, "seq_cst"))
18273 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18274 else if (!strcmp (p, "acq_rel"))
18275 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18276 else if (!strcmp (p, "release"))
18277 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
18278 else if (!strcmp (p, "acquire"))
18279 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18280 else if (!strcmp (p, "relaxed"))
18281 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
18282 else if (!strcmp (p, "hint"))
18284 c_parser_consume_token (parser);
18285 clauses = c_parser_omp_clause_hint (parser, clauses);
18286 continue;
18288 else
18290 p = NULL;
18291 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18292 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18293 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18294 "%<relaxed%> or %<hint%> clause");
18296 if (p)
18298 if (new_code != ERROR_MARK)
18300 /* OpenACC permits 'update capture'. */
18301 if (openacc
18302 && code == OMP_ATOMIC
18303 && new_code == OMP_ATOMIC_CAPTURE_NEW)
18304 code = new_code;
18305 else if (code != ERROR_MARK)
18306 error_at (cloc, "too many atomic clauses");
18307 else
18308 code = new_code;
18310 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18312 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18313 error_at (cloc, "too many memory order clauses");
18314 else
18315 memory_order = new_memory_order;
18317 else if (new_capture)
18319 if (capture)
18320 error_at (cloc, "too many %qs clauses", "capture");
18321 else
18322 capture = true;
18324 else if (new_compare)
18326 if (compare)
18327 error_at (cloc, "too many %qs clauses", "compare");
18328 else
18329 compare = true;
18331 else if (new_weak)
18333 if (weak)
18334 error_at (cloc, "too many %qs clauses", "weak");
18335 else
18336 weak = true;
18338 c_parser_consume_token (parser);
18339 continue;
18342 break;
18344 c_parser_skip_to_pragma_eol (parser);
18346 if (code == ERROR_MARK)
18347 code = OMP_ATOMIC;
18348 if (capture)
18350 if (code != OMP_ATOMIC)
18351 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18352 "clauses", "capture");
18353 else
18354 code = OMP_ATOMIC_CAPTURE_NEW;
18356 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
18358 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18359 "clauses", "compare");
18360 compare = false;
18362 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
18364 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
18365 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18367 if (weak && !compare)
18369 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
18370 weak = false;
18372 if (openacc)
18373 memory_order = OMP_MEMORY_ORDER_RELAXED;
18374 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
18376 omp_requires_mask
18377 = (enum omp_requires) (omp_requires_mask
18378 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
18379 switch ((enum omp_memory_order)
18380 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
18382 case OMP_MEMORY_ORDER_UNSPECIFIED:
18383 case OMP_MEMORY_ORDER_RELAXED:
18384 memory_order = OMP_MEMORY_ORDER_RELAXED;
18385 break;
18386 case OMP_MEMORY_ORDER_SEQ_CST:
18387 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18388 break;
18389 case OMP_MEMORY_ORDER_ACQ_REL:
18390 switch (code)
18392 case OMP_ATOMIC_READ:
18393 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18394 break;
18395 case NOP_EXPR: /* atomic write */
18396 memory_order = OMP_MEMORY_ORDER_RELEASE;
18397 break;
18398 default:
18399 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18400 break;
18402 break;
18403 default:
18404 gcc_unreachable ();
18407 else
18408 switch (code)
18410 case OMP_ATOMIC_READ:
18411 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
18413 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
18414 "%<release%> clause");
18415 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18417 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18418 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18419 break;
18420 case NOP_EXPR: /* atomic write */
18421 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
18423 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
18424 "%<acquire%> clause");
18425 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18427 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18428 memory_order = OMP_MEMORY_ORDER_RELEASE;
18429 break;
18430 default:
18431 break;
18433 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18434 memory_order
18435 = (enum omp_memory_order) (memory_order
18436 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
18438 switch (code)
18440 case OMP_ATOMIC_READ:
18441 case NOP_EXPR: /* atomic write */
18442 v = c_parser_cast_expression (parser, NULL).value;
18443 non_lvalue_p = !lvalue_p (v);
18444 v = c_fully_fold (v, false, NULL, true);
18445 if (v == error_mark_node)
18446 goto saw_error;
18447 if (non_lvalue_p)
18448 v = non_lvalue (v);
18449 loc = c_parser_peek_token (parser)->location;
18450 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18451 goto saw_error;
18452 if (code == NOP_EXPR)
18454 lhs = c_parser_expression (parser).value;
18455 lhs = c_fully_fold (lhs, false, NULL);
18456 if (lhs == error_mark_node)
18457 goto saw_error;
18459 else
18461 lhs = c_parser_cast_expression (parser, NULL).value;
18462 non_lvalue_p = !lvalue_p (lhs);
18463 lhs = c_fully_fold (lhs, false, NULL, true);
18464 if (lhs == error_mark_node)
18465 goto saw_error;
18466 if (non_lvalue_p)
18467 lhs = non_lvalue (lhs);
18469 if (code == NOP_EXPR)
18471 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18472 opcode. */
18473 code = OMP_ATOMIC;
18474 rhs = lhs;
18475 lhs = v;
18476 v = NULL_TREE;
18478 goto done;
18479 case OMP_ATOMIC_CAPTURE_NEW:
18480 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18482 c_parser_consume_token (parser);
18483 structured_block = true;
18485 else if (compare
18486 && c_parser_next_token_is_keyword (parser, RID_IF))
18487 break;
18488 else
18490 v = c_parser_cast_expression (parser, NULL).value;
18491 non_lvalue_p = !lvalue_p (v);
18492 v = c_fully_fold (v, false, NULL, true);
18493 if (v == error_mark_node)
18494 goto saw_error;
18495 if (non_lvalue_p)
18496 v = non_lvalue (v);
18497 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18498 goto saw_error;
18499 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18501 eloc = c_parser_peek_token (parser)->location;
18502 error_at (eloc, "expected expression");
18503 goto saw_error;
18506 break;
18507 default:
18508 break;
18511 /* For structured_block case we don't know yet whether
18512 old or new x should be captured. */
18513 restart:
18514 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18516 c_parser_consume_token (parser);
18518 matching_parens parens;
18519 if (!parens.require_open (parser))
18520 goto saw_error;
18521 eloc = c_parser_peek_token (parser)->location;
18522 c_expr cmp_expr;
18523 if (r)
18525 cmp_expr = c_parser_cast_expression (parser, NULL);
18526 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
18528 else
18529 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
18530 parens.skip_until_found_close (parser);
18531 if (cmp_expr.value == error_mark_node)
18532 goto saw_error;
18533 if (r)
18535 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
18536 goto bad_if;
18537 cmp_expr.value = rhs1;
18538 rhs1 = NULL_TREE;
18539 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
18541 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18543 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18545 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18546 "expected %<==%> comparison in %<if%> condition");
18547 goto saw_error;
18549 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
18550 && TREE_CODE (cmp_expr.value) != LT_EXPR)
18552 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18553 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18554 "condition");
18555 goto saw_error;
18557 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18558 goto saw_error;
18560 extra_scope = true;
18561 eloc = c_parser_peek_token (parser)->location;
18562 expr = c_parser_cast_expression (parser, NULL);
18563 lhs = expr.value;
18564 expr = default_function_array_conversion (eloc, expr);
18565 unfolded_lhs = expr.value;
18566 lhs = c_fully_fold (lhs, false, NULL, true);
18567 orig_lhs = lhs;
18568 if (lhs == error_mark_node)
18569 goto saw_error;
18570 if (!lvalue_p (unfolded_lhs))
18571 lhs = non_lvalue (lhs);
18572 if (!c_parser_next_token_is (parser, CPP_EQ))
18574 c_parser_error (parser, "expected %<=%>");
18575 goto saw_error;
18577 c_parser_consume_token (parser);
18578 eloc = c_parser_peek_token (parser)->location;
18579 expr = c_parser_expr_no_commas (parser, NULL);
18580 rhs1 = expr.value;
18582 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18583 goto saw_error;
18585 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18586 goto saw_error;
18588 extra_scope = false;
18589 no_semicolon = true;
18591 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
18593 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18595 opcode = COND_EXPR;
18596 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18597 false, NULL, true);
18598 rhs1 = c_fully_fold (rhs1, false, NULL, true);
18600 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
18602 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18603 ? MIN_EXPR : MAX_EXPR);
18604 rhs = c_fully_fold (rhs1, false, NULL, true);
18605 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
18606 false, NULL, true);
18608 else
18609 goto bad_if;
18611 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18612 goto bad_if;
18613 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
18614 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
18616 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18617 ? MAX_EXPR : MIN_EXPR);
18618 rhs = c_fully_fold (rhs1, false, NULL, true);
18619 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18620 false, NULL, true);
18622 else
18624 bad_if:
18625 c_parser_error (parser,
18626 "invalid form of %<#pragma omp atomic compare%>");
18627 goto saw_error;
18630 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
18632 if (code != OMP_ATOMIC_CAPTURE_NEW
18633 || (structured_block && r == NULL_TREE)
18634 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
18636 eloc = c_parser_peek_token (parser)->location;
18637 error_at (eloc, "unexpected %<else%>");
18638 goto saw_error;
18641 c_parser_consume_token (parser);
18643 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18644 goto saw_error;
18646 extra_scope = true;
18647 v = c_parser_cast_expression (parser, NULL).value;
18648 non_lvalue_p = !lvalue_p (v);
18649 v = c_fully_fold (v, false, NULL, true);
18650 if (v == error_mark_node)
18651 goto saw_error;
18652 if (non_lvalue_p)
18653 v = non_lvalue (v);
18654 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18655 goto saw_error;
18657 expr = c_parser_expr_no_commas (parser, NULL);
18659 if (!c_tree_equal (expr.value, unfolded_lhs))
18660 goto bad_if;
18662 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18663 goto saw_error;
18665 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18666 goto saw_error;
18668 extra_scope = false;
18669 code = OMP_ATOMIC_CAPTURE_OLD;
18670 if (r == NULL_TREE)
18671 /* Signal to c_finish_omp_atomic that in
18672 if (x == e) { x = d; } else { v = x; }
18673 case the store to v should be conditional. */
18674 r = void_list_node;
18676 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18678 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
18679 goto saw_error;
18681 else if (code == OMP_ATOMIC_CAPTURE_NEW
18682 && r != NULL_TREE
18683 && v == NULL_TREE)
18684 code = OMP_ATOMIC;
18685 goto stmt_done;
18687 eloc = c_parser_peek_token (parser)->location;
18688 expr = c_parser_cast_expression (parser, NULL);
18689 lhs = expr.value;
18690 expr = default_function_array_conversion (eloc, expr);
18691 unfolded_lhs = expr.value;
18692 lhs = c_fully_fold (lhs, false, NULL, true);
18693 orig_lhs = lhs;
18694 switch (TREE_CODE (lhs))
18696 invalid_compare:
18697 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
18698 /* FALLTHRU */
18699 case ERROR_MARK:
18700 saw_error:
18701 c_parser_skip_to_end_of_block_or_statement (parser);
18702 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18703 c_parser_consume_token (parser);
18704 if (structured_block)
18706 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18707 c_parser_consume_token (parser);
18708 else if (code == OMP_ATOMIC_CAPTURE_NEW)
18710 c_parser_skip_to_end_of_block_or_statement (parser);
18711 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18712 c_parser_consume_token (parser);
18715 return;
18717 case POSTINCREMENT_EXPR:
18718 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18719 code = OMP_ATOMIC_CAPTURE_OLD;
18720 /* FALLTHROUGH */
18721 case PREINCREMENT_EXPR:
18722 lhs = TREE_OPERAND (lhs, 0);
18723 unfolded_lhs = NULL_TREE;
18724 opcode = PLUS_EXPR;
18725 rhs = integer_one_node;
18726 if (compare)
18727 goto invalid_compare;
18728 break;
18730 case POSTDECREMENT_EXPR:
18731 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18732 code = OMP_ATOMIC_CAPTURE_OLD;
18733 /* FALLTHROUGH */
18734 case PREDECREMENT_EXPR:
18735 lhs = TREE_OPERAND (lhs, 0);
18736 unfolded_lhs = NULL_TREE;
18737 opcode = MINUS_EXPR;
18738 rhs = integer_one_node;
18739 if (compare)
18740 goto invalid_compare;
18741 break;
18743 case COMPOUND_EXPR:
18744 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
18745 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
18746 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
18747 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
18748 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18749 (TREE_OPERAND (lhs, 1), 0), 0)))
18750 == BOOLEAN_TYPE)
18751 /* Undo effects of boolean_increment for post {in,de}crement. */
18752 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
18753 /* FALLTHRU */
18754 case MODIFY_EXPR:
18755 if (TREE_CODE (lhs) == MODIFY_EXPR
18756 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
18758 /* Undo effects of boolean_increment. */
18759 if (integer_onep (TREE_OPERAND (lhs, 1)))
18761 /* This is pre or post increment. */
18762 rhs = TREE_OPERAND (lhs, 1);
18763 lhs = TREE_OPERAND (lhs, 0);
18764 unfolded_lhs = NULL_TREE;
18765 opcode = NOP_EXPR;
18766 if (code == OMP_ATOMIC_CAPTURE_NEW
18767 && !structured_block
18768 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18769 code = OMP_ATOMIC_CAPTURE_OLD;
18770 if (compare)
18771 goto invalid_compare;
18772 break;
18774 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
18775 && TREE_OPERAND (lhs, 0)
18776 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
18778 /* This is pre or post decrement. */
18779 rhs = TREE_OPERAND (lhs, 1);
18780 lhs = TREE_OPERAND (lhs, 0);
18781 unfolded_lhs = NULL_TREE;
18782 opcode = NOP_EXPR;
18783 if (code == OMP_ATOMIC_CAPTURE_NEW
18784 && !structured_block
18785 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18786 code = OMP_ATOMIC_CAPTURE_OLD;
18787 if (compare)
18788 goto invalid_compare;
18789 break;
18792 /* FALLTHRU */
18793 default:
18794 if (!lvalue_p (unfolded_lhs))
18795 lhs = non_lvalue (lhs);
18796 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
18798 c_parser_error (parser, "expected %<=%>");
18799 goto saw_error;
18801 switch (c_parser_peek_token (parser)->type)
18803 case CPP_MULT_EQ:
18804 opcode = MULT_EXPR;
18805 break;
18806 case CPP_DIV_EQ:
18807 opcode = TRUNC_DIV_EXPR;
18808 break;
18809 case CPP_PLUS_EQ:
18810 opcode = PLUS_EXPR;
18811 break;
18812 case CPP_MINUS_EQ:
18813 opcode = MINUS_EXPR;
18814 break;
18815 case CPP_LSHIFT_EQ:
18816 opcode = LSHIFT_EXPR;
18817 break;
18818 case CPP_RSHIFT_EQ:
18819 opcode = RSHIFT_EXPR;
18820 break;
18821 case CPP_AND_EQ:
18822 opcode = BIT_AND_EXPR;
18823 break;
18824 case CPP_OR_EQ:
18825 opcode = BIT_IOR_EXPR;
18826 break;
18827 case CPP_XOR_EQ:
18828 opcode = BIT_XOR_EXPR;
18829 break;
18830 case CPP_EQ:
18831 c_parser_consume_token (parser);
18832 eloc = c_parser_peek_token (parser)->location;
18833 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
18834 rhs1 = expr.value;
18835 switch (TREE_CODE (rhs1))
18837 case MULT_EXPR:
18838 case TRUNC_DIV_EXPR:
18839 case RDIV_EXPR:
18840 case PLUS_EXPR:
18841 case MINUS_EXPR:
18842 case LSHIFT_EXPR:
18843 case RSHIFT_EXPR:
18844 case BIT_AND_EXPR:
18845 case BIT_IOR_EXPR:
18846 case BIT_XOR_EXPR:
18847 if (compare)
18848 break;
18849 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
18851 opcode = TREE_CODE (rhs1);
18852 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18853 true);
18854 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18855 true);
18856 goto stmt_done;
18858 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
18860 opcode = TREE_CODE (rhs1);
18861 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18862 true);
18863 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18864 true);
18865 swapped = !commutative_tree_code (opcode);
18866 goto stmt_done;
18868 break;
18869 case COND_EXPR:
18870 if (!compare)
18871 break;
18872 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
18873 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
18874 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
18875 break;
18876 if (!TREE_OPERAND (rhs1, 1))
18877 break;
18878 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
18879 break;
18880 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18881 unfolded_lhs))
18883 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18885 opcode = COND_EXPR;
18886 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18887 0), 1),
18888 false, NULL, true);
18889 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
18890 NULL, true);
18891 goto stmt_done;
18893 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18894 TREE_OPERAND (rhs1, 1)))
18896 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18897 ? MIN_EXPR : MAX_EXPR);
18898 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18899 true);
18900 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18901 0), 0),
18902 false, NULL, true);
18903 goto stmt_done;
18906 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18907 break;
18908 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18909 unfolded_lhs))
18911 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18912 TREE_OPERAND (rhs1, 1)))
18914 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18915 ? MAX_EXPR : MIN_EXPR);
18916 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18917 true);
18918 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18919 0), 1),
18920 false, NULL, true);
18921 goto stmt_done;
18924 break;
18925 case EQ_EXPR:
18926 if (!compare
18927 || code != OMP_ATOMIC_CAPTURE_NEW
18928 || !structured_block
18929 || v
18930 || r)
18931 break;
18932 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
18933 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
18935 r = lhs;
18936 lhs = NULL_TREE;
18937 c_parser_consume_token (parser);
18938 goto restart;
18940 break;
18941 case ERROR_MARK:
18942 goto saw_error;
18943 default:
18944 break;
18946 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
18948 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18950 code = OMP_ATOMIC_CAPTURE_OLD;
18951 v = lhs;
18952 lhs = NULL_TREE;
18953 expr = default_function_array_read_conversion (eloc, expr);
18954 unfolded_lhs1 = expr.value;
18955 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
18956 rhs1 = NULL_TREE;
18957 c_parser_consume_token (parser);
18958 goto restart;
18960 if (structured_block && !compare)
18962 opcode = NOP_EXPR;
18963 expr = default_function_array_read_conversion (eloc, expr);
18964 rhs = c_fully_fold (expr.value, false, NULL, true);
18965 rhs1 = NULL_TREE;
18966 goto stmt_done;
18969 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
18970 goto saw_error;
18971 default:
18972 c_parser_error (parser,
18973 "invalid operator for %<#pragma omp atomic%>");
18974 goto saw_error;
18977 /* Arrange to pass the location of the assignment operator to
18978 c_finish_omp_atomic. */
18979 loc = c_parser_peek_token (parser)->location;
18980 c_parser_consume_token (parser);
18981 eloc = c_parser_peek_token (parser)->location;
18982 expr = c_parser_expression (parser);
18983 expr = default_function_array_read_conversion (eloc, expr);
18984 rhs = expr.value;
18985 rhs = c_fully_fold (rhs, false, NULL, true);
18986 break;
18988 stmt_done:
18989 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
18991 if (!no_semicolon
18992 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18993 goto saw_error;
18994 no_semicolon = false;
18995 v = c_parser_cast_expression (parser, NULL).value;
18996 non_lvalue_p = !lvalue_p (v);
18997 v = c_fully_fold (v, false, NULL, true);
18998 if (v == error_mark_node)
18999 goto saw_error;
19000 if (non_lvalue_p)
19001 v = non_lvalue (v);
19002 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19003 goto saw_error;
19004 eloc = c_parser_peek_token (parser)->location;
19005 expr = c_parser_cast_expression (parser, NULL);
19006 lhs1 = expr.value;
19007 expr = default_function_array_read_conversion (eloc, expr);
19008 unfolded_lhs1 = expr.value;
19009 lhs1 = c_fully_fold (lhs1, false, NULL, true);
19010 if (lhs1 == error_mark_node)
19011 goto saw_error;
19012 if (!lvalue_p (unfolded_lhs1))
19013 lhs1 = non_lvalue (lhs1);
19015 if (structured_block)
19017 if (!no_semicolon)
19018 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19019 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
19021 done:
19022 if (weak && opcode != COND_EXPR)
19024 error_at (loc, "%<weak%> clause requires atomic equality comparison");
19025 weak = false;
19027 if (unfolded_lhs && unfolded_lhs1
19028 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
19030 error ("%<#pragma omp atomic capture%> uses two different "
19031 "expressions for memory");
19032 stmt = error_mark_node;
19034 else
19035 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
19036 swapped, memory_order, weak);
19037 if (stmt != error_mark_node)
19038 add_stmt (stmt);
19040 if (!structured_block && !no_semicolon)
19041 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19045 /* OpenMP 2.5:
19046 # pragma omp barrier new-line
19049 static void
19050 c_parser_omp_barrier (c_parser *parser)
19052 location_t loc = c_parser_peek_token (parser)->location;
19053 c_parser_consume_pragma (parser);
19054 c_parser_skip_to_pragma_eol (parser);
19056 c_finish_omp_barrier (loc);
19059 /* OpenMP 2.5:
19060 # pragma omp critical [(name)] new-line
19061 structured-block
19063 OpenMP 4.5:
19064 # pragma omp critical [(name) [hint(expression)]] new-line
19066 LOC is the location of the #pragma itself. */
19068 #define OMP_CRITICAL_CLAUSE_MASK \
19069 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19071 static tree
19072 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
19074 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
19076 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19078 c_parser_consume_token (parser);
19079 if (c_parser_next_token_is (parser, CPP_NAME))
19081 name = c_parser_peek_token (parser)->value;
19082 c_parser_consume_token (parser);
19083 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
19085 else
19086 c_parser_error (parser, "expected identifier");
19088 if (c_parser_next_token_is (parser, CPP_COMMA)
19089 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
19090 c_parser_consume_token (parser);
19092 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
19093 "#pragma omp critical");
19094 stmt = c_parser_omp_structured_block (parser, if_p);
19095 return c_finish_omp_critical (loc, stmt, name, clauses);
19098 /* OpenMP 5.0:
19099 # pragma omp depobj ( depobj ) depobj-clause new-line
19101 depobj-clause:
19102 depend (dependence-type : locator)
19103 destroy
19104 update (dependence-type)
19106 dependence-type:
19109 inout
19110 mutexinout */
19112 static void
19113 c_parser_omp_depobj (c_parser *parser)
19115 location_t loc = c_parser_peek_token (parser)->location;
19116 c_parser_consume_pragma (parser);
19117 matching_parens parens;
19118 if (!parens.require_open (parser))
19120 c_parser_skip_to_pragma_eol (parser);
19121 return;
19124 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
19125 if (depobj != error_mark_node)
19127 if (!lvalue_p (depobj))
19129 error_at (EXPR_LOC_OR_LOC (depobj, loc),
19130 "%<depobj%> expression is not lvalue expression");
19131 depobj = error_mark_node;
19133 else
19135 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
19136 depobj, false);
19137 if (addr == error_mark_node)
19138 depobj = error_mark_node;
19139 else
19140 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
19141 addr, RO_UNARY_STAR);
19145 parens.skip_until_found_close (parser);
19146 tree clause = NULL_TREE;
19147 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
19148 location_t c_loc = c_parser_peek_token (parser)->location;
19149 if (c_parser_next_token_is (parser, CPP_NAME))
19151 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19153 c_parser_consume_token (parser);
19154 if (!strcmp ("depend", p))
19156 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19157 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19158 if (!clause)
19159 clause = error_mark_node;
19161 else if (!strcmp ("destroy", p))
19162 kind = OMP_CLAUSE_DEPEND_LAST;
19163 else if (!strcmp ("update", p))
19165 matching_parens c_parens;
19166 if (c_parens.require_open (parser))
19168 location_t c2_loc = c_parser_peek_token (parser)->location;
19169 if (c_parser_next_token_is (parser, CPP_NAME))
19171 const char *p2
19172 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19174 c_parser_consume_token (parser);
19175 if (!strcmp ("in", p2))
19176 kind = OMP_CLAUSE_DEPEND_IN;
19177 else if (!strcmp ("out", p2))
19178 kind = OMP_CLAUSE_DEPEND_OUT;
19179 else if (!strcmp ("inout", p2))
19180 kind = OMP_CLAUSE_DEPEND_INOUT;
19181 else if (!strcmp ("mutexinoutset", p2))
19182 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
19183 else if (!strcmp ("inoutset", p2))
19184 kind = OMP_CLAUSE_DEPEND_INOUTSET;
19186 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
19188 clause = error_mark_node;
19189 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
19190 "%<mutexinoutset%> or %<inoutset%>");
19192 c_parens.skip_until_found_close (parser);
19194 else
19195 clause = error_mark_node;
19198 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
19200 clause = error_mark_node;
19201 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
19203 c_parser_skip_to_pragma_eol (parser);
19205 c_finish_omp_depobj (loc, depobj, kind, clause);
19209 /* OpenMP 2.5:
19210 # pragma omp flush flush-vars[opt] new-line
19212 flush-vars:
19213 ( variable-list )
19215 OpenMP 5.0:
19216 # pragma omp flush memory-order-clause new-line */
19218 static void
19219 c_parser_omp_flush (c_parser *parser)
19221 location_t loc = c_parser_peek_token (parser)->location;
19222 c_parser_consume_pragma (parser);
19223 enum memmodel mo = MEMMODEL_LAST;
19224 if (c_parser_next_token_is (parser, CPP_NAME))
19226 const char *p
19227 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19229 if (!strcmp (p, "seq_cst"))
19230 mo = MEMMODEL_SEQ_CST;
19231 else if (!strcmp (p, "acq_rel"))
19232 mo = MEMMODEL_ACQ_REL;
19233 else if (!strcmp (p, "release"))
19234 mo = MEMMODEL_RELEASE;
19235 else if (!strcmp (p, "acquire"))
19236 mo = MEMMODEL_ACQUIRE;
19237 else
19238 error_at (c_parser_peek_token (parser)->location,
19239 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19240 "%<acquire%>");
19241 c_parser_consume_token (parser);
19243 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19245 if (mo != MEMMODEL_LAST)
19246 error_at (c_parser_peek_token (parser)->location,
19247 "%<flush%> list specified together with memory order "
19248 "clause");
19249 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
19251 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19252 c_parser_error (parser, "expected %<(%> or end of line");
19253 c_parser_skip_to_pragma_eol (parser);
19255 c_finish_omp_flush (loc, mo);
19258 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19259 separating directive. */
19261 static tree
19262 c_parser_omp_structured_block_sequence (c_parser *parser,
19263 enum pragma_kind kind)
19265 tree stmt = push_stmt_list ();
19266 c_parser_statement (parser, NULL);
19269 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19270 break;
19271 if (c_parser_next_token_is (parser, CPP_EOF))
19272 break;
19274 if (kind != PRAGMA_NONE
19275 && c_parser_peek_token (parser)->pragma_kind == kind)
19276 break;
19277 c_parser_statement (parser, NULL);
19279 while (1);
19280 return pop_stmt_list (stmt);
19283 /* OpenMP 5.0:
19285 scan-loop-body:
19286 { structured-block scan-directive structured-block } */
19288 static void
19289 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
19291 tree substmt;
19292 location_t loc;
19293 tree clauses = NULL_TREE;
19295 loc = c_parser_peek_token (parser)->location;
19296 if (!open_brace_parsed
19297 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19299 /* Avoid skipping until the end of the block. */
19300 parser->error = false;
19301 return;
19304 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
19305 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
19306 SET_EXPR_LOCATION (substmt, loc);
19307 add_stmt (substmt);
19309 loc = c_parser_peek_token (parser)->location;
19310 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
19312 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
19314 c_parser_consume_pragma (parser);
19316 if (c_parser_next_token_is (parser, CPP_NAME))
19318 const char *p
19319 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19320 if (strcmp (p, "inclusive") == 0)
19321 clause = OMP_CLAUSE_INCLUSIVE;
19322 else if (strcmp (p, "exclusive") == 0)
19323 clause = OMP_CLAUSE_EXCLUSIVE;
19325 if (clause != OMP_CLAUSE_ERROR)
19327 c_parser_consume_token (parser);
19328 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
19330 else
19331 c_parser_error (parser, "expected %<inclusive%> or "
19332 "%<exclusive%> clause");
19333 c_parser_skip_to_pragma_eol (parser);
19335 else
19336 error ("expected %<#pragma omp scan%>");
19338 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19339 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
19340 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
19341 SET_EXPR_LOCATION (substmt, loc);
19342 add_stmt (substmt);
19344 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19345 "expected %<}%>");
19348 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19349 The real trick here is to determine the loop control variable early
19350 so that we can push a new decl if necessary to make it private.
19351 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19352 respectively. */
19354 static tree
19355 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
19356 tree clauses, tree *cclauses, bool *if_p)
19358 tree decl, cond, incr, body, init, stmt, cl;
19359 unsigned char save_in_statement;
19360 tree declv, condv, incrv, initv, ret = NULL_TREE;
19361 tree pre_body = NULL_TREE, this_pre_body;
19362 tree ordered_cl = NULL_TREE;
19363 bool fail = false, open_brace_parsed = false;
19364 int i, collapse = 1, ordered = 0, count, nbraces = 0;
19365 location_t for_loc;
19366 bool tiling = false;
19367 bool inscan = false;
19368 vec<tree, va_gc> *for_block = make_tree_vector ();
19370 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
19371 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
19372 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
19373 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
19375 tiling = true;
19376 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
19378 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
19379 && OMP_CLAUSE_ORDERED_EXPR (cl))
19381 ordered_cl = cl;
19382 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
19384 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
19385 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
19386 && (code == OMP_SIMD || code == OMP_FOR))
19387 inscan = true;
19389 if (ordered && ordered < collapse)
19391 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
19392 "%<ordered%> clause parameter is less than %<collapse%>");
19393 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
19394 = build_int_cst (NULL_TREE, collapse);
19395 ordered = collapse;
19397 if (ordered)
19399 for (tree *pc = &clauses; *pc; )
19400 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
19402 error_at (OMP_CLAUSE_LOCATION (*pc),
19403 "%<linear%> clause may not be specified together "
19404 "with %<ordered%> clause with a parameter");
19405 *pc = OMP_CLAUSE_CHAIN (*pc);
19407 else
19408 pc = &OMP_CLAUSE_CHAIN (*pc);
19411 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
19412 count = ordered ? ordered : collapse;
19414 declv = make_tree_vec (count);
19415 initv = make_tree_vec (count);
19416 condv = make_tree_vec (count);
19417 incrv = make_tree_vec (count);
19419 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
19421 c_parser_error (parser, "for statement expected");
19422 return NULL;
19424 for_loc = c_parser_peek_token (parser)->location;
19425 c_parser_consume_token (parser);
19427 /* Forbid break/continue in the loop initializer, condition, and
19428 increment expressions. */
19429 save_in_statement = in_statement;
19430 in_statement = IN_OMP_BLOCK;
19432 for (i = 0; i < count; i++)
19434 int bracecount = 0;
19436 matching_parens parens;
19437 if (!parens.require_open (parser))
19438 goto pop_scopes;
19440 /* Parse the initialization declaration or expression. */
19441 if (c_parser_next_tokens_start_declaration (parser))
19443 if (i > 0)
19444 vec_safe_push (for_block, c_begin_compound_stmt (true));
19445 this_pre_body = push_stmt_list ();
19446 c_in_omp_for = true;
19447 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
19448 c_in_omp_for = false;
19449 if (this_pre_body)
19451 this_pre_body = pop_stmt_list (this_pre_body);
19452 if (pre_body)
19454 tree t = pre_body;
19455 pre_body = push_stmt_list ();
19456 add_stmt (t);
19457 add_stmt (this_pre_body);
19458 pre_body = pop_stmt_list (pre_body);
19460 else
19461 pre_body = this_pre_body;
19463 decl = check_for_loop_decls (for_loc, flag_isoc99);
19464 if (decl == NULL)
19465 goto error_init;
19466 if (DECL_INITIAL (decl) == error_mark_node)
19467 decl = error_mark_node;
19468 init = decl;
19470 else if (c_parser_next_token_is (parser, CPP_NAME)
19471 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
19473 struct c_expr decl_exp;
19474 struct c_expr init_exp;
19475 location_t init_loc;
19477 decl_exp = c_parser_postfix_expression (parser);
19478 decl = decl_exp.value;
19480 c_parser_require (parser, CPP_EQ, "expected %<=%>");
19482 init_loc = c_parser_peek_token (parser)->location;
19483 init_exp = c_parser_expr_no_commas (parser, NULL);
19484 init_exp = default_function_array_read_conversion (init_loc,
19485 init_exp);
19486 c_in_omp_for = true;
19487 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
19488 NOP_EXPR, init_loc, init_exp.value,
19489 init_exp.original_type);
19490 c_in_omp_for = false;
19491 init = c_process_expr_stmt (init_loc, init);
19493 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19495 else
19497 error_init:
19498 c_parser_error (parser,
19499 "expected iteration declaration or initialization");
19500 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19501 "expected %<)%>");
19502 fail = true;
19503 goto parse_next;
19506 /* Parse the loop condition. */
19507 cond = NULL_TREE;
19508 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
19510 location_t cond_loc = c_parser_peek_token (parser)->location;
19511 c_in_omp_for = true;
19512 struct c_expr cond_expr
19513 = c_parser_binary_expression (parser, NULL, NULL_TREE);
19514 c_in_omp_for = false;
19516 cond = cond_expr.value;
19517 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
19518 switch (cond_expr.original_code)
19520 case GT_EXPR:
19521 case GE_EXPR:
19522 case LT_EXPR:
19523 case LE_EXPR:
19524 break;
19525 case NE_EXPR:
19526 if (code != OACC_LOOP)
19527 break;
19528 /* FALLTHRU. */
19529 default:
19530 /* Can't be cond = error_mark_node, because we want to preserve
19531 the location until c_finish_omp_for. */
19532 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
19533 break;
19535 protected_set_expr_location (cond, cond_loc);
19537 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19539 /* Parse the increment expression. */
19540 incr = NULL_TREE;
19541 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
19543 location_t incr_loc = c_parser_peek_token (parser)->location;
19545 incr = c_process_expr_stmt (incr_loc,
19546 c_parser_expression (parser).value);
19548 parens.skip_until_found_close (parser);
19550 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
19551 fail = true;
19552 else
19554 TREE_VEC_ELT (declv, i) = decl;
19555 TREE_VEC_ELT (initv, i) = init;
19556 TREE_VEC_ELT (condv, i) = cond;
19557 TREE_VEC_ELT (incrv, i) = incr;
19560 parse_next:
19561 if (i == count - 1)
19562 break;
19564 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19565 in between the collapsed for loops to be still considered perfectly
19566 nested. Hopefully the final version clarifies this.
19567 For now handle (multiple) {'s and empty statements. */
19570 if (c_parser_next_token_is_keyword (parser, RID_FOR))
19572 c_parser_consume_token (parser);
19573 break;
19575 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19577 c_parser_consume_token (parser);
19578 bracecount++;
19580 else if (bracecount
19581 && c_parser_next_token_is (parser, CPP_SEMICOLON))
19582 c_parser_consume_token (parser);
19583 else
19585 c_parser_error (parser, "not enough perfectly nested loops");
19586 if (bracecount)
19588 open_brace_parsed = true;
19589 bracecount--;
19591 fail = true;
19592 count = 0;
19593 break;
19596 while (1);
19598 nbraces += bracecount;
19601 if (nbraces)
19602 if_p = NULL;
19604 in_statement = IN_OMP_FOR;
19605 body = push_stmt_list ();
19607 if (inscan)
19608 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
19609 else if (open_brace_parsed)
19611 location_t here = c_parser_peek_token (parser)->location;
19612 stmt = c_begin_compound_stmt (true);
19613 c_parser_compound_statement_nostart (parser);
19614 add_stmt (c_end_compound_stmt (here, stmt, true));
19616 else
19617 add_stmt (c_parser_c99_block_statement (parser, if_p));
19619 body = pop_stmt_list (body);
19620 in_statement = save_in_statement;
19622 while (nbraces)
19624 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19626 c_parser_consume_token (parser);
19627 nbraces--;
19629 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
19630 c_parser_consume_token (parser);
19631 else
19633 c_parser_error (parser, "collapsed loops not perfectly nested");
19634 while (nbraces)
19636 location_t here = c_parser_peek_token (parser)->location;
19637 stmt = c_begin_compound_stmt (true);
19638 add_stmt (body);
19639 c_parser_compound_statement_nostart (parser);
19640 body = c_end_compound_stmt (here, stmt, true);
19641 nbraces--;
19643 goto pop_scopes;
19647 /* Only bother calling c_finish_omp_for if we haven't already generated
19648 an error from the initialization parsing. */
19649 if (!fail)
19651 c_in_omp_for = true;
19652 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
19653 incrv, body, pre_body, true);
19654 c_in_omp_for = false;
19656 /* Check for iterators appearing in lb, b or incr expressions. */
19657 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
19658 stmt = NULL_TREE;
19660 if (stmt)
19662 add_stmt (stmt);
19664 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
19666 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
19667 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
19668 tree decl = TREE_OPERAND (init, 0);
19669 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
19670 gcc_assert (COMPARISON_CLASS_P (cond));
19671 gcc_assert (TREE_OPERAND (cond, 0) == decl);
19673 tree op0 = TREE_OPERAND (init, 1);
19674 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19675 || TREE_CODE (op0) != TREE_VEC)
19676 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
19677 else
19679 TREE_VEC_ELT (op0, 1)
19680 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
19681 TREE_VEC_ELT (op0, 2)
19682 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
19685 tree op1 = TREE_OPERAND (cond, 1);
19686 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19687 || TREE_CODE (op1) != TREE_VEC)
19688 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
19689 else
19691 TREE_VEC_ELT (op1, 1)
19692 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
19693 TREE_VEC_ELT (op1, 2)
19694 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
19698 if (cclauses != NULL
19699 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
19701 tree *c;
19702 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
19703 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
19704 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
19705 c = &OMP_CLAUSE_CHAIN (*c);
19706 else
19708 for (i = 0; i < count; i++)
19709 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
19710 break;
19711 if (i == count)
19712 c = &OMP_CLAUSE_CHAIN (*c);
19713 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
19715 error_at (loc,
19716 "iteration variable %qD should not be firstprivate",
19717 OMP_CLAUSE_DECL (*c));
19718 *c = OMP_CLAUSE_CHAIN (*c);
19720 else
19722 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19723 tree l = *c;
19724 *c = OMP_CLAUSE_CHAIN (*c);
19725 if (code == OMP_SIMD)
19727 OMP_CLAUSE_CHAIN (l)
19728 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19729 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
19731 else
19733 OMP_CLAUSE_CHAIN (l) = clauses;
19734 clauses = l;
19739 OMP_FOR_CLAUSES (stmt) = clauses;
19741 ret = stmt;
19743 pop_scopes:
19744 while (!for_block->is_empty ())
19746 /* FIXME diagnostics: LOC below should be the actual location of
19747 this particular for block. We need to build a list of
19748 locations to go along with FOR_BLOCK. */
19749 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
19750 add_stmt (stmt);
19752 release_tree_vector (for_block);
19753 return ret;
19756 /* Helper function for OpenMP parsing, split clauses and call
19757 finish_omp_clauses on each of the set of clauses afterwards. */
19759 static void
19760 omp_split_clauses (location_t loc, enum tree_code code,
19761 omp_clause_mask mask, tree clauses, tree *cclauses)
19763 int i;
19764 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
19765 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
19766 if (cclauses[i])
19767 cclauses[i] = c_finish_omp_clauses (cclauses[i],
19768 i == C_OMP_CLAUSE_SPLIT_TARGET
19769 ? C_ORT_OMP_TARGET : C_ORT_OMP);
19772 /* OpenMP 5.0:
19773 #pragma omp loop loop-clause[optseq] new-line
19774 for-loop
19776 LOC is the location of the #pragma token.
19779 #define OMP_LOOP_CLAUSE_MASK \
19780 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19781 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19782 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19785 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19787 static tree
19788 c_parser_omp_loop (location_t loc, c_parser *parser,
19789 char *p_name, omp_clause_mask mask, tree *cclauses,
19790 bool *if_p)
19792 tree block, clauses, ret;
19794 strcat (p_name, " loop");
19795 mask |= OMP_LOOP_CLAUSE_MASK;
19797 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19798 if (cclauses)
19800 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
19801 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
19804 block = c_begin_compound_stmt (true);
19805 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
19806 block = c_end_compound_stmt (loc, block, true);
19807 add_stmt (block);
19809 return ret;
19812 /* OpenMP 4.0:
19813 #pragma omp simd simd-clause[optseq] new-line
19814 for-loop
19816 LOC is the location of the #pragma token.
19819 #define OMP_SIMD_CLAUSE_MASK \
19820 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19830 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19832 static tree
19833 c_parser_omp_simd (location_t loc, c_parser *parser,
19834 char *p_name, omp_clause_mask mask, tree *cclauses,
19835 bool *if_p)
19837 tree block, clauses, ret;
19839 strcat (p_name, " simd");
19840 mask |= OMP_SIMD_CLAUSE_MASK;
19842 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19843 if (cclauses)
19845 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
19846 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
19847 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
19848 OMP_CLAUSE_ORDERED);
19849 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
19851 error_at (OMP_CLAUSE_LOCATION (c),
19852 "%<ordered%> clause with parameter may not be specified "
19853 "on %qs construct", p_name);
19854 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
19858 block = c_begin_compound_stmt (true);
19859 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
19860 block = c_end_compound_stmt (loc, block, true);
19861 add_stmt (block);
19863 return ret;
19866 /* OpenMP 2.5:
19867 #pragma omp for for-clause[optseq] new-line
19868 for-loop
19870 OpenMP 4.0:
19871 #pragma omp for simd for-simd-clause[optseq] new-line
19872 for-loop
19874 LOC is the location of the #pragma token.
19877 #define OMP_FOR_CLAUSE_MASK \
19878 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19883 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
19884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
19885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19890 static tree
19891 c_parser_omp_for (location_t loc, c_parser *parser,
19892 char *p_name, omp_clause_mask mask, tree *cclauses,
19893 bool *if_p)
19895 tree block, clauses, ret;
19897 strcat (p_name, " for");
19898 mask |= OMP_FOR_CLAUSE_MASK;
19899 /* parallel for{, simd} disallows nowait clause, but for
19900 target {teams distribute ,}parallel for{, simd} it should be accepted. */
19901 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
19902 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
19903 /* Composite distribute parallel for{, simd} disallows ordered clause. */
19904 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19905 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
19907 if (c_parser_next_token_is (parser, CPP_NAME))
19909 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19911 if (strcmp (p, "simd") == 0)
19913 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19914 if (cclauses == NULL)
19915 cclauses = cclauses_buf;
19917 c_parser_consume_token (parser);
19918 if (!flag_openmp) /* flag_openmp_simd */
19919 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19920 if_p);
19921 block = c_begin_compound_stmt (true);
19922 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
19923 block = c_end_compound_stmt (loc, block, true);
19924 if (ret == NULL_TREE)
19925 return ret;
19926 ret = make_node (OMP_FOR);
19927 TREE_TYPE (ret) = void_type_node;
19928 OMP_FOR_BODY (ret) = block;
19929 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19930 SET_EXPR_LOCATION (ret, loc);
19931 add_stmt (ret);
19932 return ret;
19935 if (!flag_openmp) /* flag_openmp_simd */
19937 c_parser_skip_to_pragma_eol (parser, false);
19938 return NULL_TREE;
19941 /* Composite distribute parallel for disallows linear clause. */
19942 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19943 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
19945 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19946 if (cclauses)
19948 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
19949 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19952 block = c_begin_compound_stmt (true);
19953 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
19954 block = c_end_compound_stmt (loc, block, true);
19955 add_stmt (block);
19957 return ret;
19960 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
19961 omp_clause_mask, tree *, bool *);
19963 /* OpenMP 2.5:
19964 # pragma omp master new-line
19965 structured-block
19967 LOC is the location of the #pragma token.
19970 static tree
19971 c_parser_omp_master (location_t loc, c_parser *parser,
19972 char *p_name, omp_clause_mask mask, tree *cclauses,
19973 bool *if_p)
19975 tree block, clauses, ret;
19977 strcat (p_name, " master");
19979 if (c_parser_next_token_is (parser, CPP_NAME))
19981 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19983 if (strcmp (p, "taskloop") == 0)
19985 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19986 if (cclauses == NULL)
19987 cclauses = cclauses_buf;
19989 c_parser_consume_token (parser);
19990 if (!flag_openmp) /* flag_openmp_simd */
19991 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19992 if_p);
19993 block = c_begin_compound_stmt (true);
19994 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19995 if_p);
19996 block = c_end_compound_stmt (loc, block, true);
19997 if (ret == NULL_TREE)
19998 return ret;
19999 ret = c_finish_omp_master (loc, block);
20000 OMP_MASTER_COMBINED (ret) = 1;
20001 return ret;
20004 if (!flag_openmp) /* flag_openmp_simd */
20006 c_parser_skip_to_pragma_eol (parser, false);
20007 return NULL_TREE;
20010 if (cclauses)
20012 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
20013 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
20015 else
20016 c_parser_skip_to_pragma_eol (parser);
20018 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
20019 if_p));
20022 /* OpenMP 5.1:
20023 # pragma omp masked masked-clauses new-line
20024 structured-block
20026 LOC is the location of the #pragma token.
20029 #define OMP_MASKED_CLAUSE_MASK \
20030 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20032 static tree
20033 c_parser_omp_masked (location_t loc, c_parser *parser,
20034 char *p_name, omp_clause_mask mask, tree *cclauses,
20035 bool *if_p)
20037 tree block, clauses, ret;
20039 strcat (p_name, " masked");
20040 mask |= OMP_MASKED_CLAUSE_MASK;
20042 if (c_parser_next_token_is (parser, CPP_NAME))
20044 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20046 if (strcmp (p, "taskloop") == 0)
20048 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20049 if (cclauses == NULL)
20050 cclauses = cclauses_buf;
20052 c_parser_consume_token (parser);
20053 if (!flag_openmp) /* flag_openmp_simd */
20054 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20055 if_p);
20056 block = c_begin_compound_stmt (true);
20057 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20058 if_p);
20059 block = c_end_compound_stmt (loc, block, true);
20060 if (ret == NULL_TREE)
20061 return ret;
20062 ret = c_finish_omp_masked (loc, block,
20063 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
20064 OMP_MASKED_COMBINED (ret) = 1;
20065 return ret;
20068 if (!flag_openmp) /* flag_openmp_simd */
20070 c_parser_skip_to_pragma_eol (parser, false);
20071 return NULL_TREE;
20074 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20075 if (cclauses)
20077 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
20078 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
20081 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
20082 if_p),
20083 clauses);
20086 /* OpenMP 2.5:
20087 # pragma omp ordered new-line
20088 structured-block
20090 OpenMP 4.5:
20091 # pragma omp ordered ordered-clauses new-line
20092 structured-block
20094 # pragma omp ordered depend-clauses new-line */
20096 #define OMP_ORDERED_CLAUSE_MASK \
20097 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20098 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20100 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20101 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20103 static bool
20104 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
20105 bool *if_p)
20107 location_t loc = c_parser_peek_token (parser)->location;
20108 c_parser_consume_pragma (parser);
20110 if (context != pragma_stmt && context != pragma_compound)
20112 c_parser_error (parser, "expected declaration specifiers");
20113 c_parser_skip_to_pragma_eol (parser, false);
20114 return false;
20117 if (c_parser_next_token_is (parser, CPP_NAME))
20119 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20121 if (!strcmp ("depend", p))
20123 if (!flag_openmp) /* flag_openmp_simd */
20125 c_parser_skip_to_pragma_eol (parser, false);
20126 return false;
20128 if (context == pragma_stmt)
20130 error_at (loc,
20131 "%<#pragma omp ordered%> with %<depend%> clause may "
20132 "only be used in compound statements");
20133 c_parser_skip_to_pragma_eol (parser, false);
20134 return true;
20137 tree clauses
20138 = c_parser_omp_all_clauses (parser,
20139 OMP_ORDERED_DEPEND_CLAUSE_MASK,
20140 "#pragma omp ordered");
20141 c_finish_omp_ordered (loc, clauses, NULL_TREE);
20142 return false;
20146 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20147 "#pragma omp ordered");
20149 if (!flag_openmp /* flag_openmp_simd */
20150 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20151 return false;
20153 c_finish_omp_ordered (loc, clauses,
20154 c_parser_omp_structured_block (parser, if_p));
20155 return true;
20158 /* OpenMP 2.5:
20160 section-scope:
20161 { section-sequence }
20163 section-sequence:
20164 section-directive[opt] structured-block
20165 section-sequence section-directive structured-block
20167 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20169 SECTIONS_LOC is the location of the #pragma omp sections. */
20171 static tree
20172 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20174 tree stmt, substmt;
20175 bool error_suppress = false;
20176 location_t loc;
20178 loc = c_parser_peek_token (parser)->location;
20179 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20181 /* Avoid skipping until the end of the block. */
20182 parser->error = false;
20183 return NULL_TREE;
20186 stmt = push_stmt_list ();
20188 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
20190 substmt = c_parser_omp_structured_block_sequence (parser,
20191 PRAGMA_OMP_SECTION);
20192 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20193 SET_EXPR_LOCATION (substmt, loc);
20194 add_stmt (substmt);
20197 while (1)
20199 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20200 break;
20201 if (c_parser_next_token_is (parser, CPP_EOF))
20202 break;
20204 loc = c_parser_peek_token (parser)->location;
20205 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
20207 c_parser_consume_pragma (parser);
20208 c_parser_skip_to_pragma_eol (parser);
20209 error_suppress = false;
20211 else if (!error_suppress)
20213 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
20214 error_suppress = true;
20217 substmt = c_parser_omp_structured_block_sequence (parser,
20218 PRAGMA_OMP_SECTION);
20219 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20220 SET_EXPR_LOCATION (substmt, loc);
20221 add_stmt (substmt);
20223 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20224 "expected %<#pragma omp section%> or %<}%>");
20226 substmt = pop_stmt_list (stmt);
20228 stmt = make_node (OMP_SECTIONS);
20229 SET_EXPR_LOCATION (stmt, sections_loc);
20230 TREE_TYPE (stmt) = void_type_node;
20231 OMP_SECTIONS_BODY (stmt) = substmt;
20233 return add_stmt (stmt);
20236 /* OpenMP 2.5:
20237 # pragma omp sections sections-clause[optseq] newline
20238 sections-scope
20240 LOC is the location of the #pragma token.
20243 #define OMP_SECTIONS_CLAUSE_MASK \
20244 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20251 static tree
20252 c_parser_omp_sections (location_t loc, c_parser *parser,
20253 char *p_name, omp_clause_mask mask, tree *cclauses)
20255 tree block, clauses, ret;
20257 strcat (p_name, " sections");
20258 mask |= OMP_SECTIONS_CLAUSE_MASK;
20259 if (cclauses)
20260 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20262 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20263 if (cclauses)
20265 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
20266 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
20269 block = c_begin_compound_stmt (true);
20270 ret = c_parser_omp_sections_scope (loc, parser);
20271 if (ret)
20272 OMP_SECTIONS_CLAUSES (ret) = clauses;
20273 block = c_end_compound_stmt (loc, block, true);
20274 add_stmt (block);
20276 return ret;
20279 /* OpenMP 2.5:
20280 # pragma omp parallel parallel-clause[optseq] new-line
20281 structured-block
20282 # pragma omp parallel for parallel-for-clause[optseq] new-line
20283 structured-block
20284 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20285 structured-block
20287 OpenMP 4.0:
20288 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20289 structured-block
20291 LOC is the location of the #pragma token.
20294 #define OMP_PARALLEL_CLAUSE_MASK \
20295 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20296 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20297 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20298 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20299 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20300 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20301 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20304 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20306 static tree
20307 c_parser_omp_parallel (location_t loc, c_parser *parser,
20308 char *p_name, omp_clause_mask mask, tree *cclauses,
20309 bool *if_p)
20311 tree stmt, clauses, block;
20313 strcat (p_name, " parallel");
20314 mask |= OMP_PARALLEL_CLAUSE_MASK;
20315 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20316 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
20317 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
20318 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
20320 if (c_parser_next_token_is_keyword (parser, RID_FOR))
20322 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20323 if (cclauses == NULL)
20324 cclauses = cclauses_buf;
20326 c_parser_consume_token (parser);
20327 if (!flag_openmp) /* flag_openmp_simd */
20328 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20329 block = c_begin_omp_parallel ();
20330 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20331 stmt
20332 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20333 block);
20334 if (ret == NULL_TREE)
20335 return ret;
20336 OMP_PARALLEL_COMBINED (stmt) = 1;
20337 return stmt;
20339 /* When combined with distribute, parallel has to be followed by for.
20340 #pragma omp target parallel is allowed though. */
20341 else if (cclauses
20342 && (mask & (OMP_CLAUSE_MASK_1
20343 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20345 error_at (loc, "expected %<for%> after %qs", p_name);
20346 c_parser_skip_to_pragma_eol (parser);
20347 return NULL_TREE;
20349 else if (c_parser_next_token_is (parser, CPP_NAME))
20351 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20352 if (cclauses == NULL && strcmp (p, "masked") == 0)
20354 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20355 cclauses = cclauses_buf;
20357 c_parser_consume_token (parser);
20358 if (!flag_openmp) /* flag_openmp_simd */
20359 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20360 if_p);
20361 block = c_begin_omp_parallel ();
20362 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20363 if_p);
20364 stmt = c_finish_omp_parallel (loc,
20365 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20366 block);
20367 if (ret == NULL)
20368 return ret;
20369 /* masked does have just filter clause, but during gimplification
20370 isn't represented by a gimplification omp context, so for
20371 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20372 so that
20373 #pragma omp parallel masked
20374 #pragma omp taskloop simd lastprivate (x)
20375 isn't confused with
20376 #pragma omp parallel masked taskloop simd lastprivate (x) */
20377 if (OMP_MASKED_COMBINED (ret))
20378 OMP_PARALLEL_COMBINED (stmt) = 1;
20379 return stmt;
20381 else if (cclauses == NULL && strcmp (p, "master") == 0)
20383 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20384 cclauses = cclauses_buf;
20386 c_parser_consume_token (parser);
20387 if (!flag_openmp) /* flag_openmp_simd */
20388 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20389 if_p);
20390 block = c_begin_omp_parallel ();
20391 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20392 if_p);
20393 stmt = c_finish_omp_parallel (loc,
20394 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20395 block);
20396 if (ret == NULL)
20397 return ret;
20398 /* master doesn't have any clauses and during gimplification
20399 isn't represented by a gimplification omp context, so for
20400 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20401 so that
20402 #pragma omp parallel master
20403 #pragma omp taskloop simd lastprivate (x)
20404 isn't confused with
20405 #pragma omp parallel master taskloop simd lastprivate (x) */
20406 if (OMP_MASTER_COMBINED (ret))
20407 OMP_PARALLEL_COMBINED (stmt) = 1;
20408 return stmt;
20410 else if (strcmp (p, "loop") == 0)
20412 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20413 if (cclauses == NULL)
20414 cclauses = cclauses_buf;
20416 c_parser_consume_token (parser);
20417 if (!flag_openmp) /* flag_openmp_simd */
20418 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20419 if_p);
20420 block = c_begin_omp_parallel ();
20421 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20422 if_p);
20423 stmt
20424 = c_finish_omp_parallel (loc,
20425 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20426 block);
20427 if (ret == NULL_TREE)
20428 return ret;
20429 OMP_PARALLEL_COMBINED (stmt) = 1;
20430 return stmt;
20432 else if (!flag_openmp) /* flag_openmp_simd */
20434 c_parser_skip_to_pragma_eol (parser, false);
20435 return NULL_TREE;
20437 else if (cclauses == NULL && strcmp (p, "sections") == 0)
20439 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20440 cclauses = cclauses_buf;
20442 c_parser_consume_token (parser);
20443 block = c_begin_omp_parallel ();
20444 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
20445 stmt = c_finish_omp_parallel (loc,
20446 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20447 block);
20448 OMP_PARALLEL_COMBINED (stmt) = 1;
20449 return stmt;
20452 else if (!flag_openmp) /* flag_openmp_simd */
20454 c_parser_skip_to_pragma_eol (parser, false);
20455 return NULL_TREE;
20458 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20459 if (cclauses)
20461 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
20462 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
20465 block = c_begin_omp_parallel ();
20466 c_parser_statement (parser, if_p);
20467 stmt = c_finish_omp_parallel (loc, clauses, block);
20469 return stmt;
20472 /* OpenMP 2.5:
20473 # pragma omp single single-clause[optseq] new-line
20474 structured-block
20476 LOC is the location of the #pragma.
20479 #define OMP_SINGLE_CLAUSE_MASK \
20480 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20486 static tree
20487 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
20489 tree stmt = make_node (OMP_SINGLE);
20490 SET_EXPR_LOCATION (stmt, loc);
20491 TREE_TYPE (stmt) = void_type_node;
20493 OMP_SINGLE_CLAUSES (stmt)
20494 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
20495 "#pragma omp single");
20496 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20498 return add_stmt (stmt);
20501 /* OpenMP 5.1:
20502 # pragma omp scope scope-clause[optseq] new-line
20503 structured-block
20505 LOC is the location of the #pragma.
20508 #define OMP_SCOPE_CLAUSE_MASK \
20509 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20515 static tree
20516 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
20518 tree stmt = make_node (OMP_SCOPE);
20519 SET_EXPR_LOCATION (stmt, loc);
20520 TREE_TYPE (stmt) = void_type_node;
20522 OMP_SCOPE_CLAUSES (stmt)
20523 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
20524 "#pragma omp scope");
20525 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20527 return add_stmt (stmt);
20530 /* OpenMP 3.0:
20531 # pragma omp task task-clause[optseq] new-line
20533 LOC is the location of the #pragma.
20536 #define OMP_TASK_CLAUSE_MASK \
20537 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20552 static tree
20553 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
20555 tree clauses, block;
20557 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
20558 "#pragma omp task");
20560 block = c_begin_omp_task ();
20561 c_parser_statement (parser, if_p);
20562 return c_finish_omp_task (loc, clauses, block);
20565 /* OpenMP 3.0:
20566 # pragma omp taskwait new-line
20568 OpenMP 5.0:
20569 # pragma omp taskwait taskwait-clause[optseq] new-line
20572 #define OMP_TASKWAIT_CLAUSE_MASK \
20573 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20576 static void
20577 c_parser_omp_taskwait (c_parser *parser)
20579 location_t loc = c_parser_peek_token (parser)->location;
20580 c_parser_consume_pragma (parser);
20582 tree clauses
20583 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
20584 "#pragma omp taskwait");
20586 if (clauses)
20588 tree stmt = make_node (OMP_TASK);
20589 TREE_TYPE (stmt) = void_node;
20590 OMP_TASK_CLAUSES (stmt) = clauses;
20591 OMP_TASK_BODY (stmt) = NULL_TREE;
20592 SET_EXPR_LOCATION (stmt, loc);
20593 add_stmt (stmt);
20595 else
20596 c_finish_omp_taskwait (loc);
20599 /* OpenMP 3.1:
20600 # pragma omp taskyield new-line
20603 static void
20604 c_parser_omp_taskyield (c_parser *parser)
20606 location_t loc = c_parser_peek_token (parser)->location;
20607 c_parser_consume_pragma (parser);
20608 c_parser_skip_to_pragma_eol (parser);
20610 c_finish_omp_taskyield (loc);
20613 /* OpenMP 4.0:
20614 # pragma omp taskgroup new-line
20616 OpenMP 5.0:
20617 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20620 #define OMP_TASKGROUP_CLAUSE_MASK \
20621 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20622 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20624 static tree
20625 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
20627 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
20628 "#pragma omp taskgroup");
20630 tree body = c_parser_omp_structured_block (parser, if_p);
20631 return c_finish_omp_taskgroup (loc, body, clauses);
20634 /* OpenMP 4.0:
20635 # pragma omp cancel cancel-clause[optseq] new-line
20637 LOC is the location of the #pragma.
20640 #define OMP_CANCEL_CLAUSE_MASK \
20641 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20645 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20647 static void
20648 c_parser_omp_cancel (c_parser *parser)
20650 location_t loc = c_parser_peek_token (parser)->location;
20652 c_parser_consume_pragma (parser);
20653 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
20654 "#pragma omp cancel");
20656 c_finish_omp_cancel (loc, clauses);
20659 /* OpenMP 4.0:
20660 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20662 LOC is the location of the #pragma.
20665 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20666 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20668 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20669 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20671 static bool
20672 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
20674 location_t loc = c_parser_peek_token (parser)->location;
20675 tree clauses;
20676 bool point_seen = false;
20678 c_parser_consume_pragma (parser);
20679 if (c_parser_next_token_is (parser, CPP_NAME))
20681 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20682 if (strcmp (p, "point") == 0)
20684 c_parser_consume_token (parser);
20685 point_seen = true;
20688 if (!point_seen)
20690 c_parser_error (parser, "expected %<point%>");
20691 c_parser_skip_to_pragma_eol (parser);
20692 return false;
20695 if (context != pragma_compound)
20697 if (context == pragma_stmt)
20698 error_at (loc,
20699 "%<#pragma %s%> may only be used in compound statements",
20700 "omp cancellation point");
20701 else
20702 c_parser_error (parser, "expected declaration specifiers");
20703 c_parser_skip_to_pragma_eol (parser, false);
20704 return true;
20707 clauses
20708 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
20709 "#pragma omp cancellation point");
20711 c_finish_omp_cancellation_point (loc, clauses);
20712 return true;
20715 /* OpenMP 4.0:
20716 #pragma omp distribute distribute-clause[optseq] new-line
20717 for-loop */
20719 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20720 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20728 static tree
20729 c_parser_omp_distribute (location_t loc, c_parser *parser,
20730 char *p_name, omp_clause_mask mask, tree *cclauses,
20731 bool *if_p)
20733 tree clauses, block, ret;
20735 strcat (p_name, " distribute");
20736 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
20738 if (c_parser_next_token_is (parser, CPP_NAME))
20740 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20741 bool simd = false;
20742 bool parallel = false;
20744 if (strcmp (p, "simd") == 0)
20745 simd = true;
20746 else
20747 parallel = strcmp (p, "parallel") == 0;
20748 if (parallel || simd)
20750 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20751 if (cclauses == NULL)
20752 cclauses = cclauses_buf;
20753 c_parser_consume_token (parser);
20754 if (!flag_openmp) /* flag_openmp_simd */
20756 if (simd)
20757 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20758 if_p);
20759 else
20760 return c_parser_omp_parallel (loc, parser, p_name, mask,
20761 cclauses, if_p);
20763 block = c_begin_compound_stmt (true);
20764 if (simd)
20765 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20766 if_p);
20767 else
20768 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
20769 if_p);
20770 block = c_end_compound_stmt (loc, block, true);
20771 if (ret == NULL)
20772 return ret;
20773 ret = make_node (OMP_DISTRIBUTE);
20774 TREE_TYPE (ret) = void_type_node;
20775 OMP_FOR_BODY (ret) = block;
20776 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20777 SET_EXPR_LOCATION (ret, loc);
20778 add_stmt (ret);
20779 return ret;
20782 if (!flag_openmp) /* flag_openmp_simd */
20784 c_parser_skip_to_pragma_eol (parser, false);
20785 return NULL_TREE;
20788 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20789 if (cclauses)
20791 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
20792 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20795 block = c_begin_compound_stmt (true);
20796 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
20797 if_p);
20798 block = c_end_compound_stmt (loc, block, true);
20799 add_stmt (block);
20801 return ret;
20804 /* OpenMP 4.0:
20805 # pragma omp teams teams-clause[optseq] new-line
20806 structured-block */
20808 #define OMP_TEAMS_CLAUSE_MASK \
20809 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20818 static tree
20819 c_parser_omp_teams (location_t loc, c_parser *parser,
20820 char *p_name, omp_clause_mask mask, tree *cclauses,
20821 bool *if_p)
20823 tree clauses, block, ret;
20825 strcat (p_name, " teams");
20826 mask |= OMP_TEAMS_CLAUSE_MASK;
20828 if (c_parser_next_token_is (parser, CPP_NAME))
20830 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20831 if (strcmp (p, "distribute") == 0)
20833 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20834 if (cclauses == NULL)
20835 cclauses = cclauses_buf;
20837 c_parser_consume_token (parser);
20838 if (!flag_openmp) /* flag_openmp_simd */
20839 return c_parser_omp_distribute (loc, parser, p_name, mask,
20840 cclauses, if_p);
20841 block = c_begin_omp_parallel ();
20842 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
20843 if_p);
20844 block = c_end_compound_stmt (loc, block, true);
20845 if (ret == NULL)
20846 return ret;
20847 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20848 ret = make_node (OMP_TEAMS);
20849 TREE_TYPE (ret) = void_type_node;
20850 OMP_TEAMS_CLAUSES (ret) = clauses;
20851 OMP_TEAMS_BODY (ret) = block;
20852 OMP_TEAMS_COMBINED (ret) = 1;
20853 SET_EXPR_LOCATION (ret, loc);
20854 return add_stmt (ret);
20856 else if (strcmp (p, "loop") == 0)
20858 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20859 if (cclauses == NULL)
20860 cclauses = cclauses_buf;
20862 c_parser_consume_token (parser);
20863 if (!flag_openmp) /* flag_openmp_simd */
20864 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20865 if_p);
20866 block = c_begin_omp_parallel ();
20867 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
20868 block = c_end_compound_stmt (loc, block, true);
20869 if (ret == NULL)
20870 return ret;
20871 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20872 ret = make_node (OMP_TEAMS);
20873 TREE_TYPE (ret) = void_type_node;
20874 OMP_TEAMS_CLAUSES (ret) = clauses;
20875 OMP_TEAMS_BODY (ret) = block;
20876 OMP_TEAMS_COMBINED (ret) = 1;
20877 SET_EXPR_LOCATION (ret, loc);
20878 return add_stmt (ret);
20881 if (!flag_openmp) /* flag_openmp_simd */
20883 c_parser_skip_to_pragma_eol (parser, false);
20884 return NULL_TREE;
20887 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20888 if (cclauses)
20890 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
20891 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20894 tree stmt = make_node (OMP_TEAMS);
20895 TREE_TYPE (stmt) = void_type_node;
20896 OMP_TEAMS_CLAUSES (stmt) = clauses;
20897 block = c_begin_omp_parallel ();
20898 add_stmt (c_parser_omp_structured_block (parser, if_p));
20899 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20900 SET_EXPR_LOCATION (stmt, loc);
20902 return add_stmt (stmt);
20905 /* OpenMP 4.0:
20906 # pragma omp target data target-data-clause[optseq] new-line
20907 structured-block */
20909 #define OMP_TARGET_DATA_CLAUSE_MASK \
20910 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20916 static tree
20917 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
20919 if (flag_openmp)
20920 omp_requires_mask
20921 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
20923 tree clauses
20924 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
20925 "#pragma omp target data");
20926 c_omp_adjust_map_clauses (clauses, false);
20927 int map_seen = 0;
20928 for (tree *pc = &clauses; *pc;)
20930 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20931 switch (OMP_CLAUSE_MAP_KIND (*pc))
20933 case GOMP_MAP_TO:
20934 case GOMP_MAP_ALWAYS_TO:
20935 case GOMP_MAP_FROM:
20936 case GOMP_MAP_ALWAYS_FROM:
20937 case GOMP_MAP_TOFROM:
20938 case GOMP_MAP_ALWAYS_TOFROM:
20939 case GOMP_MAP_ALLOC:
20940 map_seen = 3;
20941 break;
20942 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20943 case GOMP_MAP_ALWAYS_POINTER:
20944 case GOMP_MAP_ATTACH_DETACH:
20945 break;
20946 default:
20947 map_seen |= 1;
20948 error_at (OMP_CLAUSE_LOCATION (*pc),
20949 "%<#pragma omp target data%> with map-type other "
20950 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20951 "on %<map%> clause");
20952 *pc = OMP_CLAUSE_CHAIN (*pc);
20953 continue;
20955 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
20956 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
20957 map_seen = 3;
20958 pc = &OMP_CLAUSE_CHAIN (*pc);
20961 if (map_seen != 3)
20963 if (map_seen == 0)
20964 error_at (loc,
20965 "%<#pragma omp target data%> must contain at least "
20966 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
20967 "clause");
20968 return NULL_TREE;
20971 tree stmt = make_node (OMP_TARGET_DATA);
20972 TREE_TYPE (stmt) = void_type_node;
20973 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
20974 keep_next_level ();
20975 tree block = c_begin_compound_stmt (true);
20976 add_stmt (c_parser_omp_structured_block (parser, if_p));
20977 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20979 SET_EXPR_LOCATION (stmt, loc);
20980 return add_stmt (stmt);
20983 /* OpenMP 4.0:
20984 # pragma omp target update target-update-clause[optseq] new-line */
20986 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
20987 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
20988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20994 static bool
20995 c_parser_omp_target_update (location_t loc, c_parser *parser,
20996 enum pragma_context context)
20998 if (context == pragma_stmt)
21000 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21001 "omp target update");
21002 c_parser_skip_to_pragma_eol (parser, false);
21003 return true;
21006 tree clauses
21007 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
21008 "#pragma omp target update");
21009 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
21010 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
21012 error_at (loc,
21013 "%<#pragma omp target update%> must contain at least one "
21014 "%<from%> or %<to%> clauses");
21015 return false;
21018 if (flag_openmp)
21019 omp_requires_mask
21020 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21022 tree stmt = make_node (OMP_TARGET_UPDATE);
21023 TREE_TYPE (stmt) = void_type_node;
21024 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
21025 SET_EXPR_LOCATION (stmt, loc);
21026 add_stmt (stmt);
21027 return false;
21030 /* OpenMP 4.5:
21031 # pragma omp target enter data target-data-clause[optseq] new-line */
21033 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21034 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21035 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21036 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21037 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21038 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21040 static bool
21041 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
21042 enum pragma_context context)
21044 bool data_seen = false;
21045 if (c_parser_next_token_is (parser, CPP_NAME))
21047 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21048 if (strcmp (p, "data") == 0)
21050 c_parser_consume_token (parser);
21051 data_seen = true;
21054 if (!data_seen)
21056 c_parser_error (parser, "expected %<data%>");
21057 c_parser_skip_to_pragma_eol (parser);
21058 return false;
21061 if (context == pragma_stmt)
21063 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21064 "omp target enter data");
21065 c_parser_skip_to_pragma_eol (parser, false);
21066 return true;
21069 if (flag_openmp)
21070 omp_requires_mask
21071 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21073 tree clauses
21074 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
21075 "#pragma omp target enter data");
21076 c_omp_adjust_map_clauses (clauses, false);
21077 int map_seen = 0;
21078 for (tree *pc = &clauses; *pc;)
21080 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21081 switch (OMP_CLAUSE_MAP_KIND (*pc))
21083 case GOMP_MAP_TO:
21084 case GOMP_MAP_ALWAYS_TO:
21085 case GOMP_MAP_ALLOC:
21086 map_seen = 3;
21087 break;
21088 case GOMP_MAP_TOFROM:
21089 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
21090 map_seen = 3;
21091 break;
21092 case GOMP_MAP_ALWAYS_TOFROM:
21093 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
21094 map_seen = 3;
21095 break;
21096 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21097 case GOMP_MAP_ALWAYS_POINTER:
21098 case GOMP_MAP_ATTACH_DETACH:
21099 break;
21100 default:
21101 map_seen |= 1;
21102 error_at (OMP_CLAUSE_LOCATION (*pc),
21103 "%<#pragma omp target enter data%> with map-type other "
21104 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21105 *pc = OMP_CLAUSE_CHAIN (*pc);
21106 continue;
21108 pc = &OMP_CLAUSE_CHAIN (*pc);
21111 if (map_seen != 3)
21113 if (map_seen == 0)
21114 error_at (loc,
21115 "%<#pragma omp target enter data%> must contain at least "
21116 "one %<map%> clause");
21117 return true;
21120 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
21121 TREE_TYPE (stmt) = void_type_node;
21122 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
21123 SET_EXPR_LOCATION (stmt, loc);
21124 add_stmt (stmt);
21125 return true;
21128 /* OpenMP 4.5:
21129 # pragma omp target exit data target-data-clause[optseq] new-line */
21131 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21132 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21138 static bool
21139 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
21140 enum pragma_context context)
21142 bool data_seen = false;
21143 if (c_parser_next_token_is (parser, CPP_NAME))
21145 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21146 if (strcmp (p, "data") == 0)
21148 c_parser_consume_token (parser);
21149 data_seen = true;
21152 if (!data_seen)
21154 c_parser_error (parser, "expected %<data%>");
21155 c_parser_skip_to_pragma_eol (parser);
21156 return false;
21159 if (context == pragma_stmt)
21161 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21162 "omp target exit data");
21163 c_parser_skip_to_pragma_eol (parser, false);
21164 return true;
21167 if (flag_openmp)
21168 omp_requires_mask
21169 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21171 tree clauses
21172 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21173 "#pragma omp target exit data");
21174 c_omp_adjust_map_clauses (clauses, false);
21175 int map_seen = 0;
21176 for (tree *pc = &clauses; *pc;)
21178 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21179 switch (OMP_CLAUSE_MAP_KIND (*pc))
21181 case GOMP_MAP_FROM:
21182 case GOMP_MAP_ALWAYS_FROM:
21183 case GOMP_MAP_RELEASE:
21184 case GOMP_MAP_DELETE:
21185 map_seen = 3;
21186 break;
21187 case GOMP_MAP_TOFROM:
21188 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
21189 map_seen = 3;
21190 break;
21191 case GOMP_MAP_ALWAYS_TOFROM:
21192 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
21193 map_seen = 3;
21194 break;
21195 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21196 case GOMP_MAP_ALWAYS_POINTER:
21197 case GOMP_MAP_ATTACH_DETACH:
21198 break;
21199 default:
21200 map_seen |= 1;
21201 error_at (OMP_CLAUSE_LOCATION (*pc),
21202 "%<#pragma omp target exit data%> with map-type other "
21203 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
21204 "on %<map%> clause");
21205 *pc = OMP_CLAUSE_CHAIN (*pc);
21206 continue;
21208 pc = &OMP_CLAUSE_CHAIN (*pc);
21211 if (map_seen != 3)
21213 if (map_seen == 0)
21214 error_at (loc,
21215 "%<#pragma omp target exit data%> must contain at least one "
21216 "%<map%> clause");
21217 return true;
21220 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
21221 TREE_TYPE (stmt) = void_type_node;
21222 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
21223 SET_EXPR_LOCATION (stmt, loc);
21224 add_stmt (stmt);
21225 return true;
21228 /* OpenMP 4.0:
21229 # pragma omp target target-clause[optseq] new-line
21230 structured-block */
21232 #define OMP_TARGET_CLAUSE_MASK \
21233 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21235 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21236 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21247 static bool
21248 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
21250 location_t loc = c_parser_peek_token (parser)->location;
21251 c_parser_consume_pragma (parser);
21252 tree *pc = NULL, stmt, block;
21254 if (context != pragma_stmt && context != pragma_compound)
21256 c_parser_error (parser, "expected declaration specifiers");
21257 c_parser_skip_to_pragma_eol (parser);
21258 return false;
21261 if (flag_openmp)
21262 omp_requires_mask
21263 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21265 if (c_parser_next_token_is (parser, CPP_NAME))
21267 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21268 enum tree_code ccode = ERROR_MARK;
21270 if (strcmp (p, "teams") == 0)
21271 ccode = OMP_TEAMS;
21272 else if (strcmp (p, "parallel") == 0)
21273 ccode = OMP_PARALLEL;
21274 else if (strcmp (p, "simd") == 0)
21275 ccode = OMP_SIMD;
21276 if (ccode != ERROR_MARK)
21278 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
21279 char p_name[sizeof ("#pragma omp target teams distribute "
21280 "parallel for simd")];
21282 c_parser_consume_token (parser);
21283 strcpy (p_name, "#pragma omp target");
21284 if (!flag_openmp) /* flag_openmp_simd */
21286 tree stmt;
21287 switch (ccode)
21289 case OMP_TEAMS:
21290 stmt = c_parser_omp_teams (loc, parser, p_name,
21291 OMP_TARGET_CLAUSE_MASK,
21292 cclauses, if_p);
21293 break;
21294 case OMP_PARALLEL:
21295 stmt = c_parser_omp_parallel (loc, parser, p_name,
21296 OMP_TARGET_CLAUSE_MASK,
21297 cclauses, if_p);
21298 break;
21299 case OMP_SIMD:
21300 stmt = c_parser_omp_simd (loc, parser, p_name,
21301 OMP_TARGET_CLAUSE_MASK,
21302 cclauses, if_p);
21303 break;
21304 default:
21305 gcc_unreachable ();
21307 return stmt != NULL_TREE;
21309 keep_next_level ();
21310 tree block = c_begin_compound_stmt (true), ret;
21311 switch (ccode)
21313 case OMP_TEAMS:
21314 ret = c_parser_omp_teams (loc, parser, p_name,
21315 OMP_TARGET_CLAUSE_MASK, cclauses,
21316 if_p);
21317 break;
21318 case OMP_PARALLEL:
21319 ret = c_parser_omp_parallel (loc, parser, p_name,
21320 OMP_TARGET_CLAUSE_MASK, cclauses,
21321 if_p);
21322 break;
21323 case OMP_SIMD:
21324 ret = c_parser_omp_simd (loc, parser, p_name,
21325 OMP_TARGET_CLAUSE_MASK, cclauses,
21326 if_p);
21327 break;
21328 default:
21329 gcc_unreachable ();
21331 block = c_end_compound_stmt (loc, block, true);
21332 if (ret == NULL_TREE)
21333 return false;
21334 if (ccode == OMP_TEAMS)
21335 /* For combined target teams, ensure the num_teams and
21336 thread_limit clause expressions are evaluated on the host,
21337 before entering the target construct. */
21338 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21339 c; c = OMP_CLAUSE_CHAIN (c))
21340 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
21341 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
21342 for (int i = 0;
21343 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
21344 if (OMP_CLAUSE_OPERAND (c, i)
21345 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
21347 tree expr = OMP_CLAUSE_OPERAND (c, i);
21348 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
21349 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
21350 expr, NULL_TREE, NULL_TREE);
21351 add_stmt (expr);
21352 OMP_CLAUSE_OPERAND (c, i) = expr;
21353 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
21354 OMP_CLAUSE_FIRSTPRIVATE);
21355 OMP_CLAUSE_DECL (tc) = tmp;
21356 OMP_CLAUSE_CHAIN (tc)
21357 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21358 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
21360 tree stmt = make_node (OMP_TARGET);
21361 TREE_TYPE (stmt) = void_type_node;
21362 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21363 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21364 OMP_TARGET_BODY (stmt) = block;
21365 OMP_TARGET_COMBINED (stmt) = 1;
21366 SET_EXPR_LOCATION (stmt, loc);
21367 add_stmt (stmt);
21368 pc = &OMP_TARGET_CLAUSES (stmt);
21369 goto check_clauses;
21371 else if (!flag_openmp) /* flag_openmp_simd */
21373 c_parser_skip_to_pragma_eol (parser, false);
21374 return false;
21376 else if (strcmp (p, "data") == 0)
21378 c_parser_consume_token (parser);
21379 c_parser_omp_target_data (loc, parser, if_p);
21380 return true;
21382 else if (strcmp (p, "enter") == 0)
21384 c_parser_consume_token (parser);
21385 return c_parser_omp_target_enter_data (loc, parser, context);
21387 else if (strcmp (p, "exit") == 0)
21389 c_parser_consume_token (parser);
21390 return c_parser_omp_target_exit_data (loc, parser, context);
21392 else if (strcmp (p, "update") == 0)
21394 c_parser_consume_token (parser);
21395 return c_parser_omp_target_update (loc, parser, context);
21398 if (!flag_openmp) /* flag_openmp_simd */
21400 c_parser_skip_to_pragma_eol (parser, false);
21401 return false;
21404 stmt = make_node (OMP_TARGET);
21405 TREE_TYPE (stmt) = void_type_node;
21407 OMP_TARGET_CLAUSES (stmt)
21408 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
21409 "#pragma omp target", false);
21410 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
21411 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
21413 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
21414 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
21415 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
21416 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
21417 OMP_CLAUSE_CHAIN (c) = nc;
21419 OMP_TARGET_CLAUSES (stmt)
21420 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
21421 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21423 pc = &OMP_TARGET_CLAUSES (stmt);
21424 keep_next_level ();
21425 block = c_begin_compound_stmt (true);
21426 add_stmt (c_parser_omp_structured_block (parser, if_p));
21427 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21429 SET_EXPR_LOCATION (stmt, loc);
21430 add_stmt (stmt);
21432 check_clauses:
21433 while (*pc)
21435 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21436 switch (OMP_CLAUSE_MAP_KIND (*pc))
21438 case GOMP_MAP_TO:
21439 case GOMP_MAP_ALWAYS_TO:
21440 case GOMP_MAP_FROM:
21441 case GOMP_MAP_ALWAYS_FROM:
21442 case GOMP_MAP_TOFROM:
21443 case GOMP_MAP_ALWAYS_TOFROM:
21444 case GOMP_MAP_ALLOC:
21445 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21446 case GOMP_MAP_ALWAYS_POINTER:
21447 case GOMP_MAP_ATTACH_DETACH:
21448 break;
21449 default:
21450 error_at (OMP_CLAUSE_LOCATION (*pc),
21451 "%<#pragma omp target%> with map-type other "
21452 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21453 "on %<map%> clause");
21454 *pc = OMP_CLAUSE_CHAIN (*pc);
21455 continue;
21457 pc = &OMP_CLAUSE_CHAIN (*pc);
21459 cfun->has_omp_target = true;
21460 return true;
21463 /* OpenMP 4.0:
21464 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21466 OpenMP 5.0:
21467 # pragma omp declare variant (identifier) match(context-selector) new-line
21470 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21471 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21476 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21478 static void
21479 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
21481 c_token *token = c_parser_peek_token (parser);
21482 gcc_assert (token->type == CPP_NAME);
21483 tree kind = token->value;
21484 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
21485 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
21487 auto_vec<c_token> clauses;
21488 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21490 c_token *token = c_parser_peek_token (parser);
21491 if (token->type == CPP_EOF)
21493 c_parser_skip_to_pragma_eol (parser);
21494 return;
21496 clauses.safe_push (*token);
21497 c_parser_consume_token (parser);
21499 clauses.safe_push (*c_parser_peek_token (parser));
21500 c_parser_skip_to_pragma_eol (parser);
21502 while (c_parser_next_token_is (parser, CPP_PRAGMA))
21504 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
21505 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
21506 || c_parser_peek_2nd_token (parser)->value != kind)
21508 error ("%<#pragma omp declare %s%> must be followed by "
21509 "function declaration or definition or another "
21510 "%<#pragma omp declare %s%>",
21511 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
21512 return;
21514 c_parser_consume_pragma (parser);
21515 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21517 c_token *token = c_parser_peek_token (parser);
21518 if (token->type == CPP_EOF)
21520 c_parser_skip_to_pragma_eol (parser);
21521 return;
21523 clauses.safe_push (*token);
21524 c_parser_consume_token (parser);
21526 clauses.safe_push (*c_parser_peek_token (parser));
21527 c_parser_skip_to_pragma_eol (parser);
21530 /* Make sure nothing tries to read past the end of the tokens. */
21531 c_token eof_token;
21532 memset (&eof_token, 0, sizeof (eof_token));
21533 eof_token.type = CPP_EOF;
21534 clauses.safe_push (eof_token);
21535 clauses.safe_push (eof_token);
21537 switch (context)
21539 case pragma_external:
21540 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21541 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21543 int ext = disable_extension_diagnostics ();
21545 c_parser_consume_token (parser);
21546 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21547 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21548 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21549 NULL, &clauses);
21550 restore_extension_diagnostics (ext);
21552 else
21553 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21554 NULL, &clauses);
21555 break;
21556 case pragma_struct:
21557 case pragma_param:
21558 case pragma_stmt:
21559 error ("%<#pragma omp declare %s%> must be followed by "
21560 "function declaration or definition",
21561 IDENTIFIER_POINTER (kind));
21562 break;
21563 case pragma_compound:
21564 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21565 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21567 int ext = disable_extension_diagnostics ();
21569 c_parser_consume_token (parser);
21570 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21571 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21572 if (c_parser_next_tokens_start_declaration (parser))
21574 c_parser_declaration_or_fndef (parser, true, true, true, true,
21575 true, NULL, &clauses);
21576 restore_extension_diagnostics (ext);
21577 break;
21579 restore_extension_diagnostics (ext);
21581 else if (c_parser_next_tokens_start_declaration (parser))
21583 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
21584 NULL, &clauses);
21585 break;
21587 error ("%<#pragma omp declare %s%> must be followed by "
21588 "function declaration or definition",
21589 IDENTIFIER_POINTER (kind));
21590 break;
21591 default:
21592 gcc_unreachable ();
21596 static const char *const omp_construct_selectors[] = {
21597 "simd", "target", "teams", "parallel", "for", NULL };
21598 static const char *const omp_device_selectors[] = {
21599 "kind", "isa", "arch", NULL };
21600 static const char *const omp_implementation_selectors[] = {
21601 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21602 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
21603 static const char *const omp_user_selectors[] = {
21604 "condition", NULL };
21606 /* OpenMP 5.0:
21608 trait-selector:
21609 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21611 trait-score:
21612 score(score-expression) */
21614 static tree
21615 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
21617 tree ret = NULL_TREE;
21620 tree selector;
21621 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21622 || c_parser_next_token_is (parser, CPP_NAME))
21623 selector = c_parser_peek_token (parser)->value;
21624 else
21626 c_parser_error (parser, "expected trait selector name");
21627 return error_mark_node;
21630 tree properties = NULL_TREE;
21631 const char *const *selectors = NULL;
21632 bool allow_score = true;
21633 bool allow_user = false;
21634 int property_limit = 0;
21635 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
21636 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
21637 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
21638 switch (IDENTIFIER_POINTER (set)[0])
21640 case 'c': /* construct */
21641 selectors = omp_construct_selectors;
21642 allow_score = false;
21643 property_limit = 1;
21644 property_kind = CTX_PROPERTY_SIMD;
21645 break;
21646 case 'd': /* device */
21647 selectors = omp_device_selectors;
21648 allow_score = false;
21649 allow_user = true;
21650 property_limit = 3;
21651 property_kind = CTX_PROPERTY_NAME_LIST;
21652 break;
21653 case 'i': /* implementation */
21654 selectors = omp_implementation_selectors;
21655 allow_user = true;
21656 property_limit = 3;
21657 property_kind = CTX_PROPERTY_NAME_LIST;
21658 break;
21659 case 'u': /* user */
21660 selectors = omp_user_selectors;
21661 property_limit = 1;
21662 property_kind = CTX_PROPERTY_EXPR;
21663 break;
21664 default:
21665 gcc_unreachable ();
21667 for (int i = 0; ; i++)
21669 if (selectors[i] == NULL)
21671 if (allow_user)
21673 property_kind = CTX_PROPERTY_USER;
21674 break;
21676 else
21678 error_at (c_parser_peek_token (parser)->location,
21679 "selector %qs not allowed for context selector "
21680 "set %qs", IDENTIFIER_POINTER (selector),
21681 IDENTIFIER_POINTER (set));
21682 c_parser_consume_token (parser);
21683 return error_mark_node;
21686 if (i == property_limit)
21687 property_kind = CTX_PROPERTY_NONE;
21688 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
21689 break;
21691 if (property_kind == CTX_PROPERTY_NAME_LIST
21692 && IDENTIFIER_POINTER (set)[0] == 'i'
21693 && strcmp (IDENTIFIER_POINTER (selector),
21694 "atomic_default_mem_order") == 0)
21695 property_kind = CTX_PROPERTY_ID;
21697 c_parser_consume_token (parser);
21699 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21701 if (property_kind == CTX_PROPERTY_NONE)
21703 error_at (c_parser_peek_token (parser)->location,
21704 "selector %qs does not accept any properties",
21705 IDENTIFIER_POINTER (selector));
21706 return error_mark_node;
21709 matching_parens parens;
21710 parens.require_open (parser);
21712 c_token *token = c_parser_peek_token (parser);
21713 if (allow_score
21714 && c_parser_next_token_is (parser, CPP_NAME)
21715 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
21716 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
21718 c_parser_consume_token (parser);
21720 matching_parens parens2;
21721 parens2.require_open (parser);
21722 tree score = c_parser_expr_no_commas (parser, NULL).value;
21723 parens2.skip_until_found_close (parser);
21724 c_parser_require (parser, CPP_COLON, "expected %<:%>");
21725 if (score != error_mark_node)
21727 mark_exp_read (score);
21728 score = c_fully_fold (score, false, NULL);
21729 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
21730 || TREE_CODE (score) != INTEGER_CST)
21731 error_at (token->location, "score argument must be "
21732 "constant integer expression");
21733 else if (tree_int_cst_sgn (score) < 0)
21734 error_at (token->location, "score argument must be "
21735 "non-negative");
21736 else
21737 properties = tree_cons (get_identifier (" score"),
21738 score, properties);
21740 token = c_parser_peek_token (parser);
21743 switch (property_kind)
21745 tree t;
21746 case CTX_PROPERTY_USER:
21749 t = c_parser_expr_no_commas (parser, NULL).value;
21750 if (TREE_CODE (t) == STRING_CST)
21751 properties = tree_cons (NULL_TREE, t, properties);
21752 else if (t != error_mark_node)
21754 mark_exp_read (t);
21755 t = c_fully_fold (t, false, NULL);
21756 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21757 || !tree_fits_shwi_p (t))
21758 error_at (token->location, "property must be "
21759 "constant integer expression or string "
21760 "literal");
21761 else
21762 properties = tree_cons (NULL_TREE, t, properties);
21764 else
21765 return error_mark_node;
21767 if (c_parser_next_token_is (parser, CPP_COMMA))
21768 c_parser_consume_token (parser);
21769 else
21770 break;
21772 while (1);
21773 break;
21774 case CTX_PROPERTY_ID:
21775 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21776 || c_parser_next_token_is (parser, CPP_NAME))
21778 tree prop = c_parser_peek_token (parser)->value;
21779 c_parser_consume_token (parser);
21780 properties = tree_cons (prop, NULL_TREE, properties);
21782 else
21784 c_parser_error (parser, "expected identifier");
21785 return error_mark_node;
21787 break;
21788 case CTX_PROPERTY_NAME_LIST:
21791 tree prop = NULL_TREE, value = NULL_TREE;
21792 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21793 || c_parser_next_token_is (parser, CPP_NAME))
21795 prop = c_parser_peek_token (parser)->value;
21796 c_parser_consume_token (parser);
21798 else if (c_parser_next_token_is (parser, CPP_STRING))
21799 value = c_parser_string_literal (parser, false,
21800 false).value;
21801 else
21803 c_parser_error (parser, "expected identifier or "
21804 "string literal");
21805 return error_mark_node;
21808 properties = tree_cons (prop, value, properties);
21810 if (c_parser_next_token_is (parser, CPP_COMMA))
21811 c_parser_consume_token (parser);
21812 else
21813 break;
21815 while (1);
21816 break;
21817 case CTX_PROPERTY_EXPR:
21818 t = c_parser_expr_no_commas (parser, NULL).value;
21819 if (t != error_mark_node)
21821 mark_exp_read (t);
21822 t = c_fully_fold (t, false, NULL);
21823 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21824 || !tree_fits_shwi_p (t))
21825 error_at (token->location, "property must be "
21826 "constant integer expression");
21827 else
21828 properties = tree_cons (NULL_TREE, t, properties);
21830 else
21831 return error_mark_node;
21832 break;
21833 case CTX_PROPERTY_SIMD:
21834 if (parms == NULL_TREE)
21836 error_at (token->location, "properties for %<simd%> "
21837 "selector may not be specified in "
21838 "%<metadirective%>");
21839 return error_mark_node;
21841 tree c;
21842 c = c_parser_omp_all_clauses (parser,
21843 OMP_DECLARE_SIMD_CLAUSE_MASK,
21844 "simd", true, 2);
21845 c = c_omp_declare_simd_clauses_to_numbers (parms
21846 == error_mark_node
21847 ? NULL_TREE : parms,
21849 properties = c;
21850 break;
21851 default:
21852 gcc_unreachable ();
21855 parens.skip_until_found_close (parser);
21856 properties = nreverse (properties);
21858 else if (property_kind == CTX_PROPERTY_NAME_LIST
21859 || property_kind == CTX_PROPERTY_ID
21860 || property_kind == CTX_PROPERTY_EXPR)
21862 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
21863 return error_mark_node;
21866 ret = tree_cons (selector, properties, ret);
21868 if (c_parser_next_token_is (parser, CPP_COMMA))
21869 c_parser_consume_token (parser);
21870 else
21871 break;
21873 while (1);
21875 return nreverse (ret);
21878 /* OpenMP 5.0:
21880 trait-set-selector[,trait-set-selector[,...]]
21882 trait-set-selector:
21883 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21885 trait-set-selector-name:
21886 constructor
21887 device
21888 implementation
21889 user */
21891 static tree
21892 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
21894 tree ret = NULL_TREE;
21897 const char *setp = "";
21898 if (c_parser_next_token_is (parser, CPP_NAME))
21899 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21900 switch (setp[0])
21902 case 'c':
21903 if (strcmp (setp, "construct") == 0)
21904 setp = NULL;
21905 break;
21906 case 'd':
21907 if (strcmp (setp, "device") == 0)
21908 setp = NULL;
21909 break;
21910 case 'i':
21911 if (strcmp (setp, "implementation") == 0)
21912 setp = NULL;
21913 break;
21914 case 'u':
21915 if (strcmp (setp, "user") == 0)
21916 setp = NULL;
21917 break;
21918 default:
21919 break;
21921 if (setp)
21923 c_parser_error (parser, "expected %<construct%>, %<device%>, "
21924 "%<implementation%> or %<user%>");
21925 return error_mark_node;
21928 tree set = c_parser_peek_token (parser)->value;
21929 c_parser_consume_token (parser);
21931 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21932 return error_mark_node;
21934 matching_braces braces;
21935 if (!braces.require_open (parser))
21936 return error_mark_node;
21938 tree selectors = c_parser_omp_context_selector (parser, set, parms);
21939 if (selectors == error_mark_node)
21940 ret = error_mark_node;
21941 else if (ret != error_mark_node)
21942 ret = tree_cons (set, selectors, ret);
21944 braces.skip_until_found_close (parser);
21946 if (c_parser_next_token_is (parser, CPP_COMMA))
21947 c_parser_consume_token (parser);
21948 else
21949 break;
21951 while (1);
21953 if (ret == error_mark_node)
21954 return ret;
21955 return nreverse (ret);
21958 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21959 that into "omp declare variant base" attribute. */
21961 static void
21962 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
21964 matching_parens parens;
21965 if (!parens.require_open (parser))
21967 fail:
21968 c_parser_skip_to_pragma_eol (parser, false);
21969 return;
21972 if (c_parser_next_token_is_not (parser, CPP_NAME)
21973 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
21975 c_parser_error (parser, "expected identifier");
21976 goto fail;
21979 c_token *token = c_parser_peek_token (parser);
21980 tree variant = lookup_name (token->value);
21982 if (variant == NULL_TREE)
21984 undeclared_variable (token->location, token->value);
21985 variant = error_mark_node;
21988 c_parser_consume_token (parser);
21990 parens.require_close (parser);
21992 const char *clause = "";
21993 location_t match_loc = c_parser_peek_token (parser)->location;
21994 if (c_parser_next_token_is (parser, CPP_NAME))
21995 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21996 if (strcmp (clause, "match"))
21998 c_parser_error (parser, "expected %<match%>");
21999 goto fail;
22002 c_parser_consume_token (parser);
22004 if (!parens.require_open (parser))
22005 goto fail;
22007 if (parms == NULL_TREE)
22008 parms = error_mark_node;
22010 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
22011 if (ctx == error_mark_node)
22012 goto fail;
22013 ctx = omp_check_context_selector (match_loc, ctx);
22014 if (ctx != error_mark_node && variant != error_mark_node)
22016 if (TREE_CODE (variant) != FUNCTION_DECL)
22018 error_at (token->location, "variant %qD is not a function", variant);
22019 variant = error_mark_node;
22021 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
22022 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
22024 error_at (token->location, "variant %qD and base %qD have "
22025 "incompatible types", variant, fndecl);
22026 variant = error_mark_node;
22028 else if (fndecl_built_in_p (variant)
22029 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22030 "__builtin_", strlen ("__builtin_")) == 0
22031 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22032 "__sync_", strlen ("__sync_")) == 0
22033 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22034 "__atomic_", strlen ("__atomic_")) == 0))
22036 error_at (token->location, "variant %qD is a built-in", variant);
22037 variant = error_mark_node;
22039 if (variant != error_mark_node)
22041 C_DECL_USED (variant) = 1;
22042 tree construct = omp_get_context_selector (ctx, "construct", NULL);
22043 omp_mark_declare_variant (match_loc, variant, construct);
22044 if (omp_context_selector_matches (ctx))
22046 tree attr
22047 = tree_cons (get_identifier ("omp declare variant base"),
22048 build_tree_list (variant, ctx),
22049 DECL_ATTRIBUTES (fndecl));
22050 DECL_ATTRIBUTES (fndecl) = attr;
22055 parens.require_close (parser);
22056 c_parser_skip_to_pragma_eol (parser);
22059 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22060 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22061 or "omp declare variant base" attribute. */
22063 static void
22064 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
22065 vec<c_token> *pclauses)
22067 vec<c_token> &clauses = *pclauses;
22069 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22070 indicates error has been reported and CPP_PRAGMA that
22071 c_finish_omp_declare_simd has already processed the tokens. */
22072 if (clauses.exists () && clauses[0].type == CPP_EOF)
22073 return;
22074 const char *kind = "simd";
22075 if (clauses.exists ()
22076 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
22077 kind = IDENTIFIER_POINTER (clauses[0].value);
22078 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
22079 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
22081 error ("%<#pragma omp declare %s%> not immediately followed by "
22082 "a function declaration or definition", kind);
22083 clauses[0].type = CPP_EOF;
22084 return;
22086 if (clauses.exists () && clauses[0].type != CPP_NAME)
22088 error_at (DECL_SOURCE_LOCATION (fndecl),
22089 "%<#pragma omp declare %s%> not immediately followed by "
22090 "a single function declaration or definition", kind);
22091 clauses[0].type = CPP_EOF;
22092 return;
22095 if (parms == NULL_TREE)
22096 parms = DECL_ARGUMENTS (fndecl);
22098 unsigned int tokens_avail = parser->tokens_avail;
22099 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22101 parser->tokens = clauses.address ();
22102 parser->tokens_avail = clauses.length ();
22104 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22105 while (parser->tokens_avail > 3)
22107 c_token *token = c_parser_peek_token (parser);
22108 gcc_assert (token->type == CPP_NAME
22109 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
22110 c_parser_consume_token (parser);
22111 parser->in_pragma = true;
22113 if (strcmp (kind, "simd") == 0)
22115 tree c;
22116 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
22117 "#pragma omp declare simd");
22118 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
22119 if (c != NULL_TREE)
22120 c = tree_cons (NULL_TREE, c, NULL_TREE);
22121 c = build_tree_list (get_identifier ("omp declare simd"), c);
22122 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
22123 DECL_ATTRIBUTES (fndecl) = c;
22125 else
22127 gcc_assert (strcmp (kind, "variant") == 0);
22128 c_finish_omp_declare_variant (parser, fndecl, parms);
22132 parser->tokens = &parser->tokens_buf[0];
22133 parser->tokens_avail = tokens_avail;
22134 if (clauses.exists ())
22135 clauses[0].type = CPP_PRAGMA;
22139 /* OpenMP 4.0:
22140 # pragma omp declare target new-line
22141 declarations and definitions
22142 # pragma omp end declare target new-line
22144 OpenMP 4.5:
22145 # pragma omp declare target ( extended-list ) new-line
22147 # pragma omp declare target declare-target-clauses[seq] new-line */
22149 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22150 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22155 static void
22156 c_parser_omp_declare_target (c_parser *parser)
22158 tree clauses = NULL_TREE;
22159 int device_type = 0;
22160 bool only_device_type = true;
22161 if (c_parser_next_token_is (parser, CPP_NAME))
22162 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
22163 "#pragma omp declare target");
22164 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22166 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
22167 clauses);
22168 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22169 c_parser_skip_to_pragma_eol (parser);
22171 else
22173 c_parser_skip_to_pragma_eol (parser);
22174 current_omp_declare_target_attribute++;
22175 return;
22177 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22178 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22179 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22180 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22182 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22183 continue;
22184 tree t = OMP_CLAUSE_DECL (c), id;
22185 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
22186 tree at2 = lookup_attribute ("omp declare target link",
22187 DECL_ATTRIBUTES (t));
22188 only_device_type = false;
22189 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
22191 id = get_identifier ("omp declare target link");
22192 std::swap (at1, at2);
22194 else
22195 id = get_identifier ("omp declare target");
22196 if (at2)
22198 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
22199 error_at (OMP_CLAUSE_LOCATION (c),
22200 "%qD specified both in declare target %<link%> and %qs"
22201 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
22202 else
22203 error_at (OMP_CLAUSE_LOCATION (c),
22204 "%qD specified both in declare target %<link%> and "
22205 "%<to%> or %<enter%> clauses", t);
22206 continue;
22208 if (!at1)
22210 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22211 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
22212 continue;
22214 symtab_node *node = symtab_node::get (t);
22215 if (node != NULL)
22217 node->offloadable = 1;
22218 if (ENABLE_OFFLOADING)
22220 g->have_offload = true;
22221 if (is_a <varpool_node *> (node))
22222 vec_safe_push (offload_vars, t);
22226 if (TREE_CODE (t) != FUNCTION_DECL)
22227 continue;
22228 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
22230 tree at3 = lookup_attribute ("omp declare target host",
22231 DECL_ATTRIBUTES (t));
22232 if (at3 == NULL_TREE)
22234 id = get_identifier ("omp declare target host");
22235 DECL_ATTRIBUTES (t)
22236 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22239 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
22241 tree at3 = lookup_attribute ("omp declare target nohost",
22242 DECL_ATTRIBUTES (t));
22243 if (at3 == NULL_TREE)
22245 id = get_identifier ("omp declare target nohost");
22246 DECL_ATTRIBUTES (t)
22247 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22251 if (device_type && only_device_type)
22252 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
22253 "directive with only %<device_type%> clauses ignored");
22256 static void
22257 c_parser_omp_end_declare_target (c_parser *parser)
22259 location_t loc = c_parser_peek_token (parser)->location;
22260 c_parser_consume_pragma (parser);
22261 if (c_parser_next_token_is (parser, CPP_NAME)
22262 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22263 "declare") == 0)
22265 c_parser_consume_token (parser);
22266 if (c_parser_next_token_is (parser, CPP_NAME)
22267 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22268 "target") == 0)
22269 c_parser_consume_token (parser);
22270 else
22272 c_parser_error (parser, "expected %<target%>");
22273 c_parser_skip_to_pragma_eol (parser);
22274 return;
22277 else
22279 c_parser_error (parser, "expected %<declare%>");
22280 c_parser_skip_to_pragma_eol (parser);
22281 return;
22283 c_parser_skip_to_pragma_eol (parser);
22284 if (!current_omp_declare_target_attribute)
22285 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
22286 "%<#pragma omp declare target%>");
22287 else
22288 current_omp_declare_target_attribute--;
22292 /* OpenMP 4.0
22293 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22294 initializer-clause[opt] new-line
22296 initializer-clause:
22297 initializer (omp_priv = initializer)
22298 initializer (function-name (argument-list)) */
22300 static void
22301 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
22303 unsigned int tokens_avail = 0, i;
22304 vec<tree> types = vNULL;
22305 vec<c_token> clauses = vNULL;
22306 enum tree_code reduc_code = ERROR_MARK;
22307 tree reduc_id = NULL_TREE;
22308 tree type;
22309 location_t rloc = c_parser_peek_token (parser)->location;
22311 if (context == pragma_struct || context == pragma_param)
22313 error ("%<#pragma omp declare reduction%> not at file or block scope");
22314 goto fail;
22317 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22318 goto fail;
22320 switch (c_parser_peek_token (parser)->type)
22322 case CPP_PLUS:
22323 reduc_code = PLUS_EXPR;
22324 break;
22325 case CPP_MULT:
22326 reduc_code = MULT_EXPR;
22327 break;
22328 case CPP_MINUS:
22329 reduc_code = MINUS_EXPR;
22330 break;
22331 case CPP_AND:
22332 reduc_code = BIT_AND_EXPR;
22333 break;
22334 case CPP_XOR:
22335 reduc_code = BIT_XOR_EXPR;
22336 break;
22337 case CPP_OR:
22338 reduc_code = BIT_IOR_EXPR;
22339 break;
22340 case CPP_AND_AND:
22341 reduc_code = TRUTH_ANDIF_EXPR;
22342 break;
22343 case CPP_OR_OR:
22344 reduc_code = TRUTH_ORIF_EXPR;
22345 break;
22346 case CPP_NAME:
22347 const char *p;
22348 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22349 if (strcmp (p, "min") == 0)
22351 reduc_code = MIN_EXPR;
22352 break;
22354 if (strcmp (p, "max") == 0)
22356 reduc_code = MAX_EXPR;
22357 break;
22359 reduc_id = c_parser_peek_token (parser)->value;
22360 break;
22361 default:
22362 c_parser_error (parser,
22363 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22364 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22365 goto fail;
22368 tree orig_reduc_id, reduc_decl;
22369 orig_reduc_id = reduc_id;
22370 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
22371 reduc_decl = c_omp_reduction_decl (reduc_id);
22372 c_parser_consume_token (parser);
22374 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
22375 goto fail;
22377 while (true)
22379 location_t loc = c_parser_peek_token (parser)->location;
22380 struct c_type_name *ctype = c_parser_type_name (parser);
22381 if (ctype != NULL)
22383 type = groktypename (ctype, NULL, NULL);
22384 if (type == error_mark_node)
22386 else if ((INTEGRAL_TYPE_P (type)
22387 || TREE_CODE (type) == REAL_TYPE
22388 || TREE_CODE (type) == COMPLEX_TYPE)
22389 && orig_reduc_id == NULL_TREE)
22390 error_at (loc, "predeclared arithmetic type in "
22391 "%<#pragma omp declare reduction%>");
22392 else if (TREE_CODE (type) == FUNCTION_TYPE
22393 || TREE_CODE (type) == ARRAY_TYPE)
22394 error_at (loc, "function or array type in "
22395 "%<#pragma omp declare reduction%>");
22396 else if (TYPE_ATOMIC (type))
22397 error_at (loc, "%<_Atomic%> qualified type in "
22398 "%<#pragma omp declare reduction%>");
22399 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
22400 error_at (loc, "const, volatile or restrict qualified type in "
22401 "%<#pragma omp declare reduction%>");
22402 else
22404 tree t;
22405 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
22406 if (comptypes (TREE_PURPOSE (t), type))
22408 error_at (loc, "redeclaration of %qs "
22409 "%<#pragma omp declare reduction%> for "
22410 "type %qT",
22411 IDENTIFIER_POINTER (reduc_id)
22412 + sizeof ("omp declare reduction ") - 1,
22413 type);
22414 location_t ploc
22415 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
22416 0));
22417 error_at (ploc, "previous %<#pragma omp declare "
22418 "reduction%>");
22419 break;
22421 if (t == NULL_TREE)
22422 types.safe_push (type);
22424 if (c_parser_next_token_is (parser, CPP_COMMA))
22425 c_parser_consume_token (parser);
22426 else
22427 break;
22429 else
22430 break;
22433 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
22434 || types.is_empty ())
22436 fail:
22437 clauses.release ();
22438 types.release ();
22439 while (true)
22441 c_token *token = c_parser_peek_token (parser);
22442 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
22443 break;
22444 c_parser_consume_token (parser);
22446 c_parser_skip_to_pragma_eol (parser);
22447 return;
22450 if (types.length () > 1)
22452 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22454 c_token *token = c_parser_peek_token (parser);
22455 if (token->type == CPP_EOF)
22456 goto fail;
22457 clauses.safe_push (*token);
22458 c_parser_consume_token (parser);
22460 clauses.safe_push (*c_parser_peek_token (parser));
22461 c_parser_skip_to_pragma_eol (parser);
22463 /* Make sure nothing tries to read past the end of the tokens. */
22464 c_token eof_token;
22465 memset (&eof_token, 0, sizeof (eof_token));
22466 eof_token.type = CPP_EOF;
22467 clauses.safe_push (eof_token);
22468 clauses.safe_push (eof_token);
22471 int errs = errorcount;
22472 FOR_EACH_VEC_ELT (types, i, type)
22474 tokens_avail = parser->tokens_avail;
22475 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22476 if (!clauses.is_empty ())
22478 parser->tokens = clauses.address ();
22479 parser->tokens_avail = clauses.length ();
22480 parser->in_pragma = true;
22483 bool nested = current_function_decl != NULL_TREE;
22484 if (nested)
22485 c_push_function_context ();
22486 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
22487 reduc_id, default_function_type);
22488 current_function_decl = fndecl;
22489 allocate_struct_function (fndecl, true);
22490 push_scope ();
22491 tree stmt = push_stmt_list ();
22492 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22493 warn about these. */
22494 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
22495 get_identifier ("omp_out"), type);
22496 DECL_ARTIFICIAL (omp_out) = 1;
22497 DECL_CONTEXT (omp_out) = fndecl;
22498 pushdecl (omp_out);
22499 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
22500 get_identifier ("omp_in"), type);
22501 DECL_ARTIFICIAL (omp_in) = 1;
22502 DECL_CONTEXT (omp_in) = fndecl;
22503 pushdecl (omp_in);
22504 struct c_expr combiner = c_parser_expression (parser);
22505 struct c_expr initializer;
22506 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
22507 bool bad = false;
22508 initializer.set_error ();
22509 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22510 bad = true;
22511 else if (c_parser_next_token_is (parser, CPP_NAME)
22512 && strcmp (IDENTIFIER_POINTER
22513 (c_parser_peek_token (parser)->value),
22514 "initializer") == 0)
22516 c_parser_consume_token (parser);
22517 pop_scope ();
22518 push_scope ();
22519 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
22520 get_identifier ("omp_priv"), type);
22521 DECL_ARTIFICIAL (omp_priv) = 1;
22522 DECL_INITIAL (omp_priv) = error_mark_node;
22523 DECL_CONTEXT (omp_priv) = fndecl;
22524 pushdecl (omp_priv);
22525 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
22526 get_identifier ("omp_orig"), type);
22527 DECL_ARTIFICIAL (omp_orig) = 1;
22528 DECL_CONTEXT (omp_orig) = fndecl;
22529 pushdecl (omp_orig);
22530 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22531 bad = true;
22532 else if (!c_parser_next_token_is (parser, CPP_NAME))
22534 c_parser_error (parser, "expected %<omp_priv%> or "
22535 "function-name");
22536 bad = true;
22538 else if (strcmp (IDENTIFIER_POINTER
22539 (c_parser_peek_token (parser)->value),
22540 "omp_priv") != 0)
22542 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
22543 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22545 c_parser_error (parser, "expected function-name %<(%>");
22546 bad = true;
22548 else
22549 initializer = c_parser_postfix_expression (parser);
22550 if (initializer.value
22551 && TREE_CODE (initializer.value) == CALL_EXPR)
22553 int j;
22554 tree c = initializer.value;
22555 for (j = 0; j < call_expr_nargs (c); j++)
22557 tree a = CALL_EXPR_ARG (c, j);
22558 STRIP_NOPS (a);
22559 if (TREE_CODE (a) == ADDR_EXPR
22560 && TREE_OPERAND (a, 0) == omp_priv)
22561 break;
22563 if (j == call_expr_nargs (c))
22564 error ("one of the initializer call arguments should be "
22565 "%<&omp_priv%>");
22568 else
22570 c_parser_consume_token (parser);
22571 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22572 bad = true;
22573 else
22575 tree st = push_stmt_list ();
22576 location_t loc = c_parser_peek_token (parser)->location;
22577 rich_location richloc (line_table, loc);
22578 start_init (omp_priv, NULL_TREE, 0, &richloc);
22579 struct c_expr init = c_parser_initializer (parser);
22580 finish_init ();
22581 finish_decl (omp_priv, loc, init.value,
22582 init.original_type, NULL_TREE);
22583 pop_stmt_list (st);
22586 if (!bad
22587 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22588 bad = true;
22591 if (!bad)
22593 c_parser_skip_to_pragma_eol (parser);
22595 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
22596 DECL_INITIAL (reduc_decl));
22597 DECL_INITIAL (reduc_decl) = t;
22598 DECL_SOURCE_LOCATION (omp_out) = rloc;
22599 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
22600 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
22601 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
22602 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
22603 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
22604 if (omp_priv)
22606 DECL_SOURCE_LOCATION (omp_priv) = rloc;
22607 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
22608 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
22609 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
22610 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
22611 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22612 walk_tree (&DECL_INITIAL (omp_priv),
22613 c_check_omp_declare_reduction_r,
22614 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22618 pop_stmt_list (stmt);
22619 pop_scope ();
22620 if (cfun->language != NULL)
22622 ggc_free (cfun->language);
22623 cfun->language = NULL;
22625 set_cfun (NULL);
22626 current_function_decl = NULL_TREE;
22627 if (nested)
22628 c_pop_function_context ();
22630 if (!clauses.is_empty ())
22632 parser->tokens = &parser->tokens_buf[0];
22633 parser->tokens_avail = tokens_avail;
22635 if (bad)
22636 goto fail;
22637 if (errs != errorcount)
22638 break;
22641 clauses.release ();
22642 types.release ();
22646 /* OpenMP 4.0
22647 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22648 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22649 initializer-clause[opt] new-line
22650 #pragma omp declare target new-line
22652 OpenMP 5.0
22653 #pragma omp declare variant (identifier) match (context-selector) */
22655 static bool
22656 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
22658 c_parser_consume_pragma (parser);
22659 if (c_parser_next_token_is (parser, CPP_NAME))
22661 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22662 if (strcmp (p, "simd") == 0)
22664 /* c_parser_consume_token (parser); done in
22665 c_parser_omp_declare_simd. */
22666 c_parser_omp_declare_simd (parser, context);
22667 return true;
22669 if (strcmp (p, "reduction") == 0)
22671 c_parser_consume_token (parser);
22672 c_parser_omp_declare_reduction (parser, context);
22673 return false;
22675 if (!flag_openmp) /* flag_openmp_simd */
22677 c_parser_skip_to_pragma_eol (parser, false);
22678 return false;
22680 if (strcmp (p, "target") == 0)
22682 c_parser_consume_token (parser);
22683 c_parser_omp_declare_target (parser);
22684 return false;
22686 if (strcmp (p, "variant") == 0)
22688 /* c_parser_consume_token (parser); done in
22689 c_parser_omp_declare_simd. */
22690 c_parser_omp_declare_simd (parser, context);
22691 return true;
22695 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
22696 "%<target%> or %<variant%>");
22697 c_parser_skip_to_pragma_eol (parser);
22698 return false;
22701 /* OpenMP 5.0
22702 #pragma omp requires clauses[optseq] new-line */
22704 static void
22705 c_parser_omp_requires (c_parser *parser)
22707 bool first = true;
22708 enum omp_requires new_req = (enum omp_requires) 0;
22710 c_parser_consume_pragma (parser);
22712 location_t loc = c_parser_peek_token (parser)->location;
22713 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22715 if (!first
22716 && c_parser_next_token_is (parser, CPP_COMMA)
22717 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22718 c_parser_consume_token (parser);
22720 first = false;
22722 if (c_parser_next_token_is (parser, CPP_NAME))
22724 const char *p
22725 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22726 location_t cloc = c_parser_peek_token (parser)->location;
22727 enum omp_requires this_req = (enum omp_requires) 0;
22729 if (!strcmp (p, "unified_address"))
22730 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
22731 else if (!strcmp (p, "unified_shared_memory"))
22732 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
22733 else if (!strcmp (p, "dynamic_allocators"))
22734 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
22735 else if (!strcmp (p, "reverse_offload"))
22736 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
22737 else if (!strcmp (p, "atomic_default_mem_order"))
22739 c_parser_consume_token (parser);
22741 matching_parens parens;
22742 if (parens.require_open (parser))
22744 if (c_parser_next_token_is (parser, CPP_NAME))
22746 tree v = c_parser_peek_token (parser)->value;
22747 p = IDENTIFIER_POINTER (v);
22749 if (!strcmp (p, "seq_cst"))
22750 this_req
22751 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
22752 else if (!strcmp (p, "relaxed"))
22753 this_req
22754 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
22755 else if (!strcmp (p, "acq_rel"))
22756 this_req
22757 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
22759 if (this_req == 0)
22761 error_at (c_parser_peek_token (parser)->location,
22762 "expected %<seq_cst%>, %<relaxed%> or "
22763 "%<acq_rel%>");
22764 switch (c_parser_peek_token (parser)->type)
22766 case CPP_EOF:
22767 case CPP_PRAGMA_EOL:
22768 case CPP_CLOSE_PAREN:
22769 break;
22770 default:
22771 if (c_parser_peek_2nd_token (parser)->type
22772 == CPP_CLOSE_PAREN)
22773 c_parser_consume_token (parser);
22774 break;
22777 else
22778 c_parser_consume_token (parser);
22780 parens.skip_until_found_close (parser);
22781 if (this_req == 0)
22783 c_parser_skip_to_pragma_eol (parser, false);
22784 return;
22787 p = NULL;
22789 else
22791 error_at (cloc, "expected %<unified_address%>, "
22792 "%<unified_shared_memory%>, "
22793 "%<dynamic_allocators%>, "
22794 "%<reverse_offload%> "
22795 "or %<atomic_default_mem_order%> clause");
22796 c_parser_skip_to_pragma_eol (parser, false);
22797 return;
22799 if (p)
22800 c_parser_consume_token (parser);
22801 if (this_req)
22803 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22805 if ((this_req & new_req) != 0)
22806 error_at (cloc, "too many %qs clauses", p);
22807 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
22808 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
22809 error_at (cloc, "%qs clause used lexically after first "
22810 "target construct or offloading API", p);
22812 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22814 error_at (cloc, "too many %qs clauses",
22815 "atomic_default_mem_order");
22816 this_req = (enum omp_requires) 0;
22818 else if ((omp_requires_mask
22819 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22821 error_at (cloc, "more than one %<atomic_default_mem_order%>"
22822 " clause in a single compilation unit");
22823 this_req
22824 = (enum omp_requires)
22825 (omp_requires_mask
22826 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
22828 else if ((omp_requires_mask
22829 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
22830 error_at (cloc, "%<atomic_default_mem_order%> clause used "
22831 "lexically after first %<atomic%> construct "
22832 "without memory order clause");
22833 new_req = (enum omp_requires) (new_req | this_req);
22834 omp_requires_mask
22835 = (enum omp_requires) (omp_requires_mask | this_req);
22836 continue;
22839 break;
22841 c_parser_skip_to_pragma_eol (parser);
22843 if (new_req == 0)
22844 error_at (loc, "%<pragma omp requires%> requires at least one clause");
22847 /* Helper function for c_parser_omp_taskloop.
22848 Disallow zero sized or potentially zero sized task reductions. */
22850 static tree
22851 c_finish_taskloop_clauses (tree clauses)
22853 tree *pc = &clauses;
22854 for (tree c = clauses; c; c = *pc)
22856 bool remove = false;
22857 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
22859 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
22860 if (integer_zerop (TYPE_SIZE_UNIT (type)))
22862 error_at (OMP_CLAUSE_LOCATION (c),
22863 "zero sized type %qT in %<reduction%> clause", type);
22864 remove = true;
22866 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
22868 error_at (OMP_CLAUSE_LOCATION (c),
22869 "variable sized type %qT in %<reduction%> clause",
22870 type);
22871 remove = true;
22874 if (remove)
22875 *pc = OMP_CLAUSE_CHAIN (c);
22876 else
22877 pc = &OMP_CLAUSE_CHAIN (c);
22879 return clauses;
22882 /* OpenMP 4.5:
22883 #pragma omp taskloop taskloop-clause[optseq] new-line
22884 for-loop
22886 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22887 for-loop */
22889 #define OMP_TASKLOOP_CLAUSE_MASK \
22890 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22894 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
22896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
22897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
22903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22906 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22908 static tree
22909 c_parser_omp_taskloop (location_t loc, c_parser *parser,
22910 char *p_name, omp_clause_mask mask, tree *cclauses,
22911 bool *if_p)
22913 tree clauses, block, ret;
22915 strcat (p_name, " taskloop");
22916 mask |= OMP_TASKLOOP_CLAUSE_MASK;
22917 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22918 clause. */
22919 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
22920 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
22922 if (c_parser_next_token_is (parser, CPP_NAME))
22924 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22926 if (strcmp (p, "simd") == 0)
22928 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22929 if (cclauses == NULL)
22930 cclauses = cclauses_buf;
22931 c_parser_consume_token (parser);
22932 if (!flag_openmp) /* flag_openmp_simd */
22933 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22934 if_p);
22935 block = c_begin_compound_stmt (true);
22936 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22937 block = c_end_compound_stmt (loc, block, true);
22938 if (ret == NULL)
22939 return ret;
22940 ret = make_node (OMP_TASKLOOP);
22941 TREE_TYPE (ret) = void_type_node;
22942 OMP_FOR_BODY (ret) = block;
22943 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22944 OMP_FOR_CLAUSES (ret)
22945 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
22946 SET_EXPR_LOCATION (ret, loc);
22947 add_stmt (ret);
22948 return ret;
22951 if (!flag_openmp) /* flag_openmp_simd */
22953 c_parser_skip_to_pragma_eol (parser, false);
22954 return NULL_TREE;
22957 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22958 if (cclauses)
22960 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
22961 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22964 clauses = c_finish_taskloop_clauses (clauses);
22965 block = c_begin_compound_stmt (true);
22966 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
22967 block = c_end_compound_stmt (loc, block, true);
22968 add_stmt (block);
22970 return ret;
22973 /* OpenMP 5.1
22974 #pragma omp nothing new-line */
22976 static void
22977 c_parser_omp_nothing (c_parser *parser)
22979 c_parser_consume_pragma (parser);
22980 c_parser_skip_to_pragma_eol (parser);
22983 /* OpenMP 5.1
22984 #pragma omp error clauses[optseq] new-line */
22986 static bool
22987 c_parser_omp_error (c_parser *parser, enum pragma_context context)
22989 int at_compilation = -1;
22990 int severity_fatal = -1;
22991 tree message = NULL_TREE;
22992 bool first = true;
22993 bool bad = false;
22994 location_t loc = c_parser_peek_token (parser)->location;
22996 c_parser_consume_pragma (parser);
22998 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23000 if (!first
23001 && c_parser_next_token_is (parser, CPP_COMMA)
23002 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23003 c_parser_consume_token (parser);
23005 first = false;
23007 if (!c_parser_next_token_is (parser, CPP_NAME))
23008 break;
23010 const char *p
23011 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23012 location_t cloc = c_parser_peek_token (parser)->location;
23013 static const char *args[] = {
23014 "execution", "compilation", "warning", "fatal"
23016 int *v = NULL;
23017 int idx = 0, n = -1;
23018 tree m = NULL_TREE;
23020 if (!strcmp (p, "at"))
23021 v = &at_compilation;
23022 else if (!strcmp (p, "severity"))
23024 v = &severity_fatal;
23025 idx += 2;
23027 else if (strcmp (p, "message"))
23029 error_at (cloc,
23030 "expected %<at%>, %<severity%> or %<message%> clause");
23031 c_parser_skip_to_pragma_eol (parser, false);
23032 return false;
23035 c_parser_consume_token (parser);
23037 matching_parens parens;
23038 if (parens.require_open (parser))
23040 if (v == NULL)
23042 location_t expr_loc = c_parser_peek_token (parser)->location;
23043 c_expr expr = c_parser_expr_no_commas (parser, NULL);
23044 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
23045 m = convert (const_string_type_node, expr.value);
23046 m = c_fully_fold (m, false, NULL);
23048 else
23050 if (c_parser_next_token_is (parser, CPP_NAME))
23052 tree val = c_parser_peek_token (parser)->value;
23053 const char *q = IDENTIFIER_POINTER (val);
23055 if (!strcmp (q, args[idx]))
23056 n = 0;
23057 else if (!strcmp (q, args[idx + 1]))
23058 n = 1;
23060 if (n == -1)
23062 error_at (c_parser_peek_token (parser)->location,
23063 "expected %qs or %qs", args[idx], args[idx + 1]);
23064 bad = true;
23065 switch (c_parser_peek_token (parser)->type)
23067 case CPP_EOF:
23068 case CPP_PRAGMA_EOL:
23069 case CPP_CLOSE_PAREN:
23070 break;
23071 default:
23072 if (c_parser_peek_2nd_token (parser)->type
23073 == CPP_CLOSE_PAREN)
23074 c_parser_consume_token (parser);
23075 break;
23078 else
23079 c_parser_consume_token (parser);
23082 parens.skip_until_found_close (parser);
23084 if (v == NULL)
23086 if (message)
23088 error_at (cloc, "too many %qs clauses", p);
23089 bad = true;
23091 else
23092 message = m;
23094 else if (n != -1)
23096 if (*v != -1)
23098 error_at (cloc, "too many %qs clauses", p);
23099 bad = true;
23101 else
23102 *v = n;
23105 else
23106 bad = true;
23108 c_parser_skip_to_pragma_eol (parser);
23109 if (bad)
23110 return true;
23112 if (at_compilation == -1)
23113 at_compilation = 1;
23114 if (severity_fatal == -1)
23115 severity_fatal = 1;
23116 if (!at_compilation)
23118 if (context != pragma_compound)
23120 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
23121 "may only be used in compound statements");
23122 return true;
23124 tree fndecl
23125 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
23126 : BUILT_IN_GOMP_WARNING);
23127 if (!message)
23128 message = build_zero_cst (const_string_type_node);
23129 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
23130 build_all_ones_cst (size_type_node));
23131 add_stmt (stmt);
23132 return true;
23134 const char *msg = NULL;
23135 if (message)
23137 msg = c_getstr (message);
23138 if (msg == NULL)
23139 msg = _("<message unknown at compile time>");
23141 if (msg)
23142 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23143 "%<pragma omp error%> encountered: %s", msg);
23144 else
23145 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23146 "%<pragma omp error%> encountered");
23147 return false;
23150 /* Main entry point to parsing most OpenMP pragmas. */
23152 static void
23153 c_parser_omp_construct (c_parser *parser, bool *if_p)
23155 enum pragma_kind p_kind;
23156 location_t loc;
23157 tree stmt;
23158 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
23159 omp_clause_mask mask (0);
23161 loc = c_parser_peek_token (parser)->location;
23162 p_kind = c_parser_peek_token (parser)->pragma_kind;
23163 c_parser_consume_pragma (parser);
23165 switch (p_kind)
23167 case PRAGMA_OACC_ATOMIC:
23168 c_parser_omp_atomic (loc, parser, true);
23169 return;
23170 case PRAGMA_OACC_CACHE:
23171 strcpy (p_name, "#pragma acc");
23172 stmt = c_parser_oacc_cache (loc, parser);
23173 break;
23174 case PRAGMA_OACC_DATA:
23175 stmt = c_parser_oacc_data (loc, parser, if_p);
23176 break;
23177 case PRAGMA_OACC_HOST_DATA:
23178 stmt = c_parser_oacc_host_data (loc, parser, if_p);
23179 break;
23180 case PRAGMA_OACC_KERNELS:
23181 case PRAGMA_OACC_PARALLEL:
23182 case PRAGMA_OACC_SERIAL:
23183 strcpy (p_name, "#pragma acc");
23184 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
23185 break;
23186 case PRAGMA_OACC_LOOP:
23187 strcpy (p_name, "#pragma acc");
23188 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
23189 break;
23190 case PRAGMA_OACC_WAIT:
23191 strcpy (p_name, "#pragma wait");
23192 stmt = c_parser_oacc_wait (loc, parser, p_name);
23193 break;
23194 case PRAGMA_OMP_ALLOCATE:
23195 c_parser_omp_allocate (loc, parser);
23196 return;
23197 case PRAGMA_OMP_ATOMIC:
23198 c_parser_omp_atomic (loc, parser, false);
23199 return;
23200 case PRAGMA_OMP_CRITICAL:
23201 stmt = c_parser_omp_critical (loc, parser, if_p);
23202 break;
23203 case PRAGMA_OMP_DISTRIBUTE:
23204 strcpy (p_name, "#pragma omp");
23205 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
23206 break;
23207 case PRAGMA_OMP_FOR:
23208 strcpy (p_name, "#pragma omp");
23209 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
23210 break;
23211 case PRAGMA_OMP_LOOP:
23212 strcpy (p_name, "#pragma omp");
23213 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
23214 break;
23215 case PRAGMA_OMP_MASKED:
23216 strcpy (p_name, "#pragma omp");
23217 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
23218 break;
23219 case PRAGMA_OMP_MASTER:
23220 strcpy (p_name, "#pragma omp");
23221 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
23222 break;
23223 case PRAGMA_OMP_PARALLEL:
23224 strcpy (p_name, "#pragma omp");
23225 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
23226 break;
23227 case PRAGMA_OMP_SCOPE:
23228 stmt = c_parser_omp_scope (loc, parser, if_p);
23229 break;
23230 case PRAGMA_OMP_SECTIONS:
23231 strcpy (p_name, "#pragma omp");
23232 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
23233 break;
23234 case PRAGMA_OMP_SIMD:
23235 strcpy (p_name, "#pragma omp");
23236 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
23237 break;
23238 case PRAGMA_OMP_SINGLE:
23239 stmt = c_parser_omp_single (loc, parser, if_p);
23240 break;
23241 case PRAGMA_OMP_TASK:
23242 stmt = c_parser_omp_task (loc, parser, if_p);
23243 break;
23244 case PRAGMA_OMP_TASKGROUP:
23245 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
23246 break;
23247 case PRAGMA_OMP_TASKLOOP:
23248 strcpy (p_name, "#pragma omp");
23249 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
23250 break;
23251 case PRAGMA_OMP_TEAMS:
23252 strcpy (p_name, "#pragma omp");
23253 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
23254 break;
23255 default:
23256 gcc_unreachable ();
23259 if (stmt && stmt != error_mark_node)
23260 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
23264 /* OpenMP 2.5:
23265 # pragma omp threadprivate (variable-list) */
23267 static void
23268 c_parser_omp_threadprivate (c_parser *parser)
23270 tree vars, t;
23271 location_t loc;
23273 c_parser_consume_pragma (parser);
23274 loc = c_parser_peek_token (parser)->location;
23275 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
23277 /* Mark every variable in VARS to be assigned thread local storage. */
23278 for (t = vars; t; t = TREE_CHAIN (t))
23280 tree v = TREE_PURPOSE (t);
23282 /* FIXME diagnostics: Ideally we should keep individual
23283 locations for all the variables in the var list to make the
23284 following errors more precise. Perhaps
23285 c_parser_omp_var_list_parens() should construct a list of
23286 locations to go along with the var list. */
23288 /* If V had already been marked threadprivate, it doesn't matter
23289 whether it had been used prior to this point. */
23290 if (!VAR_P (v))
23291 error_at (loc, "%qD is not a variable", v);
23292 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
23293 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
23294 else if (! is_global_var (v))
23295 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
23296 else if (TREE_TYPE (v) == error_mark_node)
23298 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
23299 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
23300 else
23302 if (! DECL_THREAD_LOCAL_P (v))
23304 set_decl_tls_model (v, decl_default_tls_model (v));
23305 /* If rtl has been already set for this var, call
23306 make_decl_rtl once again, so that encode_section_info
23307 has a chance to look at the new decl flags. */
23308 if (DECL_RTL_SET_P (v))
23309 make_decl_rtl (v);
23311 C_DECL_THREADPRIVATE_P (v) = 1;
23315 c_parser_skip_to_pragma_eol (parser);
23318 /* Parse a transaction attribute (GCC Extension).
23320 transaction-attribute:
23321 gnu-attributes
23322 attribute-specifier
23325 static tree
23326 c_parser_transaction_attributes (c_parser *parser)
23328 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
23329 return c_parser_gnu_attributes (parser);
23331 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
23332 return NULL_TREE;
23333 return c_parser_std_attribute_specifier (parser, true);
23336 /* Parse a __transaction_atomic or __transaction_relaxed statement
23337 (GCC Extension).
23339 transaction-statement:
23340 __transaction_atomic transaction-attribute[opt] compound-statement
23341 __transaction_relaxed compound-statement
23343 Note that the only valid attribute is: "outer".
23346 static tree
23347 c_parser_transaction (c_parser *parser, enum rid keyword)
23349 unsigned int old_in = parser->in_transaction;
23350 unsigned int this_in = 1, new_in;
23351 location_t loc = c_parser_peek_token (parser)->location;
23352 tree stmt, attrs;
23354 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23355 || keyword == RID_TRANSACTION_RELAXED)
23356 && c_parser_next_token_is_keyword (parser, keyword));
23357 c_parser_consume_token (parser);
23359 if (keyword == RID_TRANSACTION_RELAXED)
23360 this_in |= TM_STMT_ATTR_RELAXED;
23361 else
23363 attrs = c_parser_transaction_attributes (parser);
23364 if (attrs)
23365 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
23368 /* Keep track if we're in the lexical scope of an outer transaction. */
23369 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
23371 parser->in_transaction = new_in;
23372 stmt = c_parser_compound_statement (parser);
23373 parser->in_transaction = old_in;
23375 if (flag_tm)
23376 stmt = c_finish_transaction (loc, stmt, this_in);
23377 else
23378 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23379 "%<__transaction_atomic%> without transactional memory support enabled"
23380 : "%<__transaction_relaxed %> "
23381 "without transactional memory support enabled"));
23383 return stmt;
23386 /* Parse a __transaction_atomic or __transaction_relaxed expression
23387 (GCC Extension).
23389 transaction-expression:
23390 __transaction_atomic ( expression )
23391 __transaction_relaxed ( expression )
23394 static struct c_expr
23395 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
23397 struct c_expr ret;
23398 unsigned int old_in = parser->in_transaction;
23399 unsigned int this_in = 1;
23400 location_t loc = c_parser_peek_token (parser)->location;
23401 tree attrs;
23403 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23404 || keyword == RID_TRANSACTION_RELAXED)
23405 && c_parser_next_token_is_keyword (parser, keyword));
23406 c_parser_consume_token (parser);
23408 if (keyword == RID_TRANSACTION_RELAXED)
23409 this_in |= TM_STMT_ATTR_RELAXED;
23410 else
23412 attrs = c_parser_transaction_attributes (parser);
23413 if (attrs)
23414 this_in |= parse_tm_stmt_attr (attrs, 0);
23417 parser->in_transaction = this_in;
23418 matching_parens parens;
23419 if (parens.require_open (parser))
23421 tree expr = c_parser_expression (parser).value;
23422 ret.original_type = TREE_TYPE (expr);
23423 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
23424 if (this_in & TM_STMT_ATTR_RELAXED)
23425 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
23426 SET_EXPR_LOCATION (ret.value, loc);
23427 ret.original_code = TRANSACTION_EXPR;
23428 if (!parens.require_close (parser))
23430 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
23431 goto error;
23434 else
23436 error:
23437 ret.set_error ();
23438 ret.original_code = ERROR_MARK;
23439 ret.original_type = NULL;
23441 parser->in_transaction = old_in;
23443 if (!flag_tm)
23444 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23445 "%<__transaction_atomic%> without transactional memory support enabled"
23446 : "%<__transaction_relaxed %> "
23447 "without transactional memory support enabled"));
23449 set_c_expr_source_range (&ret, loc, loc);
23451 return ret;
23454 /* Parse a __transaction_cancel statement (GCC Extension).
23456 transaction-cancel-statement:
23457 __transaction_cancel transaction-attribute[opt] ;
23459 Note that the only valid attribute is "outer".
23462 static tree
23463 c_parser_transaction_cancel (c_parser *parser)
23465 location_t loc = c_parser_peek_token (parser)->location;
23466 tree attrs;
23467 bool is_outer = false;
23469 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
23470 c_parser_consume_token (parser);
23472 attrs = c_parser_transaction_attributes (parser);
23473 if (attrs)
23474 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
23476 if (!flag_tm)
23478 error_at (loc, "%<__transaction_cancel%> without "
23479 "transactional memory support enabled");
23480 goto ret_error;
23482 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
23484 error_at (loc, "%<__transaction_cancel%> within a "
23485 "%<__transaction_relaxed%>");
23486 goto ret_error;
23488 else if (is_outer)
23490 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
23491 && !is_tm_may_cancel_outer (current_function_decl))
23493 error_at (loc, "outer %<__transaction_cancel%> not "
23494 "within outer %<__transaction_atomic%> or "
23495 "a %<transaction_may_cancel_outer%> function");
23496 goto ret_error;
23499 else if (parser->in_transaction == 0)
23501 error_at (loc, "%<__transaction_cancel%> not within "
23502 "%<__transaction_atomic%>");
23503 goto ret_error;
23506 return add_stmt (build_tm_abort_call (loc, is_outer));
23508 ret_error:
23509 return build1 (NOP_EXPR, void_type_node, error_mark_node);
23512 /* Parse a single source file. */
23514 void
23515 c_parse_file (void)
23517 /* Use local storage to begin. If the first token is a pragma, parse it.
23518 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23519 which will cause garbage collection. */
23520 c_parser tparser;
23522 memset (&tparser, 0, sizeof tparser);
23523 tparser.translate_strings_p = true;
23524 tparser.tokens = &tparser.tokens_buf[0];
23525 the_parser = &tparser;
23527 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
23528 c_parser_pragma_pch_preprocess (&tparser);
23529 else
23530 c_common_no_more_pch ();
23532 the_parser = ggc_alloc<c_parser> ();
23533 *the_parser = tparser;
23534 if (tparser.tokens == &tparser.tokens_buf[0])
23535 the_parser->tokens = &the_parser->tokens_buf[0];
23537 /* Initialize EH, if we've been told to do so. */
23538 if (flag_exceptions)
23539 using_eh_for_cleanups ();
23541 c_parser_translation_unit (the_parser);
23542 the_parser = NULL;
23545 /* Parse the body of a function declaration marked with "__RTL".
23547 The RTL parser works on the level of characters read from a
23548 FILE *, whereas c_parser works at the level of tokens.
23549 Square this circle by consuming all of the tokens up to and
23550 including the closing brace, recording the start/end of the RTL
23551 fragment, and reopening the file and re-reading the relevant
23552 lines within the RTL parser.
23554 This requires the opening and closing braces of the C function
23555 to be on separate lines from the RTL they wrap.
23557 Take ownership of START_WITH_PASS, if non-NULL. */
23559 location_t
23560 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
23562 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23564 free (start_with_pass);
23565 return c_parser_peek_token (parser)->location;
23568 location_t start_loc = c_parser_peek_token (parser)->location;
23570 /* Consume all tokens, up to the closing brace, handling
23571 matching pairs of braces in the rtl dump. */
23572 int num_open_braces = 1;
23573 while (1)
23575 switch (c_parser_peek_token (parser)->type)
23577 case CPP_OPEN_BRACE:
23578 num_open_braces++;
23579 break;
23580 case CPP_CLOSE_BRACE:
23581 if (--num_open_braces == 0)
23582 goto found_closing_brace;
23583 break;
23584 case CPP_EOF:
23585 error_at (start_loc, "no closing brace");
23586 free (start_with_pass);
23587 return c_parser_peek_token (parser)->location;
23588 default:
23589 break;
23591 c_parser_consume_token (parser);
23594 found_closing_brace:
23595 /* At the closing brace; record its location. */
23596 location_t end_loc = c_parser_peek_token (parser)->location;
23598 /* Consume the closing brace. */
23599 c_parser_consume_token (parser);
23601 /* Invoke the RTL parser. */
23602 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
23604 free (start_with_pass);
23605 return end_loc;
23608 /* Run the backend on the cfun created above, transferring ownership of
23609 START_WITH_PASS. */
23610 run_rtl_passes (start_with_pass);
23611 return end_loc;
23614 #include "gt-c-c-parser.h"