Fix gnat.dg/opt39.adb on hppa.
[official-gcc.git] / gcc / c / c-parser.cc
blob21bc3167ce224823c214efc064be399f2da9c787
1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2023 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* TODO:
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
27 of syntax accepted.
29 Add testcases covering every input symbol in every state in old and
30 new parsers.
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
38 #include "config.h"
39 #define INCLUDE_MEMORY
40 #include "system.h"
41 #include "coretypes.h"
42 #include "target.h"
43 #include "function.h"
44 #include "c-tree.h"
45 #include "timevar.h"
46 #include "stringpool.h"
47 #include "cgraph.h"
48 #include "attribs.h"
49 #include "stor-layout.h"
50 #include "varasm.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
53 #include "c-lang.h"
54 #include "c-family/c-objc.h"
55 #include "plugin.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
58 #include "builtins.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
62 #include "context.h"
63 #include "gcc-rich-location.h"
64 #include "c-parser.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
68 #include "intl.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
72 #include "memmodel.h"
73 #include "c-family/known-headers.h"
74 #include "bitmap.h"
75 #include "analyzer/analyzer-language.h"
76 #include "toplev.h"
78 /* We need to walk over decls with incomplete struct/union/enum types
79 after parsing the whole translation unit.
80 In finish_decl(), if the decl is static, has incomplete
81 struct/union/enum type, it is appended to incomplete_record_decls.
82 In c_parser_translation_unit(), we iterate over incomplete_record_decls
83 and report error if any of the decls are still incomplete. */
85 vec<tree> incomplete_record_decls;
87 void
88 set_c_expr_source_range (c_expr *expr,
89 location_t start, location_t finish)
91 expr->src_range.m_start = start;
92 expr->src_range.m_finish = finish;
93 if (expr->value)
94 set_source_range (expr->value, start, finish);
97 void
98 set_c_expr_source_range (c_expr *expr,
99 source_range src_range)
101 expr->src_range = src_range;
102 if (expr->value)
103 set_source_range (expr->value, src_range);
107 /* Initialization routine for this file. */
109 void
110 c_parse_init (void)
112 /* The only initialization required is of the reserved word
113 identifiers. */
114 unsigned int i;
115 tree id;
116 int mask = 0;
118 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
119 the c_token structure. */
120 gcc_assert (RID_MAX <= 255);
122 mask |= D_CXXONLY;
123 if (!flag_isoc99)
124 mask |= D_C99;
125 if (!flag_isoc2x)
126 mask |= D_C2X;
127 if (flag_no_asm)
129 mask |= D_ASM | D_EXT;
130 if (!flag_isoc99)
131 mask |= D_EXT89;
132 if (!flag_isoc2x)
133 mask |= D_EXT11;
135 if (!c_dialect_objc ())
136 mask |= D_OBJC | D_CXX_OBJC;
138 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
139 for (i = 0; i < num_c_common_reswords; i++)
141 /* If a keyword is disabled, do not enter it into the table
142 and so create a canonical spelling that isn't a keyword. */
143 if (c_common_reswords[i].disable & mask)
145 if (warn_cxx_compat
146 && (c_common_reswords[i].disable & D_CXXWARN))
148 id = get_identifier (c_common_reswords[i].word);
149 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
150 C_IS_RESERVED_WORD (id) = 1;
152 continue;
155 id = get_identifier (c_common_reswords[i].word);
156 C_SET_RID_CODE (id, c_common_reswords[i].rid);
157 C_IS_RESERVED_WORD (id) = 1;
158 ridpointers [(int) c_common_reswords[i].rid] = id;
161 for (i = 0; i < NUM_INT_N_ENTS; i++)
163 /* We always create the symbols but they aren't always supported. */
164 char name[50];
165 sprintf (name, "__int%d", int_n_data[i].bitsize);
166 id = get_identifier (name);
167 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
168 C_IS_RESERVED_WORD (id) = 1;
170 sprintf (name, "__int%d__", int_n_data[i].bitsize);
171 id = get_identifier (name);
172 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
173 C_IS_RESERVED_WORD (id) = 1;
176 if (flag_openmp)
178 id = get_identifier ("omp_all_memory");
179 C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
180 C_IS_RESERVED_WORD (id) = 1;
181 ridpointers [RID_OMP_ALL_MEMORY] = id;
185 /* A parser structure recording information about the state and
186 context of parsing. Includes lexer information with up to two
187 tokens of look-ahead; more are not needed for C. */
188 struct GTY(()) c_parser {
189 /* The look-ahead tokens. */
190 c_token * GTY((skip)) tokens;
191 /* Buffer for look-ahead tokens. */
192 c_token tokens_buf[4];
193 /* How many look-ahead tokens are available (0 - 4, or
194 more if parsing from pre-lexed tokens). */
195 unsigned int tokens_avail;
196 /* Raw look-ahead tokens, used only for checking in Objective-C
197 whether '[[' starts attributes. */
198 vec<c_token, va_gc> *raw_tokens;
199 /* The number of raw look-ahead tokens that have since been fully
200 lexed. */
201 unsigned int raw_tokens_used;
202 /* True if a syntax error is being recovered from; false otherwise.
203 c_parser_error sets this flag. It should clear this flag when
204 enough tokens have been consumed to recover from the error. */
205 BOOL_BITFIELD error : 1;
206 /* True if we're processing a pragma, and shouldn't automatically
207 consume CPP_PRAGMA_EOL. */
208 BOOL_BITFIELD in_pragma : 1;
209 /* True if we're parsing the outermost block of an if statement. */
210 BOOL_BITFIELD in_if_block : 1;
211 /* True if we want to lex a translated, joined string (for an
212 initial #pragma pch_preprocess). Otherwise the parser is
213 responsible for concatenating strings and translating to the
214 execution character set as needed. */
215 BOOL_BITFIELD lex_joined_string : 1;
216 /* True if, when the parser is concatenating string literals, it
217 should translate them to the execution character set (false
218 inside attributes). */
219 BOOL_BITFIELD translate_strings_p : 1;
221 /* Objective-C specific parser/lexer information. */
223 /* True if we are in a context where the Objective-C "PQ" keywords
224 are considered keywords. */
225 BOOL_BITFIELD objc_pq_context : 1;
226 /* True if we are parsing a (potential) Objective-C foreach
227 statement. This is set to true after we parsed 'for (' and while
228 we wait for 'in' or ';' to decide if it's a standard C for loop or an
229 Objective-C foreach loop. */
230 BOOL_BITFIELD objc_could_be_foreach_context : 1;
231 /* The following flag is needed to contextualize Objective-C lexical
232 analysis. In some cases (e.g., 'int NSObject;'), it is
233 undesirable to bind an identifier to an Objective-C class, even
234 if a class with that name exists. */
235 BOOL_BITFIELD objc_need_raw_identifier : 1;
236 /* Nonzero if we're processing a __transaction statement. The value
237 is 1 | TM_STMT_ATTR_*. */
238 unsigned int in_transaction : 4;
239 /* True if we are in a context where the Objective-C "Property attribute"
240 keywords are valid. */
241 BOOL_BITFIELD objc_property_attr_context : 1;
243 /* Whether we have just seen/constructed a string-literal. Set when
244 returning a string-literal from c_parser_string_literal. Reset
245 in consume_token. Useful when we get a parse error and see an
246 unknown token, which could have been a string-literal constant
247 macro. */
248 BOOL_BITFIELD seen_string_literal : 1;
250 /* Location of the last consumed token. */
251 location_t last_token_location;
254 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
256 c_token *
257 c_parser_tokens_buf (c_parser *parser, unsigned n)
259 return &parser->tokens_buf[n];
262 /* Return the error state of PARSER. */
264 bool
265 c_parser_error (c_parser *parser)
267 return parser->error;
270 /* Set the error state of PARSER to ERR. */
272 void
273 c_parser_set_error (c_parser *parser, bool err)
275 parser->error = err;
279 /* The actual parser and external interface. ??? Does this need to be
280 garbage-collected? */
282 static GTY (()) c_parser *the_parser;
284 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
285 context-sensitive postprocessing of the token is not done. */
287 static void
288 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
290 timevar_push (TV_LEX);
292 if (raw || vec_safe_length (parser->raw_tokens) == 0)
294 token->type = c_lex_with_flags (&token->value, &token->location,
295 &token->flags,
296 (parser->lex_joined_string
297 ? 0 : C_LEX_STRING_NO_JOIN));
298 token->id_kind = C_ID_NONE;
299 token->keyword = RID_MAX;
300 token->pragma_kind = PRAGMA_NONE;
302 else
304 /* Use a token previously lexed as a raw look-ahead token, and
305 complete the processing on it. */
306 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
307 ++parser->raw_tokens_used;
308 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
310 vec_free (parser->raw_tokens);
311 parser->raw_tokens_used = 0;
315 if (raw)
316 goto out;
318 switch (token->type)
320 case CPP_NAME:
322 tree decl;
324 bool objc_force_identifier = parser->objc_need_raw_identifier;
325 if (c_dialect_objc ())
326 parser->objc_need_raw_identifier = false;
328 if (C_IS_RESERVED_WORD (token->value))
330 enum rid rid_code = C_RID_CODE (token->value);
332 if (rid_code == RID_CXX_COMPAT_WARN)
334 warning_at (token->location,
335 OPT_Wc___compat,
336 "identifier %qE conflicts with C++ keyword",
337 token->value);
339 else if (rid_code >= RID_FIRST_ADDR_SPACE
340 && rid_code <= RID_LAST_ADDR_SPACE)
342 addr_space_t as;
343 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
344 targetm.addr_space.diagnose_usage (as, token->location);
345 token->id_kind = C_ID_ADDRSPACE;
346 token->keyword = rid_code;
347 break;
349 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
351 /* We found an Objective-C "pq" keyword (in, out,
352 inout, bycopy, byref, oneway). They need special
353 care because the interpretation depends on the
354 context. */
355 if (parser->objc_pq_context)
357 token->type = CPP_KEYWORD;
358 token->keyword = rid_code;
359 break;
361 else if (parser->objc_could_be_foreach_context
362 && rid_code == RID_IN)
364 /* We are in Objective-C, inside a (potential)
365 foreach context (which means after having
366 parsed 'for (', but before having parsed ';'),
367 and we found 'in'. We consider it the keyword
368 which terminates the declaration at the
369 beginning of a foreach-statement. Note that
370 this means you can't use 'in' for anything else
371 in that context; in particular, in Objective-C
372 you can't use 'in' as the name of the running
373 variable in a C for loop. We could potentially
374 try to add code here to disambiguate, but it
375 seems a reasonable limitation. */
376 token->type = CPP_KEYWORD;
377 token->keyword = rid_code;
378 break;
380 /* Else, "pq" keywords outside of the "pq" context are
381 not keywords, and we fall through to the code for
382 normal tokens. */
384 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
386 /* We found an Objective-C "property attribute"
387 keyword (getter, setter, readonly, etc). These are
388 only valid in the property context. */
389 if (parser->objc_property_attr_context)
391 token->type = CPP_KEYWORD;
392 token->keyword = rid_code;
393 break;
395 /* Else they are not special keywords.
398 else if (c_dialect_objc ()
399 && (OBJC_IS_AT_KEYWORD (rid_code)
400 || OBJC_IS_CXX_KEYWORD (rid_code)))
402 /* We found one of the Objective-C "@" keywords (defs,
403 selector, synchronized, etc) or one of the
404 Objective-C "cxx" keywords (class, private,
405 protected, public, try, catch, throw) without a
406 preceding '@' sign. Do nothing and fall through to
407 the code for normal tokens (in C++ we would still
408 consider the CXX ones keywords, but not in C). */
411 else
413 token->type = CPP_KEYWORD;
414 token->keyword = rid_code;
415 break;
419 decl = lookup_name (token->value);
420 if (decl)
422 if (TREE_CODE (decl) == TYPE_DECL)
424 token->id_kind = C_ID_TYPENAME;
425 break;
428 else if (c_dialect_objc ())
430 tree objc_interface_decl = objc_is_class_name (token->value);
431 /* Objective-C class names are in the same namespace as
432 variables and typedefs, and hence are shadowed by local
433 declarations. */
434 if (objc_interface_decl
435 && (!objc_force_identifier || global_bindings_p ()))
437 token->value = objc_interface_decl;
438 token->id_kind = C_ID_CLASSNAME;
439 break;
442 token->id_kind = C_ID_ID;
444 break;
445 case CPP_AT_NAME:
446 /* This only happens in Objective-C; it must be a keyword. */
447 token->type = CPP_KEYWORD;
448 switch (C_RID_CODE (token->value))
450 /* Replace 'class' with '@class', 'private' with '@private',
451 etc. This prevents confusion with the C++ keyword
452 'class', and makes the tokens consistent with other
453 Objective-C 'AT' keywords. For example '@class' is
454 reported as RID_AT_CLASS which is consistent with
455 '@synchronized', which is reported as
456 RID_AT_SYNCHRONIZED.
458 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
459 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
460 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
461 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
462 case RID_THROW: token->keyword = RID_AT_THROW; break;
463 case RID_TRY: token->keyword = RID_AT_TRY; break;
464 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
465 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
466 default: token->keyword = C_RID_CODE (token->value);
468 break;
469 case CPP_COLON:
470 case CPP_COMMA:
471 case CPP_CLOSE_PAREN:
472 case CPP_SEMICOLON:
473 /* These tokens may affect the interpretation of any identifiers
474 following, if doing Objective-C. */
475 if (c_dialect_objc ())
476 parser->objc_need_raw_identifier = false;
477 break;
478 case CPP_PRAGMA:
479 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
480 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
481 token->value = NULL;
482 break;
483 default:
484 break;
486 out:
487 timevar_pop (TV_LEX);
490 /* Return a pointer to the next token from PARSER, reading it in if
491 necessary. */
493 c_token *
494 c_parser_peek_token (c_parser *parser)
496 if (parser->tokens_avail == 0)
498 c_lex_one_token (parser, &parser->tokens[0]);
499 parser->tokens_avail = 1;
501 return &parser->tokens[0];
504 /* Return a pointer to the next-but-one token from PARSER, reading it
505 in if necessary. The next token is already read in. */
507 c_token *
508 c_parser_peek_2nd_token (c_parser *parser)
510 if (parser->tokens_avail >= 2)
511 return &parser->tokens[1];
512 gcc_assert (parser->tokens_avail == 1);
513 gcc_assert (parser->tokens[0].type != CPP_EOF);
514 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
515 c_lex_one_token (parser, &parser->tokens[1]);
516 parser->tokens_avail = 2;
517 return &parser->tokens[1];
520 /* Return a pointer to the Nth token from PARSER, reading it
521 in if necessary. The N-1th token is already read in. */
523 c_token *
524 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
526 /* N is 1-based, not zero-based. */
527 gcc_assert (n > 0);
529 if (parser->tokens_avail >= n)
530 return &parser->tokens[n - 1];
531 gcc_assert (parser->tokens_avail == n - 1);
532 c_lex_one_token (parser, &parser->tokens[n - 1]);
533 parser->tokens_avail = n;
534 return &parser->tokens[n - 1];
537 /* Return a pointer to the Nth token from PARSER, reading it in as a
538 raw look-ahead token if necessary. The N-1th token is already read
539 in. Raw look-ahead tokens remain available for when the non-raw
540 functions above are called. */
542 c_token *
543 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
545 /* N is 1-based, not zero-based. */
546 gcc_assert (n > 0);
548 if (parser->tokens_avail >= n)
549 return &parser->tokens[n - 1];
550 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
551 unsigned int raw_avail
552 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
553 gcc_assert (raw_avail >= n - 1);
554 if (raw_avail >= n)
555 return &(*parser->raw_tokens)[parser->raw_tokens_used
556 + n - 1 - parser->tokens_avail];
557 vec_safe_reserve (parser->raw_tokens, 1);
558 parser->raw_tokens->quick_grow (raw_len + 1);
559 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
560 return &(*parser->raw_tokens)[raw_len];
563 bool
564 c_keyword_starts_typename (enum rid keyword)
566 switch (keyword)
568 case RID_UNSIGNED:
569 case RID_LONG:
570 case RID_SHORT:
571 case RID_SIGNED:
572 case RID_COMPLEX:
573 case RID_INT:
574 case RID_CHAR:
575 case RID_FLOAT:
576 case RID_DOUBLE:
577 case RID_VOID:
578 case RID_DFLOAT32:
579 case RID_DFLOAT64:
580 case RID_DFLOAT128:
581 CASE_RID_FLOATN_NX:
582 case RID_BOOL:
583 case RID_ENUM:
584 case RID_STRUCT:
585 case RID_UNION:
586 case RID_TYPEOF:
587 case RID_TYPEOF_UNQUAL:
588 case RID_CONST:
589 case RID_ATOMIC:
590 case RID_VOLATILE:
591 case RID_RESTRICT:
592 case RID_ATTRIBUTE:
593 case RID_FRACT:
594 case RID_ACCUM:
595 case RID_SAT:
596 case RID_AUTO_TYPE:
597 case RID_ALIGNAS:
598 return true;
599 default:
600 if (keyword >= RID_FIRST_INT_N
601 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
602 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
603 return true;
604 return false;
608 /* Return true if TOKEN can start a type name,
609 false otherwise. */
610 bool
611 c_token_starts_typename (c_token *token)
613 switch (token->type)
615 case CPP_NAME:
616 switch (token->id_kind)
618 case C_ID_ID:
619 return false;
620 case C_ID_ADDRSPACE:
621 return true;
622 case C_ID_TYPENAME:
623 return true;
624 case C_ID_CLASSNAME:
625 gcc_assert (c_dialect_objc ());
626 return true;
627 default:
628 gcc_unreachable ();
630 case CPP_KEYWORD:
631 return c_keyword_starts_typename (token->keyword);
632 case CPP_LESS:
633 if (c_dialect_objc ())
634 return true;
635 return false;
636 default:
637 return false;
641 /* Return true if the next token from PARSER can start a type name,
642 false otherwise. LA specifies how to do lookahead in order to
643 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
645 static inline bool
646 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
648 c_token *token = c_parser_peek_token (parser);
649 if (c_token_starts_typename (token))
650 return true;
652 /* Try a bit harder to detect an unknown typename. */
653 if (la != cla_prefer_id
654 && token->type == CPP_NAME
655 && token->id_kind == C_ID_ID
657 /* Do not try too hard when we could have "object in array". */
658 && !parser->objc_could_be_foreach_context
660 && (la == cla_prefer_type
661 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
662 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
664 /* Only unknown identifiers. */
665 && !lookup_name (token->value))
666 return true;
668 return false;
671 /* Return true if TOKEN, after an open parenthesis, can start a
672 compound literal (either a storage class specifier allowed in that
673 context, or a type name), false otherwise. */
674 static bool
675 c_token_starts_compound_literal (c_token *token)
677 switch (token->type)
679 case CPP_KEYWORD:
680 switch (token->keyword)
682 case RID_CONSTEXPR:
683 case RID_REGISTER:
684 case RID_STATIC:
685 case RID_THREAD:
686 return true;
687 default:
688 break;
690 /* Fall through. */
691 default:
692 return c_token_starts_typename (token);
696 /* Return true if TOKEN is a type qualifier, false otherwise. */
697 static bool
698 c_token_is_qualifier (c_token *token)
700 switch (token->type)
702 case CPP_NAME:
703 switch (token->id_kind)
705 case C_ID_ADDRSPACE:
706 return true;
707 default:
708 return false;
710 case CPP_KEYWORD:
711 switch (token->keyword)
713 case RID_CONST:
714 case RID_VOLATILE:
715 case RID_RESTRICT:
716 case RID_ATTRIBUTE:
717 case RID_ATOMIC:
718 return true;
719 default:
720 return false;
722 case CPP_LESS:
723 return false;
724 default:
725 gcc_unreachable ();
729 /* Return true if the next token from PARSER is a type qualifier,
730 false otherwise. */
731 static inline bool
732 c_parser_next_token_is_qualifier (c_parser *parser)
734 c_token *token = c_parser_peek_token (parser);
735 return c_token_is_qualifier (token);
738 /* Return true if TOKEN can start declaration specifiers (not
739 including standard attributes), false otherwise. */
740 static bool
741 c_token_starts_declspecs (c_token *token)
743 switch (token->type)
745 case CPP_NAME:
746 switch (token->id_kind)
748 case C_ID_ID:
749 return false;
750 case C_ID_ADDRSPACE:
751 return true;
752 case C_ID_TYPENAME:
753 return true;
754 case C_ID_CLASSNAME:
755 gcc_assert (c_dialect_objc ());
756 return true;
757 default:
758 gcc_unreachable ();
760 case CPP_KEYWORD:
761 switch (token->keyword)
763 case RID_STATIC:
764 case RID_EXTERN:
765 case RID_REGISTER:
766 case RID_TYPEDEF:
767 case RID_INLINE:
768 case RID_NORETURN:
769 case RID_AUTO:
770 case RID_THREAD:
771 case RID_UNSIGNED:
772 case RID_LONG:
773 case RID_SHORT:
774 case RID_SIGNED:
775 case RID_COMPLEX:
776 case RID_INT:
777 case RID_CHAR:
778 case RID_FLOAT:
779 case RID_DOUBLE:
780 case RID_VOID:
781 case RID_DFLOAT32:
782 case RID_DFLOAT64:
783 case RID_DFLOAT128:
784 CASE_RID_FLOATN_NX:
785 case RID_BOOL:
786 case RID_ENUM:
787 case RID_STRUCT:
788 case RID_UNION:
789 case RID_TYPEOF:
790 case RID_TYPEOF_UNQUAL:
791 case RID_CONST:
792 case RID_VOLATILE:
793 case RID_RESTRICT:
794 case RID_ATTRIBUTE:
795 case RID_FRACT:
796 case RID_ACCUM:
797 case RID_SAT:
798 case RID_ALIGNAS:
799 case RID_ATOMIC:
800 case RID_AUTO_TYPE:
801 case RID_CONSTEXPR:
802 return true;
803 default:
804 if (token->keyword >= RID_FIRST_INT_N
805 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
806 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
807 return true;
808 return false;
810 case CPP_LESS:
811 if (c_dialect_objc ())
812 return true;
813 return false;
814 default:
815 return false;
820 /* Return true if TOKEN can start declaration specifiers (not
821 including standard attributes) or a static assertion, false
822 otherwise. */
823 static bool
824 c_token_starts_declaration (c_token *token)
826 if (c_token_starts_declspecs (token)
827 || token->keyword == RID_STATIC_ASSERT)
828 return true;
829 else
830 return false;
833 /* Return true if the next token from PARSER can start declaration
834 specifiers (not including standard attributes), false
835 otherwise. */
836 bool
837 c_parser_next_token_starts_declspecs (c_parser *parser)
839 c_token *token = c_parser_peek_token (parser);
841 /* In Objective-C, a classname normally starts a declspecs unless it
842 is immediately followed by a dot. In that case, it is the
843 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
844 setter/getter on the class. c_token_starts_declspecs() can't
845 differentiate between the two cases because it only checks the
846 current token, so we have a special check here. */
847 if (c_dialect_objc ()
848 && token->type == CPP_NAME
849 && token->id_kind == C_ID_CLASSNAME
850 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
851 return false;
853 return c_token_starts_declspecs (token);
856 /* Return true if the next tokens from PARSER can start declaration
857 specifiers (not including standard attributes) or a static
858 assertion, false otherwise. */
859 bool
860 c_parser_next_tokens_start_declaration (c_parser *parser)
862 c_token *token = c_parser_peek_token (parser);
864 /* Same as above. */
865 if (c_dialect_objc ()
866 && token->type == CPP_NAME
867 && token->id_kind == C_ID_CLASSNAME
868 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
869 return false;
871 /* Labels do not start declarations. */
872 if (token->type == CPP_NAME
873 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
874 return false;
876 if (c_token_starts_declaration (token))
877 return true;
879 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
880 return true;
882 return false;
885 /* Consume the next token from PARSER. */
887 void
888 c_parser_consume_token (c_parser *parser)
890 gcc_assert (parser->tokens_avail >= 1);
891 gcc_assert (parser->tokens[0].type != CPP_EOF);
892 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
893 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
894 parser->last_token_location = parser->tokens[0].location;
895 if (parser->tokens != &parser->tokens_buf[0])
896 parser->tokens++;
897 else if (parser->tokens_avail >= 2)
899 parser->tokens[0] = parser->tokens[1];
900 if (parser->tokens_avail >= 3)
902 parser->tokens[1] = parser->tokens[2];
903 if (parser->tokens_avail >= 4)
904 parser->tokens[2] = parser->tokens[3];
907 parser->tokens_avail--;
908 parser->seen_string_literal = false;
911 /* Expect the current token to be a #pragma. Consume it and remember
912 that we've begun parsing a pragma. */
914 static void
915 c_parser_consume_pragma (c_parser *parser)
917 gcc_assert (!parser->in_pragma);
918 gcc_assert (parser->tokens_avail >= 1);
919 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
920 if (parser->tokens != &parser->tokens_buf[0])
921 parser->tokens++;
922 else if (parser->tokens_avail >= 2)
924 parser->tokens[0] = parser->tokens[1];
925 if (parser->tokens_avail >= 3)
926 parser->tokens[1] = parser->tokens[2];
928 parser->tokens_avail--;
929 parser->in_pragma = true;
932 /* Update the global input_location from TOKEN. */
933 static inline void
934 c_parser_set_source_position_from_token (c_token *token)
936 if (token->type != CPP_EOF)
938 input_location = token->location;
942 /* Helper function for c_parser_error.
943 Having peeked a token of kind TOK1_KIND that might signify
944 a conflict marker, peek successor tokens to determine
945 if we actually do have a conflict marker.
946 Specifically, we consider a run of 7 '<', '=' or '>' characters
947 at the start of a line as a conflict marker.
948 These come through the lexer as three pairs and a single,
949 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
950 If it returns true, *OUT_LOC is written to with the location/range
951 of the marker. */
953 static bool
954 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
955 location_t *out_loc)
957 c_token *token2 = c_parser_peek_2nd_token (parser);
958 if (token2->type != tok1_kind)
959 return false;
960 c_token *token3 = c_parser_peek_nth_token (parser, 3);
961 if (token3->type != tok1_kind)
962 return false;
963 c_token *token4 = c_parser_peek_nth_token (parser, 4);
964 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
965 return false;
967 /* It must be at the start of the line. */
968 location_t start_loc = c_parser_peek_token (parser)->location;
969 if (LOCATION_COLUMN (start_loc) != 1)
970 return false;
972 /* We have a conflict marker. Construct a location of the form:
973 <<<<<<<
974 ^~~~~~~
975 with start == caret, finishing at the end of the marker. */
976 location_t finish_loc = get_finish (token4->location);
977 *out_loc = make_location (start_loc, start_loc, finish_loc);
979 return true;
982 /* Issue a diagnostic of the form
983 FILE:LINE: MESSAGE before TOKEN
984 where TOKEN is the next token in the input stream of PARSER.
985 MESSAGE (specified by the caller) is usually of the form "expected
986 OTHER-TOKEN".
988 Use RICHLOC as the location of the diagnostic.
990 Do not issue a diagnostic if still recovering from an error.
992 Return true iff an error was actually emitted.
994 ??? This is taken from the C++ parser, but building up messages in
995 this way is not i18n-friendly and some other approach should be
996 used. */
998 static bool
999 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
1000 rich_location *richloc)
1002 c_token *token = c_parser_peek_token (parser);
1003 if (parser->error)
1004 return false;
1005 parser->error = true;
1006 if (!gmsgid)
1007 return false;
1009 /* If this is actually a conflict marker, report it as such. */
1010 if (token->type == CPP_LSHIFT
1011 || token->type == CPP_RSHIFT
1012 || token->type == CPP_EQ_EQ)
1014 location_t loc;
1015 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
1017 error_at (loc, "version control conflict marker in file");
1018 return true;
1022 /* If we were parsing a string-literal and there is an unknown name
1023 token right after, then check to see if that could also have been
1024 a literal string by checking the name against a list of known
1025 standard string literal constants defined in header files. If
1026 there is one, then add that as an hint to the error message. */
1027 auto_diagnostic_group d;
1028 name_hint h;
1029 if (parser->seen_string_literal && token->type == CPP_NAME)
1031 tree name = token->value;
1032 const char *token_name = IDENTIFIER_POINTER (name);
1033 const char *header_hint
1034 = get_c_stdlib_header_for_string_macro_name (token_name);
1035 if (header_hint != NULL)
1036 h = name_hint (NULL, new suggest_missing_header (token->location,
1037 token_name,
1038 header_hint));
1041 c_parse_error (gmsgid,
1042 /* Because c_parse_error does not understand
1043 CPP_KEYWORD, keywords are treated like
1044 identifiers. */
1045 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1046 /* ??? The C parser does not save the cpp flags of a
1047 token, we need to pass 0 here and we will not get
1048 the source spelling of some tokens but rather the
1049 canonical spelling. */
1050 token->value, /*flags=*/0, richloc);
1051 return true;
1054 /* As c_parser_error_richloc, but issue the message at the
1055 location of PARSER's next token, or at input_location
1056 if the next token is EOF. */
1058 bool
1059 c_parser_error (c_parser *parser, const char *gmsgid)
1061 c_token *token = c_parser_peek_token (parser);
1062 c_parser_set_source_position_from_token (token);
1063 rich_location richloc (line_table, input_location);
1064 return c_parser_error_richloc (parser, gmsgid, &richloc);
1067 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1068 This class is for tracking such a matching pair of symbols.
1069 In particular, it tracks the location of the first token,
1070 so that if the second token is missing, we can highlight the
1071 location of the first token when notifying the user about the
1072 problem. */
1074 template <typename traits_t>
1075 class token_pair
1077 public:
1078 /* token_pair's ctor. */
1079 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1081 /* If the next token is the opening symbol for this pair, consume it and
1082 return true.
1083 Otherwise, issue an error and return false.
1084 In either case, record the location of the opening token. */
1086 bool require_open (c_parser *parser)
1088 c_token *token = c_parser_peek_token (parser);
1089 if (token)
1090 m_open_loc = token->location;
1092 return c_parser_require (parser, traits_t::open_token_type,
1093 traits_t::open_gmsgid);
1096 /* Consume the next token from PARSER, recording its location as
1097 that of the opening token within the pair. */
1099 void consume_open (c_parser *parser)
1101 c_token *token = c_parser_peek_token (parser);
1102 gcc_assert (token->type == traits_t::open_token_type);
1103 m_open_loc = token->location;
1104 c_parser_consume_token (parser);
1107 /* If the next token is the closing symbol for this pair, consume it
1108 and return true.
1109 Otherwise, issue an error, highlighting the location of the
1110 corresponding opening token, and return false. */
1112 bool require_close (c_parser *parser) const
1114 return c_parser_require (parser, traits_t::close_token_type,
1115 traits_t::close_gmsgid, m_open_loc);
1118 /* Like token_pair::require_close, except that tokens will be skipped
1119 until the desired token is found. An error message is still produced
1120 if the next token is not as expected. */
1122 void skip_until_found_close (c_parser *parser) const
1124 c_parser_skip_until_found (parser, traits_t::close_token_type,
1125 traits_t::close_gmsgid, m_open_loc);
1128 private:
1129 location_t m_open_loc;
1132 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1134 struct matching_paren_traits
1136 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1137 static const char * const open_gmsgid;
1138 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1139 static const char * const close_gmsgid;
1142 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1143 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1145 /* "matching_parens" is a token_pair<T> class for tracking matching
1146 pairs of parentheses. */
1148 typedef token_pair<matching_paren_traits> matching_parens;
1150 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1152 struct matching_brace_traits
1154 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1155 static const char * const open_gmsgid;
1156 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1157 static const char * const close_gmsgid;
1160 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1161 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1163 /* "matching_braces" is a token_pair<T> class for tracking matching
1164 pairs of braces. */
1166 typedef token_pair<matching_brace_traits> matching_braces;
1168 /* Get a description of the matching symbol to TYPE e.g. "(" for
1169 CPP_CLOSE_PAREN. */
1171 static const char *
1172 get_matching_symbol (enum cpp_ttype type)
1174 switch (type)
1176 default:
1177 gcc_unreachable ();
1178 case CPP_CLOSE_PAREN:
1179 return "(";
1180 case CPP_CLOSE_BRACE:
1181 return "{";
1185 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1186 issue the error MSGID. If MSGID is NULL then a message has already
1187 been produced and no message will be produced this time. Returns
1188 true if found, false otherwise.
1190 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1191 within any error as the location of an "opening" token matching
1192 the close token TYPE (e.g. the location of the '(' when TYPE is
1193 CPP_CLOSE_PAREN).
1195 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1196 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1197 attempt to generate a fix-it hint for the problem.
1198 Otherwise msgid describes multiple token types (e.g.
1199 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1200 generate a fix-it hint. */
1202 bool
1203 c_parser_require (c_parser *parser,
1204 enum cpp_ttype type,
1205 const char *msgid,
1206 location_t matching_location,
1207 bool type_is_unique)
1209 if (c_parser_next_token_is (parser, type))
1211 c_parser_consume_token (parser);
1212 return true;
1214 else
1216 location_t next_token_loc = c_parser_peek_token (parser)->location;
1217 gcc_rich_location richloc (next_token_loc);
1219 /* Potentially supply a fix-it hint, suggesting to add the
1220 missing token immediately after the *previous* token.
1221 This may move the primary location within richloc. */
1222 if (!parser->error && type_is_unique)
1223 maybe_suggest_missing_token_insertion (&richloc, type,
1224 parser->last_token_location);
1226 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1227 Attempt to consolidate diagnostics by printing it as a
1228 secondary range within the main diagnostic. */
1229 bool added_matching_location = false;
1230 if (matching_location != UNKNOWN_LOCATION)
1231 added_matching_location
1232 = richloc.add_location_if_nearby (matching_location);
1234 if (c_parser_error_richloc (parser, msgid, &richloc))
1235 /* If we weren't able to consolidate matching_location, then
1236 print it as a secondary diagnostic. */
1237 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1238 inform (matching_location, "to match this %qs",
1239 get_matching_symbol (type));
1241 return false;
1245 /* If the next token is the indicated keyword, consume it. Otherwise,
1246 issue the error MSGID. Returns true if found, false otherwise. */
1248 static bool
1249 c_parser_require_keyword (c_parser *parser,
1250 enum rid keyword,
1251 const char *msgid)
1253 if (c_parser_next_token_is_keyword (parser, keyword))
1255 c_parser_consume_token (parser);
1256 return true;
1258 else
1260 c_parser_error (parser, msgid);
1261 return false;
1265 /* Like c_parser_require, except that tokens will be skipped until the
1266 desired token is found. An error message is still produced if the
1267 next token is not as expected. If MSGID is NULL then a message has
1268 already been produced and no message will be produced this
1269 time.
1271 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1272 within any error as the location of an "opening" token matching
1273 the close token TYPE (e.g. the location of the '(' when TYPE is
1274 CPP_CLOSE_PAREN). */
1276 void
1277 c_parser_skip_until_found (c_parser *parser,
1278 enum cpp_ttype type,
1279 const char *msgid,
1280 location_t matching_location)
1282 unsigned nesting_depth = 0;
1284 if (c_parser_require (parser, type, msgid, matching_location))
1285 return;
1287 /* Skip tokens until the desired token is found. */
1288 while (true)
1290 /* Peek at the next token. */
1291 c_token *token = c_parser_peek_token (parser);
1292 /* If we've reached the token we want, consume it and stop. */
1293 if (token->type == type && !nesting_depth)
1295 c_parser_consume_token (parser);
1296 break;
1299 /* If we've run out of tokens, stop. */
1300 if (token->type == CPP_EOF)
1301 return;
1302 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1303 return;
1304 if (token->type == CPP_OPEN_BRACE
1305 || token->type == CPP_OPEN_PAREN
1306 || token->type == CPP_OPEN_SQUARE)
1307 ++nesting_depth;
1308 else if (token->type == CPP_CLOSE_BRACE
1309 || token->type == CPP_CLOSE_PAREN
1310 || token->type == CPP_CLOSE_SQUARE)
1312 if (nesting_depth-- == 0)
1313 break;
1315 /* Consume this token. */
1316 c_parser_consume_token (parser);
1318 parser->error = false;
1321 /* Skip tokens until the end of a parameter is found, but do not
1322 consume the comma, semicolon or closing delimiter. */
1324 static void
1325 c_parser_skip_to_end_of_parameter (c_parser *parser)
1327 unsigned nesting_depth = 0;
1329 while (true)
1331 c_token *token = c_parser_peek_token (parser);
1332 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1333 && !nesting_depth)
1334 break;
1335 /* If we've run out of tokens, stop. */
1336 if (token->type == CPP_EOF)
1337 return;
1338 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1339 return;
1340 if (token->type == CPP_OPEN_BRACE
1341 || token->type == CPP_OPEN_PAREN
1342 || token->type == CPP_OPEN_SQUARE)
1343 ++nesting_depth;
1344 else if (token->type == CPP_CLOSE_BRACE
1345 || token->type == CPP_CLOSE_PAREN
1346 || token->type == CPP_CLOSE_SQUARE)
1348 if (nesting_depth-- == 0)
1349 break;
1351 /* Consume this token. */
1352 c_parser_consume_token (parser);
1354 parser->error = false;
1357 /* Expect to be at the end of the pragma directive and consume an
1358 end of line marker. */
1360 static void
1361 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1363 gcc_assert (parser->in_pragma);
1364 parser->in_pragma = false;
1366 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1367 c_parser_error (parser, "expected end of line");
1369 cpp_ttype token_type;
1372 c_token *token = c_parser_peek_token (parser);
1373 token_type = token->type;
1374 if (token_type == CPP_EOF)
1375 break;
1376 c_parser_consume_token (parser);
1378 while (token_type != CPP_PRAGMA_EOL);
1380 parser->error = false;
1383 /* Skip tokens until we have consumed an entire block, or until we
1384 have consumed a non-nested ';'. */
1386 static void
1387 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1389 unsigned nesting_depth = 0;
1390 bool save_error = parser->error;
1392 while (true)
1394 c_token *token;
1396 /* Peek at the next token. */
1397 token = c_parser_peek_token (parser);
1399 switch (token->type)
1401 case CPP_EOF:
1402 return;
1404 case CPP_PRAGMA_EOL:
1405 if (parser->in_pragma)
1406 return;
1407 break;
1409 case CPP_SEMICOLON:
1410 /* If the next token is a ';', we have reached the
1411 end of the statement. */
1412 if (!nesting_depth)
1414 /* Consume the ';'. */
1415 c_parser_consume_token (parser);
1416 goto finished;
1418 break;
1420 case CPP_CLOSE_BRACE:
1421 /* If the next token is a non-nested '}', then we have
1422 reached the end of the current block. */
1423 if (nesting_depth == 0 || --nesting_depth == 0)
1425 c_parser_consume_token (parser);
1426 goto finished;
1428 break;
1430 case CPP_OPEN_BRACE:
1431 /* If it the next token is a '{', then we are entering a new
1432 block. Consume the entire block. */
1433 ++nesting_depth;
1434 break;
1436 case CPP_PRAGMA:
1437 /* If we see a pragma, consume the whole thing at once. We
1438 have some safeguards against consuming pragmas willy-nilly.
1439 Normally, we'd expect to be here with parser->error set,
1440 which disables these safeguards. But it's possible to get
1441 here for secondary error recovery, after parser->error has
1442 been cleared. */
1443 c_parser_consume_pragma (parser);
1444 c_parser_skip_to_pragma_eol (parser);
1445 parser->error = save_error;
1446 continue;
1448 default:
1449 break;
1452 c_parser_consume_token (parser);
1455 finished:
1456 parser->error = false;
1459 /* CPP's options (initialized by c-opts.cc). */
1460 extern cpp_options *cpp_opts;
1462 /* Save the warning flags which are controlled by __extension__. */
1464 static inline int
1465 disable_extension_diagnostics (void)
1467 int ret = (pedantic
1468 | (warn_pointer_arith << 1)
1469 | (warn_traditional << 2)
1470 | (flag_iso << 3)
1471 | (warn_long_long << 4)
1472 | (warn_cxx_compat << 5)
1473 | (warn_overlength_strings << 6)
1474 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1475 play tricks to properly restore it. */
1476 | ((warn_c90_c99_compat == 1) << 7)
1477 | ((warn_c90_c99_compat == -1) << 8)
1478 /* Similarly for warn_c99_c11_compat. */
1479 | ((warn_c99_c11_compat == 1) << 9)
1480 | ((warn_c99_c11_compat == -1) << 10)
1481 /* Similarly for warn_c11_c2x_compat. */
1482 | ((warn_c11_c2x_compat == 1) << 11)
1483 | ((warn_c11_c2x_compat == -1) << 12)
1485 cpp_opts->cpp_pedantic = pedantic = 0;
1486 warn_pointer_arith = 0;
1487 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1488 flag_iso = 0;
1489 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1490 warn_cxx_compat = 0;
1491 warn_overlength_strings = 0;
1492 warn_c90_c99_compat = 0;
1493 warn_c99_c11_compat = 0;
1494 warn_c11_c2x_compat = 0;
1495 return ret;
1498 /* Restore the warning flags which are controlled by __extension__.
1499 FLAGS is the return value from disable_extension_diagnostics. */
1501 static inline void
1502 restore_extension_diagnostics (int flags)
1504 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1505 warn_pointer_arith = (flags >> 1) & 1;
1506 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1507 flag_iso = (flags >> 3) & 1;
1508 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1509 warn_cxx_compat = (flags >> 5) & 1;
1510 warn_overlength_strings = (flags >> 6) & 1;
1511 /* See above for why is this needed. */
1512 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1513 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1514 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1517 /* Helper data structure for parsing #pragma acc routine. */
1518 struct oacc_routine_data {
1519 bool error_seen; /* Set if error has been reported. */
1520 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1521 tree clauses;
1522 location_t loc;
1525 /* Used for parsing objc foreach statements. */
1526 static tree objc_foreach_break_label, objc_foreach_continue_label;
1528 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1529 unsigned int);
1530 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1531 static void c_parser_external_declaration (c_parser *);
1532 static void c_parser_asm_definition (c_parser *);
1533 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1534 bool, bool, tree * = NULL,
1535 vec<c_token> * = NULL,
1536 bool have_attrs = false,
1537 tree attrs = NULL,
1538 struct oacc_routine_data * = NULL,
1539 bool * = NULL);
1540 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1541 static void c_parser_static_assert_declaration (c_parser *);
1542 static struct c_typespec c_parser_enum_specifier (c_parser *);
1543 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1544 static tree c_parser_struct_declaration (c_parser *);
1545 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1546 static tree c_parser_alignas_specifier (c_parser *);
1547 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1548 c_dtr_syn, bool *);
1549 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1550 bool,
1551 struct c_declarator *);
1552 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1553 bool);
1554 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1555 tree, bool);
1556 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1557 static tree c_parser_simple_asm_expr (c_parser *);
1558 static tree c_parser_gnu_attributes (c_parser *);
1559 static struct c_expr c_parser_initializer (c_parser *, tree);
1560 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1561 struct obstack *, tree);
1562 static void c_parser_initelt (c_parser *, struct obstack *);
1563 static void c_parser_initval (c_parser *, struct c_expr *,
1564 struct obstack *);
1565 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1566 static location_t c_parser_compound_statement_nostart (c_parser *);
1567 static void c_parser_label (c_parser *, tree);
1568 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1569 static void c_parser_statement_after_labels (c_parser *, bool *,
1570 vec<tree> * = NULL);
1571 static tree c_parser_c99_block_statement (c_parser *, bool *,
1572 location_t * = NULL);
1573 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1574 static void c_parser_switch_statement (c_parser *, bool *);
1575 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1576 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1577 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1578 static tree c_parser_asm_statement (c_parser *);
1579 static tree c_parser_asm_operands (c_parser *);
1580 static tree c_parser_asm_goto_operands (c_parser *);
1581 static tree c_parser_asm_clobbers (c_parser *);
1582 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1583 tree = NULL_TREE);
1584 static struct c_expr c_parser_conditional_expression (c_parser *,
1585 struct c_expr *, tree);
1586 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1587 tree);
1588 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1589 static struct c_expr c_parser_unary_expression (c_parser *);
1590 static struct c_expr c_parser_sizeof_expression (c_parser *);
1591 static struct c_expr c_parser_alignof_expression (c_parser *);
1592 static struct c_expr c_parser_postfix_expression (c_parser *);
1593 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1594 struct c_declspecs *,
1595 struct c_type_name *,
1596 location_t);
1597 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1598 location_t loc,
1599 struct c_expr);
1600 static tree c_parser_transaction (c_parser *, enum rid);
1601 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1602 static tree c_parser_transaction_cancel (c_parser *);
1603 static struct c_expr c_parser_expression (c_parser *);
1604 static struct c_expr c_parser_expression_conv (c_parser *);
1605 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1606 vec<tree, va_gc> **, location_t *,
1607 tree *, vec<location_t> *,
1608 unsigned int * = NULL);
1609 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1611 static void c_parser_oacc_declare (c_parser *);
1612 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1613 static void c_parser_oacc_update (c_parser *);
1614 static void c_parser_omp_construct (c_parser *, bool *);
1615 static void c_parser_omp_threadprivate (c_parser *);
1616 static void c_parser_omp_barrier (c_parser *);
1617 static void c_parser_omp_depobj (c_parser *);
1618 static void c_parser_omp_flush (c_parser *);
1619 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1620 tree, tree *, bool *);
1621 static void c_parser_omp_taskwait (c_parser *);
1622 static void c_parser_omp_taskyield (c_parser *);
1623 static void c_parser_omp_cancel (c_parser *);
1624 static void c_parser_omp_nothing (c_parser *);
1626 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1627 pragma_stmt, pragma_compound };
1628 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1629 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1630 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1631 static void c_parser_omp_begin (c_parser *);
1632 static void c_parser_omp_end (c_parser *);
1633 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1634 static void c_parser_omp_requires (c_parser *);
1635 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1636 static void c_parser_omp_assumption_clauses (c_parser *, bool);
1637 static void c_parser_omp_assumes (c_parser *);
1638 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1639 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1641 /* These Objective-C parser functions are only ever called when
1642 compiling Objective-C. */
1643 static void c_parser_objc_class_definition (c_parser *, tree);
1644 static void c_parser_objc_class_instance_variables (c_parser *);
1645 static void c_parser_objc_class_declaration (c_parser *);
1646 static void c_parser_objc_alias_declaration (c_parser *);
1647 static void c_parser_objc_protocol_definition (c_parser *, tree);
1648 static bool c_parser_objc_method_type (c_parser *);
1649 static void c_parser_objc_method_definition (c_parser *);
1650 static void c_parser_objc_methodprotolist (c_parser *);
1651 static void c_parser_objc_methodproto (c_parser *);
1652 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1653 static tree c_parser_objc_type_name (c_parser *);
1654 static tree c_parser_objc_protocol_refs (c_parser *);
1655 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1656 static void c_parser_objc_synchronized_statement (c_parser *);
1657 static tree c_parser_objc_selector (c_parser *);
1658 static tree c_parser_objc_selector_arg (c_parser *);
1659 static tree c_parser_objc_receiver (c_parser *);
1660 static tree c_parser_objc_message_args (c_parser *);
1661 static tree c_parser_objc_keywordexpr (c_parser *);
1662 static void c_parser_objc_at_property_declaration (c_parser *);
1663 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1664 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1665 static bool c_parser_objc_diagnose_bad_element_prefix
1666 (c_parser *, struct c_declspecs *);
1667 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1669 #if ENABLE_ANALYZER
1671 namespace ana {
1673 /* Concrete implementation of ana::translation_unit for the C frontend. */
1675 class c_translation_unit : public translation_unit
1677 public:
1678 /* Implementation of translation_unit::lookup_constant_by_id for use by the
1679 analyzer to look up named constants in the user's source code. */
1680 tree lookup_constant_by_id (tree id) const final override
1682 /* Consider decls. */
1683 if (tree decl = lookup_name (id))
1684 if (TREE_CODE (decl) == CONST_DECL)
1685 if (tree value = DECL_INITIAL (decl))
1686 if (TREE_CODE (value) == INTEGER_CST)
1687 return value;
1689 /* Consider macros. */
1690 cpp_hashnode *hashnode = C_CPP_HASHNODE (id);
1691 if (cpp_macro_p (hashnode))
1692 if (tree value = consider_macro (hashnode->value.macro))
1693 return value;
1695 return NULL_TREE;
1698 private:
1699 /* Attempt to get an INTEGER_CST from MACRO.
1700 Only handle the simplest cases: where MACRO's definition is a single
1701 token containing a number, by lexing the number again.
1702 This will handle e.g.
1703 #define NAME 42
1704 and other bases but not negative numbers, parentheses or e.g.
1705 #define NAME 1 << 7
1706 as doing so would require a parser. */
1707 tree consider_macro (cpp_macro *macro) const
1709 if (macro->paramc > 0)
1710 return NULL_TREE;
1711 if (macro->kind != cmk_macro)
1712 return NULL_TREE;
1713 if (macro->count != 1)
1714 return NULL_TREE;
1715 const cpp_token &tok = macro->exp.tokens[0];
1716 if (tok.type != CPP_NUMBER)
1717 return NULL_TREE;
1719 cpp_reader *old_parse_in = parse_in;
1720 parse_in = cpp_create_reader (CLK_GNUC89, NULL, line_table);
1722 pretty_printer pp;
1723 pp_string (&pp, (const char *) tok.val.str.text);
1724 pp_newline (&pp);
1725 cpp_push_buffer (parse_in,
1726 (const unsigned char *) pp_formatted_text (&pp),
1727 strlen (pp_formatted_text (&pp)),
1730 tree value;
1731 location_t loc;
1732 unsigned char cpp_flags;
1733 c_lex_with_flags (&value, &loc, &cpp_flags, 0);
1735 cpp_destroy (parse_in);
1736 parse_in = old_parse_in;
1738 if (value && TREE_CODE (value) == INTEGER_CST)
1739 return value;
1741 return NULL_TREE;
1745 } // namespace ana
1747 #endif /* #if ENABLE_ANALYZER */
1749 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1751 translation-unit:
1752 external-declarations
1754 external-declarations:
1755 external-declaration
1756 external-declarations external-declaration
1758 GNU extensions:
1760 translation-unit:
1761 empty
1764 static void
1765 c_parser_translation_unit (c_parser *parser)
1767 if (c_parser_next_token_is (parser, CPP_EOF))
1769 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1770 "ISO C forbids an empty translation unit");
1772 else
1774 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1775 mark_valid_location_for_stdc_pragma (false);
1778 ggc_collect ();
1779 c_parser_external_declaration (parser);
1780 obstack_free (&parser_obstack, obstack_position);
1782 while (c_parser_next_token_is_not (parser, CPP_EOF));
1785 unsigned int i;
1786 tree decl;
1787 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1788 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1789 error ("storage size of %q+D isn%'t known", decl);
1791 if (vec_safe_length (current_omp_declare_target_attribute))
1793 c_omp_declare_target_attr
1794 a = current_omp_declare_target_attribute->pop ();
1795 if (!errorcount)
1796 error ("%qs without corresponding %qs",
1797 a.device_type >= 0 ? "#pragma omp begin declare target"
1798 : "#pragma omp declare target",
1799 "#pragma omp end declare target");
1800 vec_safe_truncate (current_omp_declare_target_attribute, 0);
1802 if (current_omp_begin_assumes)
1804 if (!errorcount)
1805 error ("%qs without corresponding %qs",
1806 "#pragma omp begin assumes", "#pragma omp end assumes");
1807 current_omp_begin_assumes = 0;
1810 #if ENABLE_ANALYZER
1811 if (flag_analyzer)
1813 ana::c_translation_unit tu;
1814 ana::on_finish_translation_unit (tu);
1816 #endif
1819 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1821 external-declaration:
1822 function-definition
1823 declaration
1825 GNU extensions:
1827 external-declaration:
1828 asm-definition
1830 __extension__ external-declaration
1832 Objective-C:
1834 external-declaration:
1835 objc-class-definition
1836 objc-class-declaration
1837 objc-alias-declaration
1838 objc-protocol-definition
1839 objc-method-definition
1840 @end
1843 static void
1844 c_parser_external_declaration (c_parser *parser)
1846 int ext;
1847 switch (c_parser_peek_token (parser)->type)
1849 case CPP_KEYWORD:
1850 switch (c_parser_peek_token (parser)->keyword)
1852 case RID_EXTENSION:
1853 ext = disable_extension_diagnostics ();
1854 c_parser_consume_token (parser);
1855 c_parser_external_declaration (parser);
1856 restore_extension_diagnostics (ext);
1857 break;
1858 case RID_ASM:
1859 c_parser_asm_definition (parser);
1860 break;
1861 case RID_AT_INTERFACE:
1862 case RID_AT_IMPLEMENTATION:
1863 gcc_assert (c_dialect_objc ());
1864 c_parser_objc_class_definition (parser, NULL_TREE);
1865 break;
1866 case RID_AT_CLASS:
1867 gcc_assert (c_dialect_objc ());
1868 c_parser_objc_class_declaration (parser);
1869 break;
1870 case RID_AT_ALIAS:
1871 gcc_assert (c_dialect_objc ());
1872 c_parser_objc_alias_declaration (parser);
1873 break;
1874 case RID_AT_PROTOCOL:
1875 gcc_assert (c_dialect_objc ());
1876 c_parser_objc_protocol_definition (parser, NULL_TREE);
1877 break;
1878 case RID_AT_PROPERTY:
1879 gcc_assert (c_dialect_objc ());
1880 c_parser_objc_at_property_declaration (parser);
1881 break;
1882 case RID_AT_SYNTHESIZE:
1883 gcc_assert (c_dialect_objc ());
1884 c_parser_objc_at_synthesize_declaration (parser);
1885 break;
1886 case RID_AT_DYNAMIC:
1887 gcc_assert (c_dialect_objc ());
1888 c_parser_objc_at_dynamic_declaration (parser);
1889 break;
1890 case RID_AT_END:
1891 gcc_assert (c_dialect_objc ());
1892 c_parser_consume_token (parser);
1893 objc_finish_implementation ();
1894 break;
1895 default:
1896 goto decl_or_fndef;
1898 break;
1899 case CPP_SEMICOLON:
1900 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1901 "ISO C does not allow extra %<;%> outside of a function");
1902 c_parser_consume_token (parser);
1903 break;
1904 case CPP_PRAGMA:
1905 mark_valid_location_for_stdc_pragma (true);
1906 c_parser_pragma (parser, pragma_external, NULL);
1907 mark_valid_location_for_stdc_pragma (false);
1908 break;
1909 case CPP_PLUS:
1910 case CPP_MINUS:
1911 if (c_dialect_objc ())
1913 c_parser_objc_method_definition (parser);
1914 break;
1916 /* Else fall through, and yield a syntax error trying to parse
1917 as a declaration or function definition. */
1918 /* FALLTHRU */
1919 default:
1920 decl_or_fndef:
1921 /* A declaration or a function definition (or, in Objective-C,
1922 an @interface or @protocol with prefix attributes). We can
1923 only tell which after parsing the declaration specifiers, if
1924 any, and the first declarator. */
1925 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1926 break;
1930 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1931 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1933 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1935 static void
1936 add_debug_begin_stmt (location_t loc)
1938 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1939 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1940 return;
1942 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1943 SET_EXPR_LOCATION (stmt, loc);
1944 add_stmt (stmt);
1947 /* Helper function for c_parser_declaration_or_fndef and
1948 Handle assume attribute(s). */
1950 static tree
1951 handle_assume_attribute (location_t here, tree attrs, bool nested)
1953 if (nested)
1954 for (tree attr = lookup_attribute ("gnu", "assume", attrs); attr;
1955 attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
1957 tree args = TREE_VALUE (attr);
1958 int nargs = list_length (args);
1959 if (nargs != 1)
1961 error_at (here, "wrong number of arguments specified "
1962 "for %qE attribute",
1963 get_attribute_name (attr));
1964 inform (here, "expected %i, found %i", 1, nargs);
1966 else
1968 tree arg = TREE_VALUE (args);
1969 arg = c_objc_common_truthvalue_conversion (here, arg);
1970 arg = c_fully_fold (arg, false, NULL);
1971 if (arg != error_mark_node)
1973 tree fn = build_call_expr_internal_loc (here, IFN_ASSUME,
1974 void_type_node, 1,
1975 arg);
1976 add_stmt (fn);
1980 else
1981 pedwarn (here, OPT_Wattributes,
1982 "%<assume%> attribute at top level");
1984 return remove_attribute ("gnu", "assume", attrs);
1987 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1988 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1989 is accepted; otherwise (old-style parameter declarations) only other
1990 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1991 assertion is accepted; otherwise (old-style parameter declarations)
1992 it is not. If NESTED is true, we are inside a function or parsing
1993 old-style parameter declarations; any functions encountered are
1994 nested functions and declaration specifiers are required; otherwise
1995 we are at top level and functions are normal functions and
1996 declaration specifiers may be optional. If EMPTY_OK is true, empty
1997 declarations are OK (subject to all other constraints); otherwise
1998 (old-style parameter declarations) they are diagnosed. If
1999 START_ATTR_OK is true, the declaration specifiers may start with
2000 attributes (GNU or standard); otherwise they may not.
2001 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
2002 declaration when parsing an Objective-C foreach statement.
2003 FALLTHRU_ATTR_P is used to signal whether this function parsed
2004 "__attribute__((fallthrough));". ATTRS are any standard attributes
2005 parsed in the caller (in contexts where such attributes had to be
2006 parsed to determine whether what follows is a declaration or a
2007 statement); HAVE_ATTRS says whether there were any such attributes
2008 (even empty).
2010 declaration:
2011 declaration-specifiers init-declarator-list[opt] ;
2012 static_assert-declaration
2014 function-definition:
2015 declaration-specifiers[opt] declarator declaration-list[opt]
2016 compound-statement
2018 declaration-list:
2019 declaration
2020 declaration-list declaration
2022 init-declarator-list:
2023 init-declarator
2024 init-declarator-list , init-declarator
2026 init-declarator:
2027 declarator simple-asm-expr[opt] gnu-attributes[opt]
2028 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
2030 GNU extensions:
2032 nested-function-definition:
2033 declaration-specifiers declarator declaration-list[opt]
2034 compound-statement
2036 attribute ;
2038 Objective-C:
2039 gnu-attributes objc-class-definition
2040 gnu-attributes objc-category-definition
2041 gnu-attributes objc-protocol-definition
2043 The simple-asm-expr and gnu-attributes are GNU extensions.
2045 This function does not handle __extension__; that is handled in its
2046 callers. ??? Following the old parser, __extension__ may start
2047 external declarations, declarations in functions and declarations
2048 at the start of "for" loops, but not old-style parameter
2049 declarations.
2051 C99 requires declaration specifiers in a function definition; the
2052 absence is diagnosed through the diagnosis of implicit int. In GNU
2053 C we also allow but diagnose declarations without declaration
2054 specifiers, but only at top level (elsewhere they conflict with
2055 other syntax).
2057 In Objective-C, declarations of the looping variable in a foreach
2058 statement are exceptionally terminated by 'in' (for example, 'for
2059 (NSObject *object in array) { ... }').
2061 OpenMP:
2063 declaration:
2064 threadprivate-directive
2066 GIMPLE:
2068 gimple-function-definition:
2069 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
2070 declaration-list[opt] compound-statement
2072 rtl-function-definition:
2073 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
2074 declaration-list[opt] compound-statement */
2076 static void
2077 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
2078 bool static_assert_ok, bool empty_ok,
2079 bool nested, bool start_attr_ok,
2080 tree *objc_foreach_object_declaration
2081 /* = NULL */,
2082 vec<c_token> *omp_declare_simd_clauses
2083 /* = NULL */,
2084 bool have_attrs /* = false */,
2085 tree attrs /* = NULL_TREE */,
2086 struct oacc_routine_data *oacc_routine_data
2087 /* = NULL */,
2088 bool *fallthru_attr_p /* = NULL */)
2090 struct c_declspecs *specs;
2091 tree prefix_attrs;
2092 tree all_prefix_attrs;
2093 bool diagnosed_no_specs = false;
2094 location_t here = c_parser_peek_token (parser)->location;
2096 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
2098 if (static_assert_ok
2099 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
2101 c_parser_static_assert_declaration (parser);
2102 return;
2104 specs = build_null_declspecs ();
2106 /* Handle any standard attributes parsed in the caller. */
2107 if (have_attrs)
2109 declspecs_add_attrs (here, specs, attrs);
2110 specs->non_std_attrs_seen_p = false;
2113 /* Try to detect an unknown type name when we have "A B" or "A *B". */
2114 if (c_parser_peek_token (parser)->type == CPP_NAME
2115 && c_parser_peek_token (parser)->id_kind == C_ID_ID
2116 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
2117 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
2118 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
2120 tree name = c_parser_peek_token (parser)->value;
2122 /* Issue a warning about NAME being an unknown type name, perhaps
2123 with some kind of hint.
2124 If the user forgot a "struct" etc, suggest inserting
2125 it. Otherwise, attempt to look for misspellings. */
2126 gcc_rich_location richloc (here);
2127 if (tag_exists_p (RECORD_TYPE, name))
2129 /* This is not C++ with its implicit typedef. */
2130 richloc.add_fixit_insert_before ("struct ");
2131 error_at (&richloc,
2132 "unknown type name %qE;"
2133 " use %<struct%> keyword to refer to the type",
2134 name);
2136 else if (tag_exists_p (UNION_TYPE, name))
2138 richloc.add_fixit_insert_before ("union ");
2139 error_at (&richloc,
2140 "unknown type name %qE;"
2141 " use %<union%> keyword to refer to the type",
2142 name);
2144 else if (tag_exists_p (ENUMERAL_TYPE, name))
2146 richloc.add_fixit_insert_before ("enum ");
2147 error_at (&richloc,
2148 "unknown type name %qE;"
2149 " use %<enum%> keyword to refer to the type",
2150 name);
2152 else
2154 auto_diagnostic_group d;
2155 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
2156 here);
2157 if (const char *suggestion = hint.suggestion ())
2159 richloc.add_fixit_replace (suggestion);
2160 error_at (&richloc,
2161 "unknown type name %qE; did you mean %qs?",
2162 name, suggestion);
2164 else
2165 error_at (here, "unknown type name %qE", name);
2168 /* Parse declspecs normally to get a correct pointer type, but avoid
2169 a further "fails to be a type name" error. Refuse nested functions
2170 since it is not how the user likely wants us to recover. */
2171 c_parser_peek_token (parser)->type = CPP_KEYWORD;
2172 c_parser_peek_token (parser)->keyword = RID_VOID;
2173 c_parser_peek_token (parser)->value = error_mark_node;
2174 fndef_ok = !nested;
2177 /* When there are standard attributes at the start of the
2178 declaration (to apply to the entity being declared), an
2179 init-declarator-list or function definition must be present. */
2180 if (c_parser_nth_token_starts_std_attributes (parser, 1))
2181 have_attrs = true;
2183 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2184 true, true, start_attr_ok, true, cla_nonabstract_decl);
2185 if (parser->error)
2187 c_parser_skip_to_end_of_block_or_statement (parser);
2188 return;
2190 if (nested && !specs->declspecs_seen_p)
2192 c_parser_error (parser, "expected declaration specifiers");
2193 c_parser_skip_to_end_of_block_or_statement (parser);
2194 return;
2197 finish_declspecs (specs);
2198 bool gnu_auto_type_p = specs->typespec_word == cts_auto_type;
2199 bool std_auto_type_p = specs->c2x_auto_p;
2200 bool any_auto_type_p = gnu_auto_type_p || std_auto_type_p;
2201 gcc_assert (!(gnu_auto_type_p && std_auto_type_p));
2202 const char *auto_type_keyword = gnu_auto_type_p ? "__auto_type" : "auto";
2203 if (specs->constexpr_p)
2205 /* An underspecified declaration may not declare tags or members
2206 or structures or unions; it is undefined behavior to declare
2207 the members of an enumeration. Where the structure, union or
2208 enumeration type is declared within an initializer, this is
2209 diagnosed elsewhere. Diagnose here the case of declaring
2210 such a type in the type specifiers of a constexpr
2211 declaration. */
2212 switch (specs->typespec_kind)
2214 case ctsk_tagfirstref:
2215 case ctsk_tagfirstref_attrs:
2216 error_at (here, "%qT declared in underspecified object declaration",
2217 specs->type);
2218 break;
2220 case ctsk_tagdef:
2221 error_at (here, "%qT defined in underspecified object declaration",
2222 specs->type);
2223 break;
2225 default:
2226 break;
2229 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2231 bool handled_assume = false;
2232 if (specs->typespec_kind == ctsk_none
2233 && lookup_attribute ("gnu", "assume", specs->attrs))
2235 handled_assume = true;
2236 specs->attrs
2237 = handle_assume_attribute (here, specs->attrs, nested);
2239 if (any_auto_type_p)
2240 error_at (here, "%qs in empty declaration", auto_type_keyword);
2241 else if (specs->typespec_kind == ctsk_none
2242 && attribute_fallthrough_p (specs->attrs))
2244 if (fallthru_attr_p != NULL)
2245 *fallthru_attr_p = true;
2246 if (nested)
2248 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2249 void_type_node, 0);
2250 add_stmt (fn);
2252 else
2253 pedwarn (here, OPT_Wattributes,
2254 "%<fallthrough%> attribute at top level");
2256 else if (empty_ok
2257 && !(have_attrs && specs->non_std_attrs_seen_p)
2258 && !handled_assume)
2259 shadow_tag (specs);
2260 else
2262 shadow_tag_warned (specs, 1);
2263 if (!handled_assume)
2264 pedwarn (here, 0, "empty declaration");
2266 c_parser_consume_token (parser);
2267 if (oacc_routine_data)
2268 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2269 return;
2272 /* Provide better error recovery. Note that a type name here is usually
2273 better diagnosed as a redeclaration. */
2274 if (empty_ok
2275 && specs->typespec_kind == ctsk_tagdef
2276 && c_parser_next_token_starts_declspecs (parser)
2277 && !c_parser_next_token_is (parser, CPP_NAME))
2279 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2280 parser->error = false;
2281 shadow_tag_warned (specs, 1);
2282 return;
2284 else if (c_dialect_objc () && !any_auto_type_p)
2286 /* Prefix attributes are an error on method decls. */
2287 switch (c_parser_peek_token (parser)->type)
2289 case CPP_PLUS:
2290 case CPP_MINUS:
2291 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2292 return;
2293 if (specs->attrs)
2295 warning_at (c_parser_peek_token (parser)->location,
2296 OPT_Wattributes,
2297 "prefix attributes are ignored for methods");
2298 specs->attrs = NULL_TREE;
2300 if (fndef_ok)
2301 c_parser_objc_method_definition (parser);
2302 else
2303 c_parser_objc_methodproto (parser);
2304 return;
2305 break;
2306 default:
2307 break;
2309 /* This is where we parse 'attributes @interface ...',
2310 'attributes @implementation ...', 'attributes @protocol ...'
2311 (where attributes could be, for example, __attribute__
2312 ((deprecated)).
2314 switch (c_parser_peek_token (parser)->keyword)
2316 case RID_AT_INTERFACE:
2318 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2319 return;
2320 c_parser_objc_class_definition (parser, specs->attrs);
2321 return;
2323 break;
2324 case RID_AT_IMPLEMENTATION:
2326 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2327 return;
2328 if (specs->attrs)
2330 warning_at (c_parser_peek_token (parser)->location,
2331 OPT_Wattributes,
2332 "prefix attributes are ignored for implementations");
2333 specs->attrs = NULL_TREE;
2335 c_parser_objc_class_definition (parser, NULL_TREE);
2336 return;
2338 break;
2339 case RID_AT_PROTOCOL:
2341 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2342 return;
2343 c_parser_objc_protocol_definition (parser, specs->attrs);
2344 return;
2346 break;
2347 case RID_AT_ALIAS:
2348 case RID_AT_CLASS:
2349 case RID_AT_END:
2350 case RID_AT_PROPERTY:
2351 if (specs->attrs)
2353 c_parser_error (parser, "unexpected attribute");
2354 specs->attrs = NULL;
2356 break;
2357 default:
2358 break;
2361 else if (attribute_fallthrough_p (specs->attrs))
2362 warning_at (here, OPT_Wattributes,
2363 "%<fallthrough%> attribute not followed by %<;%>");
2364 else if (lookup_attribute ("gnu", "assume", specs->attrs))
2365 warning_at (here, OPT_Wattributes,
2366 "%<assume%> attribute not followed by %<;%>");
2368 pending_xref_error ();
2369 prefix_attrs = specs->attrs;
2370 all_prefix_attrs = prefix_attrs;
2371 specs->attrs = NULL_TREE;
2372 while (true)
2374 struct c_declarator *declarator;
2375 bool dummy = false;
2376 timevar_id_t tv;
2377 tree fnbody = NULL_TREE;
2378 tree underspec_name = NULL_TREE;
2379 /* Declaring either one or more declarators (in which case we
2380 should diagnose if there were no declaration specifiers) or a
2381 function definition (in which case the diagnostic for
2382 implicit int suffices). */
2383 declarator = c_parser_declarator (parser,
2384 specs->typespec_kind != ctsk_none,
2385 C_DTR_NORMAL, &dummy);
2386 if (declarator == NULL)
2388 if (omp_declare_simd_clauses)
2389 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2390 omp_declare_simd_clauses);
2391 if (oacc_routine_data)
2392 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2393 c_parser_skip_to_end_of_block_or_statement (parser);
2394 return;
2396 if (gnu_auto_type_p && declarator->kind != cdk_id)
2398 error_at (here,
2399 "%<__auto_type%> requires a plain identifier"
2400 " as declarator");
2401 c_parser_skip_to_end_of_block_or_statement (parser);
2402 return;
2404 if (std_auto_type_p)
2406 struct c_declarator *d = declarator;
2407 while (d->kind == cdk_attrs)
2408 d = d->declarator;
2409 if (d->kind != cdk_id)
2411 error_at (here,
2412 "%<auto%> requires a plain identifier, possibly with"
2413 " attributes, as declarator");
2414 c_parser_skip_to_end_of_block_or_statement (parser);
2415 return;
2417 underspec_name = d->u.id.id;
2419 else if (specs->constexpr_p)
2421 struct c_declarator *d = declarator;
2422 while (d->kind != cdk_id)
2423 d = d->declarator;
2424 underspec_name = d->u.id.id;
2426 if (c_parser_next_token_is (parser, CPP_EQ)
2427 || c_parser_next_token_is (parser, CPP_COMMA)
2428 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2429 || c_parser_next_token_is_keyword (parser, RID_ASM)
2430 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2431 || c_parser_next_token_is_keyword (parser, RID_IN))
2433 tree asm_name = NULL_TREE;
2434 tree postfix_attrs = NULL_TREE;
2435 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2437 diagnosed_no_specs = true;
2438 pedwarn (here, 0, "data definition has no type or storage class");
2440 /* Having seen a data definition, there cannot now be a
2441 function definition. */
2442 fndef_ok = false;
2443 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2444 asm_name = c_parser_simple_asm_expr (parser);
2445 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2447 postfix_attrs = c_parser_gnu_attributes (parser);
2448 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2450 /* This means there is an attribute specifier after
2451 the declarator in a function definition. Provide
2452 some more information for the user. */
2453 error_at (here, "attributes should be specified before the "
2454 "declarator in a function definition");
2455 c_parser_skip_to_end_of_block_or_statement (parser);
2456 return;
2459 if (c_parser_next_token_is (parser, CPP_EQ))
2461 tree d;
2462 struct c_expr init;
2463 location_t init_loc;
2464 c_parser_consume_token (parser);
2465 if (any_auto_type_p)
2467 init_loc = c_parser_peek_token (parser)->location;
2468 rich_location richloc (line_table, init_loc);
2469 unsigned int underspec_state = 0;
2470 if (std_auto_type_p)
2471 underspec_state =
2472 start_underspecified_init (init_loc, underspec_name);
2473 start_init (NULL_TREE, asm_name,
2474 (global_bindings_p ()
2475 || specs->storage_class == csc_static
2476 || specs->constexpr_p),
2477 specs->constexpr_p, &richloc);
2478 /* A parameter is initialized, which is invalid. Don't
2479 attempt to instrument the initializer. */
2480 int flag_sanitize_save = flag_sanitize;
2481 if (nested && !empty_ok)
2482 flag_sanitize = 0;
2483 init = c_parser_expr_no_commas (parser, NULL);
2484 if (std_auto_type_p)
2485 finish_underspecified_init (underspec_name,
2486 underspec_state);
2487 flag_sanitize = flag_sanitize_save;
2488 if (gnu_auto_type_p
2489 && TREE_CODE (init.value) == COMPONENT_REF
2490 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2491 error_at (here,
2492 "%<__auto_type%> used with a bit-field"
2493 " initializer");
2494 init = convert_lvalue_to_rvalue (init_loc, init, true, true,
2495 true);
2496 tree init_type = TREE_TYPE (init.value);
2497 bool vm_type = c_type_variably_modified_p (init_type);
2498 if (vm_type)
2499 init.value = save_expr (init.value);
2500 finish_init ();
2501 specs->typespec_kind = ctsk_typeof;
2502 specs->locations[cdw_typedef] = init_loc;
2503 specs->typedef_p = true;
2504 specs->type = init_type;
2505 if (specs->postfix_attrs)
2507 /* Postfix [[]] attributes are valid with C2X
2508 auto, although not with __auto_type, and
2509 modify the type given by the initializer. */
2510 specs->postfix_attrs =
2511 c_warn_type_attributes (specs->postfix_attrs);
2512 decl_attributes (&specs->type, specs->postfix_attrs, 0);
2513 specs->postfix_attrs = NULL_TREE;
2515 if (vm_type)
2517 bool maybe_const = true;
2518 tree type_expr = c_fully_fold (init.value, false,
2519 &maybe_const);
2520 specs->expr_const_operands &= maybe_const;
2521 if (specs->expr)
2522 specs->expr = build2 (COMPOUND_EXPR,
2523 TREE_TYPE (type_expr),
2524 specs->expr, type_expr);
2525 else
2526 specs->expr = type_expr;
2528 d = start_decl (declarator, specs, true,
2529 chainon (postfix_attrs, all_prefix_attrs));
2530 if (!d)
2531 d = error_mark_node;
2532 if (omp_declare_simd_clauses)
2533 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2534 omp_declare_simd_clauses);
2536 else
2538 /* The declaration of the variable is in effect while
2539 its initializer is parsed, except for a constexpr
2540 variable. */
2541 init_loc = c_parser_peek_token (parser)->location;
2542 rich_location richloc (line_table, init_loc);
2543 unsigned int underspec_state = 0;
2544 if (specs->constexpr_p)
2545 underspec_state =
2546 start_underspecified_init (init_loc, underspec_name);
2547 d = start_decl (declarator, specs, true,
2548 chainon (postfix_attrs,
2549 all_prefix_attrs),
2550 !specs->constexpr_p);
2551 if (!d)
2552 d = error_mark_node;
2553 if (!specs->constexpr_p && omp_declare_simd_clauses)
2554 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2555 omp_declare_simd_clauses);
2556 start_init (d, asm_name,
2557 TREE_STATIC (d) || specs->constexpr_p,
2558 specs->constexpr_p, &richloc);
2559 /* A parameter is initialized, which is invalid. Don't
2560 attempt to instrument the initializer. */
2561 int flag_sanitize_save = flag_sanitize;
2562 if (TREE_CODE (d) == PARM_DECL)
2563 flag_sanitize = 0;
2564 init = c_parser_initializer (parser, d);
2565 flag_sanitize = flag_sanitize_save;
2566 if (specs->constexpr_p)
2568 finish_underspecified_init (underspec_name,
2569 underspec_state);
2570 d = pushdecl (d);
2571 if (omp_declare_simd_clauses)
2572 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2573 omp_declare_simd_clauses);
2575 finish_init ();
2577 if (oacc_routine_data)
2578 c_finish_oacc_routine (oacc_routine_data, d, false);
2579 if (d != error_mark_node)
2581 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2582 finish_decl (d, init_loc, init.value,
2583 init.original_type, asm_name);
2586 else
2588 if (any_auto_type_p || specs->constexpr_p)
2590 error_at (here,
2591 "%qs requires an initialized data declaration",
2592 any_auto_type_p ? auto_type_keyword : "constexpr");
2593 c_parser_skip_to_end_of_block_or_statement (parser);
2594 return;
2597 location_t lastloc = UNKNOWN_LOCATION;
2598 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2599 tree d = start_decl (declarator, specs, false, attrs, true,
2600 &lastloc);
2601 if (d && TREE_CODE (d) == FUNCTION_DECL)
2603 /* Find the innermost declarator that is neither cdk_id
2604 nor cdk_attrs. */
2605 const struct c_declarator *decl = declarator;
2606 const struct c_declarator *last_non_id_attrs = NULL;
2608 while (decl)
2609 switch (decl->kind)
2611 case cdk_array:
2612 case cdk_function:
2613 case cdk_pointer:
2614 last_non_id_attrs = decl;
2615 decl = decl->declarator;
2616 break;
2618 case cdk_attrs:
2619 decl = decl->declarator;
2620 break;
2622 case cdk_id:
2623 decl = 0;
2624 break;
2626 default:
2627 gcc_unreachable ();
2630 /* If it exists and is cdk_function declaration whose
2631 arguments have not been set yet, use its arguments. */
2632 if (last_non_id_attrs
2633 && last_non_id_attrs->kind == cdk_function)
2635 tree parms = last_non_id_attrs->u.arg_info->parms;
2636 if (DECL_ARGUMENTS (d) == NULL_TREE
2637 && DECL_INITIAL (d) == NULL_TREE)
2638 DECL_ARGUMENTS (d) = parms;
2640 warn_parm_array_mismatch (lastloc, d, parms);
2643 if (omp_declare_simd_clauses)
2645 tree parms = NULL_TREE;
2646 if (d && TREE_CODE (d) == FUNCTION_DECL)
2648 struct c_declarator *ce = declarator;
2649 while (ce != NULL)
2650 if (ce->kind == cdk_function)
2652 parms = ce->u.arg_info->parms;
2653 break;
2655 else
2656 ce = ce->declarator;
2658 if (parms)
2659 temp_store_parm_decls (d, parms);
2660 c_finish_omp_declare_simd (parser, d, parms,
2661 omp_declare_simd_clauses);
2662 if (parms)
2663 temp_pop_parm_decls ();
2665 if (oacc_routine_data)
2666 c_finish_oacc_routine (oacc_routine_data, d, false);
2667 if (d)
2668 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2669 NULL_TREE, asm_name);
2671 if (c_parser_next_token_is_keyword (parser, RID_IN))
2673 if (d)
2674 *objc_foreach_object_declaration = d;
2675 else
2676 *objc_foreach_object_declaration = error_mark_node;
2679 if (c_parser_next_token_is (parser, CPP_COMMA))
2681 if (any_auto_type_p || specs->constexpr_p)
2683 error_at (here,
2684 "%qs may only be used with a single declarator",
2685 any_auto_type_p ? auto_type_keyword : "constexpr");
2686 c_parser_skip_to_end_of_block_or_statement (parser);
2687 return;
2689 c_parser_consume_token (parser);
2690 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2691 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2692 prefix_attrs);
2693 else
2694 all_prefix_attrs = prefix_attrs;
2695 continue;
2697 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2699 c_parser_consume_token (parser);
2700 return;
2702 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2704 /* This can only happen in Objective-C: we found the
2705 'in' that terminates the declaration inside an
2706 Objective-C foreach statement. Do not consume the
2707 token, so that the caller can use it to determine
2708 that this indeed is a foreach context. */
2709 return;
2711 else
2713 c_parser_error (parser, "expected %<,%> or %<;%>");
2714 c_parser_skip_to_end_of_block_or_statement (parser);
2715 return;
2718 else if (any_auto_type_p || specs->constexpr_p)
2720 error_at (here,
2721 "%qs requires an initialized data declaration",
2722 any_auto_type_p ? auto_type_keyword : "constexpr");
2723 c_parser_skip_to_end_of_block_or_statement (parser);
2724 return;
2726 else if (!fndef_ok)
2728 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2729 "%<asm%> or %<__attribute__%>");
2730 c_parser_skip_to_end_of_block_or_statement (parser);
2731 return;
2733 /* Function definition (nested or otherwise). */
2734 if (nested)
2736 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2737 c_push_function_context ();
2739 if (!start_function (specs, declarator, all_prefix_attrs))
2741 /* At this point we've consumed:
2742 declaration-specifiers declarator
2743 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2744 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2745 but the
2746 declaration-specifiers declarator
2747 aren't grokkable as a function definition, so we have
2748 an error. */
2749 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2750 if (c_parser_next_token_starts_declspecs (parser))
2752 /* If we have
2753 declaration-specifiers declarator decl-specs
2754 then assume we have a missing semicolon, which would
2755 give us:
2756 declaration-specifiers declarator decl-specs
2759 <~~~~~~~~~ declaration ~~~~~~~~~~>
2760 Use c_parser_require to get an error with a fix-it hint. */
2761 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2762 parser->error = false;
2764 else
2766 /* This can appear in many cases looking nothing like a
2767 function definition, so we don't give a more specific
2768 error suggesting there was one. */
2769 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2770 "or %<__attribute__%>");
2772 if (nested)
2773 c_pop_function_context ();
2774 break;
2777 if (DECL_DECLARED_INLINE_P (current_function_decl))
2778 tv = TV_PARSE_INLINE;
2779 else
2780 tv = TV_PARSE_FUNC;
2781 auto_timevar at (g_timer, tv);
2783 /* Parse old-style parameter declarations. ??? Attributes are
2784 not allowed to start declaration specifiers here because of a
2785 syntax conflict between a function declaration with attribute
2786 suffix and a function definition with an attribute prefix on
2787 first old-style parameter declaration. Following the old
2788 parser, they are not accepted on subsequent old-style
2789 parameter declarations either. However, there is no
2790 ambiguity after the first declaration, nor indeed on the
2791 first as long as we don't allow postfix attributes after a
2792 declarator with a nonempty identifier list in a definition;
2793 and postfix attributes have never been accepted here in
2794 function definitions either. */
2795 int save_debug_nonbind_markers_p = debug_nonbind_markers_p;
2796 debug_nonbind_markers_p = 0;
2797 while (c_parser_next_token_is_not (parser, CPP_EOF)
2798 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2799 c_parser_declaration_or_fndef (parser, false, false, false,
2800 true, false);
2801 debug_nonbind_markers_p = save_debug_nonbind_markers_p;
2802 store_parm_decls ();
2803 if (omp_declare_simd_clauses)
2804 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2805 omp_declare_simd_clauses);
2806 if (oacc_routine_data)
2807 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2808 location_t startloc = c_parser_peek_token (parser)->location;
2809 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2810 = startloc;
2811 location_t endloc = startloc;
2813 /* If the definition was marked with __RTL, use the RTL parser now,
2814 consuming the function body. */
2815 if (specs->declspec_il == cdil_rtl)
2817 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2819 /* Normally, store_parm_decls sets next_is_function_body,
2820 anticipating a function body. We need a push_scope/pop_scope
2821 pair to flush out this state, or subsequent function parsing
2822 will go wrong. */
2823 push_scope ();
2824 pop_scope ();
2826 finish_function (endloc);
2827 return;
2829 /* If the definition was marked with __GIMPLE then parse the
2830 function body as GIMPLE. */
2831 else if (specs->declspec_il != cdil_none)
2833 bool saved = in_late_binary_op;
2834 in_late_binary_op = true;
2835 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2836 specs->declspec_il,
2837 specs->entry_bb_count);
2838 in_late_binary_op = saved;
2840 else
2841 fnbody = c_parser_compound_statement (parser, &endloc);
2842 tree fndecl = current_function_decl;
2843 if (nested)
2845 tree decl = current_function_decl;
2846 /* Mark nested functions as needing static-chain initially.
2847 lower_nested_functions will recompute it but the
2848 DECL_STATIC_CHAIN flag is also used before that happens,
2849 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2850 DECL_STATIC_CHAIN (decl) = 1;
2851 add_stmt (fnbody);
2852 finish_function (endloc);
2853 c_pop_function_context ();
2854 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2856 else
2858 if (fnbody)
2859 add_stmt (fnbody);
2860 finish_function (endloc);
2862 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2863 if (specs->declspec_il != cdil_none)
2864 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2866 break;
2870 /* Parse an asm-definition (asm() outside a function body). This is a
2871 GNU extension.
2873 asm-definition:
2874 simple-asm-expr ;
2877 static void
2878 c_parser_asm_definition (c_parser *parser)
2880 tree asm_str = c_parser_simple_asm_expr (parser);
2881 if (asm_str)
2882 symtab->finalize_toplevel_asm (asm_str);
2883 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2886 /* Parse a static assertion (C11 6.7.10).
2888 static_assert-declaration:
2889 static_assert-declaration-no-semi ;
2892 static void
2893 c_parser_static_assert_declaration (c_parser *parser)
2895 c_parser_static_assert_declaration_no_semi (parser);
2896 if (parser->error
2897 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2898 c_parser_skip_to_end_of_block_or_statement (parser);
2901 /* Parse a static assertion (C11 6.7.10), without the trailing
2902 semicolon.
2904 static_assert-declaration-no-semi:
2905 _Static_assert ( constant-expression , string-literal )
2907 C2X:
2908 static_assert-declaration-no-semi:
2909 _Static_assert ( constant-expression )
2912 static void
2913 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2915 location_t assert_loc, value_loc;
2916 tree value;
2917 tree string = NULL_TREE;
2919 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2920 tree spelling = c_parser_peek_token (parser)->value;
2921 assert_loc = c_parser_peek_token (parser)->location;
2922 if (flag_isoc99)
2923 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2924 "ISO C99 does not support %qE", spelling);
2925 else
2926 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2927 "ISO C90 does not support %qE", spelling);
2928 c_parser_consume_token (parser);
2929 matching_parens parens;
2930 if (!parens.require_open (parser))
2931 return;
2932 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2933 value = convert_lvalue_to_rvalue (value_tok_loc,
2934 c_parser_expr_no_commas (parser, NULL),
2935 true, true).value;
2936 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2937 if (c_parser_next_token_is (parser, CPP_COMMA))
2939 c_parser_consume_token (parser);
2940 switch (c_parser_peek_token (parser)->type)
2942 case CPP_STRING:
2943 case CPP_STRING16:
2944 case CPP_STRING32:
2945 case CPP_WSTRING:
2946 case CPP_UTF8STRING:
2947 string = c_parser_string_literal (parser, false, true).value;
2948 break;
2949 default:
2950 c_parser_error (parser, "expected string literal");
2951 return;
2954 else if (flag_isoc11)
2955 /* If pedantic for pre-C11, the use of _Static_assert itself will
2956 have been diagnosed, so do not also diagnose the use of this
2957 new C2X feature of _Static_assert. */
2958 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2959 "ISO C11 does not support omitting the string in "
2960 "%qE", spelling);
2961 parens.require_close (parser);
2963 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2965 error_at (value_loc, "expression in static assertion is not an integer");
2966 return;
2968 if (TREE_CODE (value) != INTEGER_CST)
2970 value = c_fully_fold (value, false, NULL);
2971 /* Strip no-op conversions. */
2972 STRIP_TYPE_NOPS (value);
2973 if (TREE_CODE (value) == INTEGER_CST)
2974 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2975 "is not an integer constant expression");
2977 if (TREE_CODE (value) != INTEGER_CST)
2979 error_at (value_loc, "expression in static assertion is not constant");
2980 return;
2982 constant_expression_warning (value);
2983 if (integer_zerop (value))
2985 if (string)
2986 error_at (assert_loc, "static assertion failed: %E", string);
2987 else
2988 error_at (assert_loc, "static assertion failed");
2992 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2993 6.7, C11 6.7), adding them to SPECS (which may already include some).
2994 Storage class specifiers are accepted iff SCSPEC_OK; type
2995 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2996 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2997 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2998 addition to the syntax shown, standard attributes are accepted at
2999 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
3000 unlike gnu-attributes, they are not accepted in the middle of the
3001 list. (This combines various different syntax productions in the C
3002 standard, and in some cases gnu-attributes and standard attributes
3003 at the start may already have been parsed before this function is
3004 called.)
3006 declaration-specifiers:
3007 storage-class-specifier declaration-specifiers[opt]
3008 type-specifier declaration-specifiers[opt]
3009 type-qualifier declaration-specifiers[opt]
3010 function-specifier declaration-specifiers[opt]
3011 alignment-specifier declaration-specifiers[opt]
3013 Function specifiers (inline) are from C99, and are currently
3014 handled as storage class specifiers, as is __thread. Alignment
3015 specifiers are from C11.
3017 C90 6.5.1, C99 6.7.1, C11 6.7.1:
3018 storage-class-specifier:
3019 typedef
3020 extern
3021 static
3022 auto
3023 register
3024 _Thread_local
3026 (_Thread_local is new in C11.)
3028 C99 6.7.4, C11 6.7.4:
3029 function-specifier:
3030 inline
3031 _Noreturn
3033 (_Noreturn is new in C11.)
3035 C90 6.5.2, C99 6.7.2, C11 6.7.2:
3036 type-specifier:
3037 void
3038 char
3039 short
3041 long
3042 float
3043 double
3044 signed
3045 unsigned
3046 _Bool
3047 _Complex
3048 [_Imaginary removed in C99 TC2]
3049 struct-or-union-specifier
3050 enum-specifier
3051 typedef-name
3052 atomic-type-specifier
3054 (_Bool and _Complex are new in C99.)
3055 (atomic-type-specifier is new in C11.)
3057 C90 6.5.3, C99 6.7.3, C11 6.7.3:
3059 type-qualifier:
3060 const
3061 restrict
3062 volatile
3063 address-space-qualifier
3064 _Atomic
3066 (restrict is new in C99.)
3067 (_Atomic is new in C11.)
3069 GNU extensions:
3071 declaration-specifiers:
3072 gnu-attributes declaration-specifiers[opt]
3074 type-qualifier:
3075 address-space
3077 address-space:
3078 identifier recognized by the target
3080 storage-class-specifier:
3081 __thread
3083 type-specifier:
3084 typeof-specifier
3085 __auto_type
3086 __intN
3087 _Decimal32
3088 _Decimal64
3089 _Decimal128
3090 _Fract
3091 _Accum
3092 _Sat
3094 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
3095 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
3097 atomic-type-specifier
3098 _Atomic ( type-name )
3100 Objective-C:
3102 type-specifier:
3103 class-name objc-protocol-refs[opt]
3104 typedef-name objc-protocol-refs
3105 objc-protocol-refs
3108 void
3109 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
3110 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
3111 bool alignspec_ok, bool auto_type_ok,
3112 bool start_std_attr_ok, bool end_std_attr_ok,
3113 enum c_lookahead_kind la)
3115 bool attrs_ok = start_attr_ok;
3116 bool seen_type = specs->typespec_kind != ctsk_none;
3118 if (!typespec_ok)
3119 gcc_assert (la == cla_prefer_id);
3121 if (start_std_attr_ok
3122 && c_parser_nth_token_starts_std_attributes (parser, 1))
3124 gcc_assert (!specs->non_std_attrs_seen_p);
3125 location_t loc = c_parser_peek_token (parser)->location;
3126 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
3127 declspecs_add_attrs (loc, specs, attrs);
3128 specs->non_std_attrs_seen_p = false;
3131 while (c_parser_next_token_is (parser, CPP_NAME)
3132 || c_parser_next_token_is (parser, CPP_KEYWORD)
3133 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
3135 struct c_typespec t;
3136 tree attrs;
3137 tree align;
3138 location_t loc = c_parser_peek_token (parser)->location;
3140 /* If we cannot accept a type, exit if the next token must start
3141 one. Also, if we already have seen a tagged definition,
3142 a typename would be an error anyway and likely the user
3143 has simply forgotten a semicolon, so we exit. */
3144 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
3145 && c_parser_next_tokens_start_typename (parser, la)
3146 && !c_parser_next_token_is_qualifier (parser)
3147 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
3148 break;
3150 if (c_parser_next_token_is (parser, CPP_NAME))
3152 c_token *name_token = c_parser_peek_token (parser);
3153 tree value = name_token->value;
3154 c_id_kind kind = name_token->id_kind;
3156 if (kind == C_ID_ADDRSPACE)
3158 addr_space_t as
3159 = name_token->keyword - RID_FIRST_ADDR_SPACE;
3160 declspecs_add_addrspace (name_token->location, specs, as);
3161 c_parser_consume_token (parser);
3162 attrs_ok = true;
3163 continue;
3166 gcc_assert (!c_parser_next_token_is_qualifier (parser));
3168 /* If we cannot accept a type, and the next token must start one,
3169 exit. Do the same if we already have seen a tagged definition,
3170 since it would be an error anyway and likely the user has simply
3171 forgotten a semicolon. */
3172 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
3173 break;
3175 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
3176 a C_ID_CLASSNAME. */
3177 c_parser_consume_token (parser);
3178 seen_type = true;
3179 attrs_ok = true;
3180 if (kind == C_ID_ID)
3182 error_at (loc, "unknown type name %qE", value);
3183 t.kind = ctsk_typedef;
3184 t.spec = error_mark_node;
3186 else if (kind == C_ID_TYPENAME
3187 && (!c_dialect_objc ()
3188 || c_parser_next_token_is_not (parser, CPP_LESS)))
3190 t.kind = ctsk_typedef;
3191 /* For a typedef name, record the meaning, not the name.
3192 In case of 'foo foo, bar;'. */
3193 t.spec = lookup_name (value);
3195 else
3197 tree proto = NULL_TREE;
3198 gcc_assert (c_dialect_objc ());
3199 t.kind = ctsk_objc;
3200 if (c_parser_next_token_is (parser, CPP_LESS))
3201 proto = c_parser_objc_protocol_refs (parser);
3202 t.spec = objc_get_protocol_qualified_type (value, proto);
3204 t.expr = NULL_TREE;
3205 t.expr_const_operands = true;
3206 t.has_enum_type_specifier = false;
3207 declspecs_add_type (name_token->location, specs, t);
3208 continue;
3210 if (c_parser_next_token_is (parser, CPP_LESS))
3212 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3213 nisse@lysator.liu.se. */
3214 tree proto;
3215 gcc_assert (c_dialect_objc ());
3216 if (!typespec_ok || seen_type)
3217 break;
3218 proto = c_parser_objc_protocol_refs (parser);
3219 t.kind = ctsk_objc;
3220 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
3221 t.expr = NULL_TREE;
3222 t.expr_const_operands = true;
3223 t.has_enum_type_specifier = false;
3224 declspecs_add_type (loc, specs, t);
3225 continue;
3227 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
3228 switch (c_parser_peek_token (parser)->keyword)
3230 case RID_STATIC:
3231 case RID_EXTERN:
3232 case RID_REGISTER:
3233 case RID_TYPEDEF:
3234 case RID_INLINE:
3235 case RID_NORETURN:
3236 case RID_AUTO:
3237 case RID_THREAD:
3238 case RID_CONSTEXPR:
3239 if (!scspec_ok)
3240 goto out;
3241 attrs_ok = true;
3242 /* TODO: Distinguish between function specifiers (inline, noreturn)
3243 and storage class specifiers, either here or in
3244 declspecs_add_scspec. */
3245 declspecs_add_scspec (loc, specs,
3246 c_parser_peek_token (parser)->value);
3247 c_parser_consume_token (parser);
3248 break;
3249 case RID_AUTO_TYPE:
3250 if (!auto_type_ok)
3251 goto out;
3252 /* Fall through. */
3253 case RID_UNSIGNED:
3254 case RID_LONG:
3255 case RID_SHORT:
3256 case RID_SIGNED:
3257 case RID_COMPLEX:
3258 case RID_INT:
3259 case RID_CHAR:
3260 case RID_FLOAT:
3261 case RID_DOUBLE:
3262 case RID_VOID:
3263 case RID_DFLOAT32:
3264 case RID_DFLOAT64:
3265 case RID_DFLOAT128:
3266 CASE_RID_FLOATN_NX:
3267 case RID_BOOL:
3268 case RID_FRACT:
3269 case RID_ACCUM:
3270 case RID_SAT:
3271 case RID_INT_N_0:
3272 case RID_INT_N_1:
3273 case RID_INT_N_2:
3274 case RID_INT_N_3:
3275 if (!typespec_ok)
3276 goto out;
3277 attrs_ok = true;
3278 seen_type = true;
3279 if (c_dialect_objc ())
3280 parser->objc_need_raw_identifier = true;
3281 t.kind = ctsk_resword;
3282 t.spec = c_parser_peek_token (parser)->value;
3283 t.expr = NULL_TREE;
3284 t.expr_const_operands = true;
3285 t.has_enum_type_specifier = false;
3286 declspecs_add_type (loc, specs, t);
3287 c_parser_consume_token (parser);
3288 break;
3289 case RID_ENUM:
3290 if (!typespec_ok)
3291 goto out;
3292 attrs_ok = true;
3293 seen_type = true;
3294 t = c_parser_enum_specifier (parser);
3295 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3296 declspecs_add_type (loc, specs, t);
3297 break;
3298 case RID_STRUCT:
3299 case RID_UNION:
3300 if (!typespec_ok)
3301 goto out;
3302 attrs_ok = true;
3303 seen_type = true;
3304 t = c_parser_struct_or_union_specifier (parser);
3305 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3306 declspecs_add_type (loc, specs, t);
3307 break;
3308 case RID_TYPEOF:
3309 case RID_TYPEOF_UNQUAL:
3310 /* ??? The old parser rejected typeof after other type
3311 specifiers, but is a syntax error the best way of
3312 handling this? */
3313 if (!typespec_ok || seen_type)
3314 goto out;
3315 attrs_ok = true;
3316 seen_type = true;
3317 t = c_parser_typeof_specifier (parser);
3318 declspecs_add_type (loc, specs, t);
3319 break;
3320 case RID_ATOMIC:
3321 /* C parser handling of Objective-C constructs needs
3322 checking for correct lvalue-to-rvalue conversions, and
3323 the code in build_modify_expr handling various
3324 Objective-C cases, and that in build_unary_op handling
3325 Objective-C cases for increment / decrement, also needs
3326 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3327 and objc_types_are_equivalent may also need updates. */
3328 if (c_dialect_objc ())
3329 sorry ("%<_Atomic%> in Objective-C");
3330 if (flag_isoc99)
3331 pedwarn_c99 (loc, OPT_Wpedantic,
3332 "ISO C99 does not support the %<_Atomic%> qualifier");
3333 else
3334 pedwarn_c99 (loc, OPT_Wpedantic,
3335 "ISO C90 does not support the %<_Atomic%> qualifier");
3336 attrs_ok = true;
3337 tree value;
3338 value = c_parser_peek_token (parser)->value;
3339 c_parser_consume_token (parser);
3340 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3342 /* _Atomic ( type-name ). */
3343 seen_type = true;
3344 c_parser_consume_token (parser);
3345 struct c_type_name *type = c_parser_type_name (parser);
3346 t.kind = ctsk_typeof;
3347 t.spec = error_mark_node;
3348 t.expr = NULL_TREE;
3349 t.expr_const_operands = true;
3350 t.has_enum_type_specifier = false;
3351 if (type != NULL)
3352 t.spec = groktypename (type, &t.expr,
3353 &t.expr_const_operands);
3354 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3355 "expected %<)%>");
3356 if (t.spec != error_mark_node)
3358 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3359 error_at (loc, "%<_Atomic%>-qualified array type");
3360 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3361 error_at (loc, "%<_Atomic%>-qualified function type");
3362 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3363 error_at (loc, "%<_Atomic%> applied to a qualified type");
3364 else
3365 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3367 declspecs_add_type (loc, specs, t);
3369 else
3370 declspecs_add_qual (loc, specs, value);
3371 break;
3372 case RID_CONST:
3373 case RID_VOLATILE:
3374 case RID_RESTRICT:
3375 attrs_ok = true;
3376 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3377 c_parser_consume_token (parser);
3378 break;
3379 case RID_ATTRIBUTE:
3380 if (!attrs_ok)
3381 goto out;
3382 attrs = c_parser_gnu_attributes (parser);
3383 declspecs_add_attrs (loc, specs, attrs);
3384 break;
3385 case RID_ALIGNAS:
3386 if (!alignspec_ok)
3387 goto out;
3388 align = c_parser_alignas_specifier (parser);
3389 declspecs_add_alignas (loc, specs, align);
3390 break;
3391 case RID_GIMPLE:
3392 if (! flag_gimple)
3393 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3394 c_parser_consume_token (parser);
3395 specs->declspec_il = cdil_gimple;
3396 specs->locations[cdw_gimple] = loc;
3397 c_parser_gimple_or_rtl_pass_list (parser, specs);
3398 break;
3399 case RID_RTL:
3400 c_parser_consume_token (parser);
3401 specs->declspec_il = cdil_rtl;
3402 specs->locations[cdw_rtl] = loc;
3403 c_parser_gimple_or_rtl_pass_list (parser, specs);
3404 break;
3405 default:
3406 goto out;
3409 out:
3410 if (end_std_attr_ok
3411 && c_parser_nth_token_starts_std_attributes (parser, 1))
3412 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3415 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3417 enum-specifier:
3418 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3419 { enumerator-list } gnu-attributes[opt]
3420 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3421 { enumerator-list , } gnu-attributes[opt] enum-type-specifier[opt]
3422 enum gnu-attributes[opt] identifier
3424 The form with trailing comma is new in C99; enum-type-specifiers
3425 are new in C2x. The forms with gnu-attributes are GNU extensions.
3426 In GNU C, we accept any expression without commas in the syntax
3427 (assignment expressions, not just conditional expressions);
3428 assignment expressions will be diagnosed as non-constant.
3430 enum-type-specifier:
3431 : specifier-qualifier-list
3433 enumerator-list:
3434 enumerator
3435 enumerator-list , enumerator
3437 enumerator:
3438 enumeration-constant attribute-specifier-sequence[opt]
3439 enumeration-constant attribute-specifier-sequence[opt]
3440 = constant-expression
3442 GNU Extensions:
3444 enumerator:
3445 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3446 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3447 = constant-expression
3451 static struct c_typespec
3452 c_parser_enum_specifier (c_parser *parser)
3454 struct c_typespec ret;
3455 bool have_std_attrs;
3456 tree std_attrs = NULL_TREE;
3457 tree attrs;
3458 tree ident = NULL_TREE;
3459 tree fixed_underlying_type = NULL_TREE;
3460 location_t enum_loc;
3461 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3462 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3463 c_parser_consume_token (parser);
3464 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3465 if (have_std_attrs)
3466 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3467 attrs = c_parser_gnu_attributes (parser);
3468 enum_loc = c_parser_peek_token (parser)->location;
3469 /* Set the location in case we create a decl now. */
3470 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3471 if (c_parser_next_token_is (parser, CPP_NAME))
3473 ident = c_parser_peek_token (parser)->value;
3474 ident_loc = c_parser_peek_token (parser)->location;
3475 enum_loc = ident_loc;
3476 c_parser_consume_token (parser);
3478 if (c_parser_next_token_is (parser, CPP_COLON)
3479 /* Distinguish an enum-type-specifier from a bit-field
3480 declaration of the form "enum e : constant-expression;". */
3481 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
3483 pedwarn_c11 (enum_loc, OPT_Wpedantic,
3484 "ISO C does not support specifying %<enum%> underlying "
3485 "types before C2X");
3486 if (ident)
3488 /* The tag is in scope during the enum-type-specifier (which
3489 may refer to the tag inside typeof). */
3490 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident,
3491 have_std_attrs, std_attrs, true);
3492 if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec))
3493 error_at (enum_loc, "%<enum%> declared both with and without "
3494 "fixed underlying type");
3496 else
3498 /* There must be an enum definition, so this initialization
3499 (to avoid possible warnings about uninitialized data)
3500 will be replaced later (either with the results of that
3501 definition, or with the results of error handling for the
3502 case of no tag and no definition). */
3503 ret.spec = NULL_TREE;
3504 ret.kind = ctsk_tagdef;
3505 ret.expr = NULL_TREE;
3506 ret.expr_const_operands = true;
3507 ret.has_enum_type_specifier = true;
3509 c_parser_consume_token (parser);
3510 struct c_declspecs *specs = build_null_declspecs ();
3511 c_parser_declspecs (parser, specs, false, true, false, false, false,
3512 false, true, cla_prefer_id);
3513 finish_declspecs (specs);
3514 if (specs->default_int_p)
3515 error_at (enum_loc, "no %<enum%> underlying type specified");
3516 else if (TREE_CODE (specs->type) != INTEGER_TYPE
3517 && TREE_CODE (specs->type) != BOOLEAN_TYPE)
3519 error_at (enum_loc, "invalid %<enum%> underlying type");
3520 specs->type = integer_type_node;
3522 else if (specs->restrict_p)
3523 error_at (enum_loc, "invalid use of %<restrict%>");
3524 fixed_underlying_type = TYPE_MAIN_VARIANT (specs->type);
3525 if (ident)
3527 /* The type specified must be consistent with any previously
3528 specified underlying type. If this is a newly declared
3529 type, it is now a complete type. */
3530 if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
3531 && ENUM_UNDERLYING_TYPE (ret.spec) == NULL_TREE)
3533 TYPE_MIN_VALUE (ret.spec) =
3534 TYPE_MIN_VALUE (fixed_underlying_type);
3535 TYPE_MAX_VALUE (ret.spec) =
3536 TYPE_MAX_VALUE (fixed_underlying_type);
3537 TYPE_UNSIGNED (ret.spec) = TYPE_UNSIGNED (fixed_underlying_type);
3538 SET_TYPE_ALIGN (ret.spec, TYPE_ALIGN (fixed_underlying_type));
3539 TYPE_SIZE (ret.spec) = NULL_TREE;
3540 TYPE_PRECISION (ret.spec) =
3541 TYPE_PRECISION (fixed_underlying_type);
3542 ENUM_UNDERLYING_TYPE (ret.spec) = fixed_underlying_type;
3543 layout_type (ret.spec);
3545 else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
3546 && !comptypes (fixed_underlying_type,
3547 ENUM_UNDERLYING_TYPE (ret.spec)))
3549 error_at (enum_loc, "%<enum%> underlying type incompatible with "
3550 "previous declaration");
3551 fixed_underlying_type = ENUM_UNDERLYING_TYPE (ret.spec);
3555 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3557 /* Parse an enum definition. */
3558 struct c_enum_contents the_enum;
3559 tree type;
3560 tree postfix_attrs;
3561 /* We chain the enumerators in reverse order, then put them in
3562 forward order at the end. */
3563 tree values;
3564 timevar_push (TV_PARSE_ENUM);
3565 type = start_enum (enum_loc, &the_enum, ident, fixed_underlying_type);
3566 values = NULL_TREE;
3567 c_parser_consume_token (parser);
3568 while (true)
3570 tree enum_id;
3571 tree enum_value;
3572 tree enum_decl;
3573 bool seen_comma;
3574 c_token *token;
3575 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3576 location_t decl_loc, value_loc;
3577 if (c_parser_next_token_is_not (parser, CPP_NAME))
3579 /* Give a nicer error for "enum {}". */
3580 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3581 && !parser->error)
3583 error_at (c_parser_peek_token (parser)->location,
3584 "empty enum is invalid");
3585 parser->error = true;
3587 else
3588 c_parser_error (parser, "expected identifier");
3589 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3590 values = error_mark_node;
3591 break;
3593 token = c_parser_peek_token (parser);
3594 enum_id = token->value;
3595 /* Set the location in case we create a decl now. */
3596 c_parser_set_source_position_from_token (token);
3597 decl_loc = value_loc = token->location;
3598 c_parser_consume_token (parser);
3599 /* Parse any specified attributes. */
3600 tree std_attrs = NULL_TREE;
3601 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3602 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3603 tree enum_attrs = chainon (std_attrs,
3604 c_parser_gnu_attributes (parser));
3605 if (c_parser_next_token_is (parser, CPP_EQ))
3607 c_parser_consume_token (parser);
3608 value_loc = c_parser_peek_token (parser)->location;
3609 enum_value = convert_lvalue_to_rvalue (value_loc,
3610 (c_parser_expr_no_commas
3611 (parser, NULL)),
3612 true, true).value;
3614 else
3615 enum_value = NULL_TREE;
3616 enum_decl = build_enumerator (decl_loc, value_loc,
3617 &the_enum, enum_id, enum_value);
3618 if (enum_attrs)
3619 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3620 TREE_CHAIN (enum_decl) = values;
3621 values = enum_decl;
3622 seen_comma = false;
3623 if (c_parser_next_token_is (parser, CPP_COMMA))
3625 comma_loc = c_parser_peek_token (parser)->location;
3626 seen_comma = true;
3627 c_parser_consume_token (parser);
3629 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3631 if (seen_comma)
3632 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3633 "comma at end of enumerator list");
3634 c_parser_consume_token (parser);
3635 break;
3637 if (!seen_comma)
3639 c_parser_error (parser, "expected %<,%> or %<}%>");
3640 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3641 values = error_mark_node;
3642 break;
3645 postfix_attrs = c_parser_gnu_attributes (parser);
3646 ret.spec = finish_enum (type, nreverse (values),
3647 chainon (std_attrs,
3648 chainon (attrs, postfix_attrs)));
3649 ret.kind = ctsk_tagdef;
3650 ret.expr = NULL_TREE;
3651 ret.expr_const_operands = true;
3652 ret.has_enum_type_specifier = fixed_underlying_type != NULL_TREE;
3653 timevar_pop (TV_PARSE_ENUM);
3654 return ret;
3656 else if (!ident)
3658 c_parser_error (parser, "expected %<{%>");
3659 ret.spec = error_mark_node;
3660 ret.kind = ctsk_tagref;
3661 ret.expr = NULL_TREE;
3662 ret.expr_const_operands = true;
3663 ret.has_enum_type_specifier = false;
3664 return ret;
3666 /* Attributes may only appear when the members are defined or in
3667 certain forward declarations (treat enum forward declarations in
3668 GNU C analogously to struct and union forward declarations in
3669 standard C). */
3670 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3671 c_parser_error (parser, "expected %<;%>");
3672 if (fixed_underlying_type == NULL_TREE)
3674 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3675 std_attrs, false);
3676 /* In ISO C, enumerated types without a fixed underlying type
3677 can be referred to only if already defined. */
3678 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3680 gcc_assert (ident);
3681 pedwarn (enum_loc, OPT_Wpedantic,
3682 "ISO C forbids forward references to %<enum%> types");
3685 return ret;
3688 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3690 struct-or-union-specifier:
3691 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3692 identifier[opt] { struct-contents } gnu-attributes[opt]
3693 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3694 identifier
3696 struct-contents:
3697 struct-declaration-list
3699 struct-declaration-list:
3700 struct-declaration ;
3701 struct-declaration-list struct-declaration ;
3703 GNU extensions:
3705 struct-contents:
3706 empty
3707 struct-declaration
3708 struct-declaration-list struct-declaration
3710 struct-declaration-list:
3711 struct-declaration-list ;
3714 (Note that in the syntax here, unlike that in ISO C, the semicolons
3715 are included here rather than in struct-declaration, in order to
3716 describe the syntax with extra semicolons and missing semicolon at
3717 end.)
3719 Objective-C:
3721 struct-declaration-list:
3722 @defs ( class-name )
3724 (Note this does not include a trailing semicolon, but can be
3725 followed by further declarations, and gets a pedwarn-if-pedantic
3726 when followed by a semicolon.) */
3728 static struct c_typespec
3729 c_parser_struct_or_union_specifier (c_parser *parser)
3731 struct c_typespec ret;
3732 bool have_std_attrs;
3733 tree std_attrs = NULL_TREE;
3734 tree attrs;
3735 tree ident = NULL_TREE;
3736 location_t struct_loc;
3737 location_t ident_loc = UNKNOWN_LOCATION;
3738 enum tree_code code;
3739 switch (c_parser_peek_token (parser)->keyword)
3741 case RID_STRUCT:
3742 code = RECORD_TYPE;
3743 break;
3744 case RID_UNION:
3745 code = UNION_TYPE;
3746 break;
3747 default:
3748 gcc_unreachable ();
3750 struct_loc = c_parser_peek_token (parser)->location;
3751 c_parser_consume_token (parser);
3752 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3753 if (have_std_attrs)
3754 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3755 attrs = c_parser_gnu_attributes (parser);
3757 /* Set the location in case we create a decl now. */
3758 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3760 if (c_parser_next_token_is (parser, CPP_NAME))
3762 ident = c_parser_peek_token (parser)->value;
3763 ident_loc = c_parser_peek_token (parser)->location;
3764 struct_loc = ident_loc;
3765 c_parser_consume_token (parser);
3767 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3769 /* Parse a struct or union definition. Start the scope of the
3770 tag before parsing components. */
3771 class c_struct_parse_info *struct_info;
3772 tree type = start_struct (struct_loc, code, ident, &struct_info);
3773 tree postfix_attrs;
3774 /* We chain the components in reverse order, then put them in
3775 forward order at the end. Each struct-declaration may
3776 declare multiple components (comma-separated), so we must use
3777 chainon to join them, although when parsing each
3778 struct-declaration we can use TREE_CHAIN directly.
3780 The theory behind all this is that there will be more
3781 semicolon separated fields than comma separated fields, and
3782 so we'll be minimizing the number of node traversals required
3783 by chainon. */
3784 tree contents;
3785 timevar_push (TV_PARSE_STRUCT);
3786 contents = NULL_TREE;
3787 c_parser_consume_token (parser);
3788 /* Handle the Objective-C @defs construct,
3789 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3790 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3792 tree name;
3793 gcc_assert (c_dialect_objc ());
3794 c_parser_consume_token (parser);
3795 matching_parens parens;
3796 if (!parens.require_open (parser))
3797 goto end_at_defs;
3798 if (c_parser_next_token_is (parser, CPP_NAME)
3799 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3801 name = c_parser_peek_token (parser)->value;
3802 c_parser_consume_token (parser);
3804 else
3806 c_parser_error (parser, "expected class name");
3807 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3808 goto end_at_defs;
3810 parens.skip_until_found_close (parser);
3811 contents = nreverse (objc_get_class_ivars (name));
3813 end_at_defs:
3814 /* Parse the struct-declarations and semicolons. Problems with
3815 semicolons are diagnosed here; empty structures are diagnosed
3816 elsewhere. */
3817 while (true)
3819 tree decls;
3820 /* Parse any stray semicolon. */
3821 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3823 location_t semicolon_loc
3824 = c_parser_peek_token (parser)->location;
3825 gcc_rich_location richloc (semicolon_loc);
3826 richloc.add_fixit_remove ();
3827 pedwarn (&richloc, OPT_Wpedantic,
3828 "extra semicolon in struct or union specified");
3829 c_parser_consume_token (parser);
3830 continue;
3832 /* Stop if at the end of the struct or union contents. */
3833 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3835 c_parser_consume_token (parser);
3836 break;
3838 /* Accept #pragmas at struct scope. */
3839 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3841 c_parser_pragma (parser, pragma_struct, NULL);
3842 continue;
3844 /* Parse some comma-separated declarations, but not the
3845 trailing semicolon if any. */
3846 decls = c_parser_struct_declaration (parser);
3847 contents = chainon (decls, contents);
3848 /* If no semicolon follows, either we have a parse error or
3849 are at the end of the struct or union and should
3850 pedwarn. */
3851 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3852 c_parser_consume_token (parser);
3853 else
3855 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3856 pedwarn (c_parser_peek_token (parser)->location, 0,
3857 "no semicolon at end of struct or union");
3858 else if (parser->error
3859 || !c_parser_next_token_starts_declspecs (parser))
3861 c_parser_error (parser, "expected %<;%>");
3862 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3863 break;
3866 /* If we come here, we have already emitted an error
3867 for an expected `;', identifier or `(', and we also
3868 recovered already. Go on with the next field. */
3871 postfix_attrs = c_parser_gnu_attributes (parser);
3872 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3873 chainon (std_attrs,
3874 chainon (attrs, postfix_attrs)),
3875 struct_info);
3876 ret.kind = ctsk_tagdef;
3877 ret.expr = NULL_TREE;
3878 ret.expr_const_operands = true;
3879 ret.has_enum_type_specifier = false;
3880 timevar_pop (TV_PARSE_STRUCT);
3881 return ret;
3883 else if (!ident)
3885 c_parser_error (parser, "expected %<{%>");
3886 ret.spec = error_mark_node;
3887 ret.kind = ctsk_tagref;
3888 ret.expr = NULL_TREE;
3889 ret.expr_const_operands = true;
3890 ret.has_enum_type_specifier = false;
3891 return ret;
3893 /* Attributes may only appear when the members are defined or in
3894 certain forward declarations. */
3895 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3896 c_parser_error (parser, "expected %<;%>");
3897 /* ??? Existing practice is that GNU attributes are ignored after
3898 the struct or union keyword when not defining the members. */
3899 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs,
3900 false);
3901 return ret;
3904 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3905 *without* the trailing semicolon.
3907 struct-declaration:
3908 attribute-specifier-sequence[opt] specifier-qualifier-list
3909 attribute-specifier-sequence[opt] struct-declarator-list
3910 static_assert-declaration-no-semi
3912 specifier-qualifier-list:
3913 type-specifier specifier-qualifier-list[opt]
3914 type-qualifier specifier-qualifier-list[opt]
3915 alignment-specifier specifier-qualifier-list[opt]
3916 gnu-attributes specifier-qualifier-list[opt]
3918 struct-declarator-list:
3919 struct-declarator
3920 struct-declarator-list , gnu-attributes[opt] struct-declarator
3922 struct-declarator:
3923 declarator gnu-attributes[opt]
3924 declarator[opt] : constant-expression gnu-attributes[opt]
3926 GNU extensions:
3928 struct-declaration:
3929 __extension__ struct-declaration
3930 specifier-qualifier-list
3932 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3933 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3934 any expression without commas in the syntax (assignment
3935 expressions, not just conditional expressions); assignment
3936 expressions will be diagnosed as non-constant. */
3938 static tree
3939 c_parser_struct_declaration (c_parser *parser)
3941 struct c_declspecs *specs;
3942 tree prefix_attrs;
3943 tree all_prefix_attrs;
3944 tree decls;
3945 location_t decl_loc;
3946 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3948 int ext;
3949 tree decl;
3950 ext = disable_extension_diagnostics ();
3951 c_parser_consume_token (parser);
3952 decl = c_parser_struct_declaration (parser);
3953 restore_extension_diagnostics (ext);
3954 return decl;
3956 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3958 c_parser_static_assert_declaration_no_semi (parser);
3959 return NULL_TREE;
3961 specs = build_null_declspecs ();
3962 decl_loc = c_parser_peek_token (parser)->location;
3963 /* Strictly by the standard, we shouldn't allow _Alignas here,
3964 but it appears to have been intended to allow it there, so
3965 we're keeping it as it is until WG14 reaches a conclusion
3966 of N1731.
3967 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3968 c_parser_declspecs (parser, specs, false, true, true,
3969 true, false, true, true, cla_nonabstract_decl);
3970 if (parser->error)
3971 return NULL_TREE;
3972 if (!specs->declspecs_seen_p)
3974 c_parser_error (parser, "expected specifier-qualifier-list");
3975 return NULL_TREE;
3977 finish_declspecs (specs);
3978 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3979 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3981 tree ret;
3982 if (specs->typespec_kind == ctsk_none)
3984 pedwarn (decl_loc, OPT_Wpedantic,
3985 "ISO C forbids member declarations with no members");
3986 shadow_tag_warned (specs, pedantic);
3987 ret = NULL_TREE;
3989 else
3991 /* Support for unnamed structs or unions as members of
3992 structs or unions (which is [a] useful and [b] supports
3993 MS P-SDK). */
3994 tree attrs = NULL;
3996 ret = grokfield (c_parser_peek_token (parser)->location,
3997 build_id_declarator (NULL_TREE), specs,
3998 NULL_TREE, &attrs);
3999 if (ret)
4000 decl_attributes (&ret, attrs, 0);
4002 return ret;
4005 /* Provide better error recovery. Note that a type name here is valid,
4006 and will be treated as a field name. */
4007 if (specs->typespec_kind == ctsk_tagdef
4008 && TREE_CODE (specs->type) != ENUMERAL_TYPE
4009 && c_parser_next_token_starts_declspecs (parser)
4010 && !c_parser_next_token_is (parser, CPP_NAME))
4012 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
4013 parser->error = false;
4014 return NULL_TREE;
4017 pending_xref_error ();
4018 prefix_attrs = specs->attrs;
4019 all_prefix_attrs = prefix_attrs;
4020 specs->attrs = NULL_TREE;
4021 decls = NULL_TREE;
4022 while (true)
4024 /* Declaring one or more declarators or un-named bit-fields. */
4025 struct c_declarator *declarator;
4026 bool dummy = false;
4027 if (c_parser_next_token_is (parser, CPP_COLON))
4028 declarator = build_id_declarator (NULL_TREE);
4029 else
4030 declarator = c_parser_declarator (parser,
4031 specs->typespec_kind != ctsk_none,
4032 C_DTR_NORMAL, &dummy);
4033 if (declarator == NULL)
4035 c_parser_skip_to_end_of_block_or_statement (parser);
4036 break;
4038 if (c_parser_next_token_is (parser, CPP_COLON)
4039 || c_parser_next_token_is (parser, CPP_COMMA)
4040 || c_parser_next_token_is (parser, CPP_SEMICOLON)
4041 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
4042 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4044 tree postfix_attrs = NULL_TREE;
4045 tree width = NULL_TREE;
4046 tree d;
4047 if (c_parser_next_token_is (parser, CPP_COLON))
4049 c_parser_consume_token (parser);
4050 location_t loc = c_parser_peek_token (parser)->location;
4051 width = convert_lvalue_to_rvalue (loc,
4052 (c_parser_expr_no_commas
4053 (parser, NULL)),
4054 true, true).value;
4056 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4057 postfix_attrs = c_parser_gnu_attributes (parser);
4058 d = grokfield (c_parser_peek_token (parser)->location,
4059 declarator, specs, width, &all_prefix_attrs);
4060 decl_attributes (&d, chainon (postfix_attrs,
4061 all_prefix_attrs), 0);
4062 DECL_CHAIN (d) = decls;
4063 decls = d;
4064 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4065 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
4066 prefix_attrs);
4067 else
4068 all_prefix_attrs = prefix_attrs;
4069 if (c_parser_next_token_is (parser, CPP_COMMA))
4070 c_parser_consume_token (parser);
4071 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
4072 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4074 /* Semicolon consumed in caller. */
4075 break;
4077 else
4079 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
4080 break;
4083 else
4085 c_parser_error (parser,
4086 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
4087 "%<__attribute__%>");
4088 break;
4091 return decls;
4094 /* Parse a typeof specifier (a GNU extension adopted in C2X).
4096 typeof-specifier:
4097 typeof ( expression )
4098 typeof ( type-name )
4099 typeof_unqual ( expression )
4100 typeof_unqual ( type-name )
4103 static struct c_typespec
4104 c_parser_typeof_specifier (c_parser *parser)
4106 bool is_unqual;
4107 bool is_std;
4108 struct c_typespec ret;
4109 ret.kind = ctsk_typeof;
4110 ret.spec = error_mark_node;
4111 ret.expr = NULL_TREE;
4112 ret.expr_const_operands = true;
4113 ret.has_enum_type_specifier = false;
4114 if (c_parser_next_token_is_keyword (parser, RID_TYPEOF))
4116 is_unqual = false;
4117 tree spelling = c_parser_peek_token (parser)->value;
4118 is_std = (flag_isoc2x
4119 && strcmp (IDENTIFIER_POINTER (spelling), "typeof") == 0);
4121 else
4123 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF_UNQUAL));
4124 is_unqual = true;
4125 is_std = true;
4127 c_parser_consume_token (parser);
4128 c_inhibit_evaluation_warnings++;
4129 in_typeof++;
4130 matching_parens parens;
4131 if (!parens.require_open (parser))
4133 c_inhibit_evaluation_warnings--;
4134 in_typeof--;
4135 return ret;
4137 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
4139 struct c_type_name *type = c_parser_type_name (parser);
4140 c_inhibit_evaluation_warnings--;
4141 in_typeof--;
4142 if (type != NULL)
4144 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
4145 pop_maybe_used (c_type_variably_modified_p (ret.spec));
4148 else
4150 bool was_vm;
4151 location_t here = c_parser_peek_token (parser)->location;
4152 struct c_expr expr = c_parser_expression (parser);
4153 c_inhibit_evaluation_warnings--;
4154 in_typeof--;
4155 if (TREE_CODE (expr.value) == COMPONENT_REF
4156 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
4157 error_at (here, "%<typeof%> applied to a bit-field");
4158 mark_exp_read (expr.value);
4159 ret.spec = TREE_TYPE (expr.value);
4160 was_vm = c_type_variably_modified_p (ret.spec);
4161 /* This is returned with the type so that when the type is
4162 evaluated, this can be evaluated. */
4163 if (was_vm)
4164 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
4165 pop_maybe_used (was_vm);
4167 parens.skip_until_found_close (parser);
4168 if (ret.spec != error_mark_node)
4170 if (is_unqual && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
4171 ret.spec = TYPE_MAIN_VARIANT (ret.spec);
4172 if (is_std)
4174 /* In ISO C terms, _Noreturn is not part of the type of
4175 expressions such as &abort, but in GCC it is represented
4176 internally as a type qualifier. */
4177 if (TREE_CODE (ret.spec) == FUNCTION_TYPE
4178 && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
4179 ret.spec = TYPE_MAIN_VARIANT (ret.spec);
4180 else if (FUNCTION_POINTER_TYPE_P (ret.spec)
4181 && TYPE_QUALS (TREE_TYPE (ret.spec)) != TYPE_UNQUALIFIED)
4182 ret.spec
4183 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret.spec)));
4186 return ret;
4189 /* Parse an alignment-specifier.
4191 C11 6.7.5:
4193 alignment-specifier:
4194 _Alignas ( type-name )
4195 _Alignas ( constant-expression )
4198 static tree
4199 c_parser_alignas_specifier (c_parser * parser)
4201 tree ret = error_mark_node;
4202 location_t loc = c_parser_peek_token (parser)->location;
4203 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
4204 tree spelling = c_parser_peek_token (parser)->value;
4205 c_parser_consume_token (parser);
4206 if (flag_isoc99)
4207 pedwarn_c99 (loc, OPT_Wpedantic,
4208 "ISO C99 does not support %qE", spelling);
4209 else
4210 pedwarn_c99 (loc, OPT_Wpedantic,
4211 "ISO C90 does not support %qE", spelling);
4212 matching_parens parens;
4213 if (!parens.require_open (parser))
4214 return ret;
4215 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
4217 struct c_type_name *type = c_parser_type_name (parser);
4218 if (type != NULL)
4219 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
4220 false, true, 1);
4222 else
4223 ret = convert_lvalue_to_rvalue (loc,
4224 c_parser_expr_no_commas (parser, NULL),
4225 true, true).value;
4226 parens.skip_until_found_close (parser);
4227 return ret;
4230 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
4231 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
4232 a typedef name may be redeclared; otherwise it may not. KIND
4233 indicates which kind of declarator is wanted. Returns a valid
4234 declarator except in the case of a syntax error in which case NULL is
4235 returned. *SEEN_ID is set to true if an identifier being declared is
4236 seen; this is used to diagnose bad forms of abstract array declarators
4237 and to determine whether an identifier list is syntactically permitted.
4239 declarator:
4240 pointer[opt] direct-declarator
4242 direct-declarator:
4243 identifier
4244 ( gnu-attributes[opt] declarator )
4245 direct-declarator array-declarator
4246 direct-declarator ( parameter-type-list )
4247 direct-declarator ( identifier-list[opt] )
4249 pointer:
4250 * type-qualifier-list[opt]
4251 * type-qualifier-list[opt] pointer
4253 type-qualifier-list:
4254 type-qualifier
4255 gnu-attributes
4256 type-qualifier-list type-qualifier
4257 type-qualifier-list gnu-attributes
4259 array-declarator:
4260 [ type-qualifier-list[opt] assignment-expression[opt] ]
4261 [ static type-qualifier-list[opt] assignment-expression ]
4262 [ type-qualifier-list static assignment-expression ]
4263 [ type-qualifier-list[opt] * ]
4265 parameter-type-list:
4266 parameter-list
4267 parameter-list , ...
4269 parameter-list:
4270 parameter-declaration
4271 parameter-list , parameter-declaration
4273 parameter-declaration:
4274 declaration-specifiers declarator gnu-attributes[opt]
4275 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
4277 identifier-list:
4278 identifier
4279 identifier-list , identifier
4281 abstract-declarator:
4282 pointer
4283 pointer[opt] direct-abstract-declarator
4285 direct-abstract-declarator:
4286 ( gnu-attributes[opt] abstract-declarator )
4287 direct-abstract-declarator[opt] array-declarator
4288 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
4290 GNU extensions:
4292 direct-declarator:
4293 direct-declarator ( parameter-forward-declarations
4294 parameter-type-list[opt] )
4296 direct-abstract-declarator:
4297 direct-abstract-declarator[opt] ( parameter-forward-declarations
4298 parameter-type-list[opt] )
4300 parameter-forward-declarations:
4301 parameter-list ;
4302 parameter-forward-declarations parameter-list ;
4304 The uses of gnu-attributes shown above are GNU extensions.
4306 Some forms of array declarator are not included in C99 in the
4307 syntax for abstract declarators; these are disallowed elsewhere.
4308 This may be a defect (DR#289).
4310 This function also accepts an omitted abstract declarator as being
4311 an abstract declarator, although not part of the formal syntax. */
4313 struct c_declarator *
4314 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4315 bool *seen_id)
4317 /* Parse any initial pointer part. */
4318 if (c_parser_next_token_is (parser, CPP_MULT))
4320 struct c_declspecs *quals_attrs = build_null_declspecs ();
4321 struct c_declarator *inner;
4322 c_parser_consume_token (parser);
4323 c_parser_declspecs (parser, quals_attrs, false, false, true,
4324 false, false, true, false, cla_prefer_id);
4325 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4326 if (inner == NULL)
4327 return NULL;
4328 else
4329 return make_pointer_declarator (quals_attrs, inner);
4331 /* Now we have a direct declarator, direct abstract declarator or
4332 nothing (which counts as a direct abstract declarator here). */
4333 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
4336 /* Parse a direct declarator or direct abstract declarator; arguments
4337 as c_parser_declarator. */
4339 static struct c_declarator *
4340 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4341 bool *seen_id)
4343 /* The direct declarator must start with an identifier (possibly
4344 omitted) or a parenthesized declarator (possibly abstract). In
4345 an ordinary declarator, initial parentheses must start a
4346 parenthesized declarator. In an abstract declarator or parameter
4347 declarator, they could start a parenthesized declarator or a
4348 parameter list. To tell which, the open parenthesis and any
4349 following gnu-attributes must be read. If a declaration
4350 specifier or standard attributes follow, then it is a parameter
4351 list; if the specifier is a typedef name, there might be an
4352 ambiguity about redeclaring it, which is resolved in the
4353 direction of treating it as a typedef name. If a close
4354 parenthesis follows, it is also an empty parameter list, as the
4355 syntax does not permit empty abstract declarators. Otherwise, it
4356 is a parenthesized declarator (in which case the analysis may be
4357 repeated inside it, recursively).
4359 ??? There is an ambiguity in a parameter declaration "int
4360 (__attribute__((foo)) x)", where x is not a typedef name: it
4361 could be an abstract declarator for a function, or declare x with
4362 parentheses. The proper resolution of this ambiguity needs
4363 documenting. At present we follow an accident of the old
4364 parser's implementation, whereby the first parameter must have
4365 some declaration specifiers other than just gnu-attributes. Thus as
4366 a parameter declaration it is treated as a parenthesized
4367 parameter named x, and as an abstract declarator it is
4368 rejected.
4370 ??? Also following the old parser, gnu-attributes inside an empty
4371 parameter list are ignored, making it a list not yielding a
4372 prototype, rather than giving an error or making it have one
4373 parameter with implicit type int.
4375 ??? Also following the old parser, typedef names may be
4376 redeclared in declarators, but not Objective-C class names. */
4378 if (kind != C_DTR_ABSTRACT
4379 && c_parser_next_token_is (parser, CPP_NAME)
4380 && ((type_seen_p
4381 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
4382 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
4383 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
4385 struct c_declarator *inner
4386 = build_id_declarator (c_parser_peek_token (parser)->value);
4387 *seen_id = true;
4388 inner->id_loc = c_parser_peek_token (parser)->location;
4389 c_parser_consume_token (parser);
4390 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4391 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
4392 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4395 if (kind != C_DTR_NORMAL
4396 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4397 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4399 struct c_declarator *inner = build_id_declarator (NULL_TREE);
4400 inner->id_loc = c_parser_peek_token (parser)->location;
4401 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4404 /* Either we are at the end of an abstract declarator, or we have
4405 parentheses. */
4407 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4409 tree attrs;
4410 struct c_declarator *inner;
4411 c_parser_consume_token (parser);
4412 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4413 RID_ATTRIBUTE);
4414 attrs = c_parser_gnu_attributes (parser);
4415 if (kind != C_DTR_NORMAL
4416 && (c_parser_next_token_starts_declspecs (parser)
4417 || (!have_gnu_attrs
4418 && (c_parser_nth_token_starts_std_attributes (parser, 1)
4419 || c_parser_next_token_is (parser, CPP_ELLIPSIS)))
4420 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
4422 struct c_arg_info *args
4423 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
4424 attrs, have_gnu_attrs);
4425 if (args == NULL)
4426 return NULL;
4427 else
4429 inner = build_id_declarator (NULL_TREE);
4430 if (!(args->types
4431 && args->types != error_mark_node
4432 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4433 && c_parser_nth_token_starts_std_attributes (parser, 1))
4435 tree std_attrs
4436 = c_parser_std_attribute_specifier_sequence (parser);
4437 if (std_attrs)
4438 inner = build_attrs_declarator (std_attrs, inner);
4440 inner = build_function_declarator (args, inner);
4441 return c_parser_direct_declarator_inner (parser, *seen_id,
4442 inner);
4445 /* A parenthesized declarator. */
4446 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4447 if (inner != NULL && attrs != NULL)
4448 inner = build_attrs_declarator (attrs, inner);
4449 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4451 c_parser_consume_token (parser);
4452 if (inner == NULL)
4453 return NULL;
4454 else
4455 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4457 else
4459 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4460 "expected %<)%>");
4461 return NULL;
4464 else
4466 if (kind == C_DTR_NORMAL)
4468 c_parser_error (parser, "expected identifier or %<(%>");
4469 return NULL;
4471 else
4472 return build_id_declarator (NULL_TREE);
4476 /* Parse part of a direct declarator or direct abstract declarator,
4477 given that some (in INNER) has already been parsed; ID_PRESENT is
4478 true if an identifier is present, false for an abstract
4479 declarator. */
4481 static struct c_declarator *
4482 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4483 struct c_declarator *inner)
4485 /* Parse a sequence of array declarators and parameter lists. */
4486 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4487 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4489 location_t brace_loc = c_parser_peek_token (parser)->location;
4490 struct c_declarator *declarator;
4491 struct c_declspecs *quals_attrs = build_null_declspecs ();
4492 bool static_seen;
4493 bool star_seen;
4494 struct c_expr dimen;
4495 dimen.value = NULL_TREE;
4496 dimen.original_code = ERROR_MARK;
4497 dimen.original_type = NULL_TREE;
4498 c_parser_consume_token (parser);
4499 c_parser_declspecs (parser, quals_attrs, false, false, true,
4500 false, false, false, false, cla_prefer_id);
4501 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4502 if (static_seen)
4503 c_parser_consume_token (parser);
4504 if (static_seen && !quals_attrs->declspecs_seen_p)
4505 c_parser_declspecs (parser, quals_attrs, false, false, true,
4506 false, false, false, false, cla_prefer_id);
4507 if (!quals_attrs->declspecs_seen_p)
4508 quals_attrs = NULL;
4509 /* If "static" is present, there must be an array dimension.
4510 Otherwise, there may be a dimension, "*", or no
4511 dimension. */
4512 if (static_seen)
4514 star_seen = false;
4515 dimen = c_parser_expr_no_commas (parser, NULL);
4517 else
4519 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4521 dimen.value = NULL_TREE;
4522 star_seen = false;
4524 else if (c_parser_next_token_is (parser, CPP_MULT))
4526 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4528 dimen.value = NULL_TREE;
4529 star_seen = true;
4530 c_parser_consume_token (parser);
4532 else
4534 star_seen = false;
4535 dimen = c_parser_expr_no_commas (parser, NULL);
4538 else
4540 star_seen = false;
4541 dimen = c_parser_expr_no_commas (parser, NULL);
4544 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4545 c_parser_consume_token (parser);
4546 else
4548 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4549 "expected %<]%>");
4550 return NULL;
4552 if (dimen.value)
4553 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4554 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4555 static_seen, star_seen);
4556 if (declarator == NULL)
4557 return NULL;
4558 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4560 tree std_attrs
4561 = c_parser_std_attribute_specifier_sequence (parser);
4562 if (std_attrs)
4563 inner = build_attrs_declarator (std_attrs, inner);
4565 inner = set_array_declarator_inner (declarator, inner);
4566 return c_parser_direct_declarator_inner (parser, id_present, inner);
4568 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4570 tree attrs;
4571 struct c_arg_info *args;
4572 c_parser_consume_token (parser);
4573 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4574 RID_ATTRIBUTE);
4575 attrs = c_parser_gnu_attributes (parser);
4576 args = c_parser_parms_declarator (parser, id_present, attrs,
4577 have_gnu_attrs);
4578 if (args == NULL)
4579 return NULL;
4580 else
4582 if (!(args->types
4583 && args->types != error_mark_node
4584 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4585 && c_parser_nth_token_starts_std_attributes (parser, 1))
4587 tree std_attrs
4588 = c_parser_std_attribute_specifier_sequence (parser);
4589 if (std_attrs)
4590 inner = build_attrs_declarator (std_attrs, inner);
4592 inner = build_function_declarator (args, inner);
4593 return c_parser_direct_declarator_inner (parser, id_present, inner);
4596 return inner;
4599 /* Parse a parameter list or identifier list, including the closing
4600 parenthesis but not the opening one. ATTRS are the gnu-attributes
4601 at the start of the list. ID_LIST_OK is true if an identifier list
4602 is acceptable; such a list must not have attributes at the start.
4603 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4604 attributes) were present (in which case standard attributes cannot
4605 occur). */
4607 static struct c_arg_info *
4608 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4609 bool have_gnu_attrs)
4611 push_scope ();
4612 declare_parm_level ();
4613 /* If the list starts with an identifier, it is an identifier list.
4614 Otherwise, it is either a prototype list or an empty list. */
4615 if (id_list_ok
4616 && !attrs
4617 && c_parser_next_token_is (parser, CPP_NAME)
4618 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4620 /* Look ahead to detect typos in type names. */
4621 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4622 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4623 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4624 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4625 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4627 tree list = NULL_TREE, *nextp = &list;
4628 while (c_parser_next_token_is (parser, CPP_NAME)
4629 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4631 *nextp = build_tree_list (NULL_TREE,
4632 c_parser_peek_token (parser)->value);
4633 nextp = & TREE_CHAIN (*nextp);
4634 c_parser_consume_token (parser);
4635 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4636 break;
4637 c_parser_consume_token (parser);
4638 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4640 c_parser_error (parser, "expected identifier");
4641 break;
4644 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4646 struct c_arg_info *ret = build_arg_info ();
4647 ret->types = list;
4648 c_parser_consume_token (parser);
4649 pop_scope ();
4650 return ret;
4652 else
4654 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4655 "expected %<)%>");
4656 pop_scope ();
4657 return NULL;
4660 else
4662 struct c_arg_info *ret
4663 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4664 pop_scope ();
4665 return ret;
4669 /* Parse a parameter list (possibly empty), including the closing
4670 parenthesis but not the opening one. ATTRS are the gnu-attributes
4671 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4672 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4673 which means standard attributes cannot start the list. EXPR is
4674 NULL or an expression that needs to be evaluated for the side
4675 effects of array size expressions in the parameters. */
4677 static struct c_arg_info *
4678 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4679 bool have_gnu_attrs)
4681 bool bad_parm = false;
4683 /* ??? Following the old parser, forward parameter declarations may
4684 use abstract declarators, and if no real parameter declarations
4685 follow the forward declarations then this is not diagnosed. Also
4686 note as above that gnu-attributes are ignored as the only contents of
4687 the parentheses, or as the only contents after forward
4688 declarations. */
4689 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4691 struct c_arg_info *ret = build_arg_info ();
4692 c_parser_consume_token (parser);
4693 return ret;
4695 if (c_parser_next_token_is (parser, CPP_ELLIPSIS) && !have_gnu_attrs)
4697 struct c_arg_info *ret = build_arg_info ();
4699 ret->types = NULL_TREE;
4700 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
4701 "ISO C requires a named argument before %<...%> "
4702 "before C2X");
4703 c_parser_consume_token (parser);
4704 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4706 ret->no_named_args_stdarg_p = true;
4707 c_parser_consume_token (parser);
4708 return ret;
4710 else
4712 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4713 "expected %<)%>");
4714 return NULL;
4717 /* Nonempty list of parameters, either terminated with semicolon
4718 (forward declarations; recurse) or with close parenthesis (normal
4719 function) or with ", ... )" (variadic function). */
4720 while (true)
4722 /* Parse a parameter. */
4723 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4724 have_gnu_attrs);
4725 attrs = NULL_TREE;
4726 have_gnu_attrs = false;
4727 if (parm == NULL)
4728 bad_parm = true;
4729 else
4730 push_parm_decl (parm, &expr);
4731 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4733 tree new_attrs;
4734 c_parser_consume_token (parser);
4735 mark_forward_parm_decls ();
4736 bool new_have_gnu_attrs
4737 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4738 new_attrs = c_parser_gnu_attributes (parser);
4739 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4740 new_have_gnu_attrs);
4742 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4744 c_parser_consume_token (parser);
4745 if (bad_parm)
4746 return NULL;
4747 else
4748 return get_parm_info (false, expr);
4750 if (!c_parser_require (parser, CPP_COMMA,
4751 "expected %<;%>, %<,%> or %<)%>",
4752 UNKNOWN_LOCATION, false))
4754 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4755 return NULL;
4757 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4759 c_parser_consume_token (parser);
4760 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4762 c_parser_consume_token (parser);
4763 if (bad_parm)
4764 return NULL;
4765 else
4766 return get_parm_info (true, expr);
4768 else
4770 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4771 "expected %<)%>");
4772 return NULL;
4778 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4779 start of the declaration if it is the first parameter;
4780 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4781 empty) there. */
4783 static struct c_parm *
4784 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4785 bool have_gnu_attrs)
4787 struct c_declspecs *specs;
4788 struct c_declarator *declarator;
4789 tree prefix_attrs;
4790 tree postfix_attrs = NULL_TREE;
4791 bool dummy = false;
4793 /* Accept #pragmas between parameter declarations. */
4794 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4795 c_parser_pragma (parser, pragma_param, NULL);
4797 if (!c_parser_next_token_starts_declspecs (parser)
4798 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4800 c_token *token = c_parser_peek_token (parser);
4801 if (parser->error)
4802 return NULL;
4803 c_parser_set_source_position_from_token (token);
4804 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4806 auto_diagnostic_group d;
4807 name_hint hint = lookup_name_fuzzy (token->value,
4808 FUZZY_LOOKUP_TYPENAME,
4809 token->location);
4810 if (const char *suggestion = hint.suggestion ())
4812 gcc_rich_location richloc (token->location);
4813 richloc.add_fixit_replace (suggestion);
4814 error_at (&richloc,
4815 "unknown type name %qE; did you mean %qs?",
4816 token->value, suggestion);
4818 else
4819 error_at (token->location, "unknown type name %qE", token->value);
4820 parser->error = true;
4822 /* ??? In some Objective-C cases '...' isn't applicable so there
4823 should be a different message. */
4824 else
4825 c_parser_error (parser,
4826 "expected declaration specifiers or %<...%>");
4827 c_parser_skip_to_end_of_parameter (parser);
4828 return NULL;
4831 location_t start_loc = c_parser_peek_token (parser)->location;
4833 specs = build_null_declspecs ();
4834 if (attrs)
4836 declspecs_add_attrs (input_location, specs, attrs);
4837 attrs = NULL_TREE;
4839 c_parser_declspecs (parser, specs, true, true, true, true, false,
4840 !have_gnu_attrs, true, cla_nonabstract_decl);
4841 finish_declspecs (specs);
4842 pending_xref_error ();
4843 prefix_attrs = specs->attrs;
4844 specs->attrs = NULL_TREE;
4845 declarator = c_parser_declarator (parser,
4846 specs->typespec_kind != ctsk_none,
4847 C_DTR_PARM, &dummy);
4848 if (declarator == NULL)
4850 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4851 return NULL;
4853 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4854 postfix_attrs = c_parser_gnu_attributes (parser);
4856 /* Generate a location for the parameter, ranging from the start of the
4857 initial token to the end of the final token.
4859 If we have a identifier, then use it for the caret location, e.g.
4861 extern int callee (int one, int (*two)(int, int), float three);
4862 ~~~~~~^~~~~~~~~~~~~~
4864 otherwise, reuse the start location for the caret location e.g.:
4866 extern int callee (int one, int (*)(int, int), float three);
4867 ^~~~~~~~~~~~~~~~~
4869 location_t end_loc = parser->last_token_location;
4871 /* Find any cdk_id declarator; determine if we have an identifier. */
4872 c_declarator *id_declarator = declarator;
4873 while (id_declarator && id_declarator->kind != cdk_id)
4874 id_declarator = id_declarator->declarator;
4875 location_t caret_loc = (id_declarator->u.id.id
4876 ? id_declarator->id_loc
4877 : start_loc);
4878 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4880 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4881 declarator, param_loc);
4884 /* Parse a string literal in an asm expression. It should not be
4885 translated, and wide string literals are an error although
4886 permitted by the syntax. This is a GNU extension.
4888 asm-string-literal:
4889 string-literal
4892 static tree
4893 c_parser_asm_string_literal (c_parser *parser)
4895 tree str;
4896 int save_flag = warn_overlength_strings;
4897 warn_overlength_strings = 0;
4898 str = c_parser_string_literal (parser, false, false).value;
4899 warn_overlength_strings = save_flag;
4900 return str;
4903 /* Parse a simple asm expression. This is used in restricted
4904 contexts, where a full expression with inputs and outputs does not
4905 make sense. This is a GNU extension.
4907 simple-asm-expr:
4908 asm ( asm-string-literal )
4911 static tree
4912 c_parser_simple_asm_expr (c_parser *parser)
4914 tree str;
4915 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4916 c_parser_consume_token (parser);
4917 matching_parens parens;
4918 if (!parens.require_open (parser))
4919 return NULL_TREE;
4920 str = c_parser_asm_string_literal (parser);
4921 if (!parens.require_close (parser))
4923 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4924 return NULL_TREE;
4926 return str;
4929 static tree
4930 c_parser_gnu_attribute_any_word (c_parser *parser)
4932 tree attr_name = NULL_TREE;
4934 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4936 /* ??? See comment above about what keywords are accepted here. */
4937 bool ok;
4938 switch (c_parser_peek_token (parser)->keyword)
4940 case RID_STATIC:
4941 case RID_UNSIGNED:
4942 case RID_LONG:
4943 case RID_CONST:
4944 case RID_EXTERN:
4945 case RID_REGISTER:
4946 case RID_TYPEDEF:
4947 case RID_SHORT:
4948 case RID_INLINE:
4949 case RID_NORETURN:
4950 case RID_VOLATILE:
4951 case RID_SIGNED:
4952 case RID_AUTO:
4953 case RID_RESTRICT:
4954 case RID_COMPLEX:
4955 case RID_THREAD:
4956 case RID_INT:
4957 case RID_CHAR:
4958 case RID_FLOAT:
4959 case RID_DOUBLE:
4960 case RID_VOID:
4961 case RID_DFLOAT32:
4962 case RID_DFLOAT64:
4963 case RID_DFLOAT128:
4964 CASE_RID_FLOATN_NX:
4965 case RID_BOOL:
4966 case RID_FRACT:
4967 case RID_ACCUM:
4968 case RID_SAT:
4969 case RID_TRANSACTION_ATOMIC:
4970 case RID_TRANSACTION_CANCEL:
4971 case RID_ATOMIC:
4972 case RID_AUTO_TYPE:
4973 case RID_CONSTEXPR:
4974 case RID_INT_N_0:
4975 case RID_INT_N_1:
4976 case RID_INT_N_2:
4977 case RID_INT_N_3:
4978 ok = true;
4979 break;
4980 default:
4981 ok = false;
4982 break;
4984 if (!ok)
4985 return NULL_TREE;
4987 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4988 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4990 else if (c_parser_next_token_is (parser, CPP_NAME))
4991 attr_name = c_parser_peek_token (parser)->value;
4993 return attr_name;
4996 /* Parse attribute arguments. This is a common form of syntax
4997 covering all currently valid GNU and standard attributes.
4999 gnu-attribute-arguments:
5000 identifier
5001 identifier , nonempty-expr-list
5002 expr-list
5004 where the "identifier" must not be declared as a type. ??? Why not
5005 allow identifiers declared as types to start the arguments? */
5007 static tree
5008 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
5009 bool require_string, bool assume_attr,
5010 bool allow_empty_args)
5012 vec<tree, va_gc> *expr_list;
5013 tree attr_args;
5014 /* Parse the attribute contents. If they start with an
5015 identifier which is followed by a comma or close
5016 parenthesis, then the arguments start with that
5017 identifier; otherwise they are an expression list.
5018 In objective-c the identifier may be a classname. */
5019 if (c_parser_next_token_is (parser, CPP_NAME)
5020 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
5021 || (c_dialect_objc ()
5022 && c_parser_peek_token (parser)->id_kind
5023 == C_ID_CLASSNAME))
5024 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
5025 || (c_parser_peek_2nd_token (parser)->type
5026 == CPP_CLOSE_PAREN))
5027 && (takes_identifier
5028 || (c_dialect_objc ()
5029 && !assume_attr
5030 && c_parser_peek_token (parser)->id_kind
5031 == C_ID_CLASSNAME)))
5033 tree arg1 = c_parser_peek_token (parser)->value;
5034 c_parser_consume_token (parser);
5035 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5036 attr_args = build_tree_list (NULL_TREE, arg1);
5037 else
5039 tree tree_list;
5040 c_parser_consume_token (parser);
5041 expr_list = c_parser_expr_list (parser, false, true,
5042 NULL, NULL, NULL, NULL);
5043 tree_list = build_tree_list_vec (expr_list);
5044 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
5045 release_tree_vector (expr_list);
5048 else
5050 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5052 if (!allow_empty_args)
5053 error_at (c_parser_peek_token (parser)->location,
5054 "parentheses must be omitted if "
5055 "attribute argument list is empty");
5056 attr_args = NULL_TREE;
5058 else if (require_string)
5060 /* The only valid argument for this attribute is a string
5061 literal. Handle this specially here to avoid accepting
5062 string literals with excess parentheses. */
5063 tree string = c_parser_string_literal (parser, false, true).value;
5064 attr_args = build_tree_list (NULL_TREE, string);
5066 else if (assume_attr)
5068 tree cond
5069 = c_parser_conditional_expression (parser, NULL, NULL_TREE).value;
5070 if (!c_parser_next_token_is (parser, CPP_COMMA))
5071 attr_args = build_tree_list (NULL_TREE, cond);
5072 else
5074 tree tree_list;
5075 c_parser_consume_token (parser);
5076 expr_list = c_parser_expr_list (parser, false, true,
5077 NULL, NULL, NULL, NULL);
5078 tree_list = build_tree_list_vec (expr_list);
5079 attr_args = tree_cons (NULL_TREE, cond, tree_list);
5080 release_tree_vector (expr_list);
5083 else
5085 expr_list = c_parser_expr_list (parser, false, true,
5086 NULL, NULL, NULL, NULL);
5087 attr_args = build_tree_list_vec (expr_list);
5088 release_tree_vector (expr_list);
5091 return attr_args;
5094 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
5096 gnu-attributes:
5097 empty
5098 gnu-attributes gnu-attribute
5100 gnu-attribute:
5101 __attribute__ ( ( gnu-attribute-list ) )
5103 gnu-attribute-list:
5104 gnu-attrib
5105 gnu-attribute_list , gnu-attrib
5107 gnu-attrib:
5108 empty
5109 any-word
5110 any-word ( gnu-attribute-arguments )
5112 where "any-word" may be any identifier (including one declared as a
5113 type), a reserved word storage class specifier, type specifier or
5114 type qualifier. ??? This still leaves out most reserved keywords
5115 (following the old parser), shouldn't we include them?
5116 When EXPECT_COMMA is true, expect the attribute to be preceded
5117 by a comma and fail if it isn't.
5118 When EMPTY_OK is true, allow and consume any number of consecutive
5119 commas with no attributes in between. */
5121 static tree
5122 c_parser_gnu_attribute (c_parser *parser, tree attrs,
5123 bool expect_comma = false, bool empty_ok = true)
5125 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
5126 if (!comma_first
5127 && !c_parser_next_token_is (parser, CPP_NAME)
5128 && !c_parser_next_token_is (parser, CPP_KEYWORD))
5129 return NULL_TREE;
5131 while (c_parser_next_token_is (parser, CPP_COMMA))
5133 c_parser_consume_token (parser);
5134 if (!empty_ok)
5135 return attrs;
5138 tree attr_name = c_parser_gnu_attribute_any_word (parser);
5139 if (attr_name == NULL_TREE)
5140 return NULL_TREE;
5142 attr_name = canonicalize_attr_name (attr_name);
5143 c_parser_consume_token (parser);
5145 tree attr;
5146 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5148 if (expect_comma && !comma_first)
5150 /* A comma is missing between the last attribute on the chain
5151 and this one. */
5152 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5153 "expected %<)%>");
5154 return error_mark_node;
5156 attr = build_tree_list (attr_name, NULL_TREE);
5157 /* Add this attribute to the list. */
5158 attrs = chainon (attrs, attr);
5159 return attrs;
5161 c_parser_consume_token (parser);
5163 tree attr_args
5164 = c_parser_attribute_arguments (parser,
5165 attribute_takes_identifier_p (attr_name),
5166 false,
5167 is_attribute_p ("assume", attr_name),
5168 true);
5170 attr = build_tree_list (attr_name, attr_args);
5171 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5172 c_parser_consume_token (parser);
5173 else
5175 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5176 "expected %<)%>");
5177 return error_mark_node;
5180 if (expect_comma && !comma_first)
5182 /* A comma is missing between the last attribute on the chain
5183 and this one. */
5184 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5185 "expected %<)%>");
5186 return error_mark_node;
5189 /* Add this attribute to the list. */
5190 attrs = chainon (attrs, attr);
5191 return attrs;
5194 static tree
5195 c_parser_gnu_attributes (c_parser *parser)
5197 tree attrs = NULL_TREE;
5198 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5200 bool save_translate_strings_p = parser->translate_strings_p;
5201 parser->translate_strings_p = false;
5202 /* Consume the `__attribute__' keyword. */
5203 c_parser_consume_token (parser);
5204 /* Look for the two `(' tokens. */
5205 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5207 parser->translate_strings_p = save_translate_strings_p;
5208 return attrs;
5210 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5212 parser->translate_strings_p = save_translate_strings_p;
5213 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5214 return attrs;
5216 /* Parse the attribute list. Require a comma between successive
5217 (possibly empty) attributes. */
5218 for (bool expect_comma = false; ; expect_comma = true)
5220 /* Parse a single attribute. */
5221 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
5222 if (attr == error_mark_node)
5223 return attrs;
5224 if (!attr)
5225 break;
5226 attrs = attr;
5229 /* Look for the two `)' tokens. */
5230 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5231 c_parser_consume_token (parser);
5232 else
5234 parser->translate_strings_p = save_translate_strings_p;
5235 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5236 "expected %<)%>");
5237 return attrs;
5239 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5240 c_parser_consume_token (parser);
5241 else
5243 parser->translate_strings_p = save_translate_strings_p;
5244 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5245 "expected %<)%>");
5246 return attrs;
5248 parser->translate_strings_p = save_translate_strings_p;
5251 return attrs;
5254 /* Parse an optional balanced token sequence.
5256 balanced-token-sequence:
5257 balanced-token
5258 balanced-token-sequence balanced-token
5260 balanced-token:
5261 ( balanced-token-sequence[opt] )
5262 [ balanced-token-sequence[opt] ]
5263 { balanced-token-sequence[opt] }
5264 any token other than ()[]{}
5267 static void
5268 c_parser_balanced_token_sequence (c_parser *parser)
5270 while (true)
5272 c_token *token = c_parser_peek_token (parser);
5273 switch (token->type)
5275 case CPP_OPEN_BRACE:
5277 matching_braces braces;
5278 braces.consume_open (parser);
5279 c_parser_balanced_token_sequence (parser);
5280 braces.require_close (parser);
5281 break;
5284 case CPP_OPEN_PAREN:
5286 matching_parens parens;
5287 parens.consume_open (parser);
5288 c_parser_balanced_token_sequence (parser);
5289 parens.require_close (parser);
5290 break;
5293 case CPP_OPEN_SQUARE:
5294 c_parser_consume_token (parser);
5295 c_parser_balanced_token_sequence (parser);
5296 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5297 break;
5299 case CPP_CLOSE_BRACE:
5300 case CPP_CLOSE_PAREN:
5301 case CPP_CLOSE_SQUARE:
5302 case CPP_EOF:
5303 return;
5305 case CPP_PRAGMA:
5306 c_parser_consume_pragma (parser);
5307 c_parser_skip_to_pragma_eol (parser, false);
5308 break;
5310 default:
5311 c_parser_consume_token (parser);
5312 break;
5317 /* Parse standard (C2X) attributes (including GNU attributes in the
5318 gnu:: namespace).
5320 attribute-specifier-sequence:
5321 attribute-specifier-sequence[opt] attribute-specifier
5323 attribute-specifier:
5324 [ [ attribute-list ] ]
5326 attribute-list:
5327 attribute[opt]
5328 attribute-list, attribute[opt]
5330 attribute:
5331 attribute-token attribute-argument-clause[opt]
5333 attribute-token:
5334 standard-attribute
5335 attribute-prefixed-token
5337 standard-attribute:
5338 identifier
5340 attribute-prefixed-token:
5341 attribute-prefix :: identifier
5343 attribute-prefix:
5344 identifier
5346 attribute-argument-clause:
5347 ( balanced-token-sequence[opt] )
5349 Keywords are accepted as identifiers for this purpose.
5352 static tree
5353 c_parser_std_attribute (c_parser *parser, bool for_tm)
5355 c_token *token = c_parser_peek_token (parser);
5356 tree ns, name, attribute;
5358 /* Parse the attribute-token. */
5359 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5361 c_parser_error (parser, "expected identifier");
5362 return error_mark_node;
5364 name = canonicalize_attr_name (token->value);
5365 c_parser_consume_token (parser);
5366 if (c_parser_next_token_is (parser, CPP_SCOPE))
5368 ns = name;
5369 c_parser_consume_token (parser);
5370 token = c_parser_peek_token (parser);
5371 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5373 c_parser_error (parser, "expected identifier");
5374 return error_mark_node;
5376 name = canonicalize_attr_name (token->value);
5377 c_parser_consume_token (parser);
5379 else
5380 ns = NULL_TREE;
5381 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
5383 /* Parse the arguments, if any. */
5384 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
5385 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5386 goto out;
5388 location_t open_loc = c_parser_peek_token (parser)->location;
5389 matching_parens parens;
5390 parens.consume_open (parser);
5391 if ((as && as->max_length == 0)
5392 /* Special-case the transactional-memory attribute "outer",
5393 which is specially handled but not registered as an
5394 attribute, to avoid allowing arbitrary balanced token
5395 sequences as arguments. */
5396 || is_attribute_p ("outer", name))
5398 error_at (open_loc, "%qE attribute does not take any arguments", name);
5399 parens.skip_until_found_close (parser);
5400 return error_mark_node;
5402 /* If this is a fake attribute created to handle -Wno-attributes,
5403 we must skip parsing the arguments. */
5404 if (as && !attribute_ignored_p (as))
5406 bool takes_identifier
5407 = (ns != NULL_TREE
5408 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5409 && attribute_takes_identifier_p (name));
5410 bool require_string
5411 = (ns == NULL_TREE
5412 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
5413 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
5414 bool assume_attr
5415 = (ns != NULL_TREE
5416 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5417 && strcmp (IDENTIFIER_POINTER (name), "assume") == 0);
5418 TREE_VALUE (attribute)
5419 = c_parser_attribute_arguments (parser, takes_identifier,
5420 require_string, assume_attr, false);
5422 else
5423 c_parser_balanced_token_sequence (parser);
5424 parens.require_close (parser);
5426 out:
5427 if (ns == NULL_TREE && !for_tm && !as)
5429 /* An attribute with standard syntax and no namespace specified
5430 is a constraint violation if it is not one of the known
5431 standard attributes. Diagnose it here with a pedwarn and
5432 then discard it to prevent a duplicate warning later. */
5433 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
5434 name);
5435 return error_mark_node;
5437 return attribute;
5440 static tree
5441 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
5443 location_t loc = c_parser_peek_token (parser)->location;
5444 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5445 return NULL_TREE;
5446 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5448 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5449 return NULL_TREE;
5451 if (!for_tm)
5452 pedwarn_c11 (loc, OPT_Wpedantic,
5453 "ISO C does not support %<[[]]%> attributes before C2X");
5454 tree attributes = NULL_TREE;
5455 while (true)
5457 c_token *token = c_parser_peek_token (parser);
5458 if (token->type == CPP_CLOSE_SQUARE)
5459 break;
5460 if (token->type == CPP_COMMA)
5462 c_parser_consume_token (parser);
5463 continue;
5465 tree attribute = c_parser_std_attribute (parser, for_tm);
5466 if (attribute != error_mark_node)
5468 TREE_CHAIN (attribute) = attributes;
5469 attributes = attribute;
5471 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5472 break;
5474 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5475 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5476 return nreverse (attributes);
5479 /* Look past an optional balanced token sequence of raw look-ahead
5480 tokens starting with the *Nth token. *N is updated to point to the
5481 following token. Return true if such a sequence was found, false
5482 if the tokens parsed were not balanced. */
5484 static bool
5485 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5487 while (true)
5489 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5490 switch (token->type)
5492 case CPP_OPEN_BRACE:
5494 ++*n;
5495 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5497 token = c_parser_peek_nth_token_raw (parser, *n);
5498 if (token->type == CPP_CLOSE_BRACE)
5499 ++*n;
5500 else
5501 return false;
5503 else
5504 return false;
5505 break;
5508 case CPP_OPEN_PAREN:
5510 ++*n;
5511 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5513 token = c_parser_peek_nth_token_raw (parser, *n);
5514 if (token->type == CPP_CLOSE_PAREN)
5515 ++*n;
5516 else
5517 return false;
5519 else
5520 return false;
5521 break;
5524 case CPP_OPEN_SQUARE:
5526 ++*n;
5527 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5529 token = c_parser_peek_nth_token_raw (parser, *n);
5530 if (token->type == CPP_CLOSE_SQUARE)
5531 ++*n;
5532 else
5533 return false;
5535 else
5536 return false;
5537 break;
5540 case CPP_CLOSE_BRACE:
5541 case CPP_CLOSE_PAREN:
5542 case CPP_CLOSE_SQUARE:
5543 case CPP_EOF:
5544 return true;
5546 default:
5547 ++*n;
5548 break;
5553 /* Return whether standard attributes start with the Nth token. */
5555 static bool
5556 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5558 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5559 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5560 return false;
5561 /* In C, '[[' must start attributes. In Objective-C, we need to
5562 check whether '[[' is matched by ']]'. */
5563 if (!c_dialect_objc ())
5564 return true;
5565 n += 2;
5566 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5567 return false;
5568 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5569 if (token->type != CPP_CLOSE_SQUARE)
5570 return false;
5571 token = c_parser_peek_nth_token_raw (parser, n + 1);
5572 return token->type == CPP_CLOSE_SQUARE;
5575 static tree
5576 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5578 tree attributes = NULL_TREE;
5581 tree attrs = c_parser_std_attribute_specifier (parser, false);
5582 attributes = chainon (attributes, attrs);
5584 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5585 return attributes;
5588 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5589 says whether alignment specifiers are OK (only in cases that might
5590 be the type name of a compound literal).
5592 type-name:
5593 specifier-qualifier-list abstract-declarator[opt]
5596 struct c_type_name *
5597 c_parser_type_name (c_parser *parser, bool alignas_ok)
5599 struct c_declspecs *specs = build_null_declspecs ();
5600 struct c_declarator *declarator;
5601 struct c_type_name *ret;
5602 bool dummy = false;
5603 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5604 false, true, cla_prefer_type);
5605 if (!specs->declspecs_seen_p)
5607 c_parser_error (parser, "expected specifier-qualifier-list");
5608 return NULL;
5610 if (specs->type != error_mark_node)
5612 pending_xref_error ();
5613 finish_declspecs (specs);
5615 declarator = c_parser_declarator (parser,
5616 specs->typespec_kind != ctsk_none,
5617 C_DTR_ABSTRACT, &dummy);
5618 if (declarator == NULL)
5619 return NULL;
5620 ret = XOBNEW (&parser_obstack, struct c_type_name);
5621 ret->specs = specs;
5622 ret->declarator = declarator;
5623 return ret;
5626 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5628 initializer:
5629 assignment-expression
5630 { initializer-list }
5631 { initializer-list , }
5633 initializer-list:
5634 designation[opt] initializer
5635 initializer-list , designation[opt] initializer
5637 designation:
5638 designator-list =
5640 designator-list:
5641 designator
5642 designator-list designator
5644 designator:
5645 array-designator
5646 . identifier
5648 array-designator:
5649 [ constant-expression ]
5651 GNU extensions:
5653 initializer:
5656 designation:
5657 array-designator
5658 identifier :
5660 array-designator:
5661 [ constant-expression ... constant-expression ]
5663 Any expression without commas is accepted in the syntax for the
5664 constant-expressions, with non-constant expressions rejected later.
5666 DECL is the declaration we're parsing this initializer for.
5668 This function is only used for top-level initializers; for nested
5669 ones, see c_parser_initval. */
5671 static struct c_expr
5672 c_parser_initializer (c_parser *parser, tree decl)
5674 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5675 return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
5676 else
5678 struct c_expr ret;
5679 location_t loc = c_parser_peek_token (parser)->location;
5680 if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
5681 error_at (loc,
5682 "variable-sized object may not be initialized except "
5683 "with an empty initializer");
5684 ret = c_parser_expr_no_commas (parser, NULL);
5685 /* This is handled mostly by gimplify.cc, but we have to deal with
5686 not warning about int x = x; as it is a GCC extension to turn off
5687 this warning but only if warn_init_self is zero. */
5688 if (VAR_P (decl)
5689 && !DECL_EXTERNAL (decl)
5690 && !TREE_STATIC (decl)
5691 && ret.value == decl
5692 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl), OPT_Winit_self))
5693 suppress_warning (decl, OPT_Winit_self);
5694 if (TREE_CODE (ret.value) != STRING_CST
5695 && (TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR
5696 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
5697 (ret.value))))
5698 ret = convert_lvalue_to_rvalue (loc, ret, true, true, true);
5699 return ret;
5703 /* The location of the last comma within the current initializer list,
5704 or UNKNOWN_LOCATION if not within one. */
5706 location_t last_init_list_comma;
5708 /* Parse a braced initializer list. TYPE is the type specified for a
5709 compound literal, and NULL_TREE for other initializers and for
5710 nested braced lists. NESTED_P is true for nested braced lists,
5711 false for the list of a compound literal or the list that is the
5712 top-level initializer in a declaration. DECL is the declaration for
5713 the top-level initializer for a declaration, otherwise NULL_TREE. */
5715 static struct c_expr
5716 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5717 struct obstack *outer_obstack, tree decl)
5719 struct c_expr ret;
5720 struct obstack braced_init_obstack;
5721 location_t brace_loc = c_parser_peek_token (parser)->location;
5722 gcc_obstack_init (&braced_init_obstack);
5723 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5724 matching_braces braces;
5725 braces.consume_open (parser);
5726 if (nested_p)
5728 finish_implicit_inits (brace_loc, outer_obstack);
5729 push_init_level (brace_loc, 0, &braced_init_obstack);
5731 else
5732 really_start_incremental_init (type);
5733 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5735 pedwarn_c11 (brace_loc, OPT_Wpedantic,
5736 "ISO C forbids empty initializer braces before C2X");
5738 else
5740 if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
5741 error_at (brace_loc,
5742 "variable-sized object may not be initialized except "
5743 "with an empty initializer");
5744 /* Parse a non-empty initializer list, possibly with a trailing
5745 comma. */
5746 while (true)
5748 c_parser_initelt (parser, &braced_init_obstack);
5749 if (parser->error)
5750 break;
5751 if (c_parser_next_token_is (parser, CPP_COMMA))
5753 last_init_list_comma = c_parser_peek_token (parser)->location;
5754 c_parser_consume_token (parser);
5756 else
5757 break;
5758 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5759 break;
5762 c_token *next_tok = c_parser_peek_token (parser);
5763 if (next_tok->type != CPP_CLOSE_BRACE)
5765 ret.set_error ();
5766 ret.original_code = ERROR_MARK;
5767 ret.original_type = NULL;
5768 braces.skip_until_found_close (parser);
5769 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5770 obstack_free (&braced_init_obstack, NULL);
5771 return ret;
5773 location_t close_loc = next_tok->location;
5774 c_parser_consume_token (parser);
5775 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5776 obstack_free (&braced_init_obstack, NULL);
5777 set_c_expr_source_range (&ret, brace_loc, close_loc);
5778 return ret;
5781 /* Parse a nested initializer, including designators. */
5783 static void
5784 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5786 /* Parse any designator or designator list. A single array
5787 designator may have the subsequent "=" omitted in GNU C, but a
5788 longer list or a structure member designator may not. */
5789 if (c_parser_next_token_is (parser, CPP_NAME)
5790 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5792 /* Old-style structure member designator. */
5793 set_init_label (c_parser_peek_token (parser)->location,
5794 c_parser_peek_token (parser)->value,
5795 c_parser_peek_token (parser)->location,
5796 braced_init_obstack);
5797 /* Use the colon as the error location. */
5798 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5799 "obsolete use of designated initializer with %<:%>");
5800 c_parser_consume_token (parser);
5801 c_parser_consume_token (parser);
5803 else
5805 /* des_seen is 0 if there have been no designators, 1 if there
5806 has been a single array designator and 2 otherwise. */
5807 int des_seen = 0;
5808 /* Location of a designator. */
5809 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5810 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5811 || c_parser_next_token_is (parser, CPP_DOT))
5813 int des_prev = des_seen;
5814 if (!des_seen)
5815 des_loc = c_parser_peek_token (parser)->location;
5816 if (des_seen < 2)
5817 des_seen++;
5818 if (c_parser_next_token_is (parser, CPP_DOT))
5820 des_seen = 2;
5821 c_parser_consume_token (parser);
5822 if (c_parser_next_token_is (parser, CPP_NAME))
5824 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5825 c_parser_peek_token (parser)->location,
5826 braced_init_obstack);
5827 c_parser_consume_token (parser);
5829 else
5831 struct c_expr init;
5832 init.set_error ();
5833 init.original_code = ERROR_MARK;
5834 init.original_type = NULL;
5835 c_parser_error (parser, "expected identifier");
5836 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5837 process_init_element (input_location, init, false,
5838 braced_init_obstack);
5839 return;
5842 else
5844 struct c_expr first_expr;
5845 tree first, second;
5846 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5847 location_t array_index_loc = UNKNOWN_LOCATION;
5848 /* ??? Following the old parser, [ objc-receiver
5849 objc-message-args ] is accepted as an initializer,
5850 being distinguished from a designator by what follows
5851 the first assignment expression inside the square
5852 brackets, but after a first array designator a
5853 subsequent square bracket is for Objective-C taken to
5854 start an expression, using the obsolete form of
5855 designated initializer without '=', rather than
5856 possibly being a second level of designation: in LALR
5857 terms, the '[' is shifted rather than reducing
5858 designator to designator-list. */
5859 if (des_prev == 1 && c_dialect_objc ())
5861 des_seen = des_prev;
5862 break;
5864 if (des_prev == 0 && c_dialect_objc ())
5866 /* This might be an array designator or an
5867 Objective-C message expression. If the former,
5868 continue parsing here; if the latter, parse the
5869 remainder of the initializer given the starting
5870 primary-expression. ??? It might make sense to
5871 distinguish when des_prev == 1 as well; see
5872 previous comment. */
5873 tree rec, args;
5874 struct c_expr mexpr;
5875 c_parser_consume_token (parser);
5876 if (c_parser_peek_token (parser)->type == CPP_NAME
5877 && ((c_parser_peek_token (parser)->id_kind
5878 == C_ID_TYPENAME)
5879 || (c_parser_peek_token (parser)->id_kind
5880 == C_ID_CLASSNAME)))
5882 /* Type name receiver. */
5883 tree id = c_parser_peek_token (parser)->value;
5884 c_parser_consume_token (parser);
5885 rec = objc_get_class_reference (id);
5886 goto parse_message_args;
5888 array_index_loc = c_parser_peek_token (parser)->location;
5889 first_expr = c_parser_expr_no_commas (parser, NULL);
5890 mark_exp_read (first_expr.value);
5891 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5892 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5893 goto array_desig_after_first;
5894 first = first_expr.value;
5895 /* Expression receiver. So far only one part
5896 without commas has been parsed; there might be
5897 more of the expression. */
5898 rec = first;
5899 while (c_parser_next_token_is (parser, CPP_COMMA))
5901 struct c_expr next;
5902 location_t comma_loc, exp_loc;
5903 comma_loc = c_parser_peek_token (parser)->location;
5904 c_parser_consume_token (parser);
5905 exp_loc = c_parser_peek_token (parser)->location;
5906 next = c_parser_expr_no_commas (parser, NULL);
5907 next = convert_lvalue_to_rvalue (exp_loc, next,
5908 true, true);
5909 rec = build_compound_expr (comma_loc, rec, next.value);
5911 parse_message_args:
5912 /* Now parse the objc-message-args. */
5913 args = c_parser_objc_message_args (parser);
5914 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5915 "expected %<]%>");
5916 mexpr.value
5917 = objc_build_message_expr (rec, args);
5918 mexpr.original_code = ERROR_MARK;
5919 mexpr.original_type = NULL;
5920 mexpr.m_decimal = 0;
5921 /* Now parse and process the remainder of the
5922 initializer, starting with this message
5923 expression as a primary-expression. */
5924 c_parser_initval (parser, &mexpr, braced_init_obstack);
5925 return;
5927 c_parser_consume_token (parser);
5928 array_index_loc = c_parser_peek_token (parser)->location;
5929 first_expr = c_parser_expr_no_commas (parser, NULL);
5930 mark_exp_read (first_expr.value);
5931 array_desig_after_first:
5932 first_expr = convert_lvalue_to_rvalue (array_index_loc,
5933 first_expr,
5934 true, true);
5935 first = first_expr.value;
5936 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5938 ellipsis_loc = c_parser_peek_token (parser)->location;
5939 c_parser_consume_token (parser);
5940 second = convert_lvalue_to_rvalue (ellipsis_loc,
5941 (c_parser_expr_no_commas
5942 (parser, NULL)),
5943 true, true).value;
5944 mark_exp_read (second);
5946 else
5947 second = NULL_TREE;
5948 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5950 c_parser_consume_token (parser);
5951 set_init_index (array_index_loc, first, second,
5952 braced_init_obstack);
5953 if (second)
5954 pedwarn (ellipsis_loc, OPT_Wpedantic,
5955 "ISO C forbids specifying range of elements to initialize");
5957 else
5958 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5959 "expected %<]%>");
5962 if (des_seen >= 1)
5964 if (c_parser_next_token_is (parser, CPP_EQ))
5966 pedwarn_c90 (des_loc, OPT_Wpedantic,
5967 "ISO C90 forbids specifying subobject "
5968 "to initialize");
5969 c_parser_consume_token (parser);
5971 else
5973 if (des_seen == 1)
5974 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5975 "obsolete use of designated initializer without %<=%>");
5976 else
5978 struct c_expr init;
5979 init.set_error ();
5980 init.original_code = ERROR_MARK;
5981 init.original_type = NULL;
5982 c_parser_error (parser, "expected %<=%>");
5983 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5984 process_init_element (input_location, init, false,
5985 braced_init_obstack);
5986 return;
5991 c_parser_initval (parser, NULL, braced_init_obstack);
5994 /* Parse a nested initializer; as c_parser_initializer but parses
5995 initializers within braced lists, after any designators have been
5996 applied. If AFTER is not NULL then it is an Objective-C message
5997 expression which is the primary-expression starting the
5998 initializer. */
6000 static void
6001 c_parser_initval (c_parser *parser, struct c_expr *after,
6002 struct obstack * braced_init_obstack)
6004 struct c_expr init;
6005 gcc_assert (!after || c_dialect_objc ());
6006 location_t loc = c_parser_peek_token (parser)->location;
6008 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
6009 init = c_parser_braced_init (parser, NULL_TREE, true,
6010 braced_init_obstack, NULL_TREE);
6011 else
6013 init = c_parser_expr_no_commas (parser, after);
6014 if (init.value != NULL_TREE
6015 && TREE_CODE (init.value) != STRING_CST
6016 && (TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR
6017 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6018 (init.value))))
6019 init = convert_lvalue_to_rvalue (loc, init, true, true, true);
6021 process_init_element (loc, init, false, braced_init_obstack);
6024 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6025 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
6027 compound-statement:
6028 { block-item-list[opt] }
6029 { label-declarations block-item-list }
6031 block-item-list:
6032 block-item
6033 block-item-list block-item
6035 block-item:
6036 label
6037 nested-declaration
6038 statement
6040 nested-declaration:
6041 declaration
6043 GNU extensions:
6045 compound-statement:
6046 { label-declarations block-item-list }
6048 nested-declaration:
6049 __extension__ nested-declaration
6050 nested-function-definition
6052 label-declarations:
6053 label-declaration
6054 label-declarations label-declaration
6056 label-declaration:
6057 __label__ identifier-list ;
6059 Allowing the mixing of declarations and code is new in C99. The
6060 GNU syntax also permits (not shown above) labels at the end of
6061 compound statements, which yield an error. We don't allow labels
6062 on declarations; this might seem like a natural extension, but
6063 there would be a conflict between gnu-attributes on the label and
6064 prefix gnu-attributes on the declaration. ??? The syntax follows the
6065 old parser in requiring something after label declarations.
6066 Although they are erroneous if the labels declared aren't defined,
6067 is it useful for the syntax to be this way?
6069 OpenACC:
6071 block-item:
6072 openacc-directive
6074 openacc-directive:
6075 update-directive
6077 OpenMP:
6079 block-item:
6080 openmp-directive
6082 openmp-directive:
6083 barrier-directive
6084 flush-directive
6085 taskwait-directive
6086 taskyield-directive
6087 cancel-directive
6088 cancellation-point-directive */
6090 static tree
6091 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
6093 tree stmt;
6094 location_t brace_loc;
6095 brace_loc = c_parser_peek_token (parser)->location;
6096 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
6098 /* Ensure a scope is entered and left anyway to avoid confusion
6099 if we have just prepared to enter a function body. */
6100 stmt = c_begin_compound_stmt (true);
6101 c_end_compound_stmt (brace_loc, stmt, true);
6102 return error_mark_node;
6104 stmt = c_begin_compound_stmt (true);
6105 location_t end_loc = c_parser_compound_statement_nostart (parser);
6106 if (endlocp)
6107 *endlocp = end_loc;
6109 return c_end_compound_stmt (brace_loc, stmt, true);
6112 /* Parse a compound statement except for the opening brace. This is
6113 used for parsing both compound statements and statement expressions
6114 (which follow different paths to handling the opening). */
6116 static location_t
6117 c_parser_compound_statement_nostart (c_parser *parser)
6119 bool last_stmt = false;
6120 bool last_label = false;
6121 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
6122 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
6123 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6125 location_t endloc = c_parser_peek_token (parser)->location;
6126 add_debug_begin_stmt (endloc);
6127 c_parser_consume_token (parser);
6128 return endloc;
6130 mark_valid_location_for_stdc_pragma (true);
6131 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
6133 /* Read zero or more forward-declarations for labels that nested
6134 functions can jump to. */
6135 mark_valid_location_for_stdc_pragma (false);
6136 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
6138 label_loc = c_parser_peek_token (parser)->location;
6139 c_parser_consume_token (parser);
6140 /* Any identifiers, including those declared as type names,
6141 are OK here. */
6142 while (true)
6144 tree label;
6145 if (c_parser_next_token_is_not (parser, CPP_NAME))
6147 c_parser_error (parser, "expected identifier");
6148 break;
6150 label
6151 = declare_label (c_parser_peek_token (parser)->value);
6152 C_DECLARED_LABEL_FLAG (label) = 1;
6153 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
6154 c_parser_consume_token (parser);
6155 if (c_parser_next_token_is (parser, CPP_COMMA))
6156 c_parser_consume_token (parser);
6157 else
6158 break;
6160 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6162 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
6164 /* We must now have at least one statement, label or declaration. */
6165 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6167 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
6168 c_parser_error (parser, "expected declaration or statement");
6169 location_t endloc = c_parser_peek_token (parser)->location;
6170 c_parser_consume_token (parser);
6171 return endloc;
6173 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
6175 location_t loc = c_parser_peek_token (parser)->location;
6176 loc = expansion_point_location_if_in_system_header (loc);
6177 /* Standard attributes may start a label, statement or declaration. */
6178 bool have_std_attrs
6179 = c_parser_nth_token_starts_std_attributes (parser, 1);
6180 tree std_attrs = NULL_TREE;
6181 if (have_std_attrs)
6182 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
6183 if (c_parser_next_token_is_keyword (parser, RID_CASE)
6184 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
6185 || (c_parser_next_token_is (parser, CPP_NAME)
6186 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
6188 if (c_parser_next_token_is_keyword (parser, RID_CASE))
6189 label_loc = c_parser_peek_2nd_token (parser)->location;
6190 else
6191 label_loc = c_parser_peek_token (parser)->location;
6192 last_label = true;
6193 last_stmt = false;
6194 mark_valid_location_for_stdc_pragma (false);
6195 c_parser_label (parser, std_attrs);
6197 else if (c_parser_next_tokens_start_declaration (parser)
6198 || (have_std_attrs
6199 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
6201 if (last_label)
6202 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
6203 "a label can only be part of a statement and "
6204 "a declaration is not a statement");
6206 mark_valid_location_for_stdc_pragma (false);
6207 bool fallthru_attr_p = false;
6208 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
6209 true, true, true, NULL,
6210 NULL, have_std_attrs, std_attrs,
6211 NULL, &fallthru_attr_p);
6213 if (last_stmt && !fallthru_attr_p)
6214 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
6215 "ISO C90 forbids mixed declarations and code");
6216 last_stmt = fallthru_attr_p;
6217 last_label = false;
6219 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6221 /* __extension__ can start a declaration, but is also an
6222 unary operator that can start an expression. Consume all
6223 but the last of a possible series of __extension__ to
6224 determine which. If standard attributes have already
6225 been seen, it must start a statement, not a declaration,
6226 but standard attributes starting a declaration may appear
6227 after __extension__. */
6228 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6229 && (c_parser_peek_2nd_token (parser)->keyword
6230 == RID_EXTENSION))
6231 c_parser_consume_token (parser);
6232 if (!have_std_attrs
6233 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6234 || c_parser_nth_token_starts_std_attributes (parser, 2)))
6236 int ext;
6237 ext = disable_extension_diagnostics ();
6238 c_parser_consume_token (parser);
6239 last_label = false;
6240 mark_valid_location_for_stdc_pragma (false);
6241 c_parser_declaration_or_fndef (parser, true, true, true, true,
6242 true);
6243 /* Following the old parser, __extension__ does not
6244 disable this diagnostic. */
6245 restore_extension_diagnostics (ext);
6246 if (last_stmt)
6247 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
6248 "ISO C90 forbids mixed declarations and code");
6249 last_stmt = false;
6251 else
6252 goto statement;
6254 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
6256 if (have_std_attrs)
6257 c_parser_error (parser, "expected declaration or statement");
6258 /* External pragmas, and some omp pragmas, are not associated
6259 with regular c code, and so are not to be considered statements
6260 syntactically. This ensures that the user doesn't put them
6261 places that would turn into syntax errors if the directive
6262 were ignored. */
6263 if (c_parser_pragma (parser,
6264 last_label ? pragma_stmt : pragma_compound,
6265 NULL))
6266 last_label = false, last_stmt = true;
6268 else if (c_parser_next_token_is (parser, CPP_EOF))
6270 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
6271 c_parser_error (parser, "expected declaration or statement");
6272 return c_parser_peek_token (parser)->location;
6274 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6276 if (parser->in_if_block)
6278 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
6279 error_at (loc, "expected %<}%> before %<else%>");
6280 return c_parser_peek_token (parser)->location;
6282 else
6284 error_at (loc, "%<else%> without a previous %<if%>");
6285 c_parser_consume_token (parser);
6286 continue;
6289 else
6291 statement:
6292 c_warn_unused_attributes (std_attrs);
6293 last_label = false;
6294 last_stmt = true;
6295 mark_valid_location_for_stdc_pragma (false);
6296 c_parser_statement_after_labels (parser, NULL);
6299 parser->error = false;
6301 if (last_label)
6302 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
6303 location_t endloc = c_parser_peek_token (parser)->location;
6304 c_parser_consume_token (parser);
6305 /* Restore the value we started with. */
6306 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
6307 return endloc;
6310 /* Parse all consecutive labels, possibly preceded by standard
6311 attributes. In this context, a statement is required, not a
6312 declaration, so attributes must be followed by a statement that is
6313 not just a semicolon. */
6315 static void
6316 c_parser_all_labels (c_parser *parser)
6318 tree std_attrs = NULL;
6319 if (c_parser_nth_token_starts_std_attributes (parser, 1))
6321 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
6322 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6323 c_parser_error (parser, "expected statement");
6325 while (c_parser_next_token_is_keyword (parser, RID_CASE)
6326 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
6327 || (c_parser_next_token_is (parser, CPP_NAME)
6328 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
6330 c_parser_label (parser, std_attrs);
6331 std_attrs = NULL;
6332 if (c_parser_nth_token_starts_std_attributes (parser, 1))
6334 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
6335 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6336 c_parser_error (parser, "expected statement");
6339 if (std_attrs)
6340 c_warn_unused_attributes (std_attrs);
6343 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
6345 label:
6346 identifier : gnu-attributes[opt]
6347 case constant-expression :
6348 default :
6350 GNU extensions:
6352 label:
6353 case constant-expression ... constant-expression :
6355 The use of gnu-attributes on labels is a GNU extension. The syntax in
6356 GNU C accepts any expressions without commas, non-constant
6357 expressions being rejected later. Any standard
6358 attribute-specifier-sequence before the first label has been parsed
6359 in the caller, to distinguish statements from declarations. Any
6360 attribute-specifier-sequence after the label is parsed in this
6361 function. */
6362 static void
6363 c_parser_label (c_parser *parser, tree std_attrs)
6365 location_t loc1 = c_parser_peek_token (parser)->location;
6366 tree label = NULL_TREE;
6368 /* Remember whether this case or a user-defined label is allowed to fall
6369 through to. */
6370 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
6372 if (c_parser_next_token_is_keyword (parser, RID_CASE))
6374 tree exp1, exp2;
6375 c_parser_consume_token (parser);
6376 exp1 = convert_lvalue_to_rvalue (loc1,
6377 c_parser_expr_no_commas (parser, NULL),
6378 true, true).value;
6379 if (c_parser_next_token_is (parser, CPP_COLON))
6381 c_parser_consume_token (parser);
6382 label = do_case (loc1, exp1, NULL_TREE, std_attrs);
6384 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
6386 c_parser_consume_token (parser);
6387 exp2 = convert_lvalue_to_rvalue (loc1,
6388 c_parser_expr_no_commas (parser,
6389 NULL),
6390 true, true).value;
6391 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
6392 label = do_case (loc1, exp1, exp2, std_attrs);
6394 else
6395 c_parser_error (parser, "expected %<:%> or %<...%>");
6397 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
6399 c_parser_consume_token (parser);
6400 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
6401 label = do_case (loc1, NULL_TREE, NULL_TREE, std_attrs);
6403 else
6405 tree name = c_parser_peek_token (parser)->value;
6406 tree tlab;
6407 tree attrs;
6408 location_t loc2 = c_parser_peek_token (parser)->location;
6409 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
6410 c_parser_consume_token (parser);
6411 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
6412 c_parser_consume_token (parser);
6413 attrs = c_parser_gnu_attributes (parser);
6414 tlab = define_label (loc2, name);
6415 if (tlab)
6417 decl_attributes (&tlab, attrs, 0);
6418 decl_attributes (&tlab, std_attrs, 0);
6419 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
6421 if (attrs
6422 && c_parser_next_tokens_start_declaration (parser))
6423 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
6424 " label and declaration appertains to the label");
6426 if (label)
6428 if (TREE_CODE (label) == LABEL_EXPR)
6429 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
6430 else
6431 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
6435 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
6437 statement:
6438 labeled-statement
6439 attribute-specifier-sequence[opt] compound-statement
6440 expression-statement
6441 attribute-specifier-sequence[opt] selection-statement
6442 attribute-specifier-sequence[opt] iteration-statement
6443 attribute-specifier-sequence[opt] jump-statement
6445 labeled-statement:
6446 attribute-specifier-sequence[opt] label statement
6448 expression-statement:
6449 expression[opt] ;
6450 attribute-specifier-sequence expression ;
6452 selection-statement:
6453 if-statement
6454 switch-statement
6456 iteration-statement:
6457 while-statement
6458 do-statement
6459 for-statement
6461 jump-statement:
6462 goto identifier ;
6463 continue ;
6464 break ;
6465 return expression[opt] ;
6467 GNU extensions:
6469 statement:
6470 attribute-specifier-sequence[opt] asm-statement
6472 jump-statement:
6473 goto * expression ;
6475 expression-statement:
6476 gnu-attributes ;
6478 Objective-C:
6480 statement:
6481 attribute-specifier-sequence[opt] objc-throw-statement
6482 attribute-specifier-sequence[opt] objc-try-catch-statement
6483 attribute-specifier-sequence[opt] objc-synchronized-statement
6485 objc-throw-statement:
6486 @throw expression ;
6487 @throw ;
6489 OpenACC:
6491 statement:
6492 attribute-specifier-sequence[opt] openacc-construct
6494 openacc-construct:
6495 parallel-construct
6496 kernels-construct
6497 data-construct
6498 loop-construct
6500 parallel-construct:
6501 parallel-directive structured-block
6503 kernels-construct:
6504 kernels-directive structured-block
6506 data-construct:
6507 data-directive structured-block
6509 loop-construct:
6510 loop-directive structured-block
6512 OpenMP:
6514 statement:
6515 attribute-specifier-sequence[opt] openmp-construct
6517 openmp-construct:
6518 parallel-construct
6519 for-construct
6520 simd-construct
6521 for-simd-construct
6522 sections-construct
6523 single-construct
6524 parallel-for-construct
6525 parallel-for-simd-construct
6526 parallel-sections-construct
6527 master-construct
6528 critical-construct
6529 atomic-construct
6530 ordered-construct
6532 parallel-construct:
6533 parallel-directive structured-block
6535 for-construct:
6536 for-directive iteration-statement
6538 simd-construct:
6539 simd-directive iteration-statements
6541 for-simd-construct:
6542 for-simd-directive iteration-statements
6544 sections-construct:
6545 sections-directive section-scope
6547 single-construct:
6548 single-directive structured-block
6550 parallel-for-construct:
6551 parallel-for-directive iteration-statement
6553 parallel-for-simd-construct:
6554 parallel-for-simd-directive iteration-statement
6556 parallel-sections-construct:
6557 parallel-sections-directive section-scope
6559 master-construct:
6560 master-directive structured-block
6562 critical-construct:
6563 critical-directive structured-block
6565 atomic-construct:
6566 atomic-directive expression-statement
6568 ordered-construct:
6569 ordered-directive structured-block
6571 Transactional Memory:
6573 statement:
6574 attribute-specifier-sequence[opt] transaction-statement
6575 attribute-specifier-sequence[opt] transaction-cancel-statement
6577 IF_P is used to track whether there's a (possibly labeled) if statement
6578 which is not enclosed in braces and has an else clause. This is used to
6579 implement -Wparentheses. */
6581 static void
6582 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6584 c_parser_all_labels (parser);
6585 if (loc_after_labels)
6586 *loc_after_labels = c_parser_peek_token (parser)->location;
6587 c_parser_statement_after_labels (parser, if_p, NULL);
6590 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6591 of if-else-if conditions. All labels and standard attributes have
6592 been parsed in the caller.
6594 IF_P is used to track whether there's a (possibly labeled) if statement
6595 which is not enclosed in braces and has an else clause. This is used to
6596 implement -Wparentheses. */
6598 static void
6599 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6600 vec<tree> *chain)
6602 location_t loc = c_parser_peek_token (parser)->location;
6603 tree stmt = NULL_TREE;
6604 bool in_if_block = parser->in_if_block;
6605 parser->in_if_block = false;
6606 if (if_p != NULL)
6607 *if_p = false;
6609 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6610 add_debug_begin_stmt (loc);
6612 restart:
6613 switch (c_parser_peek_token (parser)->type)
6615 case CPP_OPEN_BRACE:
6616 add_stmt (c_parser_compound_statement (parser));
6617 break;
6618 case CPP_KEYWORD:
6619 switch (c_parser_peek_token (parser)->keyword)
6621 case RID_IF:
6622 c_parser_if_statement (parser, if_p, chain);
6623 break;
6624 case RID_SWITCH:
6625 c_parser_switch_statement (parser, if_p);
6626 break;
6627 case RID_WHILE:
6628 c_parser_while_statement (parser, false, 0, if_p);
6629 break;
6630 case RID_DO:
6631 c_parser_do_statement (parser, false, 0);
6632 break;
6633 case RID_FOR:
6634 c_parser_for_statement (parser, false, 0, if_p);
6635 break;
6636 case RID_GOTO:
6637 c_parser_consume_token (parser);
6638 if (c_parser_next_token_is (parser, CPP_NAME))
6640 stmt = c_finish_goto_label (loc,
6641 c_parser_peek_token (parser)->value);
6642 c_parser_consume_token (parser);
6644 else if (c_parser_next_token_is (parser, CPP_MULT))
6646 struct c_expr val;
6648 c_parser_consume_token (parser);
6649 val = c_parser_expression (parser);
6650 val = convert_lvalue_to_rvalue (loc, val, false, true);
6651 stmt = c_finish_goto_ptr (loc, val);
6653 else
6654 c_parser_error (parser, "expected identifier or %<*%>");
6655 goto expect_semicolon;
6656 case RID_CONTINUE:
6657 c_parser_consume_token (parser);
6658 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6659 goto expect_semicolon;
6660 case RID_BREAK:
6661 c_parser_consume_token (parser);
6662 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6663 goto expect_semicolon;
6664 case RID_RETURN:
6665 c_parser_consume_token (parser);
6666 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6668 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6669 c_parser_consume_token (parser);
6671 else
6673 location_t xloc = c_parser_peek_token (parser)->location;
6674 struct c_expr expr = c_parser_expression_conv (parser);
6675 mark_exp_read (expr.value);
6676 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6677 expr.value, expr.original_type);
6678 goto expect_semicolon;
6680 break;
6681 case RID_ASM:
6682 stmt = c_parser_asm_statement (parser);
6683 break;
6684 case RID_TRANSACTION_ATOMIC:
6685 case RID_TRANSACTION_RELAXED:
6686 stmt = c_parser_transaction (parser,
6687 c_parser_peek_token (parser)->keyword);
6688 break;
6689 case RID_TRANSACTION_CANCEL:
6690 stmt = c_parser_transaction_cancel (parser);
6691 goto expect_semicolon;
6692 case RID_AT_THROW:
6693 gcc_assert (c_dialect_objc ());
6694 c_parser_consume_token (parser);
6695 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6697 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6698 c_parser_consume_token (parser);
6700 else
6702 struct c_expr expr = c_parser_expression (parser);
6703 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6704 expr.value = c_fully_fold (expr.value, false, NULL);
6705 stmt = objc_build_throw_stmt (loc, expr.value);
6706 goto expect_semicolon;
6708 break;
6709 case RID_AT_TRY:
6710 gcc_assert (c_dialect_objc ());
6711 c_parser_objc_try_catch_finally_statement (parser);
6712 break;
6713 case RID_AT_SYNCHRONIZED:
6714 gcc_assert (c_dialect_objc ());
6715 c_parser_objc_synchronized_statement (parser);
6716 break;
6717 case RID_ATTRIBUTE:
6719 /* Allow '__attribute__((fallthrough));' or
6720 '__attribute__((assume(cond)));'. */
6721 tree attrs = c_parser_gnu_attributes (parser);
6722 bool has_assume = lookup_attribute ("assume", attrs);
6723 if (has_assume)
6725 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6726 attrs = handle_assume_attribute (loc, attrs, true);
6727 else
6729 warning_at (loc, OPT_Wattributes,
6730 "%<assume%> attribute not followed by %<;%>");
6731 has_assume = false;
6734 if (attribute_fallthrough_p (attrs))
6736 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6738 tree fn = build_call_expr_internal_loc (loc,
6739 IFN_FALLTHROUGH,
6740 void_type_node, 0);
6741 add_stmt (fn);
6742 /* Eat the ';'. */
6743 c_parser_consume_token (parser);
6745 else
6746 warning_at (loc, OPT_Wattributes,
6747 "%<fallthrough%> attribute not followed "
6748 "by %<;%>");
6750 else if (has_assume)
6751 /* Eat the ';'. */
6752 c_parser_consume_token (parser);
6753 else if (attrs != NULL_TREE)
6754 warning_at (loc, OPT_Wattributes,
6755 "only attribute %<fallthrough%> or %<assume%> can "
6756 "be applied to a null statement");
6757 break;
6759 default:
6760 goto expr_stmt;
6762 break;
6763 case CPP_SEMICOLON:
6764 c_parser_consume_token (parser);
6765 break;
6766 case CPP_CLOSE_PAREN:
6767 case CPP_CLOSE_SQUARE:
6768 /* Avoid infinite loop in error recovery:
6769 c_parser_skip_until_found stops at a closing nesting
6770 delimiter without consuming it, but here we need to consume
6771 it to proceed further. */
6772 c_parser_error (parser, "expected statement");
6773 c_parser_consume_token (parser);
6774 break;
6775 case CPP_PRAGMA:
6776 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6777 goto restart;
6778 break;
6779 default:
6780 expr_stmt:
6781 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6782 expect_semicolon:
6783 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6784 break;
6786 /* Two cases cannot and do not have line numbers associated: If stmt
6787 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6788 cannot hold line numbers. But that's OK because the statement
6789 will either be changed to a MODIFY_EXPR during gimplification of
6790 the statement expr, or discarded. If stmt was compound, but
6791 without new variables, we will have skipped the creation of a
6792 BIND and will have a bare STATEMENT_LIST. But that's OK because
6793 (recursively) all of the component statements should already have
6794 line numbers assigned. ??? Can we discard no-op statements
6795 earlier? */
6796 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6797 protected_set_expr_location (stmt, loc);
6799 parser->in_if_block = in_if_block;
6802 /* Parse the condition from an if, do, while or for statements. */
6804 static tree
6805 c_parser_condition (c_parser *parser)
6807 location_t loc = c_parser_peek_token (parser)->location;
6808 tree cond;
6809 cond = c_parser_expression_conv (parser).value;
6810 cond = c_objc_common_truthvalue_conversion (loc, cond);
6811 cond = c_fully_fold (cond, false, NULL);
6812 if (warn_sequence_point)
6813 verify_sequence_points (cond);
6814 return cond;
6817 /* Parse a parenthesized condition from an if, do or while statement.
6819 condition:
6820 ( expression )
6822 static tree
6823 c_parser_paren_condition (c_parser *parser)
6825 tree cond;
6826 matching_parens parens;
6827 if (!parens.require_open (parser))
6828 return error_mark_node;
6829 cond = c_parser_condition (parser);
6830 parens.skip_until_found_close (parser);
6831 return cond;
6834 /* Parse a statement which is a block in C99.
6836 IF_P is used to track whether there's a (possibly labeled) if statement
6837 which is not enclosed in braces and has an else clause. This is used to
6838 implement -Wparentheses. */
6840 static tree
6841 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6842 location_t *loc_after_labels)
6844 tree block = c_begin_compound_stmt (flag_isoc99);
6845 location_t loc = c_parser_peek_token (parser)->location;
6846 c_parser_statement (parser, if_p, loc_after_labels);
6847 return c_end_compound_stmt (loc, block, flag_isoc99);
6850 /* Parse the body of an if statement. This is just parsing a
6851 statement but (a) it is a block in C99, (b) we track whether the
6852 body is an if statement for the sake of -Wparentheses warnings, (c)
6853 we handle an empty body specially for the sake of -Wempty-body
6854 warnings, and (d) we call parser_compound_statement directly
6855 because c_parser_statement_after_labels resets
6856 parser->in_if_block.
6858 IF_P is used to track whether there's a (possibly labeled) if statement
6859 which is not enclosed in braces and has an else clause. This is used to
6860 implement -Wparentheses. */
6862 static tree
6863 c_parser_if_body (c_parser *parser, bool *if_p,
6864 const token_indent_info &if_tinfo)
6866 tree block = c_begin_compound_stmt (flag_isoc99);
6867 location_t body_loc = c_parser_peek_token (parser)->location;
6868 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6869 token_indent_info body_tinfo
6870 = get_token_indent_info (c_parser_peek_token (parser));
6872 c_parser_all_labels (parser);
6873 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6875 location_t loc = c_parser_peek_token (parser)->location;
6876 add_stmt (build_empty_stmt (loc));
6877 c_parser_consume_token (parser);
6878 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6879 warning_at (loc, OPT_Wempty_body,
6880 "suggest braces around empty body in an %<if%> statement");
6882 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6883 add_stmt (c_parser_compound_statement (parser));
6884 else
6886 body_loc_after_labels = c_parser_peek_token (parser)->location;
6887 c_parser_statement_after_labels (parser, if_p);
6890 token_indent_info next_tinfo
6891 = get_token_indent_info (c_parser_peek_token (parser));
6892 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6893 if (body_loc_after_labels != UNKNOWN_LOCATION
6894 && next_tinfo.type != CPP_SEMICOLON)
6895 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6896 if_tinfo.location, RID_IF);
6898 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6901 /* Parse the else body of an if statement. This is just parsing a
6902 statement but (a) it is a block in C99, (b) we handle an empty body
6903 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6904 of if-else-if conditions. */
6906 static tree
6907 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6908 vec<tree> *chain)
6910 location_t body_loc = c_parser_peek_token (parser)->location;
6911 tree block = c_begin_compound_stmt (flag_isoc99);
6912 token_indent_info body_tinfo
6913 = get_token_indent_info (c_parser_peek_token (parser));
6914 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6916 c_parser_all_labels (parser);
6917 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6919 location_t loc = c_parser_peek_token (parser)->location;
6920 warning_at (loc,
6921 OPT_Wempty_body,
6922 "suggest braces around empty body in an %<else%> statement");
6923 add_stmt (build_empty_stmt (loc));
6924 c_parser_consume_token (parser);
6926 else
6928 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6929 body_loc_after_labels = c_parser_peek_token (parser)->location;
6930 c_parser_statement_after_labels (parser, NULL, chain);
6933 token_indent_info next_tinfo
6934 = get_token_indent_info (c_parser_peek_token (parser));
6935 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6936 if (body_loc_after_labels != UNKNOWN_LOCATION
6937 && next_tinfo.type != CPP_SEMICOLON)
6938 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6939 else_tinfo.location, RID_ELSE);
6941 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6944 /* We might need to reclassify any previously-lexed identifier, e.g.
6945 when we've left a for loop with an if-statement without else in the
6946 body - we might have used a wrong scope for the token. See PR67784. */
6948 static void
6949 c_parser_maybe_reclassify_token (c_parser *parser)
6951 if (c_parser_next_token_is (parser, CPP_NAME))
6953 c_token *token = c_parser_peek_token (parser);
6955 if (token->id_kind != C_ID_CLASSNAME)
6957 tree decl = lookup_name (token->value);
6959 token->id_kind = C_ID_ID;
6960 if (decl)
6962 if (TREE_CODE (decl) == TYPE_DECL)
6963 token->id_kind = C_ID_TYPENAME;
6965 else if (c_dialect_objc ())
6967 tree objc_interface_decl = objc_is_class_name (token->value);
6968 /* Objective-C class names are in the same namespace as
6969 variables and typedefs, and hence are shadowed by local
6970 declarations. */
6971 if (objc_interface_decl)
6973 token->value = objc_interface_decl;
6974 token->id_kind = C_ID_CLASSNAME;
6981 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6983 if-statement:
6984 if ( expression ) statement
6985 if ( expression ) statement else statement
6987 CHAIN is a vector of if-else-if conditions.
6988 IF_P is used to track whether there's a (possibly labeled) if statement
6989 which is not enclosed in braces and has an else clause. This is used to
6990 implement -Wparentheses. */
6992 static void
6993 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6995 tree block;
6996 location_t loc;
6997 tree cond;
6998 bool nested_if = false;
6999 tree first_body, second_body;
7000 bool in_if_block;
7002 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
7003 token_indent_info if_tinfo
7004 = get_token_indent_info (c_parser_peek_token (parser));
7005 c_parser_consume_token (parser);
7006 block = c_begin_compound_stmt (flag_isoc99);
7007 loc = c_parser_peek_token (parser)->location;
7008 cond = c_parser_paren_condition (parser);
7009 in_if_block = parser->in_if_block;
7010 parser->in_if_block = true;
7011 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
7012 parser->in_if_block = in_if_block;
7014 if (warn_duplicated_cond)
7015 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
7017 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
7019 token_indent_info else_tinfo
7020 = get_token_indent_info (c_parser_peek_token (parser));
7021 c_parser_consume_token (parser);
7022 if (warn_duplicated_cond)
7024 if (c_parser_next_token_is_keyword (parser, RID_IF)
7025 && chain == NULL)
7027 /* We've got "if (COND) else if (COND2)". Start the
7028 condition chain and add COND as the first element. */
7029 chain = new vec<tree> ();
7030 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
7031 chain->safe_push (cond);
7033 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
7034 /* This is if-else without subsequent if. Zap the condition
7035 chain; we would have already warned at this point. */
7036 vec_free (chain);
7038 second_body = c_parser_else_body (parser, else_tinfo, chain);
7039 /* Set IF_P to true to indicate that this if statement has an
7040 else clause. This may trigger the Wparentheses warning
7041 below when we get back up to the parent if statement. */
7042 if (if_p != NULL)
7043 *if_p = true;
7045 else
7047 second_body = NULL_TREE;
7049 /* Diagnose an ambiguous else if if-then-else is nested inside
7050 if-then. */
7051 if (nested_if)
7052 warning_at (loc, OPT_Wdangling_else,
7053 "suggest explicit braces to avoid ambiguous %<else%>");
7055 if (warn_duplicated_cond)
7056 /* This if statement does not have an else clause. We don't
7057 need the condition chain anymore. */
7058 vec_free (chain);
7060 c_finish_if_stmt (loc, cond, first_body, second_body);
7061 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
7063 c_parser_maybe_reclassify_token (parser);
7066 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
7068 switch-statement:
7069 switch (expression) statement
7072 static void
7073 c_parser_switch_statement (c_parser *parser, bool *if_p)
7075 struct c_expr ce;
7076 tree block, expr, body;
7077 unsigned char save_in_statement;
7078 location_t switch_loc = c_parser_peek_token (parser)->location;
7079 location_t switch_cond_loc;
7080 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
7081 c_parser_consume_token (parser);
7082 block = c_begin_compound_stmt (flag_isoc99);
7083 bool explicit_cast_p = false;
7084 matching_parens parens;
7085 if (parens.require_open (parser))
7087 switch_cond_loc = c_parser_peek_token (parser)->location;
7088 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
7089 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
7090 explicit_cast_p = true;
7091 ce = c_parser_expression (parser);
7092 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
7093 expr = ce.value;
7094 /* ??? expr has no valid location? */
7095 parens.skip_until_found_close (parser);
7097 else
7099 switch_cond_loc = UNKNOWN_LOCATION;
7100 expr = error_mark_node;
7101 ce.original_type = error_mark_node;
7103 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
7104 save_in_statement = in_statement;
7105 in_statement |= IN_SWITCH_STMT;
7106 location_t loc_after_labels;
7107 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
7108 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
7109 location_t next_loc = c_parser_peek_token (parser)->location;
7110 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
7111 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
7112 RID_SWITCH);
7113 c_finish_switch (body, ce.original_type);
7114 in_statement = save_in_statement;
7115 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
7116 c_parser_maybe_reclassify_token (parser);
7119 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
7121 while-statement:
7122 while (expression) statement
7124 IF_P is used to track whether there's a (possibly labeled) if statement
7125 which is not enclosed in braces and has an else clause. This is used to
7126 implement -Wparentheses. */
7128 static void
7129 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
7130 bool *if_p)
7132 tree block, cond, body;
7133 unsigned char save_in_statement;
7134 location_t loc;
7135 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
7136 token_indent_info while_tinfo
7137 = get_token_indent_info (c_parser_peek_token (parser));
7138 c_parser_consume_token (parser);
7139 block = c_begin_compound_stmt (flag_isoc99);
7140 loc = c_parser_peek_token (parser)->location;
7141 cond = c_parser_paren_condition (parser);
7142 if (ivdep && cond != error_mark_node)
7143 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
7144 build_int_cst (integer_type_node,
7145 annot_expr_ivdep_kind),
7146 integer_zero_node);
7147 if (unroll && cond != error_mark_node)
7148 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
7149 build_int_cst (integer_type_node,
7150 annot_expr_unroll_kind),
7151 build_int_cst (integer_type_node, unroll));
7152 save_in_statement = in_statement;
7153 in_statement = IN_ITERATION_STMT;
7155 token_indent_info body_tinfo
7156 = get_token_indent_info (c_parser_peek_token (parser));
7158 location_t loc_after_labels;
7159 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
7160 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
7161 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
7162 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
7163 c_parser_maybe_reclassify_token (parser);
7165 token_indent_info next_tinfo
7166 = get_token_indent_info (c_parser_peek_token (parser));
7167 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
7169 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
7170 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7171 while_tinfo.location, RID_WHILE);
7173 in_statement = save_in_statement;
7176 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
7178 do-statement:
7179 do statement while ( expression ) ;
7182 static void
7183 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
7185 tree block, cond, body;
7186 unsigned char save_in_statement;
7187 location_t loc;
7188 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
7189 c_parser_consume_token (parser);
7190 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7191 warning_at (c_parser_peek_token (parser)->location,
7192 OPT_Wempty_body,
7193 "suggest braces around empty body in %<do%> statement");
7194 block = c_begin_compound_stmt (flag_isoc99);
7195 loc = c_parser_peek_token (parser)->location;
7196 save_in_statement = in_statement;
7197 in_statement = IN_ITERATION_STMT;
7198 body = c_parser_c99_block_statement (parser, NULL);
7199 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
7200 in_statement = save_in_statement;
7201 cond = c_parser_paren_condition (parser);
7202 if (ivdep && cond != error_mark_node)
7203 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
7204 build_int_cst (integer_type_node,
7205 annot_expr_ivdep_kind),
7206 integer_zero_node);
7207 if (unroll && cond != error_mark_node)
7208 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
7209 build_int_cst (integer_type_node,
7210 annot_expr_unroll_kind),
7211 build_int_cst (integer_type_node, unroll));
7212 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7213 c_parser_skip_to_end_of_block_or_statement (parser);
7215 add_stmt (build_stmt (loc, DO_STMT, cond, body));
7216 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
7219 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
7221 for-statement:
7222 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
7223 for ( nested-declaration expression[opt] ; expression[opt] ) statement
7225 The form with a declaration is new in C99.
7227 ??? In accordance with the old parser, the declaration may be a
7228 nested function, which is then rejected in check_for_loop_decls,
7229 but does it make any sense for this to be included in the grammar?
7230 Note in particular that the nested function does not include a
7231 trailing ';', whereas the "declaration" production includes one.
7232 Also, can we reject bad declarations earlier and cheaper than
7233 check_for_loop_decls?
7235 In Objective-C, there are two additional variants:
7237 foreach-statement:
7238 for ( expression in expresssion ) statement
7239 for ( declaration in expression ) statement
7241 This is inconsistent with C, because the second variant is allowed
7242 even if c99 is not enabled.
7244 The rest of the comment documents these Objective-C foreach-statement.
7246 Here is the canonical example of the first variant:
7247 for (object in array) { do something with object }
7248 we call the first expression ("object") the "object_expression" and
7249 the second expression ("array") the "collection_expression".
7250 object_expression must be an lvalue of type "id" (a generic Objective-C
7251 object) because the loop works by assigning to object_expression the
7252 various objects from the collection_expression. collection_expression
7253 must evaluate to something of type "id" which responds to the method
7254 countByEnumeratingWithState:objects:count:.
7256 The canonical example of the second variant is:
7257 for (id object in array) { do something with object }
7258 which is completely equivalent to
7260 id object;
7261 for (object in array) { do something with object }
7263 Note that initizializing 'object' in some way (eg, "for ((object =
7264 xxx) in array) { do something with object }") is possibly
7265 technically valid, but completely pointless as 'object' will be
7266 assigned to something else as soon as the loop starts. We should
7267 most likely reject it (TODO).
7269 The beginning of the Objective-C foreach-statement looks exactly
7270 like the beginning of the for-statement, and we can tell it is a
7271 foreach-statement only because the initial declaration or
7272 expression is terminated by 'in' instead of ';'.
7274 IF_P is used to track whether there's a (possibly labeled) if statement
7275 which is not enclosed in braces and has an else clause. This is used to
7276 implement -Wparentheses. */
7278 static void
7279 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
7280 bool *if_p)
7282 tree block, cond, incr, body;
7283 unsigned char save_in_statement;
7284 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
7285 /* The following are only used when parsing an ObjC foreach statement. */
7286 tree object_expression;
7287 /* Silence the bogus uninitialized warning. */
7288 tree collection_expression = NULL;
7289 location_t loc = c_parser_peek_token (parser)->location;
7290 location_t for_loc = loc;
7291 bool is_foreach_statement = false;
7292 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
7293 token_indent_info for_tinfo
7294 = get_token_indent_info (c_parser_peek_token (parser));
7295 c_parser_consume_token (parser);
7296 /* Open a compound statement in Objective-C as well, just in case this is
7297 as foreach expression. */
7298 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
7299 cond = error_mark_node;
7300 incr = error_mark_node;
7301 matching_parens parens;
7302 if (parens.require_open (parser))
7304 /* Parse the initialization declaration or expression. */
7305 object_expression = error_mark_node;
7306 parser->objc_could_be_foreach_context = c_dialect_objc ();
7307 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7309 parser->objc_could_be_foreach_context = false;
7310 c_parser_consume_token (parser);
7311 c_finish_expr_stmt (loc, NULL_TREE);
7313 else if (c_parser_next_tokens_start_declaration (parser)
7314 || c_parser_nth_token_starts_std_attributes (parser, 1))
7316 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
7317 &object_expression);
7318 parser->objc_could_be_foreach_context = false;
7320 if (c_parser_next_token_is_keyword (parser, RID_IN))
7322 c_parser_consume_token (parser);
7323 is_foreach_statement = true;
7324 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
7325 c_parser_error (parser, "multiple iterating variables in "
7326 "fast enumeration");
7328 else
7329 check_for_loop_decls (for_loc, flag_isoc99);
7331 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
7333 /* __extension__ can start a declaration, but is also an
7334 unary operator that can start an expression. Consume all
7335 but the last of a possible series of __extension__ to
7336 determine which. */
7337 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
7338 && (c_parser_peek_2nd_token (parser)->keyword
7339 == RID_EXTENSION))
7340 c_parser_consume_token (parser);
7341 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
7342 || c_parser_nth_token_starts_std_attributes (parser, 2))
7344 int ext;
7345 ext = disable_extension_diagnostics ();
7346 c_parser_consume_token (parser);
7347 c_parser_declaration_or_fndef (parser, true, true, true, true,
7348 true, &object_expression);
7349 parser->objc_could_be_foreach_context = false;
7351 restore_extension_diagnostics (ext);
7352 if (c_parser_next_token_is_keyword (parser, RID_IN))
7354 c_parser_consume_token (parser);
7355 is_foreach_statement = true;
7356 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
7357 c_parser_error (parser, "multiple iterating variables in "
7358 "fast enumeration");
7360 else
7361 check_for_loop_decls (for_loc, flag_isoc99);
7363 else
7364 goto init_expr;
7366 else
7368 init_expr:
7370 struct c_expr ce;
7371 tree init_expression;
7372 ce = c_parser_expression (parser);
7373 init_expression = ce.value;
7374 parser->objc_could_be_foreach_context = false;
7375 if (c_parser_next_token_is_keyword (parser, RID_IN))
7377 c_parser_consume_token (parser);
7378 is_foreach_statement = true;
7379 if (! lvalue_p (init_expression))
7380 c_parser_error (parser, "invalid iterating variable in "
7381 "fast enumeration");
7382 object_expression
7383 = c_fully_fold (init_expression, false, NULL);
7385 else
7387 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
7388 init_expression = ce.value;
7389 c_finish_expr_stmt (loc, init_expression);
7390 c_parser_skip_until_found (parser, CPP_SEMICOLON,
7391 "expected %<;%>");
7395 /* Parse the loop condition. In the case of a foreach
7396 statement, there is no loop condition. */
7397 gcc_assert (!parser->objc_could_be_foreach_context);
7398 if (!is_foreach_statement)
7400 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7402 if (ivdep)
7404 c_parser_error (parser, "missing loop condition in loop "
7405 "with %<GCC ivdep%> pragma");
7406 cond = error_mark_node;
7408 else if (unroll)
7410 c_parser_error (parser, "missing loop condition in loop "
7411 "with %<GCC unroll%> pragma");
7412 cond = error_mark_node;
7414 else
7416 c_parser_consume_token (parser);
7417 cond = NULL_TREE;
7420 else
7422 cond = c_parser_condition (parser);
7423 c_parser_skip_until_found (parser, CPP_SEMICOLON,
7424 "expected %<;%>");
7426 if (ivdep && cond != error_mark_node)
7427 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
7428 build_int_cst (integer_type_node,
7429 annot_expr_ivdep_kind),
7430 integer_zero_node);
7431 if (unroll && cond != error_mark_node)
7432 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
7433 build_int_cst (integer_type_node,
7434 annot_expr_unroll_kind),
7435 build_int_cst (integer_type_node, unroll));
7437 /* Parse the increment expression (the third expression in a
7438 for-statement). In the case of a foreach-statement, this is
7439 the expression that follows the 'in'. */
7440 loc = c_parser_peek_token (parser)->location;
7441 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7443 if (is_foreach_statement)
7445 c_parser_error (parser,
7446 "missing collection in fast enumeration");
7447 collection_expression = error_mark_node;
7449 else
7450 incr = c_process_expr_stmt (loc, NULL_TREE);
7452 else
7454 if (is_foreach_statement)
7455 collection_expression
7456 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
7457 else
7459 struct c_expr ce = c_parser_expression (parser);
7460 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
7461 incr = c_process_expr_stmt (loc, ce.value);
7464 parens.skip_until_found_close (parser);
7466 save_in_statement = in_statement;
7467 if (is_foreach_statement)
7469 in_statement = IN_OBJC_FOREACH;
7470 save_objc_foreach_break_label = objc_foreach_break_label;
7471 save_objc_foreach_continue_label = objc_foreach_continue_label;
7472 objc_foreach_break_label = create_artificial_label (loc);
7473 objc_foreach_continue_label = create_artificial_label (loc);
7475 else
7476 in_statement = IN_ITERATION_STMT;
7478 token_indent_info body_tinfo
7479 = get_token_indent_info (c_parser_peek_token (parser));
7481 location_t loc_after_labels;
7482 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
7483 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
7485 if (is_foreach_statement)
7486 objc_finish_foreach_loop (for_loc, object_expression,
7487 collection_expression, body,
7488 objc_foreach_break_label,
7489 objc_foreach_continue_label);
7490 else
7491 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
7492 body, NULL_TREE));
7493 add_stmt (c_end_compound_stmt (for_loc, block,
7494 flag_isoc99 || c_dialect_objc ()));
7495 c_parser_maybe_reclassify_token (parser);
7497 token_indent_info next_tinfo
7498 = get_token_indent_info (c_parser_peek_token (parser));
7499 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
7501 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
7502 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7503 for_tinfo.location, RID_FOR);
7505 in_statement = save_in_statement;
7506 if (is_foreach_statement)
7508 objc_foreach_break_label = save_objc_foreach_break_label;
7509 objc_foreach_continue_label = save_objc_foreach_continue_label;
7513 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7514 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7515 tags allowed.
7517 asm-qualifier:
7518 volatile
7519 inline
7520 goto
7522 asm-qualifier-list:
7523 asm-qualifier-list asm-qualifier
7524 asm-qualifier
7526 asm-statement:
7527 asm asm-qualifier-list[opt] ( asm-argument ) ;
7529 asm-argument:
7530 asm-string-literal
7531 asm-string-literal : asm-operands[opt]
7532 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7533 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7534 : asm-clobbers[opt]
7535 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7536 : asm-goto-operands
7538 The form with asm-goto-operands is valid if and only if the
7539 asm-qualifier-list contains goto, and is the only allowed form in that case.
7540 Duplicate asm-qualifiers are not allowed.
7542 The :: token is considered equivalent to two consecutive : tokens. */
7544 static tree
7545 c_parser_asm_statement (c_parser *parser)
7547 tree str, outputs, inputs, clobbers, labels, ret;
7548 bool simple;
7549 location_t asm_loc = c_parser_peek_token (parser)->location;
7550 int section, nsections;
7552 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7553 c_parser_consume_token (parser);
7555 /* Handle the asm-qualifier-list. */
7556 location_t volatile_loc = UNKNOWN_LOCATION;
7557 location_t inline_loc = UNKNOWN_LOCATION;
7558 location_t goto_loc = UNKNOWN_LOCATION;
7559 for (;;)
7561 c_token *token = c_parser_peek_token (parser);
7562 location_t loc = token->location;
7563 switch (token->keyword)
7565 case RID_VOLATILE:
7566 if (volatile_loc)
7568 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7569 inform (volatile_loc, "first seen here");
7571 else
7572 volatile_loc = loc;
7573 c_parser_consume_token (parser);
7574 continue;
7576 case RID_INLINE:
7577 if (inline_loc)
7579 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7580 inform (inline_loc, "first seen here");
7582 else
7583 inline_loc = loc;
7584 c_parser_consume_token (parser);
7585 continue;
7587 case RID_GOTO:
7588 if (goto_loc)
7590 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7591 inform (goto_loc, "first seen here");
7593 else
7594 goto_loc = loc;
7595 c_parser_consume_token (parser);
7596 continue;
7598 case RID_CONST:
7599 case RID_RESTRICT:
7600 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7601 c_parser_consume_token (parser);
7602 continue;
7604 default:
7605 break;
7607 break;
7610 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7611 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7612 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7614 ret = NULL;
7616 matching_parens parens;
7617 if (!parens.require_open (parser))
7618 goto error;
7620 str = c_parser_asm_string_literal (parser);
7621 if (str == NULL_TREE)
7622 goto error_close_paren;
7624 simple = true;
7625 outputs = NULL_TREE;
7626 inputs = NULL_TREE;
7627 clobbers = NULL_TREE;
7628 labels = NULL_TREE;
7630 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7631 goto done_asm;
7633 /* Parse each colon-delimited section of operands. */
7634 nsections = 3 + is_goto;
7635 for (section = 0; section < nsections; ++section)
7637 if (c_parser_next_token_is (parser, CPP_SCOPE))
7639 ++section;
7640 if (section == nsections)
7642 c_parser_error (parser, "expected %<)%>");
7643 goto error_close_paren;
7645 c_parser_consume_token (parser);
7647 else if (!c_parser_require (parser, CPP_COLON,
7648 is_goto
7649 ? G_("expected %<:%>")
7650 : G_("expected %<:%> or %<)%>"),
7651 UNKNOWN_LOCATION, is_goto))
7652 goto error_close_paren;
7654 /* Once past any colon, we're no longer a simple asm. */
7655 simple = false;
7657 if ((!c_parser_next_token_is (parser, CPP_COLON)
7658 && !c_parser_next_token_is (parser, CPP_SCOPE)
7659 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7660 || section == 3)
7661 switch (section)
7663 case 0:
7664 outputs = c_parser_asm_operands (parser);
7665 break;
7666 case 1:
7667 inputs = c_parser_asm_operands (parser);
7668 break;
7669 case 2:
7670 clobbers = c_parser_asm_clobbers (parser);
7671 break;
7672 case 3:
7673 labels = c_parser_asm_goto_operands (parser);
7674 break;
7675 default:
7676 gcc_unreachable ();
7679 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7680 goto done_asm;
7683 done_asm:
7684 if (!parens.require_close (parser))
7686 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7687 goto error;
7690 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7691 c_parser_skip_to_end_of_block_or_statement (parser);
7693 ret = build_asm_stmt (is_volatile,
7694 build_asm_expr (asm_loc, str, outputs, inputs,
7695 clobbers, labels, simple, is_inline));
7697 error:
7698 return ret;
7700 error_close_paren:
7701 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7702 goto error;
7705 /* Parse asm operands, a GNU extension.
7707 asm-operands:
7708 asm-operand
7709 asm-operands , asm-operand
7711 asm-operand:
7712 asm-string-literal ( expression )
7713 [ identifier ] asm-string-literal ( expression )
7716 static tree
7717 c_parser_asm_operands (c_parser *parser)
7719 tree list = NULL_TREE;
7720 while (true)
7722 tree name, str;
7723 struct c_expr expr;
7724 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7726 c_parser_consume_token (parser);
7727 if (c_parser_next_token_is (parser, CPP_NAME))
7729 tree id = c_parser_peek_token (parser)->value;
7730 c_parser_consume_token (parser);
7731 name = build_string (IDENTIFIER_LENGTH (id),
7732 IDENTIFIER_POINTER (id));
7734 else
7736 c_parser_error (parser, "expected identifier");
7737 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7738 return NULL_TREE;
7740 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7741 "expected %<]%>");
7743 else
7744 name = NULL_TREE;
7745 str = c_parser_asm_string_literal (parser);
7746 if (str == NULL_TREE)
7747 return NULL_TREE;
7748 matching_parens parens;
7749 if (!parens.require_open (parser))
7750 return NULL_TREE;
7751 expr = c_parser_expression (parser);
7752 mark_exp_read (expr.value);
7753 if (!parens.require_close (parser))
7755 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7756 return NULL_TREE;
7758 list = chainon (list, build_tree_list (build_tree_list (name, str),
7759 expr.value));
7760 if (c_parser_next_token_is (parser, CPP_COMMA))
7761 c_parser_consume_token (parser);
7762 else
7763 break;
7765 return list;
7768 /* Parse asm clobbers, a GNU extension.
7770 asm-clobbers:
7771 asm-string-literal
7772 asm-clobbers , asm-string-literal
7775 static tree
7776 c_parser_asm_clobbers (c_parser *parser)
7778 tree list = NULL_TREE;
7779 while (true)
7781 tree str = c_parser_asm_string_literal (parser);
7782 if (str)
7783 list = tree_cons (NULL_TREE, str, list);
7784 else
7785 return NULL_TREE;
7786 if (c_parser_next_token_is (parser, CPP_COMMA))
7787 c_parser_consume_token (parser);
7788 else
7789 break;
7791 return list;
7794 /* Parse asm goto labels, a GNU extension.
7796 asm-goto-operands:
7797 identifier
7798 asm-goto-operands , identifier
7801 static tree
7802 c_parser_asm_goto_operands (c_parser *parser)
7804 tree list = NULL_TREE;
7805 while (true)
7807 tree name, label;
7809 if (c_parser_next_token_is (parser, CPP_NAME))
7811 c_token *tok = c_parser_peek_token (parser);
7812 name = tok->value;
7813 label = lookup_label_for_goto (tok->location, name);
7814 c_parser_consume_token (parser);
7815 TREE_USED (label) = 1;
7817 else
7819 c_parser_error (parser, "expected identifier");
7820 return NULL_TREE;
7823 name = build_string (IDENTIFIER_LENGTH (name),
7824 IDENTIFIER_POINTER (name));
7825 list = tree_cons (name, label, list);
7826 if (c_parser_next_token_is (parser, CPP_COMMA))
7827 c_parser_consume_token (parser);
7828 else
7829 return nreverse (list);
7833 /* Parse a possibly concatenated sequence of string literals.
7834 TRANSLATE says whether to translate them to the execution character
7835 set; WIDE_OK says whether any kind of prefixed string literal is
7836 permitted in this context. This code is based on that in
7837 lex_string. */
7839 struct c_expr
7840 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7842 struct c_expr ret;
7843 size_t count;
7844 struct obstack str_ob;
7845 struct obstack loc_ob;
7846 cpp_string str, istr, *strs;
7847 c_token *tok;
7848 location_t loc, last_tok_loc;
7849 enum cpp_ttype type;
7850 tree value, string_tree;
7852 tok = c_parser_peek_token (parser);
7853 loc = tok->location;
7854 last_tok_loc = linemap_resolve_location (line_table, loc,
7855 LRK_MACRO_DEFINITION_LOCATION,
7856 NULL);
7857 type = tok->type;
7858 switch (type)
7860 case CPP_STRING:
7861 case CPP_WSTRING:
7862 case CPP_STRING16:
7863 case CPP_STRING32:
7864 case CPP_UTF8STRING:
7865 string_tree = tok->value;
7866 break;
7868 default:
7869 c_parser_error (parser, "expected string literal");
7870 ret.set_error ();
7871 ret.value = NULL_TREE;
7872 ret.original_code = ERROR_MARK;
7873 ret.original_type = NULL_TREE;
7874 return ret;
7877 /* Try to avoid the overhead of creating and destroying an obstack
7878 for the common case of just one string. */
7879 switch (c_parser_peek_2nd_token (parser)->type)
7881 default:
7882 c_parser_consume_token (parser);
7883 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7884 str.len = TREE_STRING_LENGTH (string_tree);
7885 count = 1;
7886 strs = &str;
7887 break;
7889 case CPP_STRING:
7890 case CPP_WSTRING:
7891 case CPP_STRING16:
7892 case CPP_STRING32:
7893 case CPP_UTF8STRING:
7894 gcc_obstack_init (&str_ob);
7895 gcc_obstack_init (&loc_ob);
7896 count = 0;
7899 c_parser_consume_token (parser);
7900 count++;
7901 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7902 str.len = TREE_STRING_LENGTH (string_tree);
7903 if (type != tok->type)
7905 if (type == CPP_STRING)
7906 type = tok->type;
7907 else if (tok->type != CPP_STRING)
7908 error ("unsupported non-standard concatenation "
7909 "of string literals");
7911 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7912 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7913 tok = c_parser_peek_token (parser);
7914 string_tree = tok->value;
7915 last_tok_loc
7916 = linemap_resolve_location (line_table, tok->location,
7917 LRK_MACRO_DEFINITION_LOCATION, NULL);
7919 while (tok->type == CPP_STRING
7920 || tok->type == CPP_WSTRING
7921 || tok->type == CPP_STRING16
7922 || tok->type == CPP_STRING32
7923 || tok->type == CPP_UTF8STRING);
7924 strs = (cpp_string *) obstack_finish (&str_ob);
7927 if (count > 1 && !in_system_header_at (input_location))
7928 warning (OPT_Wtraditional,
7929 "traditional C rejects string constant concatenation");
7931 if ((type == CPP_STRING || wide_ok)
7932 && ((translate
7933 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7934 (parse_in, strs, count, &istr, type)))
7936 value = build_string (istr.len, (const char *) istr.text);
7937 free (CONST_CAST (unsigned char *, istr.text));
7938 if (count > 1)
7940 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7941 gcc_assert (g_string_concat_db);
7942 g_string_concat_db->record_string_concatenation (count, locs);
7945 else
7947 if (type != CPP_STRING && !wide_ok)
7949 error_at (loc, "a wide string is invalid in this context");
7950 type = CPP_STRING;
7952 /* Callers cannot generally handle error_mark_node in this
7953 context, so return the empty string instead. An error has
7954 been issued, either above or from cpp_interpret_string. */
7955 switch (type)
7957 default:
7958 case CPP_STRING:
7959 case CPP_UTF8STRING:
7960 if (type == CPP_UTF8STRING && flag_char8_t)
7962 value = build_string (TYPE_PRECISION (char8_type_node)
7963 / TYPE_PRECISION (char_type_node),
7964 ""); /* char8_t is 8 bits */
7966 else
7967 value = build_string (1, "");
7968 break;
7969 case CPP_STRING16:
7970 value = build_string (TYPE_PRECISION (char16_type_node)
7971 / TYPE_PRECISION (char_type_node),
7972 "\0"); /* char16_t is 16 bits */
7973 break;
7974 case CPP_STRING32:
7975 value = build_string (TYPE_PRECISION (char32_type_node)
7976 / TYPE_PRECISION (char_type_node),
7977 "\0\0\0"); /* char32_t is 32 bits */
7978 break;
7979 case CPP_WSTRING:
7980 value = build_string (TYPE_PRECISION (wchar_type_node)
7981 / TYPE_PRECISION (char_type_node),
7982 "\0\0\0"); /* widest supported wchar_t
7983 is 32 bits */
7984 break;
7988 switch (type)
7990 default:
7991 case CPP_STRING:
7992 TREE_TYPE (value) = char_array_type_node;
7993 break;
7994 case CPP_UTF8STRING:
7995 if (flag_char8_t)
7996 TREE_TYPE (value) = char8_array_type_node;
7997 else
7998 TREE_TYPE (value) = char_array_type_node;
7999 break;
8000 case CPP_STRING16:
8001 TREE_TYPE (value) = char16_array_type_node;
8002 break;
8003 case CPP_STRING32:
8004 TREE_TYPE (value) = char32_array_type_node;
8005 break;
8006 case CPP_WSTRING:
8007 TREE_TYPE (value) = wchar_array_type_node;
8009 value = fix_string_type (value);
8011 if (count > 1)
8013 obstack_free (&str_ob, 0);
8014 obstack_free (&loc_ob, 0);
8017 ret.value = value;
8018 ret.original_code = STRING_CST;
8019 ret.original_type = NULL_TREE;
8020 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
8021 ret.m_decimal = 0;
8022 parser->seen_string_literal = true;
8023 return ret;
8026 /* Parse an expression other than a compound expression; that is, an
8027 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
8028 AFTER is not NULL then it is an Objective-C message expression which
8029 is the primary-expression starting the expression as an initializer.
8031 assignment-expression:
8032 conditional-expression
8033 unary-expression assignment-operator assignment-expression
8035 assignment-operator: one of
8036 = *= /= %= += -= <<= >>= &= ^= |=
8038 In GNU C we accept any conditional expression on the LHS and
8039 diagnose the invalid lvalue rather than producing a syntax
8040 error. */
8042 static struct c_expr
8043 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
8044 tree omp_atomic_lhs)
8046 struct c_expr lhs, rhs, ret;
8047 enum tree_code code;
8048 location_t op_location, exp_location;
8049 bool save_in_omp_for = c_in_omp_for;
8050 c_in_omp_for = false;
8051 gcc_assert (!after || c_dialect_objc ());
8052 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
8053 op_location = c_parser_peek_token (parser)->location;
8054 switch (c_parser_peek_token (parser)->type)
8056 case CPP_EQ:
8057 code = NOP_EXPR;
8058 break;
8059 case CPP_MULT_EQ:
8060 code = MULT_EXPR;
8061 break;
8062 case CPP_DIV_EQ:
8063 code = TRUNC_DIV_EXPR;
8064 break;
8065 case CPP_MOD_EQ:
8066 code = TRUNC_MOD_EXPR;
8067 break;
8068 case CPP_PLUS_EQ:
8069 code = PLUS_EXPR;
8070 break;
8071 case CPP_MINUS_EQ:
8072 code = MINUS_EXPR;
8073 break;
8074 case CPP_LSHIFT_EQ:
8075 code = LSHIFT_EXPR;
8076 break;
8077 case CPP_RSHIFT_EQ:
8078 code = RSHIFT_EXPR;
8079 break;
8080 case CPP_AND_EQ:
8081 code = BIT_AND_EXPR;
8082 break;
8083 case CPP_XOR_EQ:
8084 code = BIT_XOR_EXPR;
8085 break;
8086 case CPP_OR_EQ:
8087 code = BIT_IOR_EXPR;
8088 break;
8089 default:
8090 c_in_omp_for = save_in_omp_for;
8091 return lhs;
8093 c_parser_consume_token (parser);
8094 exp_location = c_parser_peek_token (parser)->location;
8095 rhs = c_parser_expr_no_commas (parser, NULL);
8096 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
8098 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
8099 code, exp_location, rhs.value,
8100 rhs.original_type);
8101 ret.m_decimal = 0;
8102 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
8103 if (code == NOP_EXPR)
8104 ret.original_code = MODIFY_EXPR;
8105 else
8107 suppress_warning (ret.value, OPT_Wparentheses);
8108 ret.original_code = ERROR_MARK;
8110 ret.original_type = NULL;
8111 c_in_omp_for = save_in_omp_for;
8112 return ret;
8115 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
8116 AFTER is not NULL then it is an Objective-C message expression which is
8117 the primary-expression starting the expression as an initializer.
8119 conditional-expression:
8120 logical-OR-expression
8121 logical-OR-expression ? expression : conditional-expression
8123 GNU extensions:
8125 conditional-expression:
8126 logical-OR-expression ? : conditional-expression
8129 static struct c_expr
8130 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
8131 tree omp_atomic_lhs)
8133 struct c_expr cond, exp1, exp2, ret;
8134 location_t start, cond_loc, colon_loc;
8136 gcc_assert (!after || c_dialect_objc ());
8138 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
8140 if (c_parser_next_token_is_not (parser, CPP_QUERY))
8141 return cond;
8142 if (cond.value != error_mark_node)
8143 start = cond.get_start ();
8144 else
8145 start = UNKNOWN_LOCATION;
8146 cond_loc = c_parser_peek_token (parser)->location;
8147 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
8148 c_parser_consume_token (parser);
8149 if (c_parser_next_token_is (parser, CPP_COLON))
8151 tree eptype = NULL_TREE;
8153 location_t middle_loc = c_parser_peek_token (parser)->location;
8154 pedwarn (middle_loc, OPT_Wpedantic,
8155 "ISO C forbids omitting the middle term of a %<?:%> expression");
8156 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
8158 eptype = TREE_TYPE (cond.value);
8159 cond.value = TREE_OPERAND (cond.value, 0);
8161 tree e = cond.value;
8162 while (TREE_CODE (e) == COMPOUND_EXPR)
8163 e = TREE_OPERAND (e, 1);
8164 warn_for_omitted_condop (middle_loc, e);
8165 /* Make sure first operand is calculated only once. */
8166 exp1.value = save_expr (default_conversion (cond.value));
8167 if (eptype)
8168 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
8169 exp1.original_type = NULL;
8170 exp1.src_range = cond.src_range;
8171 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
8172 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
8174 else
8176 cond.value
8177 = c_objc_common_truthvalue_conversion
8178 (cond_loc, default_conversion (cond.value));
8179 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
8180 exp1 = c_parser_expression_conv (parser);
8181 mark_exp_read (exp1.value);
8182 c_inhibit_evaluation_warnings +=
8183 ((cond.value == truthvalue_true_node)
8184 - (cond.value == truthvalue_false_node));
8187 colon_loc = c_parser_peek_token (parser)->location;
8188 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8190 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
8191 ret.set_error ();
8192 ret.original_code = ERROR_MARK;
8193 ret.original_type = NULL;
8194 return ret;
8197 location_t exp2_loc = c_parser_peek_token (parser)->location;
8198 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
8199 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
8201 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
8202 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
8203 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
8204 if (UNLIKELY (omp_atomic_lhs != NULL)
8205 && (TREE_CODE (cond.value) == GT_EXPR
8206 || TREE_CODE (cond.value) == LT_EXPR
8207 || TREE_CODE (cond.value) == EQ_EXPR)
8208 && c_tree_equal (exp2.value, omp_atomic_lhs)
8209 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
8210 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
8211 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
8212 cond.value, exp1.value, exp2.value);
8213 else
8214 ret.value
8215 = build_conditional_expr (colon_loc, cond.value,
8216 cond.original_code == C_MAYBE_CONST_EXPR,
8217 exp1.value, exp1.original_type, loc1,
8218 exp2.value, exp2.original_type, loc2);
8219 ret.original_code = ERROR_MARK;
8220 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
8221 ret.original_type = NULL;
8222 else
8224 tree t1, t2;
8226 /* If both sides are enum type, the default conversion will have
8227 made the type of the result be an integer type. We want to
8228 remember the enum types we started with. */
8229 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
8230 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
8231 ret.original_type = ((t1 != error_mark_node
8232 && t2 != error_mark_node
8233 && (TYPE_MAIN_VARIANT (t1)
8234 == TYPE_MAIN_VARIANT (t2)))
8235 ? t1
8236 : NULL);
8238 set_c_expr_source_range (&ret, start, exp2.get_finish ());
8239 ret.m_decimal = 0;
8240 return ret;
8243 /* Parse a binary expression; that is, a logical-OR-expression (C90
8244 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
8245 NULL then it is an Objective-C message expression which is the
8246 primary-expression starting the expression as an initializer.
8248 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
8249 when it should be the unfolded lhs. In a valid OpenMP source,
8250 one of the operands of the toplevel binary expression must be equal
8251 to it. In that case, just return a build2 created binary operation
8252 rather than result of parser_build_binary_op.
8254 multiplicative-expression:
8255 cast-expression
8256 multiplicative-expression * cast-expression
8257 multiplicative-expression / cast-expression
8258 multiplicative-expression % cast-expression
8260 additive-expression:
8261 multiplicative-expression
8262 additive-expression + multiplicative-expression
8263 additive-expression - multiplicative-expression
8265 shift-expression:
8266 additive-expression
8267 shift-expression << additive-expression
8268 shift-expression >> additive-expression
8270 relational-expression:
8271 shift-expression
8272 relational-expression < shift-expression
8273 relational-expression > shift-expression
8274 relational-expression <= shift-expression
8275 relational-expression >= shift-expression
8277 equality-expression:
8278 relational-expression
8279 equality-expression == relational-expression
8280 equality-expression != relational-expression
8282 AND-expression:
8283 equality-expression
8284 AND-expression & equality-expression
8286 exclusive-OR-expression:
8287 AND-expression
8288 exclusive-OR-expression ^ AND-expression
8290 inclusive-OR-expression:
8291 exclusive-OR-expression
8292 inclusive-OR-expression | exclusive-OR-expression
8294 logical-AND-expression:
8295 inclusive-OR-expression
8296 logical-AND-expression && inclusive-OR-expression
8298 logical-OR-expression:
8299 logical-AND-expression
8300 logical-OR-expression || logical-AND-expression
8303 static struct c_expr
8304 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
8305 tree omp_atomic_lhs)
8307 /* A binary expression is parsed using operator-precedence parsing,
8308 with the operands being cast expressions. All the binary
8309 operators are left-associative. Thus a binary expression is of
8310 form:
8312 E0 op1 E1 op2 E2 ...
8314 which we represent on a stack. On the stack, the precedence
8315 levels are strictly increasing. When a new operator is
8316 encountered of higher precedence than that at the top of the
8317 stack, it is pushed; its LHS is the top expression, and its RHS
8318 is everything parsed until it is popped. When a new operator is
8319 encountered with precedence less than or equal to that at the top
8320 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
8321 by the result of the operation until the operator at the top of
8322 the stack has lower precedence than the new operator or there is
8323 only one element on the stack; then the top expression is the LHS
8324 of the new operator. In the case of logical AND and OR
8325 expressions, we also need to adjust c_inhibit_evaluation_warnings
8326 as appropriate when the operators are pushed and popped. */
8328 struct {
8329 /* The expression at this stack level. */
8330 struct c_expr expr;
8331 /* The precedence of the operator on its left, PREC_NONE at the
8332 bottom of the stack. */
8333 enum c_parser_prec prec;
8334 /* The operation on its left. */
8335 enum tree_code op;
8336 /* The source location of this operation. */
8337 location_t loc;
8338 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
8339 tree sizeof_arg;
8340 } stack[NUM_PRECS];
8341 int sp;
8342 /* Location of the binary operator. */
8343 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
8344 #define POP \
8345 do { \
8346 switch (stack[sp].op) \
8348 case TRUTH_ANDIF_EXPR: \
8349 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
8350 == truthvalue_false_node); \
8351 break; \
8352 case TRUTH_ORIF_EXPR: \
8353 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
8354 == truthvalue_true_node); \
8355 break; \
8356 case TRUNC_DIV_EXPR: \
8357 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
8358 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
8359 && (stack[sp].expr.original_code == SIZEOF_EXPR \
8360 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
8362 tree type0 = stack[sp - 1].sizeof_arg; \
8363 tree type1 = stack[sp].sizeof_arg; \
8364 tree first_arg = type0; \
8365 if (!TYPE_P (type0)) \
8366 type0 = TREE_TYPE (type0); \
8367 if (!TYPE_P (type1)) \
8368 type1 = TREE_TYPE (type1); \
8369 if (POINTER_TYPE_P (type0) \
8370 && comptypes (TREE_TYPE (type0), type1) \
8371 && !(TREE_CODE (first_arg) == PARM_DECL \
8372 && C_ARRAY_PARAMETER (first_arg) \
8373 && warn_sizeof_array_argument)) \
8375 auto_diagnostic_group d; \
8376 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
8377 "division %<sizeof (%T) / sizeof (%T)%> " \
8378 "does not compute the number of array " \
8379 "elements", \
8380 type0, type1)) \
8381 if (DECL_P (first_arg)) \
8382 inform (DECL_SOURCE_LOCATION (first_arg), \
8383 "first %<sizeof%> operand was declared here"); \
8385 else if (TREE_CODE (type0) == ARRAY_TYPE \
8386 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
8387 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
8388 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
8389 stack[sp].sizeof_arg, type1); \
8391 break; \
8392 default: \
8393 break; \
8395 stack[sp - 1].expr \
8396 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
8397 stack[sp - 1].expr, true, true); \
8398 stack[sp].expr \
8399 = convert_lvalue_to_rvalue (stack[sp].loc, \
8400 stack[sp].expr, true, true); \
8401 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
8402 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
8403 && ((1 << stack[sp].prec) \
8404 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
8405 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
8406 | (1 << PREC_ADD) | (1 << PREC_MULT) \
8407 | (1 << PREC_EQ)))) \
8408 || ((c_parser_next_token_is (parser, CPP_QUERY) \
8409 || (omp_atomic_lhs == void_list_node \
8410 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
8411 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
8412 && stack[sp].op != TRUNC_MOD_EXPR \
8413 && stack[sp].op != GE_EXPR \
8414 && stack[sp].op != LE_EXPR \
8415 && stack[sp].op != NE_EXPR \
8416 && stack[0].expr.value != error_mark_node \
8417 && stack[1].expr.value != error_mark_node \
8418 && (omp_atomic_lhs == void_list_node \
8419 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
8420 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
8421 || (stack[sp].op == EQ_EXPR \
8422 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
8424 tree t = make_node (stack[1].op); \
8425 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
8426 TREE_OPERAND (t, 0) = stack[0].expr.value; \
8427 TREE_OPERAND (t, 1) = stack[1].expr.value; \
8428 stack[0].expr.value = t; \
8429 stack[0].expr.m_decimal = 0; \
8431 else \
8432 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
8433 stack[sp].op, \
8434 stack[sp - 1].expr, \
8435 stack[sp].expr); \
8436 sp--; \
8437 } while (0)
8438 gcc_assert (!after || c_dialect_objc ());
8439 stack[0].loc = c_parser_peek_token (parser)->location;
8440 stack[0].expr = c_parser_cast_expression (parser, after);
8441 stack[0].prec = PREC_NONE;
8442 stack[0].sizeof_arg = c_last_sizeof_arg;
8443 sp = 0;
8444 while (true)
8446 enum c_parser_prec oprec;
8447 enum tree_code ocode;
8448 source_range src_range;
8449 if (parser->error)
8450 goto out;
8451 switch (c_parser_peek_token (parser)->type)
8453 case CPP_MULT:
8454 oprec = PREC_MULT;
8455 ocode = MULT_EXPR;
8456 break;
8457 case CPP_DIV:
8458 oprec = PREC_MULT;
8459 ocode = TRUNC_DIV_EXPR;
8460 break;
8461 case CPP_MOD:
8462 oprec = PREC_MULT;
8463 ocode = TRUNC_MOD_EXPR;
8464 break;
8465 case CPP_PLUS:
8466 oprec = PREC_ADD;
8467 ocode = PLUS_EXPR;
8468 break;
8469 case CPP_MINUS:
8470 oprec = PREC_ADD;
8471 ocode = MINUS_EXPR;
8472 break;
8473 case CPP_LSHIFT:
8474 oprec = PREC_SHIFT;
8475 ocode = LSHIFT_EXPR;
8476 break;
8477 case CPP_RSHIFT:
8478 oprec = PREC_SHIFT;
8479 ocode = RSHIFT_EXPR;
8480 break;
8481 case CPP_LESS:
8482 oprec = PREC_REL;
8483 ocode = LT_EXPR;
8484 break;
8485 case CPP_GREATER:
8486 oprec = PREC_REL;
8487 ocode = GT_EXPR;
8488 break;
8489 case CPP_LESS_EQ:
8490 oprec = PREC_REL;
8491 ocode = LE_EXPR;
8492 break;
8493 case CPP_GREATER_EQ:
8494 oprec = PREC_REL;
8495 ocode = GE_EXPR;
8496 break;
8497 case CPP_EQ_EQ:
8498 oprec = PREC_EQ;
8499 ocode = EQ_EXPR;
8500 break;
8501 case CPP_NOT_EQ:
8502 oprec = PREC_EQ;
8503 ocode = NE_EXPR;
8504 break;
8505 case CPP_AND:
8506 oprec = PREC_BITAND;
8507 ocode = BIT_AND_EXPR;
8508 break;
8509 case CPP_XOR:
8510 oprec = PREC_BITXOR;
8511 ocode = BIT_XOR_EXPR;
8512 break;
8513 case CPP_OR:
8514 oprec = PREC_BITOR;
8515 ocode = BIT_IOR_EXPR;
8516 break;
8517 case CPP_AND_AND:
8518 oprec = PREC_LOGAND;
8519 ocode = TRUTH_ANDIF_EXPR;
8520 break;
8521 case CPP_OR_OR:
8522 oprec = PREC_LOGOR;
8523 ocode = TRUTH_ORIF_EXPR;
8524 break;
8525 default:
8526 /* Not a binary operator, so end of the binary
8527 expression. */
8528 goto out;
8530 binary_loc = c_parser_peek_token (parser)->location;
8531 while (oprec <= stack[sp].prec)
8532 POP;
8533 c_parser_consume_token (parser);
8534 switch (ocode)
8536 case TRUTH_ANDIF_EXPR:
8537 src_range = stack[sp].expr.src_range;
8538 stack[sp].expr
8539 = convert_lvalue_to_rvalue (stack[sp].loc,
8540 stack[sp].expr, true, true);
8541 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8542 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8543 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8544 == truthvalue_false_node);
8545 set_c_expr_source_range (&stack[sp].expr, src_range);
8546 break;
8547 case TRUTH_ORIF_EXPR:
8548 src_range = stack[sp].expr.src_range;
8549 stack[sp].expr
8550 = convert_lvalue_to_rvalue (stack[sp].loc,
8551 stack[sp].expr, true, true);
8552 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8553 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8554 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8555 == truthvalue_true_node);
8556 set_c_expr_source_range (&stack[sp].expr, src_range);
8557 break;
8558 default:
8559 break;
8561 sp++;
8562 stack[sp].loc = binary_loc;
8563 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8564 stack[sp].prec = oprec;
8565 stack[sp].op = ocode;
8566 stack[sp].sizeof_arg = c_last_sizeof_arg;
8568 out:
8569 while (sp > 0)
8570 POP;
8571 return stack[0].expr;
8572 #undef POP
8575 /* Parse any storage class specifiers after an open parenthesis in a
8576 context where a compound literal is permitted. */
8578 static struct c_declspecs *
8579 c_parser_compound_literal_scspecs (c_parser *parser)
8581 bool seen_scspec = false;
8582 struct c_declspecs *specs = build_null_declspecs ();
8583 while (c_parser_next_token_is (parser, CPP_KEYWORD))
8585 switch (c_parser_peek_token (parser)->keyword)
8587 case RID_CONSTEXPR:
8588 case RID_REGISTER:
8589 case RID_STATIC:
8590 case RID_THREAD:
8591 seen_scspec = true;
8592 declspecs_add_scspec (c_parser_peek_token (parser)->location,
8593 specs, c_parser_peek_token (parser)->value);
8594 c_parser_consume_token (parser);
8595 break;
8596 default:
8597 goto out;
8600 out:
8601 return seen_scspec ? specs : NULL;
8604 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8605 is not NULL then it is an Objective-C message expression which is the
8606 primary-expression starting the expression as an initializer.
8608 cast-expression:
8609 unary-expression
8610 ( type-name ) unary-expression
8613 static struct c_expr
8614 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8616 location_t cast_loc = c_parser_peek_token (parser)->location;
8617 gcc_assert (!after || c_dialect_objc ());
8618 if (after)
8619 return c_parser_postfix_expression_after_primary (parser,
8620 cast_loc, *after);
8621 /* If the expression begins with a parenthesized type name, it may
8622 be either a cast or a compound literal; we need to see whether
8623 the next character is '{' to tell the difference. If not, it is
8624 an unary expression. Full detection of unknown typenames here
8625 would require a 3-token lookahead. */
8626 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8627 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
8629 struct c_declspecs *scspecs;
8630 struct c_type_name *type_name;
8631 struct c_expr ret;
8632 struct c_expr expr;
8633 matching_parens parens;
8634 parens.consume_open (parser);
8635 scspecs = c_parser_compound_literal_scspecs (parser);
8636 type_name = c_parser_type_name (parser, true);
8637 parens.skip_until_found_close (parser);
8638 if (type_name == NULL)
8640 ret.set_error ();
8641 ret.original_code = ERROR_MARK;
8642 ret.original_type = NULL;
8643 return ret;
8646 /* Save casted types in the function's used types hash table. */
8647 used_types_insert (type_name->specs->type);
8649 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8650 return c_parser_postfix_expression_after_paren_type (parser, scspecs,
8651 type_name,
8652 cast_loc);
8653 if (scspecs)
8654 error_at (cast_loc, "storage class specifier in cast");
8655 if (type_name->specs->alignas_p)
8656 error_at (type_name->specs->locations[cdw_alignas],
8657 "alignment specified for type name in cast");
8659 location_t expr_loc = c_parser_peek_token (parser)->location;
8660 expr = c_parser_cast_expression (parser, NULL);
8661 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8663 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8664 if (ret.value && expr.value)
8665 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8666 ret.original_code = ERROR_MARK;
8667 ret.original_type = NULL;
8668 ret.m_decimal = 0;
8669 return ret;
8671 else
8672 return c_parser_unary_expression (parser);
8675 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8677 unary-expression:
8678 postfix-expression
8679 ++ unary-expression
8680 -- unary-expression
8681 unary-operator cast-expression
8682 sizeof unary-expression
8683 sizeof ( type-name )
8685 unary-operator: one of
8686 & * + - ~ !
8688 GNU extensions:
8690 unary-expression:
8691 __alignof__ unary-expression
8692 __alignof__ ( type-name )
8693 && identifier
8695 (C11 permits _Alignof with type names only.)
8697 unary-operator: one of
8698 __extension__ __real__ __imag__
8700 Transactional Memory:
8702 unary-expression:
8703 transaction-expression
8705 In addition, the GNU syntax treats ++ and -- as unary operators, so
8706 they may be applied to cast expressions with errors for non-lvalues
8707 given later. */
8709 static struct c_expr
8710 c_parser_unary_expression (c_parser *parser)
8712 int ext;
8713 struct c_expr ret, op;
8714 location_t op_loc = c_parser_peek_token (parser)->location;
8715 location_t exp_loc;
8716 location_t finish;
8717 ret.original_code = ERROR_MARK;
8718 ret.original_type = NULL;
8719 switch (c_parser_peek_token (parser)->type)
8721 case CPP_PLUS_PLUS:
8722 c_parser_consume_token (parser);
8723 exp_loc = c_parser_peek_token (parser)->location;
8724 op = c_parser_cast_expression (parser, NULL);
8726 op = default_function_array_read_conversion (exp_loc, op);
8727 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8728 case CPP_MINUS_MINUS:
8729 c_parser_consume_token (parser);
8730 exp_loc = c_parser_peek_token (parser)->location;
8731 op = c_parser_cast_expression (parser, NULL);
8733 op = default_function_array_read_conversion (exp_loc, op);
8734 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8735 case CPP_AND:
8736 c_parser_consume_token (parser);
8737 op = c_parser_cast_expression (parser, NULL);
8738 mark_exp_read (op.value);
8739 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8740 case CPP_MULT:
8742 c_parser_consume_token (parser);
8743 exp_loc = c_parser_peek_token (parser)->location;
8744 op = c_parser_cast_expression (parser, NULL);
8745 finish = op.get_finish ();
8746 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8747 location_t combined_loc = make_location (op_loc, op_loc, finish);
8748 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8749 ret.src_range.m_start = op_loc;
8750 ret.src_range.m_finish = finish;
8751 ret.m_decimal = 0;
8752 return ret;
8754 case CPP_PLUS:
8755 if (!c_dialect_objc () && !in_system_header_at (input_location))
8756 warning_at (op_loc,
8757 OPT_Wtraditional,
8758 "traditional C rejects the unary plus operator");
8759 c_parser_consume_token (parser);
8760 exp_loc = c_parser_peek_token (parser)->location;
8761 op = c_parser_cast_expression (parser, NULL);
8762 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8763 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8764 case CPP_MINUS:
8765 c_parser_consume_token (parser);
8766 exp_loc = c_parser_peek_token (parser)->location;
8767 op = c_parser_cast_expression (parser, NULL);
8768 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8769 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8770 case CPP_COMPL:
8771 c_parser_consume_token (parser);
8772 exp_loc = c_parser_peek_token (parser)->location;
8773 op = c_parser_cast_expression (parser, NULL);
8774 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8775 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8776 case CPP_NOT:
8777 c_parser_consume_token (parser);
8778 exp_loc = c_parser_peek_token (parser)->location;
8779 op = c_parser_cast_expression (parser, NULL);
8780 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8781 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8782 case CPP_AND_AND:
8783 /* Refer to the address of a label as a pointer. */
8784 c_parser_consume_token (parser);
8785 if (c_parser_next_token_is (parser, CPP_NAME))
8787 ret.value = finish_label_address_expr
8788 (c_parser_peek_token (parser)->value, op_loc);
8789 set_c_expr_source_range (&ret, op_loc,
8790 c_parser_peek_token (parser)->get_finish ());
8791 c_parser_consume_token (parser);
8793 else
8795 c_parser_error (parser, "expected identifier");
8796 ret.set_error ();
8798 return ret;
8799 case CPP_KEYWORD:
8800 switch (c_parser_peek_token (parser)->keyword)
8802 case RID_SIZEOF:
8803 return c_parser_sizeof_expression (parser);
8804 case RID_ALIGNOF:
8805 return c_parser_alignof_expression (parser);
8806 case RID_BUILTIN_HAS_ATTRIBUTE:
8807 return c_parser_has_attribute_expression (parser);
8808 case RID_EXTENSION:
8809 c_parser_consume_token (parser);
8810 ext = disable_extension_diagnostics ();
8811 ret = c_parser_cast_expression (parser, NULL);
8812 restore_extension_diagnostics (ext);
8813 return ret;
8814 case RID_REALPART:
8815 c_parser_consume_token (parser);
8816 exp_loc = c_parser_peek_token (parser)->location;
8817 op = c_parser_cast_expression (parser, NULL);
8818 op = default_function_array_conversion (exp_loc, op);
8819 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8820 case RID_IMAGPART:
8821 c_parser_consume_token (parser);
8822 exp_loc = c_parser_peek_token (parser)->location;
8823 op = c_parser_cast_expression (parser, NULL);
8824 op = default_function_array_conversion (exp_loc, op);
8825 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8826 case RID_TRANSACTION_ATOMIC:
8827 case RID_TRANSACTION_RELAXED:
8828 return c_parser_transaction_expression (parser,
8829 c_parser_peek_token (parser)->keyword);
8830 default:
8831 return c_parser_postfix_expression (parser);
8833 default:
8834 return c_parser_postfix_expression (parser);
8838 /* Parse a sizeof expression. */
8840 static struct c_expr
8841 c_parser_sizeof_expression (c_parser *parser)
8843 struct c_expr expr;
8844 struct c_expr result;
8845 location_t expr_loc;
8846 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8848 location_t start;
8849 location_t finish = UNKNOWN_LOCATION;
8851 start = c_parser_peek_token (parser)->location;
8853 c_parser_consume_token (parser);
8854 c_inhibit_evaluation_warnings++;
8855 in_sizeof++;
8856 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8857 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
8859 /* Either sizeof ( type-name ) or sizeof unary-expression
8860 starting with a compound literal. */
8861 struct c_declspecs *scspecs;
8862 struct c_type_name *type_name;
8863 matching_parens parens;
8864 parens.consume_open (parser);
8865 expr_loc = c_parser_peek_token (parser)->location;
8866 scspecs = c_parser_compound_literal_scspecs (parser);
8867 type_name = c_parser_type_name (parser, true);
8868 parens.skip_until_found_close (parser);
8869 finish = parser->tokens_buf[0].location;
8870 if (type_name == NULL)
8872 struct c_expr ret;
8873 c_inhibit_evaluation_warnings--;
8874 in_sizeof--;
8875 ret.set_error ();
8876 ret.original_code = ERROR_MARK;
8877 ret.original_type = NULL;
8878 return ret;
8880 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8882 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
8883 type_name,
8884 expr_loc);
8885 finish = expr.get_finish ();
8886 goto sizeof_expr;
8888 /* sizeof ( type-name ). */
8889 if (scspecs)
8890 error_at (expr_loc, "storage class specifier in %<sizeof%>");
8891 if (type_name->specs->alignas_p)
8892 error_at (type_name->specs->locations[cdw_alignas],
8893 "alignment specified for type name in %<sizeof%>");
8894 c_inhibit_evaluation_warnings--;
8895 in_sizeof--;
8896 result = c_expr_sizeof_type (expr_loc, type_name);
8898 else
8900 expr_loc = c_parser_peek_token (parser)->location;
8901 expr = c_parser_unary_expression (parser);
8902 finish = expr.get_finish ();
8903 sizeof_expr:
8904 c_inhibit_evaluation_warnings--;
8905 in_sizeof--;
8906 mark_exp_read (expr.value);
8907 if (TREE_CODE (expr.value) == COMPONENT_REF
8908 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8909 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8910 result = c_expr_sizeof_expr (expr_loc, expr);
8912 if (finish == UNKNOWN_LOCATION)
8913 finish = start;
8914 set_c_expr_source_range (&result, start, finish);
8915 return result;
8918 /* Parse an alignof expression. */
8920 static struct c_expr
8921 c_parser_alignof_expression (c_parser *parser)
8923 struct c_expr expr;
8924 location_t start_loc = c_parser_peek_token (parser)->location;
8925 location_t end_loc;
8926 tree alignof_spelling = c_parser_peek_token (parser)->value;
8927 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8928 bool is_c11_alignof = (strcmp (IDENTIFIER_POINTER (alignof_spelling),
8929 "_Alignof") == 0
8930 || strcmp (IDENTIFIER_POINTER (alignof_spelling),
8931 "alignof") == 0);
8932 /* A diagnostic is not required for the use of this identifier in
8933 the implementation namespace; only diagnose it for the C11 or C2X
8934 spelling because of existing code using the other spellings. */
8935 if (is_c11_alignof)
8937 if (flag_isoc99)
8938 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8939 alignof_spelling);
8940 else
8941 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8942 alignof_spelling);
8944 c_parser_consume_token (parser);
8945 c_inhibit_evaluation_warnings++;
8946 in_alignof++;
8947 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8948 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
8950 /* Either __alignof__ ( type-name ) or __alignof__
8951 unary-expression starting with a compound literal. */
8952 location_t loc;
8953 struct c_declspecs *scspecs;
8954 struct c_type_name *type_name;
8955 struct c_expr ret;
8956 matching_parens parens;
8957 parens.consume_open (parser);
8958 loc = c_parser_peek_token (parser)->location;
8959 scspecs = c_parser_compound_literal_scspecs (parser);
8960 type_name = c_parser_type_name (parser, true);
8961 end_loc = c_parser_peek_token (parser)->location;
8962 parens.skip_until_found_close (parser);
8963 if (type_name == NULL)
8965 struct c_expr ret;
8966 c_inhibit_evaluation_warnings--;
8967 in_alignof--;
8968 ret.set_error ();
8969 ret.original_code = ERROR_MARK;
8970 ret.original_type = NULL;
8971 return ret;
8973 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8975 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
8976 type_name,
8977 loc);
8978 goto alignof_expr;
8980 /* alignof ( type-name ). */
8981 if (scspecs)
8982 error_at (loc, "storage class specifier in %qE", alignof_spelling);
8983 if (type_name->specs->alignas_p)
8984 error_at (type_name->specs->locations[cdw_alignas],
8985 "alignment specified for type name in %qE",
8986 alignof_spelling);
8987 c_inhibit_evaluation_warnings--;
8988 in_alignof--;
8989 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8990 NULL, NULL),
8991 false, is_c11_alignof, 1);
8992 ret.original_code = ERROR_MARK;
8993 ret.original_type = NULL;
8994 set_c_expr_source_range (&ret, start_loc, end_loc);
8995 ret.m_decimal = 0;
8996 return ret;
8998 else
9000 struct c_expr ret;
9001 expr = c_parser_unary_expression (parser);
9002 end_loc = expr.src_range.m_finish;
9003 alignof_expr:
9004 mark_exp_read (expr.value);
9005 c_inhibit_evaluation_warnings--;
9006 in_alignof--;
9007 if (is_c11_alignof)
9008 pedwarn (start_loc,
9009 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
9010 alignof_spelling);
9011 ret.value = c_alignof_expr (start_loc, expr.value);
9012 ret.original_code = ERROR_MARK;
9013 ret.original_type = NULL;
9014 set_c_expr_source_range (&ret, start_loc, end_loc);
9015 ret.m_decimal = 0;
9016 return ret;
9020 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
9021 expression. */
9023 static struct c_expr
9024 c_parser_has_attribute_expression (c_parser *parser)
9026 gcc_assert (c_parser_next_token_is_keyword (parser,
9027 RID_BUILTIN_HAS_ATTRIBUTE));
9028 location_t start = c_parser_peek_token (parser)->location;
9029 c_parser_consume_token (parser);
9031 c_inhibit_evaluation_warnings++;
9033 matching_parens parens;
9034 if (!parens.require_open (parser))
9036 c_inhibit_evaluation_warnings--;
9037 in_typeof--;
9039 struct c_expr result;
9040 result.set_error ();
9041 result.original_code = ERROR_MARK;
9042 result.original_type = NULL;
9043 return result;
9046 /* Treat the type argument the same way as in typeof for the purposes
9047 of warnings. FIXME: Generalize this so the warning refers to
9048 __builtin_has_attribute rather than typeof. */
9049 in_typeof++;
9051 /* The first operand: one of DECL, EXPR, or TYPE. */
9052 tree oper = NULL_TREE;
9053 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
9055 struct c_type_name *tname = c_parser_type_name (parser);
9056 in_typeof--;
9057 if (tname)
9059 oper = groktypename (tname, NULL, NULL);
9060 pop_maybe_used (c_type_variably_modified_p (oper));
9063 else
9065 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
9066 c_inhibit_evaluation_warnings--;
9067 in_typeof--;
9068 if (cexpr.value != error_mark_node)
9070 mark_exp_read (cexpr.value);
9071 oper = cexpr.value;
9072 tree etype = TREE_TYPE (oper);
9073 bool was_vm = c_type_variably_modified_p (etype);
9074 /* This is returned with the type so that when the type is
9075 evaluated, this can be evaluated. */
9076 if (was_vm)
9077 oper = c_fully_fold (oper, false, NULL);
9078 pop_maybe_used (was_vm);
9082 struct c_expr result;
9083 result.original_code = ERROR_MARK;
9084 result.original_type = NULL;
9086 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9088 /* Consume the closing parenthesis if that's the next token
9089 in the likely case the built-in was invoked with fewer
9090 than two arguments. */
9091 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
9092 c_parser_consume_token (parser);
9093 c_inhibit_evaluation_warnings--;
9094 result.set_error ();
9095 return result;
9098 bool save_translate_strings_p = parser->translate_strings_p;
9100 location_t atloc = c_parser_peek_token (parser)->location;
9101 /* Parse a single attribute. Require no leading comma and do not
9102 allow empty attributes. */
9103 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
9105 parser->translate_strings_p = save_translate_strings_p;
9107 location_t finish = c_parser_peek_token (parser)->location;
9108 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
9109 c_parser_consume_token (parser);
9110 else
9112 c_parser_error (parser, "expected identifier");
9113 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9115 result.set_error ();
9116 return result;
9119 if (!attr)
9121 error_at (atloc, "expected identifier");
9122 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9123 "expected %<)%>");
9124 result.set_error ();
9125 return result;
9128 result.original_code = INTEGER_CST;
9129 result.original_type = boolean_type_node;
9131 if (has_attribute (atloc, oper, attr, default_conversion))
9132 result.value = boolean_true_node;
9133 else
9134 result.value = boolean_false_node;
9136 set_c_expr_source_range (&result, start, finish);
9137 result.m_decimal = 0;
9138 return result;
9141 /* Helper function to read arguments of builtins which are interfaces
9142 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
9143 others. The name of the builtin is passed using BNAME parameter.
9144 Function returns true if there were no errors while parsing and
9145 stores the arguments in CEXPR_LIST. If it returns true,
9146 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
9147 parenthesis. */
9148 static bool
9149 c_parser_get_builtin_args (c_parser *parser, const char *bname,
9150 vec<c_expr_t, va_gc> **ret_cexpr_list,
9151 bool choose_expr_p,
9152 location_t *out_close_paren_loc)
9154 location_t loc = c_parser_peek_token (parser)->location;
9155 vec<c_expr_t, va_gc> *cexpr_list;
9156 c_expr_t expr;
9157 bool saved_force_folding_builtin_constant_p;
9159 *ret_cexpr_list = NULL;
9160 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
9162 error_at (loc, "cannot take address of %qs", bname);
9163 return false;
9166 c_parser_consume_token (parser);
9168 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
9170 *out_close_paren_loc = c_parser_peek_token (parser)->location;
9171 c_parser_consume_token (parser);
9172 return true;
9175 saved_force_folding_builtin_constant_p
9176 = force_folding_builtin_constant_p;
9177 force_folding_builtin_constant_p |= choose_expr_p;
9178 expr = c_parser_expr_no_commas (parser, NULL);
9179 force_folding_builtin_constant_p
9180 = saved_force_folding_builtin_constant_p;
9181 vec_alloc (cexpr_list, 1);
9182 vec_safe_push (cexpr_list, expr);
9183 while (c_parser_next_token_is (parser, CPP_COMMA))
9185 c_parser_consume_token (parser);
9186 expr = c_parser_expr_no_commas (parser, NULL);
9187 vec_safe_push (cexpr_list, expr);
9190 *out_close_paren_loc = c_parser_peek_token (parser)->location;
9191 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
9192 return false;
9194 *ret_cexpr_list = cexpr_list;
9195 return true;
9198 /* This represents a single generic-association. */
9200 struct c_generic_association
9202 /* The location of the starting token of the type. */
9203 location_t type_location;
9204 /* The association's type, or NULL_TREE for 'default'. */
9205 tree type;
9206 /* The association's expression. */
9207 struct c_expr expression;
9210 /* Parse a generic-selection. (C11 6.5.1.1).
9212 generic-selection:
9213 _Generic ( assignment-expression , generic-assoc-list )
9215 generic-assoc-list:
9216 generic-association
9217 generic-assoc-list , generic-association
9219 generic-association:
9220 type-name : assignment-expression
9221 default : assignment-expression
9224 static struct c_expr
9225 c_parser_generic_selection (c_parser *parser)
9227 struct c_expr selector, error_expr;
9228 tree selector_type;
9229 struct c_generic_association matched_assoc;
9230 int match_found = -1;
9231 location_t generic_loc, selector_loc;
9233 error_expr.original_code = ERROR_MARK;
9234 error_expr.original_type = NULL;
9235 error_expr.set_error ();
9236 matched_assoc.type_location = UNKNOWN_LOCATION;
9237 matched_assoc.type = NULL_TREE;
9238 matched_assoc.expression = error_expr;
9240 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
9241 generic_loc = c_parser_peek_token (parser)->location;
9242 c_parser_consume_token (parser);
9243 if (flag_isoc99)
9244 pedwarn_c99 (generic_loc, OPT_Wpedantic,
9245 "ISO C99 does not support %<_Generic%>");
9246 else
9247 pedwarn_c99 (generic_loc, OPT_Wpedantic,
9248 "ISO C90 does not support %<_Generic%>");
9250 matching_parens parens;
9251 if (!parens.require_open (parser))
9252 return error_expr;
9254 c_inhibit_evaluation_warnings++;
9255 selector_loc = c_parser_peek_token (parser)->location;
9256 selector = c_parser_expr_no_commas (parser, NULL);
9257 selector = default_function_array_conversion (selector_loc, selector);
9258 c_inhibit_evaluation_warnings--;
9260 if (selector.value == error_mark_node)
9262 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9263 return selector;
9265 mark_exp_read (selector.value);
9266 selector_type = TREE_TYPE (selector.value);
9267 /* In ISO C terms, rvalues (including the controlling expression of
9268 _Generic) do not have qualified types. */
9269 if (TREE_CODE (selector_type) != ARRAY_TYPE)
9270 selector_type = TYPE_MAIN_VARIANT (selector_type);
9271 /* In ISO C terms, _Noreturn is not part of the type of expressions
9272 such as &abort, but in GCC it is represented internally as a type
9273 qualifier. */
9274 if (FUNCTION_POINTER_TYPE_P (selector_type)
9275 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
9276 selector_type
9277 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
9279 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9281 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9282 return error_expr;
9285 auto_vec<c_generic_association> associations;
9286 while (1)
9288 struct c_generic_association assoc, *iter;
9289 unsigned int ix;
9290 c_token *token = c_parser_peek_token (parser);
9292 assoc.type_location = token->location;
9293 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
9295 c_parser_consume_token (parser);
9296 assoc.type = NULL_TREE;
9298 else
9300 struct c_type_name *type_name;
9302 type_name = c_parser_type_name (parser);
9303 if (type_name == NULL)
9305 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9306 return error_expr;
9308 assoc.type = groktypename (type_name, NULL, NULL);
9309 if (assoc.type == error_mark_node)
9311 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9312 return error_expr;
9315 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
9316 error_at (assoc.type_location,
9317 "%<_Generic%> association has function type");
9318 else if (!COMPLETE_TYPE_P (assoc.type))
9319 error_at (assoc.type_location,
9320 "%<_Generic%> association has incomplete type");
9322 if (c_type_variably_modified_p (assoc.type))
9323 error_at (assoc.type_location,
9324 "%<_Generic%> association has "
9325 "variable length type");
9328 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
9330 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9331 return error_expr;
9334 assoc.expression = c_parser_expr_no_commas (parser, NULL);
9335 if (assoc.expression.value == error_mark_node)
9337 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9338 return error_expr;
9341 for (ix = 0; associations.iterate (ix, &iter); ++ix)
9343 if (assoc.type == NULL_TREE)
9345 if (iter->type == NULL_TREE)
9347 error_at (assoc.type_location,
9348 "duplicate %<default%> case in %<_Generic%>");
9349 inform (iter->type_location, "original %<default%> is here");
9352 else if (iter->type != NULL_TREE)
9354 if (comptypes (assoc.type, iter->type))
9356 error_at (assoc.type_location,
9357 "%<_Generic%> specifies two compatible types");
9358 inform (iter->type_location, "compatible type is here");
9363 if (assoc.type == NULL_TREE)
9365 if (match_found < 0)
9367 matched_assoc = assoc;
9368 match_found = associations.length ();
9371 else if (comptypes (assoc.type, selector_type))
9373 if (match_found < 0 || matched_assoc.type == NULL_TREE)
9375 matched_assoc = assoc;
9376 match_found = associations.length ();
9378 else
9380 error_at (assoc.type_location,
9381 "%<_Generic%> selector matches multiple associations");
9382 inform (matched_assoc.type_location,
9383 "other match is here");
9387 associations.safe_push (assoc);
9389 if (c_parser_peek_token (parser)->type != CPP_COMMA)
9390 break;
9391 c_parser_consume_token (parser);
9394 unsigned int ix;
9395 struct c_generic_association *iter;
9396 FOR_EACH_VEC_ELT (associations, ix, iter)
9397 if (ix != (unsigned) match_found)
9398 mark_exp_read (iter->expression.value);
9400 if (!parens.require_close (parser))
9402 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9403 return error_expr;
9406 if (match_found < 0)
9408 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
9409 "compatible with any association",
9410 selector_type);
9411 return error_expr;
9414 return matched_assoc.expression;
9417 /* Check the validity of a function pointer argument *EXPR (argument
9418 position POS) to __builtin_tgmath. Return the number of function
9419 arguments if possibly valid; return 0 having reported an error if
9420 not valid. */
9422 static unsigned int
9423 check_tgmath_function (c_expr *expr, unsigned int pos)
9425 tree type = TREE_TYPE (expr->value);
9426 if (!FUNCTION_POINTER_TYPE_P (type))
9428 error_at (expr->get_location (),
9429 "argument %u of %<__builtin_tgmath%> is not a function pointer",
9430 pos);
9431 return 0;
9433 type = TREE_TYPE (type);
9434 if (!prototype_p (type))
9436 error_at (expr->get_location (),
9437 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
9438 return 0;
9440 if (stdarg_p (type))
9442 error_at (expr->get_location (),
9443 "argument %u of %<__builtin_tgmath%> has variable arguments",
9444 pos);
9445 return 0;
9447 unsigned int nargs = 0;
9448 function_args_iterator iter;
9449 tree t;
9450 FOREACH_FUNCTION_ARGS (type, t, iter)
9452 if (t == void_type_node)
9453 break;
9454 nargs++;
9456 if (nargs == 0)
9458 error_at (expr->get_location (),
9459 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
9460 return 0;
9462 return nargs;
9465 /* Ways in which a parameter or return value of a type-generic macro
9466 may vary between the different functions the macro may call. */
9467 enum tgmath_parm_kind
9469 tgmath_fixed, tgmath_real, tgmath_complex
9472 /* Helper function for c_parser_postfix_expression. Parse predefined
9473 identifiers. */
9475 static struct c_expr
9476 c_parser_predefined_identifier (c_parser *parser)
9478 location_t loc = c_parser_peek_token (parser)->location;
9479 switch (c_parser_peek_token (parser)->keyword)
9481 case RID_FUNCTION_NAME:
9482 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
9483 "identifier", "__FUNCTION__");
9484 break;
9485 case RID_PRETTY_FUNCTION_NAME:
9486 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
9487 "identifier", "__PRETTY_FUNCTION__");
9488 break;
9489 case RID_C99_FUNCTION_NAME:
9490 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
9491 "%<__func__%> predefined identifier");
9492 break;
9493 default:
9494 gcc_unreachable ();
9497 struct c_expr expr;
9498 expr.original_code = ERROR_MARK;
9499 expr.original_type = NULL;
9500 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
9501 c_parser_peek_token (parser)->value);
9502 set_c_expr_source_range (&expr, loc, loc);
9503 expr.m_decimal = 0;
9504 c_parser_consume_token (parser);
9505 return expr;
9508 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
9509 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
9510 call c_parser_postfix_expression_after_paren_type on encountering them.
9512 postfix-expression:
9513 primary-expression
9514 postfix-expression [ expression ]
9515 postfix-expression ( argument-expression-list[opt] )
9516 postfix-expression . identifier
9517 postfix-expression -> identifier
9518 postfix-expression ++
9519 postfix-expression --
9520 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
9521 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
9523 argument-expression-list:
9524 argument-expression
9525 argument-expression-list , argument-expression
9527 primary-expression:
9528 identifier
9529 constant
9530 string-literal
9531 ( expression )
9532 generic-selection
9534 GNU extensions:
9536 primary-expression:
9537 __func__
9538 (treated as a keyword in GNU C)
9539 __FUNCTION__
9540 __PRETTY_FUNCTION__
9541 ( compound-statement )
9542 __builtin_va_arg ( assignment-expression , type-name )
9543 __builtin_offsetof ( type-name , offsetof-member-designator )
9544 __builtin_choose_expr ( assignment-expression ,
9545 assignment-expression ,
9546 assignment-expression )
9547 __builtin_types_compatible_p ( type-name , type-name )
9548 __builtin_tgmath ( expr-list )
9549 __builtin_complex ( assignment-expression , assignment-expression )
9550 __builtin_shuffle ( assignment-expression , assignment-expression )
9551 __builtin_shuffle ( assignment-expression ,
9552 assignment-expression ,
9553 assignment-expression, )
9554 __builtin_convertvector ( assignment-expression , type-name )
9555 __builtin_assoc_barrier ( assignment-expression )
9557 offsetof-member-designator:
9558 identifier
9559 offsetof-member-designator . identifier
9560 offsetof-member-designator [ expression ]
9562 Objective-C:
9564 primary-expression:
9565 [ objc-receiver objc-message-args ]
9566 @selector ( objc-selector-arg )
9567 @protocol ( identifier )
9568 @encode ( type-name )
9569 objc-string-literal
9570 Classname . identifier
9573 static struct c_expr
9574 c_parser_postfix_expression (c_parser *parser)
9576 struct c_expr expr, e1;
9577 struct c_type_name *t1, *t2;
9578 location_t loc = c_parser_peek_token (parser)->location;
9579 source_range tok_range = c_parser_peek_token (parser)->get_range ();
9580 expr.original_code = ERROR_MARK;
9581 expr.original_type = NULL;
9582 expr.m_decimal = 0;
9583 switch (c_parser_peek_token (parser)->type)
9585 case CPP_NUMBER:
9586 expr.value = c_parser_peek_token (parser)->value;
9587 set_c_expr_source_range (&expr, tok_range);
9588 loc = c_parser_peek_token (parser)->location;
9589 expr.m_decimal = c_parser_peek_token (parser)->flags & DECIMAL_INT;
9590 c_parser_consume_token (parser);
9591 if (TREE_CODE (expr.value) == FIXED_CST
9592 && !targetm.fixed_point_supported_p ())
9594 error_at (loc, "fixed-point types not supported for this target");
9595 expr.set_error ();
9597 break;
9598 case CPP_CHAR:
9599 case CPP_CHAR16:
9600 case CPP_CHAR32:
9601 case CPP_UTF8CHAR:
9602 case CPP_WCHAR:
9603 expr.value = c_parser_peek_token (parser)->value;
9604 /* For the purpose of warning when a pointer is compared with
9605 a zero character constant. */
9606 expr.original_type = char_type_node;
9607 set_c_expr_source_range (&expr, tok_range);
9608 c_parser_consume_token (parser);
9609 break;
9610 case CPP_STRING:
9611 case CPP_STRING16:
9612 case CPP_STRING32:
9613 case CPP_WSTRING:
9614 case CPP_UTF8STRING:
9615 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9616 true);
9617 break;
9618 case CPP_OBJC_STRING:
9619 gcc_assert (c_dialect_objc ());
9620 expr.value
9621 = objc_build_string_object (c_parser_peek_token (parser)->value);
9622 set_c_expr_source_range (&expr, tok_range);
9623 c_parser_consume_token (parser);
9624 break;
9625 case CPP_NAME:
9626 switch (c_parser_peek_token (parser)->id_kind)
9628 case C_ID_ID:
9630 tree id = c_parser_peek_token (parser)->value;
9631 c_parser_consume_token (parser);
9632 expr.value = build_external_ref (loc, id,
9633 (c_parser_peek_token (parser)->type
9634 == CPP_OPEN_PAREN),
9635 &expr.original_type);
9636 set_c_expr_source_range (&expr, tok_range);
9637 break;
9639 case C_ID_CLASSNAME:
9641 /* Here we parse the Objective-C 2.0 Class.name dot
9642 syntax. */
9643 tree class_name = c_parser_peek_token (parser)->value;
9644 tree component;
9645 c_parser_consume_token (parser);
9646 gcc_assert (c_dialect_objc ());
9647 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9649 expr.set_error ();
9650 break;
9652 if (c_parser_next_token_is_not (parser, CPP_NAME))
9654 c_parser_error (parser, "expected identifier");
9655 expr.set_error ();
9656 break;
9658 c_token *component_tok = c_parser_peek_token (parser);
9659 component = component_tok->value;
9660 location_t end_loc = component_tok->get_finish ();
9661 c_parser_consume_token (parser);
9662 expr.value = objc_build_class_component_ref (class_name,
9663 component);
9664 set_c_expr_source_range (&expr, loc, end_loc);
9665 break;
9667 default:
9668 c_parser_error (parser, "expected expression");
9669 expr.set_error ();
9670 break;
9672 break;
9673 case CPP_OPEN_PAREN:
9674 /* A parenthesized expression, statement expression or compound
9675 literal. */
9676 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9678 /* A statement expression. */
9679 tree stmt;
9680 location_t brace_loc;
9681 c_parser_consume_token (parser);
9682 brace_loc = c_parser_peek_token (parser)->location;
9683 c_parser_consume_token (parser);
9684 /* If we've not yet started the current function's statement list,
9685 or we're in the parameter scope of an old-style function
9686 declaration, statement expressions are not allowed. */
9687 if (!building_stmt_list_p () || old_style_parameter_scope ())
9689 error_at (loc, "braced-group within expression allowed "
9690 "only inside a function");
9691 parser->error = true;
9692 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9693 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9694 expr.set_error ();
9695 break;
9697 stmt = c_begin_stmt_expr ();
9698 c_parser_compound_statement_nostart (parser);
9699 location_t close_loc = c_parser_peek_token (parser)->location;
9700 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9701 "expected %<)%>");
9702 pedwarn (loc, OPT_Wpedantic,
9703 "ISO C forbids braced-groups within expressions");
9704 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9705 set_c_expr_source_range (&expr, loc, close_loc);
9706 mark_exp_read (expr.value);
9708 else
9710 /* A parenthesized expression. */
9711 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9712 c_parser_consume_token (parser);
9713 expr = c_parser_expression (parser);
9714 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9715 suppress_warning (expr.value, OPT_Wparentheses);
9716 if (expr.original_code != C_MAYBE_CONST_EXPR
9717 && expr.original_code != SIZEOF_EXPR)
9718 expr.original_code = ERROR_MARK;
9719 /* Remember that we saw ( ) around the sizeof. */
9720 if (expr.original_code == SIZEOF_EXPR)
9721 expr.original_code = PAREN_SIZEOF_EXPR;
9722 /* Don't change EXPR.ORIGINAL_TYPE. */
9723 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9724 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9725 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9726 "expected %<)%>", loc_open_paren);
9728 break;
9729 case CPP_KEYWORD:
9730 switch (c_parser_peek_token (parser)->keyword)
9732 case RID_FUNCTION_NAME:
9733 case RID_PRETTY_FUNCTION_NAME:
9734 case RID_C99_FUNCTION_NAME:
9735 expr = c_parser_predefined_identifier (parser);
9736 break;
9737 case RID_VA_ARG:
9739 location_t start_loc = loc;
9740 c_parser_consume_token (parser);
9741 matching_parens parens;
9742 if (!parens.require_open (parser))
9744 expr.set_error ();
9745 break;
9747 e1 = c_parser_expr_no_commas (parser, NULL);
9748 mark_exp_read (e1.value);
9749 e1.value = c_fully_fold (e1.value, false, NULL);
9750 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9752 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9753 expr.set_error ();
9754 break;
9756 loc = c_parser_peek_token (parser)->location;
9757 t1 = c_parser_type_name (parser);
9758 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9759 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9760 "expected %<)%>");
9761 if (t1 == NULL)
9763 expr.set_error ();
9765 else
9767 tree type_expr = NULL_TREE;
9768 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9769 groktypename (t1, &type_expr, NULL));
9770 if (type_expr)
9772 expr.value = build2 (C_MAYBE_CONST_EXPR,
9773 TREE_TYPE (expr.value), type_expr,
9774 expr.value);
9775 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9777 set_c_expr_source_range (&expr, start_loc, end_loc);
9780 break;
9781 case RID_OFFSETOF:
9783 c_parser_consume_token (parser);
9784 matching_parens parens;
9785 if (!parens.require_open (parser))
9787 expr.set_error ();
9788 break;
9790 t1 = c_parser_type_name (parser);
9791 if (t1 == NULL)
9792 parser->error = true;
9793 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9794 gcc_assert (parser->error);
9795 if (parser->error)
9797 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9798 expr.set_error ();
9799 break;
9801 tree type = groktypename (t1, NULL, NULL);
9802 tree offsetof_ref;
9803 if (type == error_mark_node)
9804 offsetof_ref = error_mark_node;
9805 else
9807 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9808 SET_EXPR_LOCATION (offsetof_ref, loc);
9810 /* Parse the second argument to __builtin_offsetof. We
9811 must have one identifier, and beyond that we want to
9812 accept sub structure and sub array references. */
9813 if (c_parser_next_token_is (parser, CPP_NAME))
9815 c_token *comp_tok = c_parser_peek_token (parser);
9816 offsetof_ref
9817 = build_component_ref (loc, offsetof_ref, comp_tok->value,
9818 comp_tok->location, UNKNOWN_LOCATION);
9819 c_parser_consume_token (parser);
9820 while (c_parser_next_token_is (parser, CPP_DOT)
9821 || c_parser_next_token_is (parser,
9822 CPP_OPEN_SQUARE)
9823 || c_parser_next_token_is (parser,
9824 CPP_DEREF))
9826 if (c_parser_next_token_is (parser, CPP_DEREF))
9828 loc = c_parser_peek_token (parser)->location;
9829 offsetof_ref = build_array_ref (loc,
9830 offsetof_ref,
9831 integer_zero_node);
9832 goto do_dot;
9834 else if (c_parser_next_token_is (parser, CPP_DOT))
9836 do_dot:
9837 c_parser_consume_token (parser);
9838 if (c_parser_next_token_is_not (parser,
9839 CPP_NAME))
9841 c_parser_error (parser, "expected identifier");
9842 break;
9844 c_token *comp_tok = c_parser_peek_token (parser);
9845 offsetof_ref
9846 = build_component_ref (loc, offsetof_ref,
9847 comp_tok->value,
9848 comp_tok->location,
9849 UNKNOWN_LOCATION);
9850 c_parser_consume_token (parser);
9852 else
9854 struct c_expr ce;
9855 tree idx;
9856 loc = c_parser_peek_token (parser)->location;
9857 c_parser_consume_token (parser);
9858 ce = c_parser_expression (parser);
9859 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9860 idx = ce.value;
9861 idx = c_fully_fold (idx, false, NULL);
9862 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9863 "expected %<]%>");
9864 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9868 else
9869 c_parser_error (parser, "expected identifier");
9870 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9871 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9872 "expected %<)%>");
9873 expr.value = fold_offsetof (offsetof_ref);
9874 set_c_expr_source_range (&expr, loc, end_loc);
9876 break;
9877 case RID_CHOOSE_EXPR:
9879 vec<c_expr_t, va_gc> *cexpr_list;
9880 c_expr_t *e1_p, *e2_p, *e3_p;
9881 tree c;
9882 location_t close_paren_loc;
9884 c_parser_consume_token (parser);
9885 if (!c_parser_get_builtin_args (parser,
9886 "__builtin_choose_expr",
9887 &cexpr_list, true,
9888 &close_paren_loc))
9890 expr.set_error ();
9891 break;
9894 if (vec_safe_length (cexpr_list) != 3)
9896 error_at (loc, "wrong number of arguments to "
9897 "%<__builtin_choose_expr%>");
9898 expr.set_error ();
9899 break;
9902 e1_p = &(*cexpr_list)[0];
9903 e2_p = &(*cexpr_list)[1];
9904 e3_p = &(*cexpr_list)[2];
9906 c = e1_p->value;
9907 mark_exp_read (e2_p->value);
9908 mark_exp_read (e3_p->value);
9909 if (TREE_CODE (c) != INTEGER_CST
9910 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9911 error_at (loc,
9912 "first argument to %<__builtin_choose_expr%> not"
9913 " a constant");
9914 constant_expression_warning (c);
9915 expr = integer_zerop (c) ? *e3_p : *e2_p;
9916 set_c_expr_source_range (&expr, loc, close_paren_loc);
9917 break;
9919 case RID_TYPES_COMPATIBLE_P:
9921 c_parser_consume_token (parser);
9922 matching_parens parens;
9923 if (!parens.require_open (parser))
9925 expr.set_error ();
9926 break;
9928 t1 = c_parser_type_name (parser);
9929 if (t1 == NULL)
9931 expr.set_error ();
9932 break;
9934 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9936 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9937 expr.set_error ();
9938 break;
9940 t2 = c_parser_type_name (parser);
9941 if (t2 == NULL)
9943 expr.set_error ();
9944 break;
9946 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9947 parens.skip_until_found_close (parser);
9948 tree e1, e2;
9949 e1 = groktypename (t1, NULL, NULL);
9950 e2 = groktypename (t2, NULL, NULL);
9951 if (e1 == error_mark_node || e2 == error_mark_node)
9953 expr.set_error ();
9954 break;
9957 e1 = TYPE_MAIN_VARIANT (e1);
9958 e2 = TYPE_MAIN_VARIANT (e2);
9960 expr.value
9961 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9962 set_c_expr_source_range (&expr, loc, close_paren_loc);
9964 break;
9965 case RID_BUILTIN_TGMATH:
9967 vec<c_expr_t, va_gc> *cexpr_list;
9968 location_t close_paren_loc;
9970 c_parser_consume_token (parser);
9971 if (!c_parser_get_builtin_args (parser,
9972 "__builtin_tgmath",
9973 &cexpr_list, false,
9974 &close_paren_loc))
9976 expr.set_error ();
9977 break;
9980 if (vec_safe_length (cexpr_list) < 3)
9982 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9983 expr.set_error ();
9984 break;
9987 unsigned int i;
9988 c_expr_t *p;
9989 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9990 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9991 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9992 if (nargs == 0)
9994 expr.set_error ();
9995 break;
9997 if (vec_safe_length (cexpr_list) < nargs)
9999 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
10000 expr.set_error ();
10001 break;
10003 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
10004 if (num_functions < 2)
10006 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
10007 expr.set_error ();
10008 break;
10011 /* The first NUM_FUNCTIONS expressions are the function
10012 pointers. The remaining NARGS expressions are the
10013 arguments that are to be passed to one of those
10014 functions, chosen following <tgmath.h> rules. */
10015 for (unsigned int j = 1; j < num_functions; j++)
10017 unsigned int this_nargs
10018 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
10019 if (this_nargs == 0)
10021 expr.set_error ();
10022 goto out;
10024 if (this_nargs != nargs)
10026 error_at ((*cexpr_list)[j].get_location (),
10027 "argument %u of %<__builtin_tgmath%> has "
10028 "wrong number of arguments", j + 1);
10029 expr.set_error ();
10030 goto out;
10034 /* The functions all have the same number of arguments.
10035 Determine whether arguments and return types vary in
10036 ways permitted for <tgmath.h> functions. */
10037 /* The first entry in each of these vectors is for the
10038 return type, subsequent entries for parameter
10039 types. */
10040 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
10041 auto_vec<tree> parm_first (nargs + 1);
10042 auto_vec<bool> parm_complex (nargs + 1);
10043 auto_vec<bool> parm_varies (nargs + 1);
10044 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
10045 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
10046 parm_first.quick_push (first_ret);
10047 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
10048 parm_varies.quick_push (false);
10049 function_args_iterator iter;
10050 tree t;
10051 unsigned int argpos;
10052 FOREACH_FUNCTION_ARGS (first_type, t, iter)
10054 if (t == void_type_node)
10055 break;
10056 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
10057 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
10058 parm_varies.quick_push (false);
10060 for (unsigned int j = 1; j < num_functions; j++)
10062 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
10063 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
10064 if (ret != parm_first[0])
10066 parm_varies[0] = true;
10067 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
10068 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
10070 error_at ((*cexpr_list)[0].get_location (),
10071 "invalid type-generic return type for "
10072 "argument %u of %<__builtin_tgmath%>",
10074 expr.set_error ();
10075 goto out;
10077 if (!SCALAR_FLOAT_TYPE_P (ret)
10078 && !COMPLEX_FLOAT_TYPE_P (ret))
10080 error_at ((*cexpr_list)[j].get_location (),
10081 "invalid type-generic return type for "
10082 "argument %u of %<__builtin_tgmath%>",
10083 j + 1);
10084 expr.set_error ();
10085 goto out;
10088 if (TREE_CODE (ret) == COMPLEX_TYPE)
10089 parm_complex[0] = true;
10090 argpos = 1;
10091 FOREACH_FUNCTION_ARGS (type, t, iter)
10093 if (t == void_type_node)
10094 break;
10095 t = TYPE_MAIN_VARIANT (t);
10096 if (t != parm_first[argpos])
10098 parm_varies[argpos] = true;
10099 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
10100 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
10102 error_at ((*cexpr_list)[0].get_location (),
10103 "invalid type-generic type for "
10104 "argument %u of argument %u of "
10105 "%<__builtin_tgmath%>", argpos, 1);
10106 expr.set_error ();
10107 goto out;
10109 if (!SCALAR_FLOAT_TYPE_P (t)
10110 && !COMPLEX_FLOAT_TYPE_P (t))
10112 error_at ((*cexpr_list)[j].get_location (),
10113 "invalid type-generic type for "
10114 "argument %u of argument %u of "
10115 "%<__builtin_tgmath%>", argpos, j + 1);
10116 expr.set_error ();
10117 goto out;
10120 if (TREE_CODE (t) == COMPLEX_TYPE)
10121 parm_complex[argpos] = true;
10122 argpos++;
10125 enum tgmath_parm_kind max_variation = tgmath_fixed;
10126 for (unsigned int j = 0; j <= nargs; j++)
10128 enum tgmath_parm_kind this_kind;
10129 if (parm_varies[j])
10131 if (parm_complex[j])
10132 max_variation = this_kind = tgmath_complex;
10133 else
10135 this_kind = tgmath_real;
10136 if (max_variation != tgmath_complex)
10137 max_variation = tgmath_real;
10140 else
10141 this_kind = tgmath_fixed;
10142 parm_kind.quick_push (this_kind);
10144 if (max_variation == tgmath_fixed)
10146 error_at (loc, "function arguments of %<__builtin_tgmath%> "
10147 "all have the same type");
10148 expr.set_error ();
10149 break;
10152 /* Identify a parameter (not the return type) that varies,
10153 including with complex types if any variation includes
10154 complex types; there must be at least one such
10155 parameter. */
10156 unsigned int tgarg = 0;
10157 for (unsigned int j = 1; j <= nargs; j++)
10158 if (parm_kind[j] == max_variation)
10160 tgarg = j;
10161 break;
10163 if (tgarg == 0)
10165 error_at (loc, "function arguments of %<__builtin_tgmath%> "
10166 "lack type-generic parameter");
10167 expr.set_error ();
10168 break;
10171 /* Determine the type of the relevant parameter for each
10172 function. */
10173 auto_vec<tree> tg_type (num_functions);
10174 for (unsigned int j = 0; j < num_functions; j++)
10176 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
10177 argpos = 1;
10178 FOREACH_FUNCTION_ARGS (type, t, iter)
10180 if (argpos == tgarg)
10182 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
10183 break;
10185 argpos++;
10189 /* Verify that the corresponding types are different for
10190 all the listed functions. Also determine whether all
10191 the types are complex, whether all the types are
10192 standard or binary, and whether all the types are
10193 decimal. */
10194 bool all_complex = true;
10195 bool all_binary = true;
10196 bool all_decimal = true;
10197 hash_set<tree> tg_types;
10198 FOR_EACH_VEC_ELT (tg_type, i, t)
10200 if (TREE_CODE (t) == COMPLEX_TYPE)
10201 all_decimal = false;
10202 else
10204 all_complex = false;
10205 if (DECIMAL_FLOAT_TYPE_P (t))
10206 all_binary = false;
10207 else
10208 all_decimal = false;
10210 if (tg_types.add (t))
10212 error_at ((*cexpr_list)[i].get_location (),
10213 "duplicate type-generic parameter type for "
10214 "function argument %u of %<__builtin_tgmath%>",
10215 i + 1);
10216 expr.set_error ();
10217 goto out;
10221 /* Verify that other parameters and the return type whose
10222 types vary have their types varying in the correct
10223 way. */
10224 for (unsigned int j = 0; j < num_functions; j++)
10226 tree exp_type = tg_type[j];
10227 tree exp_real_type = exp_type;
10228 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
10229 exp_real_type = TREE_TYPE (exp_type);
10230 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
10231 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
10232 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
10233 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
10235 error_at ((*cexpr_list)[j].get_location (),
10236 "bad return type for function argument %u "
10237 "of %<__builtin_tgmath%>", j + 1);
10238 expr.set_error ();
10239 goto out;
10241 argpos = 1;
10242 FOREACH_FUNCTION_ARGS (type, t, iter)
10244 if (t == void_type_node)
10245 break;
10246 t = TYPE_MAIN_VARIANT (t);
10247 if ((parm_kind[argpos] == tgmath_complex
10248 && t != exp_type)
10249 || (parm_kind[argpos] == tgmath_real
10250 && t != exp_real_type))
10252 error_at ((*cexpr_list)[j].get_location (),
10253 "bad type for argument %u of "
10254 "function argument %u of "
10255 "%<__builtin_tgmath%>", argpos, j + 1);
10256 expr.set_error ();
10257 goto out;
10259 argpos++;
10263 /* The functions listed are a valid set of functions for a
10264 <tgmath.h> macro to select between. Identify the
10265 matching function, if any. First, the argument types
10266 must be combined following <tgmath.h> rules. Integer
10267 types are treated as _Decimal64 if any type-generic
10268 argument is decimal, or if the only alternatives for
10269 type-generic arguments are of decimal types, and are
10270 otherwise treated as _Float32x (or _Complex _Float32x
10271 for complex integer types) if any type-generic argument
10272 has _FloatNx type, otherwise as double (or _Complex
10273 double for complex integer types). After that
10274 adjustment, types are combined following the usual
10275 arithmetic conversions. If the function only accepts
10276 complex arguments, a complex type is produced. */
10277 bool arg_complex = all_complex;
10278 bool arg_binary = all_binary;
10279 bool arg_int_decimal = all_decimal;
10280 bool arg_int_floatnx = false;
10281 for (unsigned int j = 1; j <= nargs; j++)
10283 if (parm_kind[j] == tgmath_fixed)
10284 continue;
10285 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
10286 tree type = TREE_TYPE (ce->value);
10287 if (!INTEGRAL_TYPE_P (type)
10288 && !SCALAR_FLOAT_TYPE_P (type)
10289 && TREE_CODE (type) != COMPLEX_TYPE)
10291 error_at (ce->get_location (),
10292 "invalid type of argument %u of type-generic "
10293 "function", j);
10294 expr.set_error ();
10295 goto out;
10297 if (DECIMAL_FLOAT_TYPE_P (type))
10299 arg_int_decimal = true;
10300 if (all_complex)
10302 error_at (ce->get_location (),
10303 "decimal floating-point argument %u to "
10304 "complex-only type-generic function", j);
10305 expr.set_error ();
10306 goto out;
10308 else if (all_binary)
10310 error_at (ce->get_location (),
10311 "decimal floating-point argument %u to "
10312 "binary-only type-generic function", j);
10313 expr.set_error ();
10314 goto out;
10316 else if (arg_complex)
10318 error_at (ce->get_location (),
10319 "both complex and decimal floating-point "
10320 "arguments to type-generic function");
10321 expr.set_error ();
10322 goto out;
10324 else if (arg_binary)
10326 error_at (ce->get_location (),
10327 "both binary and decimal floating-point "
10328 "arguments to type-generic function");
10329 expr.set_error ();
10330 goto out;
10333 else if (TREE_CODE (type) == COMPLEX_TYPE)
10335 arg_complex = true;
10336 if (COMPLEX_FLOAT_TYPE_P (type))
10337 arg_binary = true;
10338 if (all_decimal)
10340 error_at (ce->get_location (),
10341 "complex argument %u to "
10342 "decimal-only type-generic function", j);
10343 expr.set_error ();
10344 goto out;
10346 else if (arg_int_decimal)
10348 error_at (ce->get_location (),
10349 "both complex and decimal floating-point "
10350 "arguments to type-generic function");
10351 expr.set_error ();
10352 goto out;
10355 else if (SCALAR_FLOAT_TYPE_P (type))
10357 arg_binary = true;
10358 if (all_decimal)
10360 error_at (ce->get_location (),
10361 "binary argument %u to "
10362 "decimal-only type-generic function", j);
10363 expr.set_error ();
10364 goto out;
10366 else if (arg_int_decimal)
10368 error_at (ce->get_location (),
10369 "both binary and decimal floating-point "
10370 "arguments to type-generic function");
10371 expr.set_error ();
10372 goto out;
10375 tree rtype = TYPE_MAIN_VARIANT (type);
10376 if (TREE_CODE (rtype) == COMPLEX_TYPE)
10377 rtype = TREE_TYPE (rtype);
10378 if (SCALAR_FLOAT_TYPE_P (rtype))
10379 for (unsigned int j = 0; j < NUM_FLOATNX_TYPES; j++)
10380 if (rtype == FLOATNX_TYPE_NODE (j))
10382 arg_int_floatnx = true;
10383 break;
10386 tree arg_real = NULL_TREE;
10387 for (unsigned int j = 1; j <= nargs; j++)
10389 if (parm_kind[j] == tgmath_fixed)
10390 continue;
10391 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
10392 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
10393 if (TREE_CODE (type) == COMPLEX_TYPE)
10394 type = TREE_TYPE (type);
10395 if (INTEGRAL_TYPE_P (type))
10396 type = (arg_int_decimal
10397 ? dfloat64_type_node
10398 : arg_int_floatnx
10399 ? float32x_type_node
10400 : double_type_node);
10401 if (arg_real == NULL_TREE)
10402 arg_real = type;
10403 else
10404 arg_real = common_type (arg_real, type);
10405 if (arg_real == error_mark_node)
10407 expr.set_error ();
10408 goto out;
10411 tree arg_type = (arg_complex
10412 ? build_complex_type (arg_real)
10413 : arg_real);
10415 /* Look for a function to call with type-generic parameter
10416 type ARG_TYPE. */
10417 c_expr_t *fn = NULL;
10418 for (unsigned int j = 0; j < num_functions; j++)
10420 if (tg_type[j] == arg_type)
10422 fn = &(*cexpr_list)[j];
10423 break;
10426 if (fn == NULL
10427 && parm_kind[0] == tgmath_fixed
10428 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
10430 /* Presume this is a macro that rounds its result to a
10431 narrower type, and look for the first function with
10432 at least the range and precision of the argument
10433 type. */
10434 for (unsigned int j = 0; j < num_functions; j++)
10436 if (arg_complex
10437 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
10438 continue;
10439 tree real_tg_type = (arg_complex
10440 ? TREE_TYPE (tg_type[j])
10441 : tg_type[j]);
10442 if (DECIMAL_FLOAT_TYPE_P (arg_real)
10443 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
10444 continue;
10445 scalar_float_mode arg_mode
10446 = SCALAR_FLOAT_TYPE_MODE (arg_real);
10447 scalar_float_mode tg_mode
10448 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
10449 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
10450 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
10451 if (arg_fmt->b == tg_fmt->b
10452 && arg_fmt->p <= tg_fmt->p
10453 && arg_fmt->emax <= tg_fmt->emax
10454 && (arg_fmt->emin - arg_fmt->p
10455 >= tg_fmt->emin - tg_fmt->p))
10457 fn = &(*cexpr_list)[j];
10458 break;
10462 if (fn == NULL)
10464 error_at (loc, "no matching function for type-generic call");
10465 expr.set_error ();
10466 break;
10469 /* Construct a call to FN. */
10470 vec<tree, va_gc> *args;
10471 vec_alloc (args, nargs);
10472 vec<tree, va_gc> *origtypes;
10473 vec_alloc (origtypes, nargs);
10474 auto_vec<location_t> arg_loc (nargs);
10475 for (unsigned int j = 0; j < nargs; j++)
10477 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
10478 args->quick_push (ce->value);
10479 arg_loc.quick_push (ce->get_location ());
10480 origtypes->quick_push (ce->original_type);
10482 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
10483 args, origtypes);
10484 set_c_expr_source_range (&expr, loc, close_paren_loc);
10485 break;
10487 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
10489 vec<c_expr_t, va_gc> *cexpr_list;
10490 c_expr_t *e2_p;
10491 tree chain_value;
10492 location_t close_paren_loc;
10494 c_parser_consume_token (parser);
10495 if (!c_parser_get_builtin_args (parser,
10496 "__builtin_call_with_static_chain",
10497 &cexpr_list, false,
10498 &close_paren_loc))
10500 expr.set_error ();
10501 break;
10503 if (vec_safe_length (cexpr_list) != 2)
10505 error_at (loc, "wrong number of arguments to "
10506 "%<__builtin_call_with_static_chain%>");
10507 expr.set_error ();
10508 break;
10511 expr = (*cexpr_list)[0];
10512 e2_p = &(*cexpr_list)[1];
10513 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
10514 chain_value = e2_p->value;
10515 mark_exp_read (chain_value);
10517 if (TREE_CODE (expr.value) != CALL_EXPR)
10518 error_at (loc, "first argument to "
10519 "%<__builtin_call_with_static_chain%> "
10520 "must be a call expression");
10521 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
10522 error_at (loc, "second argument to "
10523 "%<__builtin_call_with_static_chain%> "
10524 "must be a pointer type");
10525 else
10526 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
10527 set_c_expr_source_range (&expr, loc, close_paren_loc);
10528 break;
10530 case RID_BUILTIN_COMPLEX:
10532 vec<c_expr_t, va_gc> *cexpr_list;
10533 c_expr_t *e1_p, *e2_p;
10534 location_t close_paren_loc;
10536 c_parser_consume_token (parser);
10537 if (!c_parser_get_builtin_args (parser,
10538 "__builtin_complex",
10539 &cexpr_list, false,
10540 &close_paren_loc))
10542 expr.set_error ();
10543 break;
10546 if (vec_safe_length (cexpr_list) != 2)
10548 error_at (loc, "wrong number of arguments to "
10549 "%<__builtin_complex%>");
10550 expr.set_error ();
10551 break;
10554 e1_p = &(*cexpr_list)[0];
10555 e2_p = &(*cexpr_list)[1];
10557 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
10558 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
10559 e1_p->value = convert (TREE_TYPE (e1_p->value),
10560 TREE_OPERAND (e1_p->value, 0));
10561 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
10562 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
10563 e2_p->value = convert (TREE_TYPE (e2_p->value),
10564 TREE_OPERAND (e2_p->value, 0));
10565 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10566 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10567 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
10568 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
10570 error_at (loc, "%<__builtin_complex%> operand "
10571 "not of real binary floating-point type");
10572 expr.set_error ();
10573 break;
10575 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10576 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10578 error_at (loc,
10579 "%<__builtin_complex%> operands of different types");
10580 expr.set_error ();
10581 break;
10583 pedwarn_c90 (loc, OPT_Wpedantic,
10584 "ISO C90 does not support complex types");
10585 expr.value = build2_loc (loc, COMPLEX_EXPR,
10586 build_complex_type
10587 (TYPE_MAIN_VARIANT
10588 (TREE_TYPE (e1_p->value))),
10589 e1_p->value, e2_p->value);
10590 set_c_expr_source_range (&expr, loc, close_paren_loc);
10591 break;
10593 case RID_BUILTIN_SHUFFLE:
10595 vec<c_expr_t, va_gc> *cexpr_list;
10596 unsigned int i;
10597 c_expr_t *p;
10598 location_t close_paren_loc;
10600 c_parser_consume_token (parser);
10601 if (!c_parser_get_builtin_args (parser,
10602 "__builtin_shuffle",
10603 &cexpr_list, false,
10604 &close_paren_loc))
10606 expr.set_error ();
10607 break;
10610 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10611 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10613 if (vec_safe_length (cexpr_list) == 2)
10614 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10615 NULL_TREE,
10616 (*cexpr_list)[1].value);
10618 else if (vec_safe_length (cexpr_list) == 3)
10619 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10620 (*cexpr_list)[1].value,
10621 (*cexpr_list)[2].value);
10622 else
10624 error_at (loc, "wrong number of arguments to "
10625 "%<__builtin_shuffle%>");
10626 expr.set_error ();
10628 set_c_expr_source_range (&expr, loc, close_paren_loc);
10629 break;
10631 case RID_BUILTIN_SHUFFLEVECTOR:
10633 vec<c_expr_t, va_gc> *cexpr_list;
10634 unsigned int i;
10635 c_expr_t *p;
10636 location_t close_paren_loc;
10638 c_parser_consume_token (parser);
10639 if (!c_parser_get_builtin_args (parser,
10640 "__builtin_shufflevector",
10641 &cexpr_list, false,
10642 &close_paren_loc))
10644 expr.set_error ();
10645 break;
10648 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10649 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10651 if (vec_safe_length (cexpr_list) < 3)
10653 error_at (loc, "wrong number of arguments to "
10654 "%<__builtin_shuffle%>");
10655 expr.set_error ();
10657 else
10659 auto_vec<tree, 16> mask;
10660 for (i = 2; i < cexpr_list->length (); ++i)
10661 mask.safe_push ((*cexpr_list)[i].value);
10662 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10663 (*cexpr_list)[1].value,
10664 mask);
10666 set_c_expr_source_range (&expr, loc, close_paren_loc);
10667 break;
10669 case RID_BUILTIN_CONVERTVECTOR:
10671 location_t start_loc = loc;
10672 c_parser_consume_token (parser);
10673 matching_parens parens;
10674 if (!parens.require_open (parser))
10676 expr.set_error ();
10677 break;
10679 e1 = c_parser_expr_no_commas (parser, NULL);
10680 mark_exp_read (e1.value);
10681 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10683 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10684 expr.set_error ();
10685 break;
10687 loc = c_parser_peek_token (parser)->location;
10688 t1 = c_parser_type_name (parser);
10689 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10690 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10691 "expected %<)%>");
10692 if (t1 == NULL)
10693 expr.set_error ();
10694 else
10696 tree type_expr = NULL_TREE;
10697 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10698 groktypename (t1, &type_expr,
10699 NULL));
10700 set_c_expr_source_range (&expr, start_loc, end_loc);
10703 break;
10704 case RID_BUILTIN_ASSOC_BARRIER:
10706 location_t start_loc = loc;
10707 c_parser_consume_token (parser);
10708 matching_parens parens;
10709 if (!parens.require_open (parser))
10711 expr.set_error ();
10712 break;
10714 e1 = c_parser_expr_no_commas (parser, NULL);
10715 mark_exp_read (e1.value);
10716 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10717 parens.skip_until_found_close (parser);
10718 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10719 set_c_expr_source_range (&expr, start_loc, end_loc);
10721 break;
10722 case RID_AT_SELECTOR:
10724 gcc_assert (c_dialect_objc ());
10725 c_parser_consume_token (parser);
10726 matching_parens parens;
10727 if (!parens.require_open (parser))
10729 expr.set_error ();
10730 break;
10732 tree sel = c_parser_objc_selector_arg (parser);
10733 location_t close_loc = c_parser_peek_token (parser)->location;
10734 parens.skip_until_found_close (parser);
10735 expr.value = objc_build_selector_expr (loc, sel);
10736 set_c_expr_source_range (&expr, loc, close_loc);
10738 break;
10739 case RID_AT_PROTOCOL:
10741 gcc_assert (c_dialect_objc ());
10742 c_parser_consume_token (parser);
10743 matching_parens parens;
10744 if (!parens.require_open (parser))
10746 expr.set_error ();
10747 break;
10749 if (c_parser_next_token_is_not (parser, CPP_NAME))
10751 c_parser_error (parser, "expected identifier");
10752 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10753 expr.set_error ();
10754 break;
10756 tree id = c_parser_peek_token (parser)->value;
10757 c_parser_consume_token (parser);
10758 location_t close_loc = c_parser_peek_token (parser)->location;
10759 parens.skip_until_found_close (parser);
10760 expr.value = objc_build_protocol_expr (id);
10761 set_c_expr_source_range (&expr, loc, close_loc);
10763 break;
10764 case RID_AT_ENCODE:
10766 /* Extension to support C-structures in the archiver. */
10767 gcc_assert (c_dialect_objc ());
10768 c_parser_consume_token (parser);
10769 matching_parens parens;
10770 if (!parens.require_open (parser))
10772 expr.set_error ();
10773 break;
10775 t1 = c_parser_type_name (parser);
10776 if (t1 == NULL)
10778 expr.set_error ();
10779 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10780 break;
10782 location_t close_loc = c_parser_peek_token (parser)->location;
10783 parens.skip_until_found_close (parser);
10784 tree type = groktypename (t1, NULL, NULL);
10785 expr.value = objc_build_encode_expr (type);
10786 set_c_expr_source_range (&expr, loc, close_loc);
10788 break;
10789 case RID_GENERIC:
10790 expr = c_parser_generic_selection (parser);
10791 break;
10792 case RID_OMP_ALL_MEMORY:
10793 gcc_assert (flag_openmp);
10794 c_parser_consume_token (parser);
10795 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
10796 "%<depend%> clause");
10797 expr.set_error ();
10798 break;
10799 /* C23 'nullptr' literal. */
10800 case RID_NULLPTR:
10801 c_parser_consume_token (parser);
10802 expr.value = nullptr_node;
10803 set_c_expr_source_range (&expr, tok_range);
10804 pedwarn_c11 (loc, OPT_Wpedantic,
10805 "ISO C does not support %qs before C2X", "nullptr");
10806 break;
10807 case RID_TRUE:
10808 c_parser_consume_token (parser);
10809 expr.value = boolean_true_node;
10810 set_c_expr_source_range (&expr, tok_range);
10811 break;
10812 case RID_FALSE:
10813 c_parser_consume_token (parser);
10814 expr.value = boolean_false_node;
10815 set_c_expr_source_range (&expr, tok_range);
10816 break;
10817 default:
10818 c_parser_error (parser, "expected expression");
10819 expr.set_error ();
10820 break;
10822 break;
10823 case CPP_OPEN_SQUARE:
10824 if (c_dialect_objc ())
10826 tree receiver, args;
10827 c_parser_consume_token (parser);
10828 receiver = c_parser_objc_receiver (parser);
10829 args = c_parser_objc_message_args (parser);
10830 location_t close_loc = c_parser_peek_token (parser)->location;
10831 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10832 "expected %<]%>");
10833 expr.value = objc_build_message_expr (receiver, args);
10834 set_c_expr_source_range (&expr, loc, close_loc);
10835 break;
10837 /* Else fall through to report error. */
10838 /* FALLTHRU */
10839 default:
10840 c_parser_error (parser, "expected expression");
10841 expr.set_error ();
10842 break;
10844 out:
10845 return c_parser_postfix_expression_after_primary
10846 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10849 /* Parse a postfix expression after a parenthesized type name: the
10850 brace-enclosed initializer of a compound literal, possibly followed
10851 by some postfix operators. This is separate because it is not
10852 possible to tell until after the type name whether a cast
10853 expression has a cast or a compound literal, or whether the operand
10854 of sizeof is a parenthesized type name or starts with a compound
10855 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10856 location of the first token after the parentheses around the type
10857 name. */
10859 static struct c_expr
10860 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10861 struct c_declspecs *scspecs,
10862 struct c_type_name *type_name,
10863 location_t type_loc)
10865 tree type;
10866 struct c_expr init;
10867 bool non_const;
10868 struct c_expr expr;
10869 location_t start_loc;
10870 tree type_expr = NULL_TREE;
10871 bool type_expr_const = true;
10872 bool constexpr_p = scspecs ? scspecs->constexpr_p : false;
10873 unsigned int underspec_state = 0;
10874 check_compound_literal_type (type_loc, type_name);
10875 rich_location richloc (line_table, type_loc);
10876 start_loc = c_parser_peek_token (parser)->location;
10877 if (constexpr_p)
10879 underspec_state = start_underspecified_init (start_loc, NULL_TREE);
10880 /* A constexpr compound literal is subject to the constraints on
10881 underspecified declarations, which may not declare tags or
10882 members or structures or unions; it is undefined behavior to
10883 declare the members of an enumeration. Where the structure,
10884 union or enumeration type is declared within the compound
10885 literal initializer, this is diagnosed elsewhere as a result
10886 of the above call to start_underspecified_init. Diagnose
10887 here the case of declaring such a type in the type specifiers
10888 of the compound literal. */
10889 switch (type_name->specs->typespec_kind)
10891 case ctsk_tagfirstref:
10892 case ctsk_tagfirstref_attrs:
10893 error_at (type_loc, "%qT declared in %<constexpr%> compound literal",
10894 type_name->specs->type);
10895 break;
10897 case ctsk_tagdef:
10898 error_at (type_loc, "%qT defined in %<constexpr%> compound literal",
10899 type_name->specs->type);
10900 break;
10902 default:
10903 break;
10906 start_init (NULL_TREE, NULL,
10907 (global_bindings_p ()
10908 || (scspecs && scspecs->storage_class == csc_static)
10909 || constexpr_p), constexpr_p, &richloc);
10910 type = groktypename (type_name, &type_expr, &type_expr_const);
10911 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10913 error_at (type_loc, "compound literal has variable size");
10914 type = error_mark_node;
10916 else if (TREE_CODE (type) == FUNCTION_TYPE)
10918 error_at (type_loc, "compound literal has function type");
10919 type = error_mark_node;
10921 if (constexpr_p && type != error_mark_node)
10923 tree type_no_array = strip_array_types (type);
10924 /* The type of a constexpr object must not be variably modified
10925 (which applies to all compound literals), volatile, atomic or
10926 restrict qualified or have a member with such a qualifier.
10927 const qualification is implicitly added. */
10928 if (TYPE_QUALS (type_no_array)
10929 & (TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC))
10930 error_at (type_loc, "invalid qualifiers for %<constexpr%> object");
10931 else if (RECORD_OR_UNION_TYPE_P (type_no_array)
10932 && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array))
10933 error_at (type_loc, "invalid qualifiers for field of "
10934 "%<constexpr%> object");
10935 type = c_build_qualified_type (type,
10936 (TYPE_QUALS (type_no_array)
10937 | TYPE_QUAL_CONST));
10939 init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
10940 if (constexpr_p)
10941 finish_underspecified_init (NULL_TREE, underspec_state);
10942 finish_init ();
10943 maybe_warn_string_init (type_loc, type, init);
10945 if (type != error_mark_node
10946 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10947 && current_function_decl)
10949 error ("compound literal qualified by address-space qualifier");
10950 type = error_mark_node;
10953 if (!pedwarn_c90 (start_loc, OPT_Wpedantic,
10954 "ISO C90 forbids compound literals") && scspecs)
10955 pedwarn_c11 (start_loc, OPT_Wpedantic,
10956 "ISO C forbids storage class specifiers in compound literals "
10957 "before C2X");
10958 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10959 ? CONSTRUCTOR_NON_CONST (init.value)
10960 : init.original_code == C_MAYBE_CONST_EXPR);
10961 non_const |= !type_expr_const;
10962 unsigned int alignas_align = 0;
10963 if (type != error_mark_node
10964 && type_name->specs->align_log != -1)
10966 alignas_align = 1U << type_name->specs->align_log;
10967 if (alignas_align < min_align_of_type (type))
10969 error_at (type_name->specs->locations[cdw_alignas],
10970 "%<_Alignas%> specifiers cannot reduce "
10971 "alignment of compound literal");
10972 alignas_align = 0;
10975 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10976 alignas_align, scspecs);
10977 set_c_expr_source_range (&expr, init.src_range);
10978 expr.m_decimal = 0;
10979 expr.original_code = ERROR_MARK;
10980 expr.original_type = NULL;
10981 if (type != error_mark_node
10982 && expr.value != error_mark_node
10983 && type_expr)
10985 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10987 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10988 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10990 else
10992 gcc_assert (!non_const);
10993 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10994 type_expr, expr.value);
10997 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
11000 /* Callback function for sizeof_pointer_memaccess_warning to compare
11001 types. */
11003 static bool
11004 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
11006 return comptypes (type1, type2) == 1;
11009 /* Warn for patterns where abs-like function appears to be used incorrectly,
11010 gracefully ignore any non-abs-like function. The warning location should
11011 be LOC. FNDECL is the declaration of called function, it must be a
11012 BUILT_IN_NORMAL function. ARG is the first and only argument of the
11013 call. */
11015 static void
11016 warn_for_abs (location_t loc, tree fndecl, tree arg)
11018 /* Avoid warning in unreachable subexpressions. */
11019 if (c_inhibit_evaluation_warnings)
11020 return;
11022 tree atype = TREE_TYPE (arg);
11024 /* Casts from pointers (and thus arrays and fndecls) will generate
11025 -Wint-conversion warnings. Most other wrong types hopefully lead to type
11026 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
11027 types and possibly other exotic types. */
11028 if (!INTEGRAL_TYPE_P (atype)
11029 && !SCALAR_FLOAT_TYPE_P (atype)
11030 && TREE_CODE (atype) != COMPLEX_TYPE)
11031 return;
11033 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
11035 switch (fcode)
11037 case BUILT_IN_ABS:
11038 case BUILT_IN_LABS:
11039 case BUILT_IN_LLABS:
11040 case BUILT_IN_IMAXABS:
11041 if (!INTEGRAL_TYPE_P (atype))
11043 if (SCALAR_FLOAT_TYPE_P (atype))
11044 warning_at (loc, OPT_Wabsolute_value,
11045 "using integer absolute value function %qD when "
11046 "argument is of floating-point type %qT",
11047 fndecl, atype);
11048 else if (TREE_CODE (atype) == COMPLEX_TYPE)
11049 warning_at (loc, OPT_Wabsolute_value,
11050 "using integer absolute value function %qD when "
11051 "argument is of complex type %qT", fndecl, atype);
11052 else
11053 gcc_unreachable ();
11054 return;
11056 if (TYPE_UNSIGNED (atype))
11057 warning_at (loc, OPT_Wabsolute_value,
11058 "taking the absolute value of unsigned type %qT "
11059 "has no effect", atype);
11060 break;
11062 CASE_FLT_FN (BUILT_IN_FABS):
11063 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
11064 if (!SCALAR_FLOAT_TYPE_P (atype)
11065 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
11067 if (INTEGRAL_TYPE_P (atype))
11068 warning_at (loc, OPT_Wabsolute_value,
11069 "using floating-point absolute value function %qD "
11070 "when argument is of integer type %qT", fndecl, atype);
11071 else if (DECIMAL_FLOAT_TYPE_P (atype))
11072 warning_at (loc, OPT_Wabsolute_value,
11073 "using floating-point absolute value function %qD "
11074 "when argument is of decimal floating-point type %qT",
11075 fndecl, atype);
11076 else if (TREE_CODE (atype) == COMPLEX_TYPE)
11077 warning_at (loc, OPT_Wabsolute_value,
11078 "using floating-point absolute value function %qD when "
11079 "argument is of complex type %qT", fndecl, atype);
11080 else
11081 gcc_unreachable ();
11082 return;
11084 break;
11086 CASE_FLT_FN (BUILT_IN_CABS):
11087 if (TREE_CODE (atype) != COMPLEX_TYPE)
11089 if (INTEGRAL_TYPE_P (atype))
11090 warning_at (loc, OPT_Wabsolute_value,
11091 "using complex absolute value function %qD when "
11092 "argument is of integer type %qT", fndecl, atype);
11093 else if (SCALAR_FLOAT_TYPE_P (atype))
11094 warning_at (loc, OPT_Wabsolute_value,
11095 "using complex absolute value function %qD when "
11096 "argument is of floating-point type %qT",
11097 fndecl, atype);
11098 else
11099 gcc_unreachable ();
11101 return;
11103 break;
11105 case BUILT_IN_FABSD32:
11106 case BUILT_IN_FABSD64:
11107 case BUILT_IN_FABSD128:
11108 if (!DECIMAL_FLOAT_TYPE_P (atype))
11110 if (INTEGRAL_TYPE_P (atype))
11111 warning_at (loc, OPT_Wabsolute_value,
11112 "using decimal floating-point absolute value "
11113 "function %qD when argument is of integer type %qT",
11114 fndecl, atype);
11115 else if (SCALAR_FLOAT_TYPE_P (atype))
11116 warning_at (loc, OPT_Wabsolute_value,
11117 "using decimal floating-point absolute value "
11118 "function %qD when argument is of floating-point "
11119 "type %qT", fndecl, atype);
11120 else if (TREE_CODE (atype) == COMPLEX_TYPE)
11121 warning_at (loc, OPT_Wabsolute_value,
11122 "using decimal floating-point absolute value "
11123 "function %qD when argument is of complex type %qT",
11124 fndecl, atype);
11125 else
11126 gcc_unreachable ();
11127 return;
11129 break;
11131 default:
11132 return;
11135 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
11136 return;
11138 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
11139 if (TREE_CODE (atype) == COMPLEX_TYPE)
11141 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
11142 atype = TREE_TYPE (atype);
11143 ftype = TREE_TYPE (ftype);
11146 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
11147 warning_at (loc, OPT_Wabsolute_value,
11148 "absolute value function %qD given an argument of type %qT "
11149 "but has parameter of type %qT which may cause truncation "
11150 "of value", fndecl, atype, ftype);
11154 /* Parse a postfix expression after the initial primary or compound
11155 literal; that is, parse a series of postfix operators.
11157 EXPR_LOC is the location of the primary expression. */
11159 static struct c_expr
11160 c_parser_postfix_expression_after_primary (c_parser *parser,
11161 location_t expr_loc,
11162 struct c_expr expr)
11164 struct c_expr orig_expr;
11165 tree ident, idx;
11166 location_t sizeof_arg_loc[3], comp_loc;
11167 tree sizeof_arg[3];
11168 unsigned int literal_zero_mask;
11169 unsigned int i;
11170 vec<tree, va_gc> *exprlist;
11171 vec<tree, va_gc> *origtypes = NULL;
11172 vec<location_t> arg_loc = vNULL;
11173 location_t start;
11174 location_t finish;
11176 while (true)
11178 location_t op_loc = c_parser_peek_token (parser)->location;
11179 switch (c_parser_peek_token (parser)->type)
11181 case CPP_OPEN_SQUARE:
11182 /* Array reference. */
11183 c_parser_consume_token (parser);
11184 idx = c_parser_expression (parser).value;
11185 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
11186 "expected %<]%>");
11187 start = expr.get_start ();
11188 finish = parser->tokens_buf[0].location;
11189 expr.value = build_array_ref (op_loc, expr.value, idx);
11190 set_c_expr_source_range (&expr, start, finish);
11191 expr.original_code = ERROR_MARK;
11192 expr.original_type = NULL;
11193 expr.m_decimal = 0;
11194 break;
11195 case CPP_OPEN_PAREN:
11196 /* Function call. */
11198 matching_parens parens;
11199 parens.consume_open (parser);
11200 for (i = 0; i < 3; i++)
11202 sizeof_arg[i] = NULL_TREE;
11203 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
11205 literal_zero_mask = 0;
11206 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11207 exprlist = NULL;
11208 else
11209 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
11210 sizeof_arg_loc, sizeof_arg,
11211 &arg_loc, &literal_zero_mask);
11212 parens.skip_until_found_close (parser);
11214 orig_expr = expr;
11215 mark_exp_read (expr.value);
11216 if (warn_sizeof_pointer_memaccess)
11217 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
11218 expr.value, exprlist,
11219 sizeof_arg,
11220 sizeof_ptr_memacc_comptypes);
11221 if (TREE_CODE (expr.value) == FUNCTION_DECL)
11223 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
11224 && vec_safe_length (exprlist) == 3)
11226 tree arg0 = (*exprlist)[0];
11227 tree arg2 = (*exprlist)[2];
11228 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
11230 if (warn_absolute_value
11231 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
11232 && vec_safe_length (exprlist) == 1)
11233 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
11236 start = expr.get_start ();
11237 finish = parser->tokens_buf[0].get_finish ();
11238 expr.value
11239 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
11240 exprlist, origtypes);
11241 set_c_expr_source_range (&expr, start, finish);
11242 expr.m_decimal = 0;
11244 expr.original_code = ERROR_MARK;
11245 if (TREE_CODE (expr.value) == INTEGER_CST
11246 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
11247 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
11248 expr.original_code = C_MAYBE_CONST_EXPR;
11249 expr.original_type = NULL;
11250 if (exprlist)
11252 release_tree_vector (exprlist);
11253 release_tree_vector (origtypes);
11255 arg_loc.release ();
11256 break;
11257 case CPP_DOT:
11258 /* Structure element reference. */
11259 c_parser_consume_token (parser);
11260 expr = default_function_array_conversion (expr_loc, expr);
11261 if (c_parser_next_token_is (parser, CPP_NAME))
11263 c_token *comp_tok = c_parser_peek_token (parser);
11264 ident = comp_tok->value;
11265 comp_loc = comp_tok->location;
11267 else
11269 c_parser_error (parser, "expected identifier");
11270 expr.set_error ();
11271 expr.original_code = ERROR_MARK;
11272 expr.original_type = NULL;
11273 return expr;
11275 start = expr.get_start ();
11276 finish = c_parser_peek_token (parser)->get_finish ();
11277 c_parser_consume_token (parser);
11278 expr.value = build_component_ref (op_loc, expr.value, ident,
11279 comp_loc, UNKNOWN_LOCATION);
11280 set_c_expr_source_range (&expr, start, finish);
11281 expr.original_code = ERROR_MARK;
11282 if (TREE_CODE (expr.value) != COMPONENT_REF)
11283 expr.original_type = NULL;
11284 else
11286 /* Remember the original type of a bitfield. */
11287 tree field = TREE_OPERAND (expr.value, 1);
11288 if (TREE_CODE (field) != FIELD_DECL)
11289 expr.original_type = NULL;
11290 else
11291 expr.original_type = DECL_BIT_FIELD_TYPE (field);
11293 expr.m_decimal = 0;
11294 break;
11295 case CPP_DEREF:
11296 /* Structure element reference. */
11297 c_parser_consume_token (parser);
11298 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
11299 if (c_parser_next_token_is (parser, CPP_NAME))
11301 c_token *comp_tok = c_parser_peek_token (parser);
11302 ident = comp_tok->value;
11303 comp_loc = comp_tok->location;
11305 else
11307 c_parser_error (parser, "expected identifier");
11308 expr.set_error ();
11309 expr.original_code = ERROR_MARK;
11310 expr.original_type = NULL;
11311 return expr;
11313 start = expr.get_start ();
11314 finish = c_parser_peek_token (parser)->get_finish ();
11315 c_parser_consume_token (parser);
11316 expr.value = build_component_ref (op_loc,
11317 build_indirect_ref (op_loc,
11318 expr.value,
11319 RO_ARROW),
11320 ident, comp_loc,
11321 expr.get_location ());
11322 set_c_expr_source_range (&expr, start, finish);
11323 expr.original_code = ERROR_MARK;
11324 if (TREE_CODE (expr.value) != COMPONENT_REF)
11325 expr.original_type = NULL;
11326 else
11328 /* Remember the original type of a bitfield. */
11329 tree field = TREE_OPERAND (expr.value, 1);
11330 if (TREE_CODE (field) != FIELD_DECL)
11331 expr.original_type = NULL;
11332 else
11333 expr.original_type = DECL_BIT_FIELD_TYPE (field);
11335 expr.m_decimal = 0;
11336 break;
11337 case CPP_PLUS_PLUS:
11338 /* Postincrement. */
11339 start = expr.get_start ();
11340 finish = c_parser_peek_token (parser)->get_finish ();
11341 c_parser_consume_token (parser);
11342 expr = default_function_array_read_conversion (expr_loc, expr);
11343 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
11344 expr.value, false);
11345 set_c_expr_source_range (&expr, start, finish);
11346 expr.original_code = ERROR_MARK;
11347 expr.original_type = NULL;
11348 break;
11349 case CPP_MINUS_MINUS:
11350 /* Postdecrement. */
11351 start = expr.get_start ();
11352 finish = c_parser_peek_token (parser)->get_finish ();
11353 c_parser_consume_token (parser);
11354 expr = default_function_array_read_conversion (expr_loc, expr);
11355 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
11356 expr.value, false);
11357 set_c_expr_source_range (&expr, start, finish);
11358 expr.original_code = ERROR_MARK;
11359 expr.original_type = NULL;
11360 break;
11361 default:
11362 return expr;
11367 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
11369 expression:
11370 assignment-expression
11371 expression , assignment-expression
11374 static struct c_expr
11375 c_parser_expression (c_parser *parser)
11377 location_t tloc = c_parser_peek_token (parser)->location;
11378 struct c_expr expr;
11379 expr = c_parser_expr_no_commas (parser, NULL);
11380 if (c_parser_next_token_is (parser, CPP_COMMA))
11381 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
11382 while (c_parser_next_token_is (parser, CPP_COMMA))
11384 struct c_expr next;
11385 tree lhsval;
11386 location_t loc = c_parser_peek_token (parser)->location;
11387 location_t expr_loc;
11388 c_parser_consume_token (parser);
11389 expr_loc = c_parser_peek_token (parser)->location;
11390 lhsval = expr.value;
11391 while (TREE_CODE (lhsval) == COMPOUND_EXPR
11392 || TREE_CODE (lhsval) == NOP_EXPR)
11394 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
11395 lhsval = TREE_OPERAND (lhsval, 1);
11396 else
11397 lhsval = TREE_OPERAND (lhsval, 0);
11399 if (DECL_P (lhsval) || handled_component_p (lhsval))
11400 mark_exp_read (lhsval);
11401 next = c_parser_expr_no_commas (parser, NULL);
11402 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
11403 expr.value = build_compound_expr (loc, expr.value, next.value);
11404 expr.original_code = COMPOUND_EXPR;
11405 expr.original_type = next.original_type;
11406 expr.m_decimal = 0;
11408 return expr;
11411 /* Parse an expression and convert functions or arrays to pointers and
11412 lvalues to rvalues. */
11414 static struct c_expr
11415 c_parser_expression_conv (c_parser *parser)
11417 struct c_expr expr;
11418 location_t loc = c_parser_peek_token (parser)->location;
11419 expr = c_parser_expression (parser);
11420 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
11421 return expr;
11424 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
11425 argument is a literal zero alone and if so, set it in literal_zero_mask. */
11427 static inline void
11428 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
11429 unsigned int idx)
11431 if (idx >= HOST_BITS_PER_INT)
11432 return;
11434 c_token *tok = c_parser_peek_token (parser);
11435 switch (tok->type)
11437 case CPP_NUMBER:
11438 case CPP_CHAR:
11439 case CPP_WCHAR:
11440 case CPP_CHAR16:
11441 case CPP_CHAR32:
11442 case CPP_UTF8CHAR:
11443 /* If a parameter is literal zero alone, remember it
11444 for -Wmemset-transposed-args warning. */
11445 if (integer_zerop (tok->value)
11446 && !TREE_OVERFLOW (tok->value)
11447 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11448 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
11449 *literal_zero_mask |= 1U << idx;
11450 default:
11451 break;
11455 /* Parse a non-empty list of expressions. If CONVERT_P, convert
11456 functions and arrays to pointers and lvalues to rvalues. If
11457 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
11458 locations of function arguments into this vector.
11460 nonempty-expr-list:
11461 assignment-expression
11462 nonempty-expr-list , assignment-expression
11465 static vec<tree, va_gc> *
11466 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
11467 vec<tree, va_gc> **p_orig_types,
11468 location_t *sizeof_arg_loc, tree *sizeof_arg,
11469 vec<location_t> *locations,
11470 unsigned int *literal_zero_mask)
11472 vec<tree, va_gc> *ret;
11473 vec<tree, va_gc> *orig_types;
11474 struct c_expr expr;
11475 unsigned int idx = 0;
11477 ret = make_tree_vector ();
11478 if (p_orig_types == NULL)
11479 orig_types = NULL;
11480 else
11481 orig_types = make_tree_vector ();
11483 if (literal_zero_mask)
11484 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
11485 expr = c_parser_expr_no_commas (parser, NULL);
11486 if (convert_p)
11487 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
11488 if (fold_p)
11489 expr.value = c_fully_fold (expr.value, false, NULL);
11490 ret->quick_push (expr.value);
11491 if (orig_types)
11492 orig_types->quick_push (expr.original_type);
11493 if (locations)
11494 locations->safe_push (expr.get_location ());
11495 if (sizeof_arg != NULL
11496 && (expr.original_code == SIZEOF_EXPR
11497 || expr.original_code == PAREN_SIZEOF_EXPR))
11499 sizeof_arg[0] = c_last_sizeof_arg;
11500 sizeof_arg_loc[0] = c_last_sizeof_loc;
11502 while (c_parser_next_token_is (parser, CPP_COMMA))
11504 c_parser_consume_token (parser);
11505 if (literal_zero_mask)
11506 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
11507 expr = c_parser_expr_no_commas (parser, NULL);
11508 if (convert_p)
11509 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
11510 true);
11511 if (fold_p)
11512 expr.value = c_fully_fold (expr.value, false, NULL);
11513 vec_safe_push (ret, expr.value);
11514 if (orig_types)
11515 vec_safe_push (orig_types, expr.original_type);
11516 if (locations)
11517 locations->safe_push (expr.get_location ());
11518 if (++idx < 3
11519 && sizeof_arg != NULL
11520 && (expr.original_code == SIZEOF_EXPR
11521 || expr.original_code == PAREN_SIZEOF_EXPR))
11523 sizeof_arg[idx] = c_last_sizeof_arg;
11524 sizeof_arg_loc[idx] = c_last_sizeof_loc;
11527 if (orig_types)
11528 *p_orig_types = orig_types;
11529 return ret;
11532 /* Parse Objective-C-specific constructs. */
11534 /* Parse an objc-class-definition.
11536 objc-class-definition:
11537 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
11538 objc-class-instance-variables[opt] objc-methodprotolist @end
11539 @implementation identifier objc-superclass[opt]
11540 objc-class-instance-variables[opt]
11541 @interface identifier ( identifier ) objc-protocol-refs[opt]
11542 objc-methodprotolist @end
11543 @interface identifier ( ) objc-protocol-refs[opt]
11544 objc-methodprotolist @end
11545 @implementation identifier ( identifier )
11547 objc-superclass:
11548 : identifier
11550 "@interface identifier (" must start "@interface identifier (
11551 identifier ) ...": objc-methodprotolist in the first production may
11552 not start with a parenthesized identifier as a declarator of a data
11553 definition with no declaration specifiers if the objc-superclass,
11554 objc-protocol-refs and objc-class-instance-variables are omitted. */
11556 static void
11557 c_parser_objc_class_definition (c_parser *parser, tree attributes)
11559 bool iface_p;
11560 tree id1;
11561 tree superclass;
11562 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
11563 iface_p = true;
11564 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
11565 iface_p = false;
11566 else
11567 gcc_unreachable ();
11569 c_parser_consume_token (parser);
11570 if (c_parser_next_token_is_not (parser, CPP_NAME))
11572 c_parser_error (parser, "expected identifier");
11573 return;
11575 id1 = c_parser_peek_token (parser)->value;
11576 location_t loc1 = c_parser_peek_token (parser)->location;
11577 c_parser_consume_token (parser);
11578 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11580 /* We have a category or class extension. */
11581 tree id2;
11582 tree proto = NULL_TREE;
11583 matching_parens parens;
11584 parens.consume_open (parser);
11585 if (c_parser_next_token_is_not (parser, CPP_NAME))
11587 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11589 /* We have a class extension. */
11590 id2 = NULL_TREE;
11592 else
11594 c_parser_error (parser, "expected identifier or %<)%>");
11595 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
11596 return;
11599 else
11601 id2 = c_parser_peek_token (parser)->value;
11602 c_parser_consume_token (parser);
11604 parens.skip_until_found_close (parser);
11605 if (!iface_p)
11607 objc_start_category_implementation (id1, id2);
11608 return;
11610 if (c_parser_next_token_is (parser, CPP_LESS))
11611 proto = c_parser_objc_protocol_refs (parser);
11612 objc_start_category_interface (id1, id2, proto, attributes);
11613 c_parser_objc_methodprotolist (parser);
11614 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11615 objc_finish_interface ();
11616 return;
11618 if (c_parser_next_token_is (parser, CPP_COLON))
11620 c_parser_consume_token (parser);
11621 if (c_parser_next_token_is_not (parser, CPP_NAME))
11623 c_parser_error (parser, "expected identifier");
11624 return;
11626 superclass = c_parser_peek_token (parser)->value;
11627 c_parser_consume_token (parser);
11629 else
11630 superclass = NULL_TREE;
11631 if (iface_p)
11633 tree proto = NULL_TREE;
11634 if (c_parser_next_token_is (parser, CPP_LESS))
11635 proto = c_parser_objc_protocol_refs (parser);
11636 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
11638 else
11639 objc_start_class_implementation (id1, superclass);
11640 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11641 c_parser_objc_class_instance_variables (parser);
11642 if (iface_p)
11644 objc_continue_interface ();
11645 c_parser_objc_methodprotolist (parser);
11646 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11647 objc_finish_interface ();
11649 else
11651 objc_continue_implementation ();
11652 return;
11656 /* Parse objc-class-instance-variables.
11658 objc-class-instance-variables:
11659 { objc-instance-variable-decl-list[opt] }
11661 objc-instance-variable-decl-list:
11662 objc-visibility-spec
11663 objc-instance-variable-decl ;
11665 objc-instance-variable-decl-list objc-visibility-spec
11666 objc-instance-variable-decl-list objc-instance-variable-decl ;
11667 objc-instance-variable-decl-list ;
11669 objc-visibility-spec:
11670 @private
11671 @protected
11672 @public
11674 objc-instance-variable-decl:
11675 struct-declaration
11678 static void
11679 c_parser_objc_class_instance_variables (c_parser *parser)
11681 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
11682 c_parser_consume_token (parser);
11683 while (c_parser_next_token_is_not (parser, CPP_EOF))
11685 tree decls;
11686 /* Parse any stray semicolon. */
11687 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11689 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11690 "extra semicolon");
11691 c_parser_consume_token (parser);
11692 continue;
11694 /* Stop if at the end of the instance variables. */
11695 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11697 c_parser_consume_token (parser);
11698 break;
11700 /* Parse any objc-visibility-spec. */
11701 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11703 c_parser_consume_token (parser);
11704 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11705 continue;
11707 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11709 c_parser_consume_token (parser);
11710 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11711 continue;
11713 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11715 c_parser_consume_token (parser);
11716 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11717 continue;
11719 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11721 c_parser_consume_token (parser);
11722 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11723 continue;
11725 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11727 c_parser_pragma (parser, pragma_external, NULL);
11728 continue;
11731 /* Parse some comma-separated declarations. */
11732 decls = c_parser_struct_declaration (parser);
11733 if (decls == NULL)
11735 /* There is a syntax error. We want to skip the offending
11736 tokens up to the next ';' (included) or '}'
11737 (excluded). */
11739 /* First, skip manually a ')' or ']'. This is because they
11740 reduce the nesting level, so c_parser_skip_until_found()
11741 wouldn't be able to skip past them. */
11742 c_token *token = c_parser_peek_token (parser);
11743 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11744 c_parser_consume_token (parser);
11746 /* Then, do the standard skipping. */
11747 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11749 /* We hopefully recovered. Start normal parsing again. */
11750 parser->error = false;
11751 continue;
11753 else
11755 /* Comma-separated instance variables are chained together
11756 in reverse order; add them one by one. */
11757 tree ivar = nreverse (decls);
11758 for (; ivar; ivar = DECL_CHAIN (ivar))
11759 objc_add_instance_variable (copy_node (ivar));
11761 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11765 /* Parse an objc-class-declaration.
11767 objc-class-declaration:
11768 @class identifier-list ;
11771 static void
11772 c_parser_objc_class_declaration (c_parser *parser)
11774 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11775 c_parser_consume_token (parser);
11776 /* Any identifiers, including those declared as type names, are OK
11777 here. */
11778 while (true)
11780 tree id;
11781 if (c_parser_next_token_is_not (parser, CPP_NAME))
11783 c_parser_error (parser, "expected identifier");
11784 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11785 parser->error = false;
11786 return;
11788 id = c_parser_peek_token (parser)->value;
11789 objc_declare_class (id);
11790 c_parser_consume_token (parser);
11791 if (c_parser_next_token_is (parser, CPP_COMMA))
11792 c_parser_consume_token (parser);
11793 else
11794 break;
11796 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11799 /* Parse an objc-alias-declaration.
11801 objc-alias-declaration:
11802 @compatibility_alias identifier identifier ;
11805 static void
11806 c_parser_objc_alias_declaration (c_parser *parser)
11808 tree id1, id2;
11809 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11810 c_parser_consume_token (parser);
11811 if (c_parser_next_token_is_not (parser, CPP_NAME))
11813 c_parser_error (parser, "expected identifier");
11814 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11815 return;
11817 id1 = c_parser_peek_token (parser)->value;
11818 c_parser_consume_token (parser);
11819 if (c_parser_next_token_is_not (parser, CPP_NAME))
11821 c_parser_error (parser, "expected identifier");
11822 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11823 return;
11825 id2 = c_parser_peek_token (parser)->value;
11826 c_parser_consume_token (parser);
11827 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11828 objc_declare_alias (id1, id2);
11831 /* Parse an objc-protocol-definition.
11833 objc-protocol-definition:
11834 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11835 @protocol identifier-list ;
11837 "@protocol identifier ;" should be resolved as "@protocol
11838 identifier-list ;": objc-methodprotolist may not start with a
11839 semicolon in the first alternative if objc-protocol-refs are
11840 omitted. */
11842 static void
11843 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11845 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11847 c_parser_consume_token (parser);
11848 if (c_parser_next_token_is_not (parser, CPP_NAME))
11850 c_parser_error (parser, "expected identifier");
11851 return;
11853 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11854 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11856 /* Any identifiers, including those declared as type names, are
11857 OK here. */
11858 while (true)
11860 tree id;
11861 if (c_parser_next_token_is_not (parser, CPP_NAME))
11863 c_parser_error (parser, "expected identifier");
11864 break;
11866 id = c_parser_peek_token (parser)->value;
11867 objc_declare_protocol (id, attributes);
11868 c_parser_consume_token (parser);
11869 if (c_parser_next_token_is (parser, CPP_COMMA))
11870 c_parser_consume_token (parser);
11871 else
11872 break;
11874 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11876 else
11878 tree id = c_parser_peek_token (parser)->value;
11879 tree proto = NULL_TREE;
11880 c_parser_consume_token (parser);
11881 if (c_parser_next_token_is (parser, CPP_LESS))
11882 proto = c_parser_objc_protocol_refs (parser);
11883 parser->objc_pq_context = true;
11884 objc_start_protocol (id, proto, attributes);
11885 c_parser_objc_methodprotolist (parser);
11886 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11887 parser->objc_pq_context = false;
11888 objc_finish_interface ();
11892 /* Parse an objc-method-type.
11894 objc-method-type:
11898 Return true if it is a class method (+) and false if it is
11899 an instance method (-).
11901 static inline bool
11902 c_parser_objc_method_type (c_parser *parser)
11904 switch (c_parser_peek_token (parser)->type)
11906 case CPP_PLUS:
11907 c_parser_consume_token (parser);
11908 return true;
11909 case CPP_MINUS:
11910 c_parser_consume_token (parser);
11911 return false;
11912 default:
11913 gcc_unreachable ();
11917 /* Parse an objc-method-definition.
11919 objc-method-definition:
11920 objc-method-type objc-method-decl ;[opt] compound-statement
11923 static void
11924 c_parser_objc_method_definition (c_parser *parser)
11926 bool is_class_method = c_parser_objc_method_type (parser);
11927 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11928 parser->objc_pq_context = true;
11929 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11930 &expr);
11931 if (decl == error_mark_node)
11932 return; /* Bail here. */
11934 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11936 c_parser_consume_token (parser);
11937 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11938 "extra semicolon in method definition specified");
11941 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11943 c_parser_error (parser, "expected %<{%>");
11944 return;
11947 parser->objc_pq_context = false;
11948 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11950 add_stmt (c_parser_compound_statement (parser));
11951 objc_finish_method_definition (current_function_decl);
11953 else
11955 /* This code is executed when we find a method definition
11956 outside of an @implementation context (or invalid for other
11957 reasons). Parse the method (to keep going) but do not emit
11958 any code.
11960 c_parser_compound_statement (parser);
11964 /* Parse an objc-methodprotolist.
11966 objc-methodprotolist:
11967 empty
11968 objc-methodprotolist objc-methodproto
11969 objc-methodprotolist declaration
11970 objc-methodprotolist ;
11971 @optional
11972 @required
11974 The declaration is a data definition, which may be missing
11975 declaration specifiers under the same rules and diagnostics as
11976 other data definitions outside functions, and the stray semicolon
11977 is diagnosed the same way as a stray semicolon outside a
11978 function. */
11980 static void
11981 c_parser_objc_methodprotolist (c_parser *parser)
11983 while (true)
11985 /* The list is terminated by @end. */
11986 switch (c_parser_peek_token (parser)->type)
11988 case CPP_SEMICOLON:
11989 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11990 "ISO C does not allow extra %<;%> outside of a function");
11991 c_parser_consume_token (parser);
11992 break;
11993 case CPP_PLUS:
11994 case CPP_MINUS:
11995 c_parser_objc_methodproto (parser);
11996 break;
11997 case CPP_PRAGMA:
11998 c_parser_pragma (parser, pragma_external, NULL);
11999 break;
12000 case CPP_EOF:
12001 return;
12002 default:
12003 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
12004 return;
12005 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
12006 c_parser_objc_at_property_declaration (parser);
12007 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
12009 objc_set_method_opt (true);
12010 c_parser_consume_token (parser);
12012 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
12014 objc_set_method_opt (false);
12015 c_parser_consume_token (parser);
12017 else
12018 c_parser_declaration_or_fndef (parser, false, false, true,
12019 false, true);
12020 break;
12025 /* Parse an objc-methodproto.
12027 objc-methodproto:
12028 objc-method-type objc-method-decl ;
12031 static void
12032 c_parser_objc_methodproto (c_parser *parser)
12034 bool is_class_method = c_parser_objc_method_type (parser);
12035 tree decl, attributes = NULL_TREE;
12037 /* Remember protocol qualifiers in prototypes. */
12038 parser->objc_pq_context = true;
12039 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
12040 NULL);
12041 /* Forget protocol qualifiers now. */
12042 parser->objc_pq_context = false;
12044 /* Do not allow the presence of attributes to hide an erroneous
12045 method implementation in the interface section. */
12046 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
12048 c_parser_error (parser, "expected %<;%>");
12049 return;
12052 if (decl != error_mark_node)
12053 objc_add_method_declaration (is_class_method, decl, attributes);
12055 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12058 /* If we are at a position that method attributes may be present, check that
12059 there are not any parsed already (a syntax error) and then collect any
12060 specified at the current location. Finally, if new attributes were present,
12061 check that the next token is legal ( ';' for decls and '{' for defs). */
12063 static bool
12064 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
12066 bool bad = false;
12067 if (*attributes)
12069 c_parser_error (parser,
12070 "method attributes must be specified at the end only");
12071 *attributes = NULL_TREE;
12072 bad = true;
12075 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
12076 *attributes = c_parser_gnu_attributes (parser);
12078 /* If there were no attributes here, just report any earlier error. */
12079 if (*attributes == NULL_TREE || bad)
12080 return bad;
12082 /* If the attributes are followed by a ; or {, then just report any earlier
12083 error. */
12084 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
12085 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
12086 return bad;
12088 /* We've got attributes, but not at the end. */
12089 c_parser_error (parser,
12090 "expected %<;%> or %<{%> after method attribute definition");
12091 return true;
12094 /* Parse an objc-method-decl.
12096 objc-method-decl:
12097 ( objc-type-name ) objc-selector
12098 objc-selector
12099 ( objc-type-name ) objc-keyword-selector objc-optparmlist
12100 objc-keyword-selector objc-optparmlist
12101 gnu-attributes
12103 objc-keyword-selector:
12104 objc-keyword-decl
12105 objc-keyword-selector objc-keyword-decl
12107 objc-keyword-decl:
12108 objc-selector : ( objc-type-name ) identifier
12109 objc-selector : identifier
12110 : ( objc-type-name ) identifier
12111 : identifier
12113 objc-optparmlist:
12114 objc-optparms objc-optellipsis
12116 objc-optparms:
12117 empty
12118 objc-opt-parms , parameter-declaration
12120 objc-optellipsis:
12121 empty
12122 , ...
12125 static tree
12126 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
12127 tree *attributes, tree *expr)
12129 tree type = NULL_TREE;
12130 tree sel;
12131 tree parms = NULL_TREE;
12132 bool ellipsis = false;
12133 bool attr_err = false;
12135 *attributes = NULL_TREE;
12136 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12138 matching_parens parens;
12139 parens.consume_open (parser);
12140 type = c_parser_objc_type_name (parser);
12141 parens.skip_until_found_close (parser);
12143 sel = c_parser_objc_selector (parser);
12144 /* If there is no selector, or a colon follows, we have an
12145 objc-keyword-selector. If there is a selector, and a colon does
12146 not follow, that selector ends the objc-method-decl. */
12147 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
12149 tree tsel = sel;
12150 tree list = NULL_TREE;
12151 while (true)
12153 tree atype = NULL_TREE, id, keyworddecl;
12154 tree param_attr = NULL_TREE;
12155 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
12156 break;
12157 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12159 c_parser_consume_token (parser);
12160 atype = c_parser_objc_type_name (parser);
12161 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
12162 "expected %<)%>");
12164 /* New ObjC allows attributes on method parameters. */
12165 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
12166 param_attr = c_parser_gnu_attributes (parser);
12167 if (c_parser_next_token_is_not (parser, CPP_NAME))
12169 c_parser_error (parser, "expected identifier");
12170 return error_mark_node;
12172 id = c_parser_peek_token (parser)->value;
12173 c_parser_consume_token (parser);
12174 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
12175 list = chainon (list, keyworddecl);
12176 tsel = c_parser_objc_selector (parser);
12177 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
12178 break;
12181 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
12183 /* Parse the optional parameter list. Optional Objective-C
12184 method parameters follow the C syntax, and may include '...'
12185 to denote a variable number of arguments. */
12186 parms = make_node (TREE_LIST);
12187 while (c_parser_next_token_is (parser, CPP_COMMA))
12189 struct c_parm *parm;
12190 c_parser_consume_token (parser);
12191 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
12193 ellipsis = true;
12194 c_parser_consume_token (parser);
12195 attr_err |= c_parser_objc_maybe_method_attributes
12196 (parser, attributes) ;
12197 break;
12199 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
12200 if (parm == NULL)
12201 break;
12202 parms = chainon (parms,
12203 build_tree_list (NULL_TREE, grokparm (parm, expr)));
12205 sel = list;
12207 else
12208 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
12210 if (sel == NULL)
12212 c_parser_error (parser, "objective-c method declaration is expected");
12213 return error_mark_node;
12216 if (attr_err)
12217 return error_mark_node;
12219 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
12222 /* Parse an objc-type-name.
12224 objc-type-name:
12225 objc-type-qualifiers[opt] type-name
12226 objc-type-qualifiers[opt]
12228 objc-type-qualifiers:
12229 objc-type-qualifier
12230 objc-type-qualifiers objc-type-qualifier
12232 objc-type-qualifier: one of
12233 in out inout bycopy byref oneway
12236 static tree
12237 c_parser_objc_type_name (c_parser *parser)
12239 tree quals = NULL_TREE;
12240 struct c_type_name *type_name = NULL;
12241 tree type = NULL_TREE;
12242 while (true)
12244 c_token *token = c_parser_peek_token (parser);
12245 if (token->type == CPP_KEYWORD
12246 && (token->keyword == RID_IN
12247 || token->keyword == RID_OUT
12248 || token->keyword == RID_INOUT
12249 || token->keyword == RID_BYCOPY
12250 || token->keyword == RID_BYREF
12251 || token->keyword == RID_ONEWAY))
12253 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
12254 c_parser_consume_token (parser);
12256 else
12257 break;
12259 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
12260 type_name = c_parser_type_name (parser);
12261 if (type_name)
12262 type = groktypename (type_name, NULL, NULL);
12264 /* If the type is unknown, and error has already been produced and
12265 we need to recover from the error. In that case, use NULL_TREE
12266 for the type, as if no type had been specified; this will use the
12267 default type ('id') which is good for error recovery. */
12268 if (type == error_mark_node)
12269 type = NULL_TREE;
12271 return build_tree_list (quals, type);
12274 /* Parse objc-protocol-refs.
12276 objc-protocol-refs:
12277 < identifier-list >
12280 static tree
12281 c_parser_objc_protocol_refs (c_parser *parser)
12283 tree list = NULL_TREE;
12284 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
12285 c_parser_consume_token (parser);
12286 /* Any identifiers, including those declared as type names, are OK
12287 here. */
12288 while (true)
12290 tree id;
12291 if (c_parser_next_token_is_not (parser, CPP_NAME))
12293 c_parser_error (parser, "expected identifier");
12294 break;
12296 id = c_parser_peek_token (parser)->value;
12297 list = chainon (list, build_tree_list (NULL_TREE, id));
12298 c_parser_consume_token (parser);
12299 if (c_parser_next_token_is (parser, CPP_COMMA))
12300 c_parser_consume_token (parser);
12301 else
12302 break;
12304 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
12305 return list;
12308 /* Parse an objc-try-catch-finally-statement.
12310 objc-try-catch-finally-statement:
12311 @try compound-statement objc-catch-list[opt]
12312 @try compound-statement objc-catch-list[opt] @finally compound-statement
12314 objc-catch-list:
12315 @catch ( objc-catch-parameter-declaration ) compound-statement
12316 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
12318 objc-catch-parameter-declaration:
12319 parameter-declaration
12320 '...'
12322 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
12324 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
12325 for C++. Keep them in sync. */
12327 static void
12328 c_parser_objc_try_catch_finally_statement (c_parser *parser)
12330 location_t location;
12331 tree stmt;
12333 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
12334 c_parser_consume_token (parser);
12335 location = c_parser_peek_token (parser)->location;
12336 objc_maybe_warn_exceptions (location);
12337 stmt = c_parser_compound_statement (parser);
12338 objc_begin_try_stmt (location, stmt);
12340 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
12342 struct c_parm *parm;
12343 tree parameter_declaration = error_mark_node;
12344 bool seen_open_paren = false;
12346 c_parser_consume_token (parser);
12347 matching_parens parens;
12348 if (!parens.require_open (parser))
12349 seen_open_paren = true;
12350 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
12352 /* We have "@catch (...)" (where the '...' are literally
12353 what is in the code). Skip the '...'.
12354 parameter_declaration is set to NULL_TREE, and
12355 objc_being_catch_clauses() knows that that means
12356 '...'. */
12357 c_parser_consume_token (parser);
12358 parameter_declaration = NULL_TREE;
12360 else
12362 /* We have "@catch (NSException *exception)" or something
12363 like that. Parse the parameter declaration. */
12364 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
12365 if (parm == NULL)
12366 parameter_declaration = error_mark_node;
12367 else
12368 parameter_declaration = grokparm (parm, NULL);
12370 if (seen_open_paren)
12371 parens.require_close (parser);
12372 else
12374 /* If there was no open parenthesis, we are recovering from
12375 an error, and we are trying to figure out what mistake
12376 the user has made. */
12378 /* If there is an immediate closing parenthesis, the user
12379 probably forgot the opening one (ie, they typed "@catch
12380 NSException *e)". Parse the closing parenthesis and keep
12381 going. */
12382 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12383 c_parser_consume_token (parser);
12385 /* If these is no immediate closing parenthesis, the user
12386 probably doesn't know that parenthesis are required at
12387 all (ie, they typed "@catch NSException *e"). So, just
12388 forget about the closing parenthesis and keep going. */
12390 objc_begin_catch_clause (parameter_declaration);
12391 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
12392 c_parser_compound_statement_nostart (parser);
12393 objc_finish_catch_clause ();
12395 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
12397 c_parser_consume_token (parser);
12398 location = c_parser_peek_token (parser)->location;
12399 stmt = c_parser_compound_statement (parser);
12400 objc_build_finally_clause (location, stmt);
12402 objc_finish_try_stmt ();
12405 /* Parse an objc-synchronized-statement.
12407 objc-synchronized-statement:
12408 @synchronized ( expression ) compound-statement
12411 static void
12412 c_parser_objc_synchronized_statement (c_parser *parser)
12414 location_t loc;
12415 tree expr, stmt;
12416 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
12417 c_parser_consume_token (parser);
12418 loc = c_parser_peek_token (parser)->location;
12419 objc_maybe_warn_exceptions (loc);
12420 matching_parens parens;
12421 if (parens.require_open (parser))
12423 struct c_expr ce = c_parser_expression (parser);
12424 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
12425 expr = ce.value;
12426 expr = c_fully_fold (expr, false, NULL);
12427 parens.skip_until_found_close (parser);
12429 else
12430 expr = error_mark_node;
12431 stmt = c_parser_compound_statement (parser);
12432 objc_build_synchronized (loc, expr, stmt);
12435 /* Parse an objc-selector; return NULL_TREE without an error if the
12436 next token is not an objc-selector.
12438 objc-selector:
12439 identifier
12440 one of
12441 enum struct union if else while do for switch case default
12442 break continue return goto asm sizeof typeof typeof_unqual __alignof
12443 unsigned long const short volatile signed restrict _Complex
12444 in out inout bycopy byref oneway int char float double void _Bool
12445 _Atomic
12447 ??? Why this selection of keywords but not, for example, storage
12448 class specifiers? */
12450 static tree
12451 c_parser_objc_selector (c_parser *parser)
12453 c_token *token = c_parser_peek_token (parser);
12454 tree value = token->value;
12455 if (token->type == CPP_NAME)
12457 c_parser_consume_token (parser);
12458 return value;
12460 if (token->type != CPP_KEYWORD)
12461 return NULL_TREE;
12462 switch (token->keyword)
12464 case RID_ENUM:
12465 case RID_STRUCT:
12466 case RID_UNION:
12467 case RID_IF:
12468 case RID_ELSE:
12469 case RID_WHILE:
12470 case RID_DO:
12471 case RID_FOR:
12472 case RID_SWITCH:
12473 case RID_CASE:
12474 case RID_DEFAULT:
12475 case RID_BREAK:
12476 case RID_CONTINUE:
12477 case RID_RETURN:
12478 case RID_GOTO:
12479 case RID_ASM:
12480 case RID_SIZEOF:
12481 case RID_TYPEOF:
12482 case RID_TYPEOF_UNQUAL:
12483 case RID_ALIGNOF:
12484 case RID_UNSIGNED:
12485 case RID_LONG:
12486 case RID_CONST:
12487 case RID_SHORT:
12488 case RID_VOLATILE:
12489 case RID_SIGNED:
12490 case RID_RESTRICT:
12491 case RID_COMPLEX:
12492 case RID_IN:
12493 case RID_OUT:
12494 case RID_INOUT:
12495 case RID_BYCOPY:
12496 case RID_BYREF:
12497 case RID_ONEWAY:
12498 case RID_INT:
12499 case RID_CHAR:
12500 case RID_FLOAT:
12501 case RID_DOUBLE:
12502 CASE_RID_FLOATN_NX:
12503 case RID_VOID:
12504 case RID_BOOL:
12505 case RID_ATOMIC:
12506 case RID_AUTO_TYPE:
12507 case RID_INT_N_0:
12508 case RID_INT_N_1:
12509 case RID_INT_N_2:
12510 case RID_INT_N_3:
12511 c_parser_consume_token (parser);
12512 return value;
12513 default:
12514 return NULL_TREE;
12518 /* Parse an objc-selector-arg.
12520 objc-selector-arg:
12521 objc-selector
12522 objc-keywordname-list
12524 objc-keywordname-list:
12525 objc-keywordname
12526 objc-keywordname-list objc-keywordname
12528 objc-keywordname:
12529 objc-selector :
12533 static tree
12534 c_parser_objc_selector_arg (c_parser *parser)
12536 tree sel = c_parser_objc_selector (parser);
12537 tree list = NULL_TREE;
12538 if (sel
12539 && c_parser_next_token_is_not (parser, CPP_COLON)
12540 && c_parser_next_token_is_not (parser, CPP_SCOPE))
12541 return sel;
12542 while (true)
12544 if (c_parser_next_token_is (parser, CPP_SCOPE))
12546 c_parser_consume_token (parser);
12547 list = chainon (list, build_tree_list (sel, NULL_TREE));
12548 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
12550 else
12552 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
12553 return list;
12554 list = chainon (list, build_tree_list (sel, NULL_TREE));
12556 sel = c_parser_objc_selector (parser);
12557 if (!sel
12558 && c_parser_next_token_is_not (parser, CPP_COLON)
12559 && c_parser_next_token_is_not (parser, CPP_SCOPE))
12560 break;
12562 return list;
12565 /* Parse an objc-receiver.
12567 objc-receiver:
12568 expression
12569 class-name
12570 type-name
12573 static tree
12574 c_parser_objc_receiver (c_parser *parser)
12576 location_t loc = c_parser_peek_token (parser)->location;
12578 if (c_parser_peek_token (parser)->type == CPP_NAME
12579 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
12580 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
12582 tree id = c_parser_peek_token (parser)->value;
12583 c_parser_consume_token (parser);
12584 return objc_get_class_reference (id);
12586 struct c_expr ce = c_parser_expression (parser);
12587 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
12588 return c_fully_fold (ce.value, false, NULL);
12591 /* Parse objc-message-args.
12593 objc-message-args:
12594 objc-selector
12595 objc-keywordarg-list
12597 objc-keywordarg-list:
12598 objc-keywordarg
12599 objc-keywordarg-list objc-keywordarg
12601 objc-keywordarg:
12602 objc-selector : objc-keywordexpr
12603 : objc-keywordexpr
12606 static tree
12607 c_parser_objc_message_args (c_parser *parser)
12609 tree sel = c_parser_objc_selector (parser);
12610 tree list = NULL_TREE;
12611 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
12612 return sel;
12613 while (true)
12615 tree keywordexpr;
12616 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
12617 return error_mark_node;
12618 keywordexpr = c_parser_objc_keywordexpr (parser);
12619 list = chainon (list, build_tree_list (sel, keywordexpr));
12620 sel = c_parser_objc_selector (parser);
12621 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
12622 break;
12624 return list;
12627 /* Parse an objc-keywordexpr.
12629 objc-keywordexpr:
12630 nonempty-expr-list
12633 static tree
12634 c_parser_objc_keywordexpr (c_parser *parser)
12636 tree ret;
12637 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
12638 NULL, NULL, NULL, NULL);
12639 if (vec_safe_length (expr_list) == 1)
12641 /* Just return the expression, remove a level of
12642 indirection. */
12643 ret = (*expr_list)[0];
12645 else
12647 /* We have a comma expression, we will collapse later. */
12648 ret = build_tree_list_vec (expr_list);
12650 release_tree_vector (expr_list);
12651 return ret;
12654 /* A check, needed in several places, that ObjC interface, implementation or
12655 method definitions are not prefixed by incorrect items. */
12656 static bool
12657 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
12658 struct c_declspecs *specs)
12660 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
12661 || specs->typespec_kind != ctsk_none)
12663 c_parser_error (parser,
12664 "no type or storage class may be specified here,");
12665 c_parser_skip_to_end_of_block_or_statement (parser);
12666 return true;
12668 return false;
12671 /* Parse an Objective-C @property declaration. The syntax is:
12673 objc-property-declaration:
12674 '@property' objc-property-attributes[opt] struct-declaration ;
12676 objc-property-attributes:
12677 '(' objc-property-attribute-list ')'
12679 objc-property-attribute-list:
12680 objc-property-attribute
12681 objc-property-attribute-list, objc-property-attribute
12683 objc-property-attribute
12684 'getter' = identifier
12685 'setter' = identifier
12686 'readonly'
12687 'readwrite'
12688 'assign'
12689 'retain'
12690 'copy'
12691 'nonatomic'
12693 For example:
12694 @property NSString *name;
12695 @property (readonly) id object;
12696 @property (retain, nonatomic, getter=getTheName) id name;
12697 @property int a, b, c;
12699 PS: This function is identical to cp_parser_objc_at_propery_declaration
12700 for C++. Keep them in sync. */
12701 static void
12702 c_parser_objc_at_property_declaration (c_parser *parser)
12704 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12705 location_t loc = c_parser_peek_token (parser)->location;
12706 c_parser_consume_token (parser); /* Eat '@property'. */
12708 /* Parse the optional attribute list.
12710 A list of parsed, but not verified, attributes. */
12711 vec<property_attribute_info *> prop_attr_list = vNULL;
12713 bool syntax_error = false;
12714 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12716 matching_parens parens;
12718 location_t attr_start = c_parser_peek_token (parser)->location;
12719 /* Eat the '(' */
12720 parens.consume_open (parser);
12722 /* Property attribute keywords are valid now. */
12723 parser->objc_property_attr_context = true;
12725 /* Allow @property (), with a warning. */
12726 location_t attr_end = c_parser_peek_token (parser)->location;
12728 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12730 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12731 warning_at (attr_comb, OPT_Wattributes,
12732 "empty property attribute list");
12734 else
12735 while (true)
12737 c_token *token = c_parser_peek_token (parser);
12738 attr_start = token->location;
12739 attr_end = get_finish (token->location);
12740 location_t attr_comb = make_location (attr_start, attr_start,
12741 attr_end);
12743 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12745 warning_at (attr_comb, OPT_Wattributes,
12746 "missing property attribute");
12747 if (token->type == CPP_CLOSE_PAREN)
12748 break;
12749 c_parser_consume_token (parser);
12750 continue;
12753 tree attr_name = NULL_TREE;
12754 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12755 bool add_at = false;
12756 if (token->type == CPP_KEYWORD)
12758 keyword = token->keyword;
12759 if (OBJC_IS_AT_KEYWORD (keyword))
12761 /* For '@' keywords the token value has the keyword,
12762 prepend the '@' for diagnostics. */
12763 attr_name = token->value;
12764 add_at = true;
12766 else
12767 attr_name = ridpointers[(int)keyword];
12769 else if (token->type == CPP_NAME)
12770 attr_name = token->value;
12771 c_parser_consume_token (parser);
12773 enum objc_property_attribute_kind prop_kind
12774 = objc_prop_attr_kind_for_rid (keyword);
12775 property_attribute_info *prop
12776 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12777 prop_attr_list.safe_push (prop);
12779 tree meth_name;
12780 switch (prop->prop_kind)
12782 default: break;
12783 case OBJC_PROPERTY_ATTR_UNKNOWN:
12784 if (attr_name)
12785 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12786 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12787 else
12788 error_at (attr_comb, "unknown property attribute");
12789 prop->parse_error = syntax_error = true;
12790 break;
12792 case OBJC_PROPERTY_ATTR_GETTER:
12793 case OBJC_PROPERTY_ATTR_SETTER:
12794 if (c_parser_next_token_is_not (parser, CPP_EQ))
12796 attr_comb = make_location (attr_end, attr_start, attr_end);
12797 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12798 attr_name);
12799 prop->parse_error = syntax_error = true;
12800 break;
12802 token = c_parser_peek_token (parser);
12803 attr_end = token->location;
12804 c_parser_consume_token (parser); /* eat the = */
12805 if (c_parser_next_token_is_not (parser, CPP_NAME))
12807 attr_comb = make_location (attr_end, attr_start, attr_end);
12808 error_at (attr_comb, "expected %qE selector name",
12809 attr_name);
12810 prop->parse_error = syntax_error = true;
12811 break;
12813 /* Get the end of the method name, and consume the name. */
12814 token = c_parser_peek_token (parser);
12815 attr_end = get_finish (token->location);
12816 meth_name = token->value;
12817 c_parser_consume_token (parser);
12818 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12820 if (c_parser_next_token_is_not (parser, CPP_COLON))
12822 attr_comb = make_location (attr_end, attr_start,
12823 attr_end);
12824 error_at (attr_comb, "setter method names must"
12825 " terminate with %<:%>");
12826 prop->parse_error = syntax_error = true;
12828 else
12830 attr_end = get_finish (c_parser_peek_token
12831 (parser)->location);
12832 c_parser_consume_token (parser);
12834 attr_comb = make_location (attr_start, attr_start,
12835 attr_end);
12837 else
12838 attr_comb = make_location (attr_start, attr_start,
12839 attr_end);
12840 prop->ident = meth_name;
12841 /* Updated location including all that was successfully
12842 parsed. */
12843 prop->prop_loc = attr_comb;
12844 break;
12847 /* If we see a comma here, then keep going - even if we already
12848 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12849 this makes a more useful output and avoid spurious warnings about
12850 missing attributes that are, in fact, specified after the one with
12851 the syntax error. */
12852 if (c_parser_next_token_is (parser, CPP_COMMA))
12853 c_parser_consume_token (parser);
12854 else
12855 break;
12857 parser->objc_property_attr_context = false;
12859 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12860 /* We don't really want to chew the whole of the file looking for a
12861 matching closing parenthesis, so we will try to read the decl and
12862 let the error handling for that close out the statement. */
12864 else
12865 syntax_error = false, parens.skip_until_found_close (parser);
12868 /* 'properties' is the list of properties that we read. Usually a
12869 single one, but maybe more (eg, in "@property int a, b, c;" there
12870 are three). */
12871 tree properties = c_parser_struct_declaration (parser);
12873 if (properties == error_mark_node)
12874 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12875 else
12877 if (properties == NULL_TREE)
12878 c_parser_error (parser, "expected identifier");
12879 else
12881 /* Comma-separated properties are chained together in reverse order;
12882 add them one by one. */
12883 properties = nreverse (properties);
12884 for (; properties; properties = TREE_CHAIN (properties))
12885 objc_add_property_declaration (loc, copy_node (properties),
12886 prop_attr_list);
12888 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12891 while (!prop_attr_list.is_empty())
12892 delete prop_attr_list.pop ();
12893 prop_attr_list.release ();
12894 parser->error = false;
12897 /* Parse an Objective-C @synthesize declaration. The syntax is:
12899 objc-synthesize-declaration:
12900 @synthesize objc-synthesize-identifier-list ;
12902 objc-synthesize-identifier-list:
12903 objc-synthesize-identifier
12904 objc-synthesize-identifier-list, objc-synthesize-identifier
12906 objc-synthesize-identifier
12907 identifier
12908 identifier = identifier
12910 For example:
12911 @synthesize MyProperty;
12912 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12914 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12915 for C++. Keep them in sync.
12917 static void
12918 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12920 tree list = NULL_TREE;
12921 location_t loc;
12922 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12923 loc = c_parser_peek_token (parser)->location;
12925 c_parser_consume_token (parser);
12926 while (true)
12928 tree property, ivar;
12929 if (c_parser_next_token_is_not (parser, CPP_NAME))
12931 c_parser_error (parser, "expected identifier");
12932 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12933 /* Once we find the semicolon, we can resume normal parsing.
12934 We have to reset parser->error manually because
12935 c_parser_skip_until_found() won't reset it for us if the
12936 next token is precisely a semicolon. */
12937 parser->error = false;
12938 return;
12940 property = c_parser_peek_token (parser)->value;
12941 c_parser_consume_token (parser);
12942 if (c_parser_next_token_is (parser, CPP_EQ))
12944 c_parser_consume_token (parser);
12945 if (c_parser_next_token_is_not (parser, CPP_NAME))
12947 c_parser_error (parser, "expected identifier");
12948 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12949 parser->error = false;
12950 return;
12952 ivar = c_parser_peek_token (parser)->value;
12953 c_parser_consume_token (parser);
12955 else
12956 ivar = NULL_TREE;
12957 list = chainon (list, build_tree_list (ivar, property));
12958 if (c_parser_next_token_is (parser, CPP_COMMA))
12959 c_parser_consume_token (parser);
12960 else
12961 break;
12963 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12964 objc_add_synthesize_declaration (loc, list);
12967 /* Parse an Objective-C @dynamic declaration. The syntax is:
12969 objc-dynamic-declaration:
12970 @dynamic identifier-list ;
12972 For example:
12973 @dynamic MyProperty;
12974 @dynamic MyProperty, AnotherProperty;
12976 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12977 for C++. Keep them in sync.
12979 static void
12980 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12982 tree list = NULL_TREE;
12983 location_t loc;
12984 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12985 loc = c_parser_peek_token (parser)->location;
12987 c_parser_consume_token (parser);
12988 while (true)
12990 tree property;
12991 if (c_parser_next_token_is_not (parser, CPP_NAME))
12993 c_parser_error (parser, "expected identifier");
12994 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12995 parser->error = false;
12996 return;
12998 property = c_parser_peek_token (parser)->value;
12999 list = chainon (list, build_tree_list (NULL_TREE, property));
13000 c_parser_consume_token (parser);
13001 if (c_parser_next_token_is (parser, CPP_COMMA))
13002 c_parser_consume_token (parser);
13003 else
13004 break;
13006 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
13007 objc_add_dynamic_declaration (loc, list);
13011 /* Parse a pragma GCC ivdep. */
13013 static bool
13014 c_parse_pragma_ivdep (c_parser *parser)
13016 c_parser_consume_pragma (parser);
13017 c_parser_skip_to_pragma_eol (parser);
13018 return true;
13021 /* Parse a pragma GCC unroll. */
13023 static unsigned short
13024 c_parser_pragma_unroll (c_parser *parser)
13026 unsigned short unroll;
13027 c_parser_consume_pragma (parser);
13028 location_t location = c_parser_peek_token (parser)->location;
13029 tree expr = c_parser_expr_no_commas (parser, NULL).value;
13030 mark_exp_read (expr);
13031 expr = c_fully_fold (expr, false, NULL);
13032 HOST_WIDE_INT lunroll = 0;
13033 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
13034 || TREE_CODE (expr) != INTEGER_CST
13035 || (lunroll = tree_to_shwi (expr)) < 0
13036 || lunroll >= USHRT_MAX)
13038 error_at (location, "%<#pragma GCC unroll%> requires an"
13039 " assignment-expression that evaluates to a non-negative"
13040 " integral constant less than %u", USHRT_MAX);
13041 unroll = 0;
13043 else
13045 unroll = (unsigned short)lunroll;
13046 if (unroll == 0)
13047 unroll = 1;
13050 c_parser_skip_to_pragma_eol (parser);
13051 return unroll;
13054 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
13055 should be considered, statements. ALLOW_STMT is true if we're within
13056 the context of a function and such pragmas are to be allowed. Returns
13057 true if we actually parsed such a pragma. */
13059 static bool
13060 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
13062 unsigned int id;
13063 const char *construct = NULL;
13065 input_location = c_parser_peek_token (parser)->location;
13066 id = c_parser_peek_token (parser)->pragma_kind;
13067 gcc_assert (id != PRAGMA_NONE);
13069 switch (id)
13071 case PRAGMA_OACC_DECLARE:
13072 c_parser_oacc_declare (parser);
13073 return false;
13075 case PRAGMA_OACC_ENTER_DATA:
13076 if (context != pragma_compound)
13078 construct = "acc enter data";
13079 in_compound:
13080 if (context == pragma_stmt)
13082 error_at (c_parser_peek_token (parser)->location,
13083 "%<#pragma %s%> may only be used in compound "
13084 "statements", construct);
13085 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
13086 return true;
13088 goto bad_stmt;
13090 c_parser_oacc_enter_exit_data (parser, true);
13091 return false;
13093 case PRAGMA_OACC_EXIT_DATA:
13094 if (context != pragma_compound)
13096 construct = "acc exit data";
13097 goto in_compound;
13099 c_parser_oacc_enter_exit_data (parser, false);
13100 return false;
13102 case PRAGMA_OACC_ROUTINE:
13103 if (context != pragma_external)
13105 error_at (c_parser_peek_token (parser)->location,
13106 "%<#pragma acc routine%> must be at file scope");
13107 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
13108 return false;
13110 c_parser_oacc_routine (parser, context);
13111 return false;
13113 case PRAGMA_OACC_UPDATE:
13114 if (context != pragma_compound)
13116 construct = "acc update";
13117 goto in_compound;
13119 c_parser_oacc_update (parser);
13120 return false;
13122 case PRAGMA_OMP_BARRIER:
13123 if (context != pragma_compound)
13125 construct = "omp barrier";
13126 goto in_compound;
13128 c_parser_omp_barrier (parser);
13129 return false;
13131 case PRAGMA_OMP_DEPOBJ:
13132 if (context != pragma_compound)
13134 construct = "omp depobj";
13135 goto in_compound;
13137 c_parser_omp_depobj (parser);
13138 return false;
13140 case PRAGMA_OMP_FLUSH:
13141 if (context != pragma_compound)
13143 construct = "omp flush";
13144 goto in_compound;
13146 c_parser_omp_flush (parser);
13147 return false;
13149 case PRAGMA_OMP_TASKWAIT:
13150 if (context != pragma_compound)
13152 construct = "omp taskwait";
13153 goto in_compound;
13155 c_parser_omp_taskwait (parser);
13156 return false;
13158 case PRAGMA_OMP_TASKYIELD:
13159 if (context != pragma_compound)
13161 construct = "omp taskyield";
13162 goto in_compound;
13164 c_parser_omp_taskyield (parser);
13165 return false;
13167 case PRAGMA_OMP_CANCEL:
13168 if (context != pragma_compound)
13170 construct = "omp cancel";
13171 goto in_compound;
13173 c_parser_omp_cancel (parser);
13174 return false;
13176 case PRAGMA_OMP_CANCELLATION_POINT:
13177 return c_parser_omp_cancellation_point (parser, context);
13179 case PRAGMA_OMP_THREADPRIVATE:
13180 c_parser_omp_threadprivate (parser);
13181 return false;
13183 case PRAGMA_OMP_TARGET:
13184 return c_parser_omp_target (parser, context, if_p);
13186 case PRAGMA_OMP_BEGIN:
13187 c_parser_omp_begin (parser);
13188 return false;
13190 case PRAGMA_OMP_END:
13191 c_parser_omp_end (parser);
13192 return false;
13194 case PRAGMA_OMP_SCAN:
13195 error_at (c_parser_peek_token (parser)->location,
13196 "%<#pragma omp scan%> may only be used in "
13197 "a loop construct with %<inscan%> %<reduction%> clause");
13198 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
13199 return false;
13201 case PRAGMA_OMP_SECTION:
13202 error_at (c_parser_peek_token (parser)->location,
13203 "%<#pragma omp section%> may only be used in "
13204 "%<#pragma omp sections%> construct");
13205 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
13206 return false;
13208 case PRAGMA_OMP_DECLARE:
13209 return c_parser_omp_declare (parser, context);
13211 case PRAGMA_OMP_REQUIRES:
13212 if (context != pragma_external)
13214 error_at (c_parser_peek_token (parser)->location,
13215 "%<#pragma %s%> may only be used at file scope",
13216 "omp requires");
13217 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
13218 return false;
13220 c_parser_omp_requires (parser);
13221 return false;
13223 case PRAGMA_OMP_ASSUMES:
13224 if (context != pragma_external)
13226 error_at (c_parser_peek_token (parser)->location,
13227 "%<#pragma %s%> may only be used at file scope",
13228 "omp assumes");
13229 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
13230 return false;
13232 c_parser_omp_assumes (parser);
13233 return false;
13235 case PRAGMA_OMP_NOTHING:
13236 c_parser_omp_nothing (parser);
13237 return false;
13239 case PRAGMA_OMP_ERROR:
13240 return c_parser_omp_error (parser, context);
13242 case PRAGMA_OMP_ORDERED:
13243 return c_parser_omp_ordered (parser, context, if_p);
13245 case PRAGMA_IVDEP:
13247 const bool ivdep = c_parse_pragma_ivdep (parser);
13248 unsigned short unroll;
13249 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
13250 unroll = c_parser_pragma_unroll (parser);
13251 else
13252 unroll = 0;
13253 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
13254 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
13255 && !c_parser_next_token_is_keyword (parser, RID_DO))
13257 c_parser_error (parser, "for, while or do statement expected");
13258 return false;
13260 if (c_parser_next_token_is_keyword (parser, RID_FOR))
13261 c_parser_for_statement (parser, ivdep, unroll, if_p);
13262 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
13263 c_parser_while_statement (parser, ivdep, unroll, if_p);
13264 else
13265 c_parser_do_statement (parser, ivdep, unroll);
13267 return true;
13269 case PRAGMA_UNROLL:
13271 unsigned short unroll = c_parser_pragma_unroll (parser);
13272 bool ivdep;
13273 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
13274 ivdep = c_parse_pragma_ivdep (parser);
13275 else
13276 ivdep = false;
13277 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
13278 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
13279 && !c_parser_next_token_is_keyword (parser, RID_DO))
13281 c_parser_error (parser, "for, while or do statement expected");
13282 return false;
13284 if (c_parser_next_token_is_keyword (parser, RID_FOR))
13285 c_parser_for_statement (parser, ivdep, unroll, if_p);
13286 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
13287 c_parser_while_statement (parser, ivdep, unroll, if_p);
13288 else
13289 c_parser_do_statement (parser, ivdep, unroll);
13291 return true;
13293 case PRAGMA_GCC_PCH_PREPROCESS:
13294 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
13295 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
13296 return false;
13298 case PRAGMA_OACC_WAIT:
13299 if (context != pragma_compound)
13301 construct = "acc wait";
13302 goto in_compound;
13304 /* FALL THROUGH. */
13306 default:
13307 if (id < PRAGMA_FIRST_EXTERNAL)
13309 if (context != pragma_stmt && context != pragma_compound)
13311 bad_stmt:
13312 c_parser_error (parser, "expected declaration specifiers");
13313 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
13314 return false;
13316 c_parser_omp_construct (parser, if_p);
13317 return true;
13319 break;
13322 c_parser_consume_pragma (parser);
13323 c_invoke_pragma_handler (id);
13325 /* Skip to EOL, but suppress any error message. Those will have been
13326 generated by the handler routine through calling error, as opposed
13327 to calling c_parser_error. */
13328 parser->error = true;
13329 c_parser_skip_to_pragma_eol (parser);
13331 return false;
13334 /* The interface the pragma parsers have to the lexer. */
13336 enum cpp_ttype
13337 pragma_lex (tree *value, location_t *loc)
13339 c_token *tok = c_parser_peek_token (the_parser);
13340 enum cpp_ttype ret = tok->type;
13342 *value = tok->value;
13343 if (loc)
13344 *loc = tok->location;
13346 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
13347 ret = CPP_EOF;
13348 else if (ret == CPP_STRING)
13349 *value = c_parser_string_literal (the_parser, false, false).value;
13350 else
13352 if (ret == CPP_KEYWORD)
13353 ret = CPP_NAME;
13354 c_parser_consume_token (the_parser);
13357 return ret;
13360 static void
13361 c_parser_pragma_pch_preprocess (c_parser *parser)
13363 tree name = NULL;
13365 parser->lex_joined_string = true;
13366 c_parser_consume_pragma (parser);
13367 if (c_parser_next_token_is (parser, CPP_STRING))
13369 name = c_parser_peek_token (parser)->value;
13370 c_parser_consume_token (parser);
13372 else
13373 c_parser_error (parser, "expected string literal");
13374 c_parser_skip_to_pragma_eol (parser);
13375 parser->lex_joined_string = false;
13377 if (name)
13378 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
13381 /* OpenACC and OpenMP parsing routines. */
13383 /* Returns name of the next clause.
13384 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
13385 the token is not consumed. Otherwise appropriate pragma_omp_clause is
13386 returned and the token is consumed. */
13388 static pragma_omp_clause
13389 c_parser_omp_clause_name (c_parser *parser)
13391 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
13393 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
13394 result = PRAGMA_OACC_CLAUSE_AUTO;
13395 else if (c_parser_next_token_is_keyword (parser, RID_IF))
13396 result = PRAGMA_OMP_CLAUSE_IF;
13397 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
13398 result = PRAGMA_OMP_CLAUSE_DEFAULT;
13399 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
13400 result = PRAGMA_OMP_CLAUSE_FOR;
13401 else if (c_parser_next_token_is (parser, CPP_NAME))
13403 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13405 switch (p[0])
13407 case 'a':
13408 if (!strcmp ("affinity", p))
13409 result = PRAGMA_OMP_CLAUSE_AFFINITY;
13410 else if (!strcmp ("aligned", p))
13411 result = PRAGMA_OMP_CLAUSE_ALIGNED;
13412 else if (!strcmp ("allocate", p))
13413 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
13414 else if (!strcmp ("async", p))
13415 result = PRAGMA_OACC_CLAUSE_ASYNC;
13416 else if (!strcmp ("attach", p))
13417 result = PRAGMA_OACC_CLAUSE_ATTACH;
13418 break;
13419 case 'b':
13420 if (!strcmp ("bind", p))
13421 result = PRAGMA_OMP_CLAUSE_BIND;
13422 break;
13423 case 'c':
13424 if (!strcmp ("collapse", p))
13425 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
13426 else if (!strcmp ("copy", p))
13427 result = PRAGMA_OACC_CLAUSE_COPY;
13428 else if (!strcmp ("copyin", p))
13429 result = PRAGMA_OMP_CLAUSE_COPYIN;
13430 else if (!strcmp ("copyout", p))
13431 result = PRAGMA_OACC_CLAUSE_COPYOUT;
13432 else if (!strcmp ("copyprivate", p))
13433 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
13434 else if (!strcmp ("create", p))
13435 result = PRAGMA_OACC_CLAUSE_CREATE;
13436 break;
13437 case 'd':
13438 if (!strcmp ("defaultmap", p))
13439 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
13440 else if (!strcmp ("delete", p))
13441 result = PRAGMA_OACC_CLAUSE_DELETE;
13442 else if (!strcmp ("depend", p))
13443 result = PRAGMA_OMP_CLAUSE_DEPEND;
13444 else if (!strcmp ("detach", p))
13445 result = PRAGMA_OACC_CLAUSE_DETACH;
13446 else if (!strcmp ("device", p))
13447 result = PRAGMA_OMP_CLAUSE_DEVICE;
13448 else if (!strcmp ("deviceptr", p))
13449 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
13450 else if (!strcmp ("device_resident", p))
13451 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
13452 else if (!strcmp ("device_type", p))
13453 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
13454 else if (!strcmp ("dist_schedule", p))
13455 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
13456 else if (!strcmp ("doacross", p))
13457 result = PRAGMA_OMP_CLAUSE_DOACROSS;
13458 break;
13459 case 'e':
13460 if (!strcmp ("enter", p))
13461 result = PRAGMA_OMP_CLAUSE_ENTER;
13462 break;
13463 case 'f':
13464 if (!strcmp ("filter", p))
13465 result = PRAGMA_OMP_CLAUSE_FILTER;
13466 else if (!strcmp ("final", p))
13467 result = PRAGMA_OMP_CLAUSE_FINAL;
13468 else if (!strcmp ("finalize", p))
13469 result = PRAGMA_OACC_CLAUSE_FINALIZE;
13470 else if (!strcmp ("firstprivate", p))
13471 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
13472 else if (!strcmp ("from", p))
13473 result = PRAGMA_OMP_CLAUSE_FROM;
13474 break;
13475 case 'g':
13476 if (!strcmp ("gang", p))
13477 result = PRAGMA_OACC_CLAUSE_GANG;
13478 else if (!strcmp ("grainsize", p))
13479 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
13480 break;
13481 case 'h':
13482 if (!strcmp ("has_device_addr", p))
13483 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
13484 else if (!strcmp ("hint", p))
13485 result = PRAGMA_OMP_CLAUSE_HINT;
13486 else if (!strcmp ("host", p))
13487 result = PRAGMA_OACC_CLAUSE_HOST;
13488 break;
13489 case 'i':
13490 if (!strcmp ("if_present", p))
13491 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
13492 else if (!strcmp ("in_reduction", p))
13493 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
13494 else if (!strcmp ("inbranch", p))
13495 result = PRAGMA_OMP_CLAUSE_INBRANCH;
13496 else if (!strcmp ("independent", p))
13497 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
13498 else if (!strcmp ("is_device_ptr", p))
13499 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
13500 break;
13501 case 'l':
13502 if (!strcmp ("lastprivate", p))
13503 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
13504 else if (!strcmp ("linear", p))
13505 result = PRAGMA_OMP_CLAUSE_LINEAR;
13506 else if (!strcmp ("link", p))
13507 result = PRAGMA_OMP_CLAUSE_LINK;
13508 break;
13509 case 'm':
13510 if (!strcmp ("map", p))
13511 result = PRAGMA_OMP_CLAUSE_MAP;
13512 else if (!strcmp ("mergeable", p))
13513 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
13514 break;
13515 case 'n':
13516 if (!strcmp ("no_create", p))
13517 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
13518 else if (!strcmp ("nogroup", p))
13519 result = PRAGMA_OMP_CLAUSE_NOGROUP;
13520 else if (!strcmp ("nohost", p))
13521 result = PRAGMA_OACC_CLAUSE_NOHOST;
13522 else if (!strcmp ("nontemporal", p))
13523 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
13524 else if (!strcmp ("notinbranch", p))
13525 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
13526 else if (!strcmp ("nowait", p))
13527 result = PRAGMA_OMP_CLAUSE_NOWAIT;
13528 else if (!strcmp ("num_gangs", p))
13529 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
13530 else if (!strcmp ("num_tasks", p))
13531 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
13532 else if (!strcmp ("num_teams", p))
13533 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
13534 else if (!strcmp ("num_threads", p))
13535 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
13536 else if (!strcmp ("num_workers", p))
13537 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
13538 break;
13539 case 'o':
13540 if (!strcmp ("ordered", p))
13541 result = PRAGMA_OMP_CLAUSE_ORDERED;
13542 else if (!strcmp ("order", p))
13543 result = PRAGMA_OMP_CLAUSE_ORDER;
13544 break;
13545 case 'p':
13546 if (!strcmp ("parallel", p))
13547 result = PRAGMA_OMP_CLAUSE_PARALLEL;
13548 else if (!strcmp ("present", p))
13549 result = PRAGMA_OACC_CLAUSE_PRESENT;
13550 /* As of OpenACC 2.5, these are now aliases of the non-present_or
13551 clauses. */
13552 else if (!strcmp ("present_or_copy", p)
13553 || !strcmp ("pcopy", p))
13554 result = PRAGMA_OACC_CLAUSE_COPY;
13555 else if (!strcmp ("present_or_copyin", p)
13556 || !strcmp ("pcopyin", p))
13557 result = PRAGMA_OACC_CLAUSE_COPYIN;
13558 else if (!strcmp ("present_or_copyout", p)
13559 || !strcmp ("pcopyout", p))
13560 result = PRAGMA_OACC_CLAUSE_COPYOUT;
13561 else if (!strcmp ("present_or_create", p)
13562 || !strcmp ("pcreate", p))
13563 result = PRAGMA_OACC_CLAUSE_CREATE;
13564 else if (!strcmp ("priority", p))
13565 result = PRAGMA_OMP_CLAUSE_PRIORITY;
13566 else if (!strcmp ("private", p))
13567 result = PRAGMA_OMP_CLAUSE_PRIVATE;
13568 else if (!strcmp ("proc_bind", p))
13569 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
13570 break;
13571 case 'r':
13572 if (!strcmp ("reduction", p))
13573 result = PRAGMA_OMP_CLAUSE_REDUCTION;
13574 break;
13575 case 's':
13576 if (!strcmp ("safelen", p))
13577 result = PRAGMA_OMP_CLAUSE_SAFELEN;
13578 else if (!strcmp ("schedule", p))
13579 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
13580 else if (!strcmp ("sections", p))
13581 result = PRAGMA_OMP_CLAUSE_SECTIONS;
13582 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
13583 result = PRAGMA_OACC_CLAUSE_HOST;
13584 else if (!strcmp ("seq", p))
13585 result = PRAGMA_OACC_CLAUSE_SEQ;
13586 else if (!strcmp ("shared", p))
13587 result = PRAGMA_OMP_CLAUSE_SHARED;
13588 else if (!strcmp ("simd", p))
13589 result = PRAGMA_OMP_CLAUSE_SIMD;
13590 else if (!strcmp ("simdlen", p))
13591 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
13592 break;
13593 case 't':
13594 if (!strcmp ("task_reduction", p))
13595 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
13596 else if (!strcmp ("taskgroup", p))
13597 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
13598 else if (!strcmp ("thread_limit", p))
13599 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
13600 else if (!strcmp ("threads", p))
13601 result = PRAGMA_OMP_CLAUSE_THREADS;
13602 else if (!strcmp ("tile", p))
13603 result = PRAGMA_OACC_CLAUSE_TILE;
13604 else if (!strcmp ("to", p))
13605 result = PRAGMA_OMP_CLAUSE_TO;
13606 break;
13607 case 'u':
13608 if (!strcmp ("uniform", p))
13609 result = PRAGMA_OMP_CLAUSE_UNIFORM;
13610 else if (!strcmp ("untied", p))
13611 result = PRAGMA_OMP_CLAUSE_UNTIED;
13612 else if (!strcmp ("use_device", p))
13613 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
13614 else if (!strcmp ("use_device_addr", p))
13615 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
13616 else if (!strcmp ("use_device_ptr", p))
13617 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
13618 break;
13619 case 'v':
13620 if (!strcmp ("vector", p))
13621 result = PRAGMA_OACC_CLAUSE_VECTOR;
13622 else if (!strcmp ("vector_length", p))
13623 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
13624 break;
13625 case 'w':
13626 if (!strcmp ("wait", p))
13627 result = PRAGMA_OACC_CLAUSE_WAIT;
13628 else if (!strcmp ("worker", p))
13629 result = PRAGMA_OACC_CLAUSE_WORKER;
13630 break;
13634 if (result != PRAGMA_OMP_CLAUSE_NONE)
13635 c_parser_consume_token (parser);
13637 return result;
13640 /* Validate that a clause of the given type does not already exist. */
13642 static void
13643 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
13644 const char *name)
13646 if (tree c = omp_find_clause (clauses, code))
13647 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
13650 /* OpenACC 2.0
13651 Parse wait clause or wait directive parameters. */
13653 static tree
13654 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
13656 vec<tree, va_gc> *args;
13657 tree t, args_tree;
13659 matching_parens parens;
13660 if (!parens.require_open (parser))
13661 return list;
13663 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
13664 args_tree = build_tree_list_vec (args);
13666 for (t = args_tree; t; t = TREE_CHAIN (t))
13668 tree targ = TREE_VALUE (t);
13670 if (targ != error_mark_node)
13672 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
13674 c_parser_error (parser, "expression must be integral");
13675 targ = error_mark_node;
13677 else
13679 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
13681 OMP_CLAUSE_DECL (c) = targ;
13682 OMP_CLAUSE_CHAIN (c) = list;
13683 list = c;
13688 release_tree_vector (args);
13689 parens.require_close (parser);
13690 return list;
13693 /* OpenACC 2.0, OpenMP 2.5:
13694 variable-list:
13695 identifier
13696 variable-list , identifier
13698 If KIND is nonzero, create the appropriate node and install the
13699 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13700 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13702 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13703 return the list created.
13705 The optional ALLOW_DEREF argument is true if list items can use the deref
13706 (->) operator. */
13708 struct omp_dim
13710 tree low_bound, length;
13711 location_t loc;
13712 bool no_colon;
13713 omp_dim (tree lb, tree len, location_t lo, bool nc)
13714 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13717 static tree
13718 c_parser_omp_variable_list (c_parser *parser,
13719 location_t clause_loc,
13720 enum omp_clause_code kind, tree list,
13721 bool allow_deref = false)
13723 auto_vec<omp_dim> dims;
13724 bool array_section_p;
13725 auto_vec<c_token> tokens;
13726 unsigned int tokens_avail = 0;
13727 bool first = true;
13729 while (1)
13731 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13733 if (c_parser_next_token_is_not (parser, CPP_NAME)
13734 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13736 struct c_expr expr;
13737 if (kind == OMP_CLAUSE_DEPEND
13738 && c_parser_next_token_is_keyword (parser,
13739 RID_OMP_ALL_MEMORY)
13740 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13741 || (c_parser_peek_2nd_token (parser)->type
13742 == CPP_CLOSE_PAREN)))
13744 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
13745 c_parser_consume_token (parser);
13747 else
13748 expr = c_parser_expr_no_commas (parser, NULL);
13749 if (expr.value != error_mark_node)
13751 tree u = build_omp_clause (clause_loc, kind);
13752 OMP_CLAUSE_DECL (u) = expr.value;
13753 OMP_CLAUSE_CHAIN (u) = list;
13754 list = u;
13757 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13758 break;
13760 c_parser_consume_token (parser);
13761 first = false;
13762 continue;
13765 tokens.truncate (0);
13766 unsigned int nesting_depth = 0;
13767 while (1)
13769 c_token *token = c_parser_peek_token (parser);
13770 switch (token->type)
13772 case CPP_EOF:
13773 case CPP_PRAGMA_EOL:
13774 break;
13775 case CPP_OPEN_BRACE:
13776 case CPP_OPEN_PAREN:
13777 case CPP_OPEN_SQUARE:
13778 ++nesting_depth;
13779 goto add;
13780 case CPP_CLOSE_BRACE:
13781 case CPP_CLOSE_PAREN:
13782 case CPP_CLOSE_SQUARE:
13783 if (nesting_depth-- == 0)
13784 break;
13785 goto add;
13786 case CPP_COMMA:
13787 if (nesting_depth == 0)
13788 break;
13789 goto add;
13790 default:
13791 add:
13792 tokens.safe_push (*token);
13793 c_parser_consume_token (parser);
13794 continue;
13796 break;
13799 /* Make sure nothing tries to read past the end of the tokens. */
13800 c_token eof_token;
13801 memset (&eof_token, 0, sizeof (eof_token));
13802 eof_token.type = CPP_EOF;
13803 tokens.safe_push (eof_token);
13804 tokens.safe_push (eof_token);
13806 tokens_avail = parser->tokens_avail;
13807 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13808 parser->tokens = tokens.address ();
13809 parser->tokens_avail = tokens.length ();
13812 tree t = NULL_TREE;
13814 if (c_parser_next_token_is (parser, CPP_NAME)
13815 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13817 t = lookup_name (c_parser_peek_token (parser)->value);
13819 if (t == NULL_TREE)
13821 undeclared_variable (c_parser_peek_token (parser)->location,
13822 c_parser_peek_token (parser)->value);
13823 t = error_mark_node;
13826 c_parser_consume_token (parser);
13828 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13829 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13830 || (c_parser_peek_token (parser)->keyword
13831 == RID_PRETTY_FUNCTION_NAME)
13832 || (c_parser_peek_token (parser)->keyword
13833 == RID_C99_FUNCTION_NAME)))
13834 t = c_parser_predefined_identifier (parser).value;
13835 else
13837 if (first)
13838 c_parser_error (parser, "expected identifier");
13839 break;
13842 if (t == error_mark_node)
13844 else if (kind != 0)
13846 switch (kind)
13848 case OMP_CLAUSE__CACHE_:
13849 /* The OpenACC cache directive explicitly only allows "array
13850 elements or subarrays". */
13851 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13853 c_parser_error (parser, "expected %<[%>");
13854 t = error_mark_node;
13855 break;
13857 /* FALLTHROUGH */
13858 case OMP_CLAUSE_MAP:
13859 case OMP_CLAUSE_FROM:
13860 case OMP_CLAUSE_TO:
13861 start_component_ref:
13862 while (c_parser_next_token_is (parser, CPP_DOT)
13863 || (allow_deref
13864 && c_parser_next_token_is (parser, CPP_DEREF)))
13866 location_t op_loc = c_parser_peek_token (parser)->location;
13867 location_t arrow_loc = UNKNOWN_LOCATION;
13868 if (c_parser_next_token_is (parser, CPP_DEREF))
13870 c_expr t_expr;
13871 t_expr.value = t;
13872 t_expr.original_code = ERROR_MARK;
13873 t_expr.original_type = NULL;
13874 set_c_expr_source_range (&t_expr, op_loc, op_loc);
13875 t_expr.m_decimal = 0;
13876 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13877 true, false);
13878 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13879 arrow_loc = t_expr.get_location ();
13881 c_parser_consume_token (parser);
13882 if (!c_parser_next_token_is (parser, CPP_NAME))
13884 c_parser_error (parser, "expected identifier");
13885 t = error_mark_node;
13886 break;
13889 c_token *comp_tok = c_parser_peek_token (parser);
13890 tree ident = comp_tok->value;
13891 location_t comp_loc = comp_tok->location;
13892 c_parser_consume_token (parser);
13893 t = build_component_ref (op_loc, t, ident, comp_loc,
13894 arrow_loc);
13896 /* FALLTHROUGH */
13897 case OMP_CLAUSE_AFFINITY:
13898 case OMP_CLAUSE_DEPEND:
13899 case OMP_CLAUSE_REDUCTION:
13900 case OMP_CLAUSE_IN_REDUCTION:
13901 case OMP_CLAUSE_TASK_REDUCTION:
13902 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13903 array_section_p = false;
13904 dims.truncate (0);
13905 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13907 location_t loc = UNKNOWN_LOCATION;
13908 tree low_bound = NULL_TREE, length = NULL_TREE;
13909 bool no_colon = false;
13911 c_parser_consume_token (parser);
13912 if (!c_parser_next_token_is (parser, CPP_COLON))
13914 location_t expr_loc
13915 = c_parser_peek_token (parser)->location;
13916 c_expr expr = c_parser_expression (parser);
13917 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13918 false, true);
13919 low_bound = expr.value;
13920 loc = expr_loc;
13922 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13924 length = integer_one_node;
13925 no_colon = true;
13927 else
13929 /* Look for `:'. */
13930 if (!c_parser_require (parser, CPP_COLON,
13931 "expected %<:%>"))
13933 t = error_mark_node;
13934 break;
13936 array_section_p = true;
13937 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13939 location_t expr_loc
13940 = c_parser_peek_token (parser)->location;
13941 c_expr expr = c_parser_expression (parser);
13942 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13943 false, true);
13944 length = expr.value;
13947 /* Look for the closing `]'. */
13948 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13949 "expected %<]%>"))
13951 t = error_mark_node;
13952 break;
13955 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13958 if (t != error_mark_node)
13960 if ((kind == OMP_CLAUSE_MAP
13961 || kind == OMP_CLAUSE_FROM
13962 || kind == OMP_CLAUSE_TO)
13963 && !array_section_p
13964 && (c_parser_next_token_is (parser, CPP_DOT)
13965 || (allow_deref
13966 && c_parser_next_token_is (parser,
13967 CPP_DEREF))))
13969 for (unsigned i = 0; i < dims.length (); i++)
13971 gcc_assert (dims[i].length == integer_one_node);
13972 t = build_array_ref (dims[i].loc,
13973 t, dims[i].low_bound);
13975 goto start_component_ref;
13977 else
13978 for (unsigned i = 0; i < dims.length (); i++)
13979 t = tree_cons (dims[i].low_bound, dims[i].length, t);
13982 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13983 && t != error_mark_node
13984 && parser->tokens_avail != 2)
13986 if (array_section_p)
13988 error_at (c_parser_peek_token (parser)->location,
13989 "expected %<)%> or %<,%>");
13990 t = error_mark_node;
13992 else
13994 parser->tokens = tokens.address ();
13995 parser->tokens_avail = tokens.length ();
13997 t = c_parser_expr_no_commas (parser, NULL).value;
13998 if (t != error_mark_node && parser->tokens_avail != 2)
14000 error_at (c_parser_peek_token (parser)->location,
14001 "expected %<)%> or %<,%>");
14002 t = error_mark_node;
14006 break;
14007 default:
14008 break;
14011 if (t != error_mark_node)
14013 tree u = build_omp_clause (clause_loc, kind);
14014 OMP_CLAUSE_DECL (u) = t;
14015 OMP_CLAUSE_CHAIN (u) = list;
14016 list = u;
14019 else
14020 list = tree_cons (t, NULL_TREE, list);
14022 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
14024 parser->tokens = &parser->tokens_buf[0];
14025 parser->tokens_avail = tokens_avail;
14027 if (c_parser_next_token_is_not (parser, CPP_COMMA))
14028 break;
14030 c_parser_consume_token (parser);
14031 first = false;
14034 return list;
14037 /* Similarly, but expect leading and trailing parenthesis. This is a very
14038 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
14039 argument is true if list items can use the deref (->) operator. */
14041 static tree
14042 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
14043 tree list, bool allow_deref = false)
14045 /* The clauses location. */
14046 location_t loc = c_parser_peek_token (parser)->location;
14048 matching_parens parens;
14049 if (parens.require_open (parser))
14051 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
14052 parens.skip_until_found_close (parser);
14054 return list;
14057 /* OpenACC 2.0:
14058 copy ( variable-list )
14059 copyin ( variable-list )
14060 copyout ( variable-list )
14061 create ( variable-list )
14062 delete ( variable-list )
14063 present ( variable-list )
14065 OpenACC 2.6:
14066 no_create ( variable-list )
14067 attach ( variable-list )
14068 detach ( variable-list ) */
14070 static tree
14071 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
14072 tree list)
14074 enum gomp_map_kind kind;
14075 switch (c_kind)
14077 case PRAGMA_OACC_CLAUSE_ATTACH:
14078 kind = GOMP_MAP_ATTACH;
14079 break;
14080 case PRAGMA_OACC_CLAUSE_COPY:
14081 kind = GOMP_MAP_TOFROM;
14082 break;
14083 case PRAGMA_OACC_CLAUSE_COPYIN:
14084 kind = GOMP_MAP_TO;
14085 break;
14086 case PRAGMA_OACC_CLAUSE_COPYOUT:
14087 kind = GOMP_MAP_FROM;
14088 break;
14089 case PRAGMA_OACC_CLAUSE_CREATE:
14090 kind = GOMP_MAP_ALLOC;
14091 break;
14092 case PRAGMA_OACC_CLAUSE_DELETE:
14093 kind = GOMP_MAP_RELEASE;
14094 break;
14095 case PRAGMA_OACC_CLAUSE_DETACH:
14096 kind = GOMP_MAP_DETACH;
14097 break;
14098 case PRAGMA_OACC_CLAUSE_DEVICE:
14099 kind = GOMP_MAP_FORCE_TO;
14100 break;
14101 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
14102 kind = GOMP_MAP_DEVICE_RESIDENT;
14103 break;
14104 case PRAGMA_OACC_CLAUSE_HOST:
14105 kind = GOMP_MAP_FORCE_FROM;
14106 break;
14107 case PRAGMA_OACC_CLAUSE_LINK:
14108 kind = GOMP_MAP_LINK;
14109 break;
14110 case PRAGMA_OACC_CLAUSE_NO_CREATE:
14111 kind = GOMP_MAP_IF_PRESENT;
14112 break;
14113 case PRAGMA_OACC_CLAUSE_PRESENT:
14114 kind = GOMP_MAP_FORCE_PRESENT;
14115 break;
14116 default:
14117 gcc_unreachable ();
14119 tree nl, c;
14120 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
14122 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14123 OMP_CLAUSE_SET_MAP_KIND (c, kind);
14125 return nl;
14128 /* OpenACC 2.0:
14129 deviceptr ( variable-list ) */
14131 static tree
14132 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
14134 location_t loc = c_parser_peek_token (parser)->location;
14135 tree vars, t;
14137 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
14138 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
14139 variable-list must only allow for pointer variables. */
14140 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
14141 for (t = vars; t && t; t = TREE_CHAIN (t))
14143 tree v = TREE_PURPOSE (t);
14145 /* FIXME diagnostics: Ideally we should keep individual
14146 locations for all the variables in the var list to make the
14147 following errors more precise. Perhaps
14148 c_parser_omp_var_list_parens() should construct a list of
14149 locations to go along with the var list. */
14151 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
14152 error_at (loc, "%qD is not a variable", v);
14153 else if (TREE_TYPE (v) == error_mark_node)
14155 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
14156 error_at (loc, "%qD is not a pointer variable", v);
14158 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
14159 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
14160 OMP_CLAUSE_DECL (u) = v;
14161 OMP_CLAUSE_CHAIN (u) = list;
14162 list = u;
14165 return list;
14168 /* OpenACC 2.0, OpenMP 3.0:
14169 collapse ( constant-expression ) */
14171 static tree
14172 c_parser_omp_clause_collapse (c_parser *parser, tree list)
14174 tree c, num = error_mark_node;
14175 HOST_WIDE_INT n;
14176 location_t loc;
14178 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14179 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14181 loc = c_parser_peek_token (parser)->location;
14182 matching_parens parens;
14183 if (parens.require_open (parser))
14185 num = c_parser_expr_no_commas (parser, NULL).value;
14186 parens.skip_until_found_close (parser);
14188 if (num == error_mark_node)
14189 return list;
14190 mark_exp_read (num);
14191 num = c_fully_fold (num, false, NULL);
14192 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14193 || !tree_fits_shwi_p (num)
14194 || (n = tree_to_shwi (num)) <= 0
14195 || (int) n != n)
14197 error_at (loc,
14198 "collapse argument needs positive constant integer expression");
14199 return list;
14201 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
14202 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
14203 OMP_CLAUSE_CHAIN (c) = list;
14204 return c;
14207 /* OpenMP 2.5:
14208 copyin ( variable-list ) */
14210 static tree
14211 c_parser_omp_clause_copyin (c_parser *parser, tree list)
14213 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
14216 /* OpenMP 2.5:
14217 copyprivate ( variable-list ) */
14219 static tree
14220 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
14222 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
14225 /* OpenMP 2.5:
14226 default ( none | shared )
14228 OpenMP 5.1:
14229 default ( private | firstprivate )
14231 OpenACC:
14232 default ( none | present ) */
14234 static tree
14235 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
14237 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
14238 location_t loc = c_parser_peek_token (parser)->location;
14239 tree c;
14241 matching_parens parens;
14242 if (!parens.require_open (parser))
14243 return list;
14244 if (c_parser_next_token_is (parser, CPP_NAME))
14246 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14248 switch (p[0])
14250 case 'n':
14251 if (strcmp ("none", p) != 0)
14252 goto invalid_kind;
14253 kind = OMP_CLAUSE_DEFAULT_NONE;
14254 break;
14256 case 'p':
14257 if (is_oacc)
14259 if (strcmp ("present", p) != 0)
14260 goto invalid_kind;
14261 kind = OMP_CLAUSE_DEFAULT_PRESENT;
14263 else
14265 if (strcmp ("private", p) != 0)
14266 goto invalid_kind;
14267 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
14269 break;
14271 case 'f':
14272 if (strcmp ("firstprivate", p) != 0 || is_oacc)
14273 goto invalid_kind;
14274 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
14275 break;
14277 case 's':
14278 if (strcmp ("shared", p) != 0 || is_oacc)
14279 goto invalid_kind;
14280 kind = OMP_CLAUSE_DEFAULT_SHARED;
14281 break;
14283 default:
14284 goto invalid_kind;
14287 c_parser_consume_token (parser);
14289 else
14291 invalid_kind:
14292 if (is_oacc)
14293 c_parser_error (parser, "expected %<none%> or %<present%>");
14294 else
14295 c_parser_error (parser, "expected %<none%>, %<shared%>, "
14296 "%<private%> or %<firstprivate%>");
14298 parens.skip_until_found_close (parser);
14300 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
14301 return list;
14303 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
14304 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
14305 OMP_CLAUSE_CHAIN (c) = list;
14306 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
14308 return c;
14311 /* OpenMP 2.5:
14312 firstprivate ( variable-list ) */
14314 static tree
14315 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
14317 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
14320 /* OpenMP 3.1:
14321 final ( expression ) */
14323 static tree
14324 c_parser_omp_clause_final (c_parser *parser, tree list)
14326 location_t loc = c_parser_peek_token (parser)->location;
14327 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14329 matching_parens parens;
14330 tree t, c;
14331 if (!parens.require_open (parser))
14332 t = error_mark_node;
14333 else
14335 location_t eloc = c_parser_peek_token (parser)->location;
14336 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14337 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
14338 t = c_objc_common_truthvalue_conversion (eloc, t);
14339 t = c_fully_fold (t, false, NULL);
14340 parens.skip_until_found_close (parser);
14343 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
14345 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
14346 OMP_CLAUSE_FINAL_EXPR (c) = t;
14347 OMP_CLAUSE_CHAIN (c) = list;
14348 list = c;
14350 else
14351 c_parser_error (parser, "expected %<(%>");
14353 return list;
14356 /* OpenACC, OpenMP 2.5:
14357 if ( expression )
14359 OpenMP 4.5:
14360 if ( directive-name-modifier : expression )
14362 directive-name-modifier:
14363 parallel | task | taskloop | target data | target | target update
14364 | target enter data | target exit data
14366 OpenMP 5.0:
14367 directive-name-modifier:
14368 ... | simd | cancel */
14370 static tree
14371 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
14373 location_t location = c_parser_peek_token (parser)->location;
14374 enum tree_code if_modifier = ERROR_MARK;
14376 matching_parens parens;
14377 if (!parens.require_open (parser))
14378 return list;
14380 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
14382 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14383 int n = 2;
14384 if (strcmp (p, "cancel") == 0)
14385 if_modifier = VOID_CST;
14386 else if (strcmp (p, "parallel") == 0)
14387 if_modifier = OMP_PARALLEL;
14388 else if (strcmp (p, "simd") == 0)
14389 if_modifier = OMP_SIMD;
14390 else if (strcmp (p, "task") == 0)
14391 if_modifier = OMP_TASK;
14392 else if (strcmp (p, "taskloop") == 0)
14393 if_modifier = OMP_TASKLOOP;
14394 else if (strcmp (p, "target") == 0)
14396 if_modifier = OMP_TARGET;
14397 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
14399 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
14400 if (strcmp ("data", p) == 0)
14401 if_modifier = OMP_TARGET_DATA;
14402 else if (strcmp ("update", p) == 0)
14403 if_modifier = OMP_TARGET_UPDATE;
14404 else if (strcmp ("enter", p) == 0)
14405 if_modifier = OMP_TARGET_ENTER_DATA;
14406 else if (strcmp ("exit", p) == 0)
14407 if_modifier = OMP_TARGET_EXIT_DATA;
14408 if (if_modifier != OMP_TARGET)
14410 n = 3;
14411 c_parser_consume_token (parser);
14413 else
14415 location_t loc = c_parser_peek_2nd_token (parser)->location;
14416 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
14417 "or %<exit%>");
14418 if_modifier = ERROR_MARK;
14420 if (if_modifier == OMP_TARGET_ENTER_DATA
14421 || if_modifier == OMP_TARGET_EXIT_DATA)
14423 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
14425 p = IDENTIFIER_POINTER
14426 (c_parser_peek_2nd_token (parser)->value);
14427 if (strcmp ("data", p) == 0)
14428 n = 4;
14430 if (n == 4)
14431 c_parser_consume_token (parser);
14432 else
14434 location_t loc
14435 = c_parser_peek_2nd_token (parser)->location;
14436 error_at (loc, "expected %<data%>");
14437 if_modifier = ERROR_MARK;
14442 if (if_modifier != ERROR_MARK)
14444 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14446 c_parser_consume_token (parser);
14447 c_parser_consume_token (parser);
14449 else
14451 if (n > 2)
14453 location_t loc = c_parser_peek_2nd_token (parser)->location;
14454 error_at (loc, "expected %<:%>");
14456 if_modifier = ERROR_MARK;
14461 location_t loc = c_parser_peek_token (parser)->location;
14462 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14463 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
14464 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
14465 t = c_fully_fold (t, false, NULL);
14466 parens.skip_until_found_close (parser);
14468 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14469 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
14471 if (if_modifier != ERROR_MARK
14472 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
14474 const char *p = NULL;
14475 switch (if_modifier)
14477 case VOID_CST: p = "cancel"; break;
14478 case OMP_PARALLEL: p = "parallel"; break;
14479 case OMP_SIMD: p = "simd"; break;
14480 case OMP_TASK: p = "task"; break;
14481 case OMP_TASKLOOP: p = "taskloop"; break;
14482 case OMP_TARGET_DATA: p = "target data"; break;
14483 case OMP_TARGET: p = "target"; break;
14484 case OMP_TARGET_UPDATE: p = "target update"; break;
14485 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
14486 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
14487 default: gcc_unreachable ();
14489 error_at (location, "too many %<if%> clauses with %qs modifier",
14491 return list;
14493 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
14495 if (!is_omp)
14496 error_at (location, "too many %<if%> clauses");
14497 else
14498 error_at (location, "too many %<if%> clauses without modifier");
14499 return list;
14501 else if (if_modifier == ERROR_MARK
14502 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
14504 error_at (location, "if any %<if%> clause has modifier, then all "
14505 "%<if%> clauses have to use modifier");
14506 return list;
14510 c = build_omp_clause (location, OMP_CLAUSE_IF);
14511 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
14512 OMP_CLAUSE_IF_EXPR (c) = t;
14513 OMP_CLAUSE_CHAIN (c) = list;
14514 return c;
14517 /* OpenMP 2.5:
14518 lastprivate ( variable-list )
14520 OpenMP 5.0:
14521 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
14523 static tree
14524 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
14526 /* The clauses location. */
14527 location_t loc = c_parser_peek_token (parser)->location;
14529 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14531 bool conditional = false;
14532 if (c_parser_next_token_is (parser, CPP_NAME)
14533 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14535 const char *p
14536 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14537 if (strcmp (p, "conditional") == 0)
14539 conditional = true;
14540 c_parser_consume_token (parser);
14541 c_parser_consume_token (parser);
14544 tree nlist = c_parser_omp_variable_list (parser, loc,
14545 OMP_CLAUSE_LASTPRIVATE, list);
14546 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
14547 if (conditional)
14548 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
14549 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
14550 return nlist;
14552 return list;
14555 /* OpenMP 3.1:
14556 mergeable */
14558 static tree
14559 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14561 tree c;
14563 /* FIXME: Should we allow duplicates? */
14564 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
14566 c = build_omp_clause (c_parser_peek_token (parser)->location,
14567 OMP_CLAUSE_MERGEABLE);
14568 OMP_CLAUSE_CHAIN (c) = list;
14570 return c;
14573 /* OpenMP 2.5:
14574 nowait */
14576 static tree
14577 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14579 tree c;
14580 location_t loc = c_parser_peek_token (parser)->location;
14582 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
14584 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
14585 OMP_CLAUSE_CHAIN (c) = list;
14586 return c;
14589 /* OpenMP 2.5:
14590 num_threads ( expression ) */
14592 static tree
14593 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
14595 location_t num_threads_loc = c_parser_peek_token (parser)->location;
14596 matching_parens parens;
14597 if (parens.require_open (parser))
14599 location_t expr_loc = c_parser_peek_token (parser)->location;
14600 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14601 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14602 tree c, t = expr.value;
14603 t = c_fully_fold (t, false, NULL);
14605 parens.skip_until_found_close (parser);
14607 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14609 c_parser_error (parser, "expected integer expression");
14610 return list;
14613 /* Attempt to statically determine when the number isn't positive. */
14614 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14615 build_int_cst (TREE_TYPE (t), 0));
14616 protected_set_expr_location (c, expr_loc);
14617 if (c == boolean_true_node)
14619 warning_at (expr_loc, 0,
14620 "%<num_threads%> value must be positive");
14621 t = integer_one_node;
14624 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
14626 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
14627 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
14628 OMP_CLAUSE_CHAIN (c) = list;
14629 list = c;
14632 return list;
14635 /* OpenMP 4.5:
14636 num_tasks ( expression )
14638 OpenMP 5.1:
14639 num_tasks ( strict : expression ) */
14641 static tree
14642 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
14644 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
14645 matching_parens parens;
14646 if (parens.require_open (parser))
14648 bool strict = false;
14649 if (c_parser_next_token_is (parser, CPP_NAME)
14650 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14651 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14652 "strict") == 0)
14654 strict = true;
14655 c_parser_consume_token (parser);
14656 c_parser_consume_token (parser);
14659 location_t expr_loc = c_parser_peek_token (parser)->location;
14660 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14661 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14662 tree c, t = expr.value;
14663 t = c_fully_fold (t, false, NULL);
14665 parens.skip_until_found_close (parser);
14667 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14669 c_parser_error (parser, "expected integer expression");
14670 return list;
14673 /* Attempt to statically determine when the number isn't positive. */
14674 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14675 build_int_cst (TREE_TYPE (t), 0));
14676 if (CAN_HAVE_LOCATION_P (c))
14677 SET_EXPR_LOCATION (c, expr_loc);
14678 if (c == boolean_true_node)
14680 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
14681 t = integer_one_node;
14684 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
14686 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
14687 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
14688 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
14689 OMP_CLAUSE_CHAIN (c) = list;
14690 list = c;
14693 return list;
14696 /* OpenMP 4.5:
14697 grainsize ( expression )
14699 OpenMP 5.1:
14700 grainsize ( strict : expression ) */
14702 static tree
14703 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
14705 location_t grainsize_loc = c_parser_peek_token (parser)->location;
14706 matching_parens parens;
14707 if (parens.require_open (parser))
14709 bool strict = false;
14710 if (c_parser_next_token_is (parser, CPP_NAME)
14711 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14712 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14713 "strict") == 0)
14715 strict = true;
14716 c_parser_consume_token (parser);
14717 c_parser_consume_token (parser);
14720 location_t expr_loc = c_parser_peek_token (parser)->location;
14721 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14722 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14723 tree c, t = expr.value;
14724 t = c_fully_fold (t, false, NULL);
14726 parens.skip_until_found_close (parser);
14728 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14730 c_parser_error (parser, "expected integer expression");
14731 return list;
14734 /* Attempt to statically determine when the number isn't positive. */
14735 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14736 build_int_cst (TREE_TYPE (t), 0));
14737 if (CAN_HAVE_LOCATION_P (c))
14738 SET_EXPR_LOCATION (c, expr_loc);
14739 if (c == boolean_true_node)
14741 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14742 t = integer_one_node;
14745 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14747 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14748 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14749 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14750 OMP_CLAUSE_CHAIN (c) = list;
14751 list = c;
14754 return list;
14757 /* OpenMP 4.5:
14758 priority ( expression ) */
14760 static tree
14761 c_parser_omp_clause_priority (c_parser *parser, tree list)
14763 location_t priority_loc = c_parser_peek_token (parser)->location;
14764 matching_parens parens;
14765 if (parens.require_open (parser))
14767 location_t expr_loc = c_parser_peek_token (parser)->location;
14768 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14769 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14770 tree c, t = expr.value;
14771 t = c_fully_fold (t, false, NULL);
14773 parens.skip_until_found_close (parser);
14775 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14777 c_parser_error (parser, "expected integer expression");
14778 return list;
14781 /* Attempt to statically determine when the number isn't
14782 non-negative. */
14783 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14784 build_int_cst (TREE_TYPE (t), 0));
14785 if (CAN_HAVE_LOCATION_P (c))
14786 SET_EXPR_LOCATION (c, expr_loc);
14787 if (c == boolean_true_node)
14789 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14790 t = integer_one_node;
14793 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14795 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14796 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14797 OMP_CLAUSE_CHAIN (c) = list;
14798 list = c;
14801 return list;
14804 /* OpenMP 4.5:
14805 hint ( expression ) */
14807 static tree
14808 c_parser_omp_clause_hint (c_parser *parser, tree list)
14810 location_t hint_loc = c_parser_peek_token (parser)->location;
14811 matching_parens parens;
14812 if (parens.require_open (parser))
14814 location_t expr_loc = c_parser_peek_token (parser)->location;
14815 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14816 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14817 tree c, t = expr.value;
14818 t = c_fully_fold (t, false, NULL);
14819 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14820 || TREE_CODE (t) != INTEGER_CST
14821 || tree_int_cst_sgn (t) == -1)
14823 c_parser_error (parser, "expected constant integer expression "
14824 "with valid sync-hint value");
14825 return list;
14827 parens.skip_until_found_close (parser);
14828 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14830 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14831 OMP_CLAUSE_HINT_EXPR (c) = t;
14832 OMP_CLAUSE_CHAIN (c) = list;
14833 list = c;
14836 return list;
14839 /* OpenMP 5.1:
14840 filter ( integer-expression ) */
14842 static tree
14843 c_parser_omp_clause_filter (c_parser *parser, tree list)
14845 location_t hint_loc = c_parser_peek_token (parser)->location;
14846 matching_parens parens;
14847 if (parens.require_open (parser))
14849 location_t expr_loc = c_parser_peek_token (parser)->location;
14850 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14851 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14852 tree c, t = expr.value;
14853 t = c_fully_fold (t, false, NULL);
14854 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14856 c_parser_error (parser, "expected integer expression");
14857 return list;
14859 parens.skip_until_found_close (parser);
14860 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14862 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14863 OMP_CLAUSE_FILTER_EXPR (c) = t;
14864 OMP_CLAUSE_CHAIN (c) = list;
14865 list = c;
14868 return list;
14871 /* OpenMP 4.5:
14872 defaultmap ( tofrom : scalar )
14874 OpenMP 5.0:
14875 defaultmap ( implicit-behavior [ : variable-category ] ) */
14877 static tree
14878 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14880 location_t loc = c_parser_peek_token (parser)->location;
14881 tree c;
14882 const char *p;
14883 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14884 enum omp_clause_defaultmap_kind category
14885 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14887 matching_parens parens;
14888 if (!parens.require_open (parser))
14889 return list;
14890 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14891 p = "default";
14892 else if (!c_parser_next_token_is (parser, CPP_NAME))
14894 invalid_behavior:
14895 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14896 "%<tofrom%>, %<firstprivate%>, %<none%> "
14897 "or %<default%>");
14898 goto out_err;
14900 else
14901 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14903 switch (p[0])
14905 case 'a':
14906 if (strcmp ("alloc", p) == 0)
14907 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14908 else
14909 goto invalid_behavior;
14910 break;
14912 case 'd':
14913 if (strcmp ("default", p) == 0)
14914 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14915 else
14916 goto invalid_behavior;
14917 break;
14919 case 'f':
14920 if (strcmp ("firstprivate", p) == 0)
14921 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14922 else if (strcmp ("from", p) == 0)
14923 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14924 else
14925 goto invalid_behavior;
14926 break;
14928 case 'n':
14929 if (strcmp ("none", p) == 0)
14930 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14931 else
14932 goto invalid_behavior;
14933 break;
14935 case 't':
14936 if (strcmp ("tofrom", p) == 0)
14937 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14938 else if (strcmp ("to", p) == 0)
14939 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14940 else
14941 goto invalid_behavior;
14942 break;
14944 default:
14945 goto invalid_behavior;
14947 c_parser_consume_token (parser);
14949 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14951 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14952 goto out_err;
14953 if (!c_parser_next_token_is (parser, CPP_NAME))
14955 invalid_category:
14956 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14957 "%<pointer%>");
14958 goto out_err;
14960 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14961 switch (p[0])
14963 case 'a':
14964 if (strcmp ("aggregate", p) == 0)
14965 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14966 else
14967 goto invalid_category;
14968 break;
14970 case 'p':
14971 if (strcmp ("pointer", p) == 0)
14972 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14973 else
14974 goto invalid_category;
14975 break;
14977 case 's':
14978 if (strcmp ("scalar", p) == 0)
14979 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14980 else
14981 goto invalid_category;
14982 break;
14984 default:
14985 goto invalid_category;
14988 c_parser_consume_token (parser);
14990 parens.skip_until_found_close (parser);
14992 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14993 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14994 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14995 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14996 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14997 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14999 enum omp_clause_defaultmap_kind cat = category;
15000 location_t loc = OMP_CLAUSE_LOCATION (c);
15001 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
15002 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
15003 p = NULL;
15004 switch (cat)
15006 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
15007 p = NULL;
15008 break;
15009 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
15010 p = "aggregate";
15011 break;
15012 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
15013 p = "pointer";
15014 break;
15015 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
15016 p = "scalar";
15017 break;
15018 default:
15019 gcc_unreachable ();
15021 if (p)
15022 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
15024 else
15025 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
15026 "category");
15027 break;
15030 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
15031 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
15032 OMP_CLAUSE_CHAIN (c) = list;
15033 return c;
15035 out_err:
15036 parens.skip_until_found_close (parser);
15037 return list;
15040 /* OpenACC 2.0:
15041 use_device ( variable-list )
15043 OpenMP 4.5:
15044 use_device_ptr ( variable-list ) */
15046 static tree
15047 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
15049 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
15050 list);
15053 /* OpenMP 5.0:
15054 use_device_addr ( variable-list ) */
15056 static tree
15057 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
15059 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
15060 list);
15063 /* OpenMP 5.1:
15064 has_device_addr ( variable-list ) */
15066 static tree
15067 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
15069 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
15070 list);
15073 /* OpenMP 4.5:
15074 is_device_ptr ( variable-list ) */
15076 static tree
15077 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
15079 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
15082 /* OpenACC:
15083 num_gangs ( expression )
15084 num_workers ( expression )
15085 vector_length ( expression ) */
15087 static tree
15088 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
15089 tree list)
15091 location_t loc = c_parser_peek_token (parser)->location;
15093 matching_parens parens;
15094 if (!parens.require_open (parser))
15095 return list;
15097 location_t expr_loc = c_parser_peek_token (parser)->location;
15098 c_expr expr = c_parser_expression (parser);
15099 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15100 tree c, t = expr.value;
15101 t = c_fully_fold (t, false, NULL);
15103 parens.skip_until_found_close (parser);
15105 if (t == error_mark_node)
15106 return list;
15107 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15109 error_at (expr_loc, "%qs expression must be integral",
15110 omp_clause_code_name[code]);
15111 return list;
15114 /* Attempt to statically determine when the number isn't positive. */
15115 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15116 build_int_cst (TREE_TYPE (t), 0));
15117 protected_set_expr_location (c, expr_loc);
15118 if (c == boolean_true_node)
15120 warning_at (expr_loc, 0,
15121 "%qs value must be positive",
15122 omp_clause_code_name[code]);
15123 t = integer_one_node;
15126 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15128 c = build_omp_clause (loc, code);
15129 OMP_CLAUSE_OPERAND (c, 0) = t;
15130 OMP_CLAUSE_CHAIN (c) = list;
15131 return c;
15134 /* OpenACC:
15136 gang [( gang-arg-list )]
15137 worker [( [num:] int-expr )]
15138 vector [( [length:] int-expr )]
15140 where gang-arg is one of:
15142 [num:] int-expr
15143 static: size-expr
15145 and size-expr may be:
15148 int-expr
15151 static tree
15152 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
15153 omp_clause_code kind,
15154 const char *str, tree list)
15156 const char *id = "num";
15157 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
15159 if (kind == OMP_CLAUSE_VECTOR)
15160 id = "length";
15162 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
15164 c_parser_consume_token (parser);
15168 c_token *next = c_parser_peek_token (parser);
15169 int idx = 0;
15171 /* Gang static argument. */
15172 if (kind == OMP_CLAUSE_GANG
15173 && c_parser_next_token_is_keyword (parser, RID_STATIC))
15175 c_parser_consume_token (parser);
15177 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15178 goto cleanup_error;
15180 idx = 1;
15181 if (ops[idx] != NULL_TREE)
15183 c_parser_error (parser, "too many %<static%> arguments");
15184 goto cleanup_error;
15187 /* Check for the '*' argument. */
15188 if (c_parser_next_token_is (parser, CPP_MULT)
15189 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
15190 || c_parser_peek_2nd_token (parser)->type
15191 == CPP_CLOSE_PAREN))
15193 c_parser_consume_token (parser);
15194 ops[idx] = integer_minus_one_node;
15196 if (c_parser_next_token_is (parser, CPP_COMMA))
15198 c_parser_consume_token (parser);
15199 continue;
15201 else
15202 break;
15205 /* Worker num: argument and vector length: arguments. */
15206 else if (c_parser_next_token_is (parser, CPP_NAME)
15207 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
15208 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15210 c_parser_consume_token (parser); /* id */
15211 c_parser_consume_token (parser); /* ':' */
15214 /* Now collect the actual argument. */
15215 if (ops[idx] != NULL_TREE)
15217 c_parser_error (parser, "unexpected argument");
15218 goto cleanup_error;
15221 location_t expr_loc = c_parser_peek_token (parser)->location;
15222 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
15223 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
15224 tree expr = cexpr.value;
15225 if (expr == error_mark_node)
15226 goto cleanup_error;
15228 expr = c_fully_fold (expr, false, NULL);
15230 /* Attempt to statically determine when the number isn't a
15231 positive integer. */
15233 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
15235 c_parser_error (parser, "expected integer expression");
15236 return list;
15239 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
15240 build_int_cst (TREE_TYPE (expr), 0));
15241 if (c == boolean_true_node)
15243 warning_at (loc, 0,
15244 "%qs value must be positive", str);
15245 expr = integer_one_node;
15248 ops[idx] = expr;
15250 if (kind == OMP_CLAUSE_GANG
15251 && c_parser_next_token_is (parser, CPP_COMMA))
15253 c_parser_consume_token (parser);
15254 continue;
15256 break;
15258 while (1);
15260 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
15261 goto cleanup_error;
15264 check_no_duplicate_clause (list, kind, str);
15266 c = build_omp_clause (loc, kind);
15268 if (ops[1])
15269 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
15271 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
15272 OMP_CLAUSE_CHAIN (c) = list;
15274 return c;
15276 cleanup_error:
15277 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15278 return list;
15281 /* OpenACC 2.5:
15282 auto
15283 finalize
15284 independent
15285 nohost
15286 seq */
15288 static tree
15289 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
15290 tree list)
15292 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15294 tree c = build_omp_clause (loc, code);
15295 OMP_CLAUSE_CHAIN (c) = list;
15297 return c;
15300 /* OpenACC:
15301 async [( int-expr )] */
15303 static tree
15304 c_parser_oacc_clause_async (c_parser *parser, tree list)
15306 tree c, t;
15307 location_t loc = c_parser_peek_token (parser)->location;
15309 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
15311 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
15313 c_parser_consume_token (parser);
15315 t = c_parser_expr_no_commas (parser, NULL).value;
15316 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15317 c_parser_error (parser, "expected integer expression");
15318 else if (t == error_mark_node
15319 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
15320 return list;
15322 else
15323 t = c_fully_fold (t, false, NULL);
15325 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
15327 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
15328 OMP_CLAUSE_ASYNC_EXPR (c) = t;
15329 OMP_CLAUSE_CHAIN (c) = list;
15330 list = c;
15332 return list;
15335 /* OpenACC 2.0:
15336 tile ( size-expr-list ) */
15338 static tree
15339 c_parser_oacc_clause_tile (c_parser *parser, tree list)
15341 tree c, expr = error_mark_node;
15342 location_t loc;
15343 tree tile = NULL_TREE;
15345 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
15346 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
15348 loc = c_parser_peek_token (parser)->location;
15349 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
15350 return list;
15354 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
15355 return list;
15357 if (c_parser_next_token_is (parser, CPP_MULT)
15358 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
15359 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
15361 c_parser_consume_token (parser);
15362 expr = integer_zero_node;
15364 else
15366 location_t expr_loc = c_parser_peek_token (parser)->location;
15367 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
15368 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
15369 expr = cexpr.value;
15371 if (expr == error_mark_node)
15373 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15374 "expected %<)%>");
15375 return list;
15378 expr = c_fully_fold (expr, false, NULL);
15380 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
15381 || !tree_fits_shwi_p (expr)
15382 || tree_to_shwi (expr) <= 0)
15384 error_at (expr_loc, "%<tile%> argument needs positive"
15385 " integral constant");
15386 expr = integer_zero_node;
15390 tile = tree_cons (NULL_TREE, expr, tile);
15392 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
15394 /* Consume the trailing ')'. */
15395 c_parser_consume_token (parser);
15397 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
15398 tile = nreverse (tile);
15399 OMP_CLAUSE_TILE_LIST (c) = tile;
15400 OMP_CLAUSE_CHAIN (c) = list;
15401 return c;
15404 /* OpenACC:
15405 wait [( int-expr-list )] */
15407 static tree
15408 c_parser_oacc_clause_wait (c_parser *parser, tree list)
15410 location_t clause_loc = c_parser_peek_token (parser)->location;
15412 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
15413 list = c_parser_oacc_wait_list (parser, clause_loc, list);
15414 else
15416 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
15418 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
15419 OMP_CLAUSE_CHAIN (c) = list;
15420 list = c;
15423 return list;
15427 /* OpenMP 5.0:
15428 order ( concurrent )
15430 OpenMP 5.1:
15431 order ( order-modifier : concurrent )
15433 order-modifier:
15434 reproducible
15435 unconstrained */
15437 static tree
15438 c_parser_omp_clause_order (c_parser *parser, tree list)
15440 location_t loc = c_parser_peek_token (parser)->location;
15441 tree c;
15442 const char *p;
15443 bool unconstrained = false;
15444 bool reproducible = false;
15446 matching_parens parens;
15447 if (!parens.require_open (parser))
15448 return list;
15449 if (c_parser_next_token_is (parser, CPP_NAME)
15450 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15452 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15453 if (strcmp (p, "unconstrained") == 0)
15454 unconstrained = true;
15455 else if (strcmp (p, "reproducible") == 0)
15456 reproducible = true;
15457 else
15459 c_parser_error (parser, "expected %<reproducible%> or "
15460 "%<unconstrained%>");
15461 goto out_err;
15463 c_parser_consume_token (parser);
15464 c_parser_consume_token (parser);
15466 if (!c_parser_next_token_is (parser, CPP_NAME))
15468 c_parser_error (parser, "expected %<concurrent%>");
15469 goto out_err;
15471 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15472 if (strcmp (p, "concurrent") != 0)
15474 c_parser_error (parser, "expected %<concurrent%>");
15475 goto out_err;
15477 c_parser_consume_token (parser);
15478 parens.skip_until_found_close (parser);
15479 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
15480 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
15481 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
15482 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
15483 OMP_CLAUSE_CHAIN (c) = list;
15484 return c;
15486 out_err:
15487 parens.skip_until_found_close (parser);
15488 return list;
15492 /* OpenMP 5.0:
15493 bind ( teams | parallel | thread ) */
15495 static tree
15496 c_parser_omp_clause_bind (c_parser *parser, tree list)
15498 location_t loc = c_parser_peek_token (parser)->location;
15499 tree c;
15500 const char *p;
15501 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
15503 matching_parens parens;
15504 if (!parens.require_open (parser))
15505 return list;
15506 if (!c_parser_next_token_is (parser, CPP_NAME))
15508 invalid:
15509 c_parser_error (parser,
15510 "expected %<teams%>, %<parallel%> or %<thread%>");
15511 parens.skip_until_found_close (parser);
15512 return list;
15514 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15515 if (strcmp (p, "teams") == 0)
15516 kind = OMP_CLAUSE_BIND_TEAMS;
15517 else if (strcmp (p, "parallel") == 0)
15518 kind = OMP_CLAUSE_BIND_PARALLEL;
15519 else if (strcmp (p, "thread") != 0)
15520 goto invalid;
15521 c_parser_consume_token (parser);
15522 parens.skip_until_found_close (parser);
15523 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
15524 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
15525 OMP_CLAUSE_BIND_KIND (c) = kind;
15526 OMP_CLAUSE_CHAIN (c) = list;
15527 return c;
15531 /* OpenMP 2.5:
15532 ordered
15534 OpenMP 4.5:
15535 ordered ( constant-expression ) */
15537 static tree
15538 c_parser_omp_clause_ordered (c_parser *parser, tree list)
15540 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
15542 tree c, num = NULL_TREE;
15543 HOST_WIDE_INT n;
15544 location_t loc = c_parser_peek_token (parser)->location;
15545 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
15547 matching_parens parens;
15548 parens.consume_open (parser);
15549 num = c_parser_expr_no_commas (parser, NULL).value;
15550 parens.skip_until_found_close (parser);
15552 if (num == error_mark_node)
15553 return list;
15554 if (num)
15556 mark_exp_read (num);
15557 num = c_fully_fold (num, false, NULL);
15558 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
15559 || !tree_fits_shwi_p (num)
15560 || (n = tree_to_shwi (num)) <= 0
15561 || (int) n != n)
15563 error_at (loc, "ordered argument needs positive "
15564 "constant integer expression");
15565 return list;
15568 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
15569 OMP_CLAUSE_ORDERED_EXPR (c) = num;
15570 OMP_CLAUSE_CHAIN (c) = list;
15571 return c;
15574 /* OpenMP 2.5:
15575 private ( variable-list ) */
15577 static tree
15578 c_parser_omp_clause_private (c_parser *parser, tree list)
15580 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
15583 /* OpenMP 2.5:
15584 reduction ( reduction-operator : variable-list )
15586 reduction-operator:
15587 One of: + * - & ^ | && ||
15589 OpenMP 3.1:
15591 reduction-operator:
15592 One of: + * - & ^ | && || max min
15594 OpenMP 4.0:
15596 reduction-operator:
15597 One of: + * - & ^ | && ||
15598 identifier
15600 OpenMP 5.0:
15601 reduction ( reduction-modifier, reduction-operator : variable-list )
15602 in_reduction ( reduction-operator : variable-list )
15603 task_reduction ( reduction-operator : variable-list ) */
15605 static tree
15606 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
15607 bool is_omp, tree list)
15609 location_t clause_loc = c_parser_peek_token (parser)->location;
15610 matching_parens parens;
15611 if (parens.require_open (parser))
15613 bool task = false;
15614 bool inscan = false;
15615 enum tree_code code = ERROR_MARK;
15616 tree reduc_id = NULL_TREE;
15618 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
15620 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
15621 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
15623 c_parser_consume_token (parser);
15624 c_parser_consume_token (parser);
15626 else if (c_parser_next_token_is (parser, CPP_NAME)
15627 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
15629 const char *p
15630 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15631 if (strcmp (p, "task") == 0)
15632 task = true;
15633 else if (strcmp (p, "inscan") == 0)
15634 inscan = true;
15635 if (task || inscan)
15637 c_parser_consume_token (parser);
15638 c_parser_consume_token (parser);
15643 switch (c_parser_peek_token (parser)->type)
15645 case CPP_PLUS:
15646 code = PLUS_EXPR;
15647 break;
15648 case CPP_MULT:
15649 code = MULT_EXPR;
15650 break;
15651 case CPP_MINUS:
15652 code = MINUS_EXPR;
15653 break;
15654 case CPP_AND:
15655 code = BIT_AND_EXPR;
15656 break;
15657 case CPP_XOR:
15658 code = BIT_XOR_EXPR;
15659 break;
15660 case CPP_OR:
15661 code = BIT_IOR_EXPR;
15662 break;
15663 case CPP_AND_AND:
15664 code = TRUTH_ANDIF_EXPR;
15665 break;
15666 case CPP_OR_OR:
15667 code = TRUTH_ORIF_EXPR;
15668 break;
15669 case CPP_NAME:
15671 const char *p
15672 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15673 if (strcmp (p, "min") == 0)
15675 code = MIN_EXPR;
15676 break;
15678 if (strcmp (p, "max") == 0)
15680 code = MAX_EXPR;
15681 break;
15683 reduc_id = c_parser_peek_token (parser)->value;
15684 break;
15686 default:
15687 c_parser_error (parser,
15688 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15689 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15690 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15691 return list;
15693 c_parser_consume_token (parser);
15694 reduc_id = c_omp_reduction_id (code, reduc_id);
15695 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15697 tree nl, c;
15699 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
15700 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15702 tree d = OMP_CLAUSE_DECL (c), type;
15703 if (TREE_CODE (d) != TREE_LIST)
15704 type = TREE_TYPE (d);
15705 else
15707 int cnt = 0;
15708 tree t;
15709 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
15710 cnt++;
15711 type = TREE_TYPE (t);
15712 while (cnt > 0)
15714 if (TREE_CODE (type) != POINTER_TYPE
15715 && TREE_CODE (type) != ARRAY_TYPE)
15716 break;
15717 type = TREE_TYPE (type);
15718 cnt--;
15721 while (TREE_CODE (type) == ARRAY_TYPE)
15722 type = TREE_TYPE (type);
15723 OMP_CLAUSE_REDUCTION_CODE (c) = code;
15724 if (task)
15725 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15726 else if (inscan)
15727 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15728 if (code == ERROR_MARK
15729 || !(INTEGRAL_TYPE_P (type)
15730 || TREE_CODE (type) == REAL_TYPE
15731 || TREE_CODE (type) == COMPLEX_TYPE))
15732 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15733 = c_omp_reduction_lookup (reduc_id,
15734 TYPE_MAIN_VARIANT (type));
15737 list = nl;
15739 parens.skip_until_found_close (parser);
15741 return list;
15744 /* OpenMP 2.5:
15745 schedule ( schedule-kind )
15746 schedule ( schedule-kind , expression )
15748 schedule-kind:
15749 static | dynamic | guided | runtime | auto
15751 OpenMP 4.5:
15752 schedule ( schedule-modifier : schedule-kind )
15753 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15755 schedule-modifier:
15756 simd
15757 monotonic
15758 nonmonotonic */
15760 static tree
15761 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15763 tree c, t;
15764 location_t loc = c_parser_peek_token (parser)->location;
15765 int modifiers = 0, nmodifiers = 0;
15767 matching_parens parens;
15768 if (!parens.require_open (parser))
15769 return list;
15771 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15773 location_t comma = UNKNOWN_LOCATION;
15774 while (c_parser_next_token_is (parser, CPP_NAME))
15776 tree kind = c_parser_peek_token (parser)->value;
15777 const char *p = IDENTIFIER_POINTER (kind);
15778 if (strcmp ("simd", p) == 0)
15779 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15780 else if (strcmp ("monotonic", p) == 0)
15781 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15782 else if (strcmp ("nonmonotonic", p) == 0)
15783 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15784 else
15785 break;
15786 comma = UNKNOWN_LOCATION;
15787 c_parser_consume_token (parser);
15788 if (nmodifiers++ == 0
15789 && c_parser_next_token_is (parser, CPP_COMMA))
15791 comma = c_parser_peek_token (parser)->location;
15792 c_parser_consume_token (parser);
15794 else
15796 c_parser_require (parser, CPP_COLON, "expected %<:%>");
15797 break;
15800 if (comma != UNKNOWN_LOCATION)
15801 error_at (comma, "expected %<:%>");
15803 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15804 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15805 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15806 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15808 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15809 "specified");
15810 modifiers = 0;
15813 if (c_parser_next_token_is (parser, CPP_NAME))
15815 tree kind = c_parser_peek_token (parser)->value;
15816 const char *p = IDENTIFIER_POINTER (kind);
15818 switch (p[0])
15820 case 'd':
15821 if (strcmp ("dynamic", p) != 0)
15822 goto invalid_kind;
15823 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15824 break;
15826 case 'g':
15827 if (strcmp ("guided", p) != 0)
15828 goto invalid_kind;
15829 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15830 break;
15832 case 'r':
15833 if (strcmp ("runtime", p) != 0)
15834 goto invalid_kind;
15835 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15836 break;
15838 default:
15839 goto invalid_kind;
15842 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15843 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15844 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15845 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15846 else
15847 goto invalid_kind;
15849 c_parser_consume_token (parser);
15850 if (c_parser_next_token_is (parser, CPP_COMMA))
15852 location_t here;
15853 c_parser_consume_token (parser);
15855 here = c_parser_peek_token (parser)->location;
15856 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15857 expr = convert_lvalue_to_rvalue (here, expr, false, true);
15858 t = expr.value;
15859 t = c_fully_fold (t, false, NULL);
15861 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15862 error_at (here, "schedule %<runtime%> does not take "
15863 "a %<chunk_size%> parameter");
15864 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15865 error_at (here,
15866 "schedule %<auto%> does not take "
15867 "a %<chunk_size%> parameter");
15868 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15870 /* Attempt to statically determine when the number isn't
15871 positive. */
15872 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15873 build_int_cst (TREE_TYPE (t), 0));
15874 protected_set_expr_location (s, loc);
15875 if (s == boolean_true_node)
15877 warning_at (loc, 0,
15878 "chunk size value must be positive");
15879 t = integer_one_node;
15881 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15883 else
15884 c_parser_error (parser, "expected integer expression");
15886 parens.skip_until_found_close (parser);
15888 else
15889 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15890 "expected %<,%> or %<)%>");
15892 OMP_CLAUSE_SCHEDULE_KIND (c)
15893 = (enum omp_clause_schedule_kind)
15894 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15896 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15897 OMP_CLAUSE_CHAIN (c) = list;
15898 return c;
15900 invalid_kind:
15901 c_parser_error (parser, "invalid schedule kind");
15902 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15903 return list;
15906 /* OpenMP 2.5:
15907 shared ( variable-list ) */
15909 static tree
15910 c_parser_omp_clause_shared (c_parser *parser, tree list)
15912 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15915 /* OpenMP 3.0:
15916 untied */
15918 static tree
15919 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15921 tree c;
15923 /* FIXME: Should we allow duplicates? */
15924 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15926 c = build_omp_clause (c_parser_peek_token (parser)->location,
15927 OMP_CLAUSE_UNTIED);
15928 OMP_CLAUSE_CHAIN (c) = list;
15930 return c;
15933 /* OpenMP 4.0:
15934 inbranch
15935 notinbranch */
15937 static tree
15938 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15939 enum omp_clause_code code, tree list)
15941 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15943 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15944 OMP_CLAUSE_CHAIN (c) = list;
15946 return c;
15949 /* OpenMP 4.0:
15950 parallel
15952 sections
15953 taskgroup */
15955 static tree
15956 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15957 enum omp_clause_code code, tree list)
15959 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15960 OMP_CLAUSE_CHAIN (c) = list;
15962 return c;
15965 /* OpenMP 4.5:
15966 nogroup */
15968 static tree
15969 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15971 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15972 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15973 OMP_CLAUSE_NOGROUP);
15974 OMP_CLAUSE_CHAIN (c) = list;
15975 return c;
15978 /* OpenMP 4.5:
15979 simd
15980 threads */
15982 static tree
15983 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15984 enum omp_clause_code code, tree list)
15986 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15987 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15988 OMP_CLAUSE_CHAIN (c) = list;
15989 return c;
15992 /* OpenMP 4.0:
15993 num_teams ( expression )
15995 OpenMP 5.1:
15996 num_teams ( expression : expression ) */
15998 static tree
15999 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
16001 location_t num_teams_loc = c_parser_peek_token (parser)->location;
16002 matching_parens parens;
16003 if (parens.require_open (parser))
16005 location_t upper_loc = c_parser_peek_token (parser)->location;
16006 location_t lower_loc = UNKNOWN_LOCATION;
16007 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16008 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
16009 tree c, upper = expr.value, lower = NULL_TREE;
16010 upper = c_fully_fold (upper, false, NULL);
16012 if (c_parser_next_token_is (parser, CPP_COLON))
16014 c_parser_consume_token (parser);
16015 lower_loc = upper_loc;
16016 lower = upper;
16017 upper_loc = c_parser_peek_token (parser)->location;
16018 expr = c_parser_expr_no_commas (parser, NULL);
16019 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
16020 upper = expr.value;
16021 upper = c_fully_fold (upper, false, NULL);
16024 parens.skip_until_found_close (parser);
16026 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
16027 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
16029 c_parser_error (parser, "expected integer expression");
16030 return list;
16033 /* Attempt to statically determine when the number isn't positive. */
16034 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
16035 build_int_cst (TREE_TYPE (upper), 0));
16036 protected_set_expr_location (c, upper_loc);
16037 if (c == boolean_true_node)
16039 warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
16040 upper = integer_one_node;
16042 if (lower)
16044 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
16045 build_int_cst (TREE_TYPE (lower), 0));
16046 protected_set_expr_location (c, lower_loc);
16047 if (c == boolean_true_node)
16049 warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
16050 lower = NULL_TREE;
16052 else if (TREE_CODE (lower) == INTEGER_CST
16053 && TREE_CODE (upper) == INTEGER_CST
16054 && tree_int_cst_lt (upper, lower))
16056 warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
16057 "than upper bound %qE", lower, upper);
16058 lower = NULL_TREE;
16062 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
16064 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
16065 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
16066 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
16067 OMP_CLAUSE_CHAIN (c) = list;
16068 list = c;
16071 return list;
16074 /* OpenMP 4.0:
16075 thread_limit ( expression ) */
16077 static tree
16078 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
16080 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
16081 matching_parens parens;
16082 if (parens.require_open (parser))
16084 location_t expr_loc = c_parser_peek_token (parser)->location;
16085 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16086 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16087 tree c, t = expr.value;
16088 t = c_fully_fold (t, false, NULL);
16090 parens.skip_until_found_close (parser);
16092 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16094 c_parser_error (parser, "expected integer expression");
16095 return list;
16098 /* Attempt to statically determine when the number isn't positive. */
16099 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
16100 build_int_cst (TREE_TYPE (t), 0));
16101 protected_set_expr_location (c, expr_loc);
16102 if (c == boolean_true_node)
16104 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
16105 t = integer_one_node;
16108 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
16109 "thread_limit");
16111 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
16112 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
16113 OMP_CLAUSE_CHAIN (c) = list;
16114 list = c;
16117 return list;
16120 /* OpenMP 4.0:
16121 aligned ( variable-list )
16122 aligned ( variable-list : constant-expression ) */
16124 static tree
16125 c_parser_omp_clause_aligned (c_parser *parser, tree list)
16127 location_t clause_loc = c_parser_peek_token (parser)->location;
16128 tree nl, c;
16130 matching_parens parens;
16131 if (!parens.require_open (parser))
16132 return list;
16134 nl = c_parser_omp_variable_list (parser, clause_loc,
16135 OMP_CLAUSE_ALIGNED, list);
16137 if (c_parser_next_token_is (parser, CPP_COLON))
16139 c_parser_consume_token (parser);
16140 location_t expr_loc = c_parser_peek_token (parser)->location;
16141 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16142 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16143 tree alignment = expr.value;
16144 alignment = c_fully_fold (alignment, false, NULL);
16145 if (TREE_CODE (alignment) != INTEGER_CST
16146 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
16147 || tree_int_cst_sgn (alignment) != 1)
16149 error_at (clause_loc, "%<aligned%> clause alignment expression must "
16150 "be positive constant integer expression");
16151 alignment = NULL_TREE;
16154 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16155 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
16158 parens.skip_until_found_close (parser);
16159 return nl;
16162 /* OpenMP 5.0:
16163 allocate ( variable-list )
16164 allocate ( expression : variable-list )
16166 OpenMP 5.1:
16167 allocate ( allocator-modifier : variable-list )
16168 allocate ( allocator-modifier , allocator-modifier : variable-list )
16170 allocator-modifier:
16171 allocator ( expression )
16172 align ( expression ) */
16174 static tree
16175 c_parser_omp_clause_allocate (c_parser *parser, tree list)
16177 location_t clause_loc = c_parser_peek_token (parser)->location;
16178 tree nl, c;
16179 tree allocator = NULL_TREE;
16180 tree align = NULL_TREE;
16182 matching_parens parens;
16183 if (!parens.require_open (parser))
16184 return list;
16186 if ((c_parser_next_token_is_not (parser, CPP_NAME)
16187 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
16188 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
16189 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
16191 bool has_modifiers = false;
16192 tree orig_type = NULL_TREE;
16193 if (c_parser_next_token_is (parser, CPP_NAME)
16194 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
16196 unsigned int n = 3;
16197 const char *p
16198 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16199 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
16200 && c_parser_check_balanced_raw_token_sequence (parser, &n)
16201 && (c_parser_peek_nth_token_raw (parser, n)->type
16202 == CPP_CLOSE_PAREN))
16204 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
16205 == CPP_COLON)
16206 has_modifiers = true;
16207 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
16208 == CPP_COMMA
16209 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
16210 == CPP_NAME)
16211 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
16212 == CPP_OPEN_PAREN))
16214 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
16215 const char *q = IDENTIFIER_POINTER (tok->value);
16216 n += 4;
16217 if ((strcmp (q, "allocator") == 0
16218 || strcmp (q, "align") == 0)
16219 && c_parser_check_balanced_raw_token_sequence (parser,
16221 && (c_parser_peek_nth_token_raw (parser, n)->type
16222 == CPP_CLOSE_PAREN)
16223 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
16224 == CPP_COLON))
16225 has_modifiers = true;
16228 if (has_modifiers)
16230 c_parser_consume_token (parser);
16231 matching_parens parens2;;
16232 parens2.require_open (parser);
16233 location_t expr_loc = c_parser_peek_token (parser)->location;
16234 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16235 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16236 if (strcmp (p, "allocator") == 0)
16238 allocator = expr.value;
16239 allocator = c_fully_fold (allocator, false, NULL);
16240 orig_type = expr.original_type
16241 ? expr.original_type : TREE_TYPE (allocator);
16242 orig_type = TYPE_MAIN_VARIANT (orig_type);
16244 else
16246 align = expr.value;
16247 align = c_fully_fold (align, false, NULL);
16249 parens2.skip_until_found_close (parser);
16250 if (c_parser_next_token_is (parser, CPP_COMMA))
16252 c_parser_consume_token (parser);
16253 c_token *tok = c_parser_peek_token (parser);
16254 const char *q = "";
16255 if (c_parser_next_token_is (parser, CPP_NAME))
16256 q = IDENTIFIER_POINTER (tok->value);
16257 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
16259 c_parser_error (parser, "expected %<allocator%> or "
16260 "%<align%>");
16261 parens.skip_until_found_close (parser);
16262 return list;
16264 else if (strcmp (p, q) == 0)
16266 error_at (tok->location, "duplicate %qs modifier", p);
16267 parens.skip_until_found_close (parser);
16268 return list;
16270 c_parser_consume_token (parser);
16271 if (!parens2.require_open (parser))
16273 parens.skip_until_found_close (parser);
16274 return list;
16276 expr_loc = c_parser_peek_token (parser)->location;
16277 expr = c_parser_expr_no_commas (parser, NULL);
16278 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
16279 true);
16280 if (strcmp (q, "allocator") == 0)
16282 allocator = expr.value;
16283 allocator = c_fully_fold (allocator, false, NULL);
16284 orig_type = expr.original_type
16285 ? expr.original_type : TREE_TYPE (allocator);
16286 orig_type = TYPE_MAIN_VARIANT (orig_type);
16288 else
16290 align = expr.value;
16291 align = c_fully_fold (align, false, NULL);
16293 parens2.skip_until_found_close (parser);
16297 if (!has_modifiers)
16299 location_t expr_loc = c_parser_peek_token (parser)->location;
16300 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16301 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16302 allocator = expr.value;
16303 allocator = c_fully_fold (allocator, false, NULL);
16304 orig_type = expr.original_type
16305 ? expr.original_type : TREE_TYPE (allocator);
16306 orig_type = TYPE_MAIN_VARIANT (orig_type);
16308 if (allocator
16309 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
16310 || TREE_CODE (orig_type) != ENUMERAL_TYPE
16311 || (TYPE_NAME (orig_type)
16312 != get_identifier ("omp_allocator_handle_t"))))
16314 error_at (clause_loc, "%<allocate%> clause allocator expression "
16315 "has type %qT rather than "
16316 "%<omp_allocator_handle_t%>",
16317 TREE_TYPE (allocator));
16318 allocator = NULL_TREE;
16320 if (align
16321 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
16322 || !tree_fits_uhwi_p (align)
16323 || !integer_pow2p (align)))
16325 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
16326 "argument needs to be positive constant "
16327 "power of two integer expression");
16328 align = NULL_TREE;
16330 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16332 parens.skip_until_found_close (parser);
16333 return list;
16337 nl = c_parser_omp_variable_list (parser, clause_loc,
16338 OMP_CLAUSE_ALLOCATE, list);
16340 if (allocator || align)
16341 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16343 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
16344 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
16347 parens.skip_until_found_close (parser);
16348 return nl;
16351 /* OpenMP 4.0:
16352 linear ( variable-list )
16353 linear ( variable-list : expression )
16355 OpenMP 4.5:
16356 linear ( modifier ( variable-list ) )
16357 linear ( modifier ( variable-list ) : expression )
16359 modifier:
16362 OpenMP 5.2:
16363 linear ( variable-list : modifiers-list )
16365 modifiers:
16367 step ( expression ) */
16369 static tree
16370 c_parser_omp_clause_linear (c_parser *parser, tree list)
16372 location_t clause_loc = c_parser_peek_token (parser)->location;
16373 tree nl, c, step;
16374 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
16375 bool old_linear_modifier = false;
16377 matching_parens parens;
16378 if (!parens.require_open (parser))
16379 return list;
16381 if (c_parser_next_token_is (parser, CPP_NAME))
16383 c_token *tok = c_parser_peek_token (parser);
16384 const char *p = IDENTIFIER_POINTER (tok->value);
16385 if (strcmp ("val", p) == 0)
16386 kind = OMP_CLAUSE_LINEAR_VAL;
16387 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
16388 kind = OMP_CLAUSE_LINEAR_DEFAULT;
16389 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
16391 old_linear_modifier = true;
16392 c_parser_consume_token (parser);
16393 c_parser_consume_token (parser);
16397 nl = c_parser_omp_variable_list (parser, clause_loc,
16398 OMP_CLAUSE_LINEAR, list);
16400 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
16401 parens.skip_until_found_close (parser);
16403 if (c_parser_next_token_is (parser, CPP_COLON))
16405 c_parser_consume_token (parser);
16406 location_t expr_loc = c_parser_peek_token (parser)->location;
16407 bool has_modifiers = false;
16408 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
16409 && c_parser_next_token_is (parser, CPP_NAME))
16411 c_token *tok = c_parser_peek_token (parser);
16412 const char *p = IDENTIFIER_POINTER (tok->value);
16413 unsigned int pos = 0;
16414 if (strcmp ("val", p) == 0)
16415 pos = 2;
16416 else if (strcmp ("step", p) == 0
16417 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
16419 pos = 3;
16420 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
16421 && (c_parser_peek_nth_token_raw (parser, pos)->type
16422 == CPP_CLOSE_PAREN))
16423 ++pos;
16424 else
16425 pos = 0;
16427 if (pos)
16429 tok = c_parser_peek_nth_token_raw (parser, pos);
16430 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
16431 has_modifiers = true;
16434 if (has_modifiers)
16436 step = NULL_TREE;
16437 while (c_parser_next_token_is (parser, CPP_NAME))
16439 c_token *tok = c_parser_peek_token (parser);
16440 const char *p = IDENTIFIER_POINTER (tok->value);
16441 if (strcmp ("val", p) == 0)
16443 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
16444 error_at (tok->location, "multiple linear modifiers");
16445 kind = OMP_CLAUSE_LINEAR_DEFAULT;
16446 c_parser_consume_token (parser);
16448 else if (strcmp ("step", p) == 0)
16450 c_parser_consume_token (parser);
16451 matching_parens parens2;
16452 if (parens2.require_open (parser))
16454 if (step)
16455 error_at (tok->location,
16456 "multiple %<step%> modifiers");
16457 expr_loc = c_parser_peek_token (parser)->location;
16458 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16459 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
16460 true);
16461 step = c_fully_fold (expr.value, false, NULL);
16462 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
16464 error_at (clause_loc, "%<linear%> clause step "
16465 "expression must be integral");
16466 step = integer_one_node;
16468 parens2.skip_until_found_close (parser);
16470 else
16471 break;
16473 else
16474 break;
16475 if (c_parser_next_token_is (parser, CPP_COMMA))
16477 c_parser_consume_token (parser);
16478 continue;
16480 break;
16482 if (!step)
16483 step = integer_one_node;
16485 else
16487 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16488 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16489 step = c_fully_fold (expr.value, false, NULL);
16490 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
16492 error_at (clause_loc, "%<linear%> clause step expression must "
16493 "be integral");
16494 step = integer_one_node;
16499 else
16500 step = integer_one_node;
16502 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16504 OMP_CLAUSE_LINEAR_STEP (c) = step;
16505 OMP_CLAUSE_LINEAR_KIND (c) = kind;
16506 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
16509 parens.skip_until_found_close (parser);
16510 return nl;
16513 /* OpenMP 5.0:
16514 nontemporal ( variable-list ) */
16516 static tree
16517 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
16519 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
16522 /* OpenMP 4.0:
16523 safelen ( constant-expression ) */
16525 static tree
16526 c_parser_omp_clause_safelen (c_parser *parser, tree list)
16528 location_t clause_loc = c_parser_peek_token (parser)->location;
16529 tree c, t;
16531 matching_parens parens;
16532 if (!parens.require_open (parser))
16533 return list;
16535 location_t expr_loc = c_parser_peek_token (parser)->location;
16536 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16537 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16538 t = expr.value;
16539 t = c_fully_fold (t, false, NULL);
16540 if (TREE_CODE (t) != INTEGER_CST
16541 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
16542 || tree_int_cst_sgn (t) != 1)
16544 error_at (clause_loc, "%<safelen%> clause expression must "
16545 "be positive constant integer expression");
16546 t = NULL_TREE;
16549 parens.skip_until_found_close (parser);
16550 if (t == NULL_TREE || t == error_mark_node)
16551 return list;
16553 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
16555 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
16556 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
16557 OMP_CLAUSE_CHAIN (c) = list;
16558 return c;
16561 /* OpenMP 4.0:
16562 simdlen ( constant-expression ) */
16564 static tree
16565 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
16567 location_t clause_loc = c_parser_peek_token (parser)->location;
16568 tree c, t;
16570 matching_parens parens;
16571 if (!parens.require_open (parser))
16572 return list;
16574 location_t expr_loc = c_parser_peek_token (parser)->location;
16575 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16576 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16577 t = expr.value;
16578 t = c_fully_fold (t, false, NULL);
16579 if (TREE_CODE (t) != INTEGER_CST
16580 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
16581 || tree_int_cst_sgn (t) != 1)
16583 error_at (clause_loc, "%<simdlen%> clause expression must "
16584 "be positive constant integer expression");
16585 t = NULL_TREE;
16588 parens.skip_until_found_close (parser);
16589 if (t == NULL_TREE || t == error_mark_node)
16590 return list;
16592 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
16594 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
16595 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
16596 OMP_CLAUSE_CHAIN (c) = list;
16597 return c;
16600 /* OpenMP 4.5:
16601 vec:
16602 identifier [+/- integer]
16603 vec , identifier [+/- integer]
16606 static tree
16607 c_parser_omp_clause_doacross_sink (c_parser *parser, location_t clause_loc,
16608 tree list, bool depend_p)
16610 tree vec = NULL;
16611 if (c_parser_next_token_is_not (parser, CPP_NAME)
16612 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16614 c_parser_error (parser, "expected identifier");
16615 return list;
16618 if (!depend_p)
16620 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16621 if (strcmp (p, "omp_cur_iteration") == 0
16622 && c_parser_peek_2nd_token (parser)->type == CPP_MINUS
16623 && c_parser_peek_nth_token (parser, 3)->type == CPP_NUMBER
16624 && c_parser_peek_nth_token (parser, 4)->type == CPP_CLOSE_PAREN)
16626 tree val = c_parser_peek_nth_token (parser, 3)->value;
16627 if (integer_onep (val))
16629 c_parser_consume_token (parser);
16630 c_parser_consume_token (parser);
16631 c_parser_consume_token (parser);
16632 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16633 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
16634 OMP_CLAUSE_CHAIN (u) = list;
16635 return u;
16642 while (c_parser_next_token_is (parser, CPP_NAME)
16643 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
16645 tree t = lookup_name (c_parser_peek_token (parser)->value);
16646 tree addend = NULL;
16648 if (t == NULL_TREE)
16650 undeclared_variable (c_parser_peek_token (parser)->location,
16651 c_parser_peek_token (parser)->value);
16652 t = error_mark_node;
16655 c_parser_consume_token (parser);
16657 bool neg = false;
16658 if (c_parser_next_token_is (parser, CPP_MINUS))
16659 neg = true;
16660 else if (!c_parser_next_token_is (parser, CPP_PLUS))
16662 addend = integer_zero_node;
16663 neg = false;
16664 goto add_to_vector;
16666 c_parser_consume_token (parser);
16668 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
16670 c_parser_error (parser, "expected integer");
16671 return list;
16674 addend = c_parser_peek_token (parser)->value;
16675 if (TREE_CODE (addend) != INTEGER_CST)
16677 c_parser_error (parser, "expected integer");
16678 return list;
16680 c_parser_consume_token (parser);
16682 add_to_vector:
16683 if (t != error_mark_node)
16685 vec = tree_cons (addend, t, vec);
16686 if (neg)
16687 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
16690 if (c_parser_next_token_is_not (parser, CPP_COMMA)
16691 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
16692 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
16693 break;
16695 c_parser_consume_token (parser);
16698 if (vec == NULL_TREE)
16699 return list;
16701 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16702 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
16703 OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
16704 OMP_CLAUSE_DECL (u) = nreverse (vec);
16705 OMP_CLAUSE_CHAIN (u) = list;
16706 return u;
16709 /* OpenMP 5.0:
16710 iterators ( iterators-definition )
16712 iterators-definition:
16713 iterator-specifier
16714 iterator-specifier , iterators-definition
16716 iterator-specifier:
16717 identifier = range-specification
16718 iterator-type identifier = range-specification
16720 range-specification:
16721 begin : end
16722 begin : end : step */
16724 static tree
16725 c_parser_omp_iterators (c_parser *parser)
16727 tree ret = NULL_TREE, *last = &ret;
16728 c_parser_consume_token (parser);
16730 push_scope ();
16732 matching_parens parens;
16733 if (!parens.require_open (parser))
16734 return error_mark_node;
16738 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
16739 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
16741 struct c_type_name *type = c_parser_type_name (parser);
16742 if (type != NULL)
16743 iter_type = groktypename (type, &type_expr, NULL);
16745 if (iter_type == NULL_TREE)
16746 iter_type = integer_type_node;
16748 location_t loc = c_parser_peek_token (parser)->location;
16749 if (!c_parser_next_token_is (parser, CPP_NAME))
16751 c_parser_error (parser, "expected identifier");
16752 break;
16755 tree id = c_parser_peek_token (parser)->value;
16756 c_parser_consume_token (parser);
16758 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16759 break;
16761 location_t eloc = c_parser_peek_token (parser)->location;
16762 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16763 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16764 tree begin = expr.value;
16766 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16767 break;
16769 eloc = c_parser_peek_token (parser)->location;
16770 expr = c_parser_expr_no_commas (parser, NULL);
16771 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16772 tree end = expr.value;
16774 tree step = integer_one_node;
16775 if (c_parser_next_token_is (parser, CPP_COLON))
16777 c_parser_consume_token (parser);
16778 eloc = c_parser_peek_token (parser)->location;
16779 expr = c_parser_expr_no_commas (parser, NULL);
16780 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16781 step = expr.value;
16784 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
16785 DECL_ARTIFICIAL (iter_var) = 1;
16786 DECL_CONTEXT (iter_var) = current_function_decl;
16787 pushdecl (iter_var);
16789 *last = make_tree_vec (6);
16790 TREE_VEC_ELT (*last, 0) = iter_var;
16791 TREE_VEC_ELT (*last, 1) = begin;
16792 TREE_VEC_ELT (*last, 2) = end;
16793 TREE_VEC_ELT (*last, 3) = step;
16794 last = &TREE_CHAIN (*last);
16796 if (c_parser_next_token_is (parser, CPP_COMMA))
16798 c_parser_consume_token (parser);
16799 continue;
16801 break;
16803 while (1);
16805 parens.skip_until_found_close (parser);
16806 return ret ? ret : error_mark_node;
16809 /* OpenMP 5.0:
16810 affinity ( [aff-modifier :] variable-list )
16811 aff-modifier:
16812 iterator ( iterators-definition ) */
16814 static tree
16815 c_parser_omp_clause_affinity (c_parser *parser, tree list)
16817 location_t clause_loc = c_parser_peek_token (parser)->location;
16818 tree nl, iterators = NULL_TREE;
16820 matching_parens parens;
16821 if (!parens.require_open (parser))
16822 return list;
16824 if (c_parser_next_token_is (parser, CPP_NAME))
16826 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16827 bool parse_iter = ((strcmp ("iterator", p) == 0)
16828 && (c_parser_peek_2nd_token (parser)->type
16829 == CPP_OPEN_PAREN));
16830 if (parse_iter)
16832 unsigned n = 3;
16833 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
16834 && (c_parser_peek_nth_token_raw (parser, n)->type
16835 == CPP_CLOSE_PAREN)
16836 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
16837 == CPP_COLON));
16839 if (parse_iter)
16841 iterators = c_parser_omp_iterators (parser);
16842 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16844 if (iterators)
16845 pop_scope ();
16846 parens.skip_until_found_close (parser);
16847 return list;
16851 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16852 list);
16853 if (iterators)
16855 tree block = pop_scope ();
16856 if (iterators != error_mark_node)
16858 TREE_VEC_ELT (iterators, 5) = block;
16859 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16860 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16861 OMP_CLAUSE_DECL (c));
16865 parens.skip_until_found_close (parser);
16866 return nl;
16870 /* OpenMP 4.0:
16871 depend ( depend-kind: variable-list )
16873 depend-kind:
16874 in | out | inout
16876 OpenMP 4.5:
16877 depend ( source )
16879 depend ( sink : vec )
16881 OpenMP 5.0:
16882 depend ( depend-modifier , depend-kind: variable-list )
16884 depend-kind:
16885 in | out | inout | mutexinoutset | depobj | inoutset
16887 depend-modifier:
16888 iterator ( iterators-definition ) */
16890 static tree
16891 c_parser_omp_clause_depend (c_parser *parser, tree list)
16893 location_t clause_loc = c_parser_peek_token (parser)->location;
16894 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16895 enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
16896 tree nl, c, iterators = NULL_TREE;
16898 matching_parens parens;
16899 if (!parens.require_open (parser))
16900 return list;
16904 if (c_parser_next_token_is_not (parser, CPP_NAME))
16905 goto invalid_kind;
16907 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16908 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16910 iterators = c_parser_omp_iterators (parser);
16911 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16912 continue;
16914 if (strcmp ("in", p) == 0)
16915 kind = OMP_CLAUSE_DEPEND_IN;
16916 else if (strcmp ("inout", p) == 0)
16917 kind = OMP_CLAUSE_DEPEND_INOUT;
16918 else if (strcmp ("inoutset", p) == 0)
16919 kind = OMP_CLAUSE_DEPEND_INOUTSET;
16920 else if (strcmp ("mutexinoutset", p) == 0)
16921 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16922 else if (strcmp ("out", p) == 0)
16923 kind = OMP_CLAUSE_DEPEND_OUT;
16924 else if (strcmp ("depobj", p) == 0)
16925 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16926 else if (strcmp ("sink", p) == 0)
16927 dkind = OMP_CLAUSE_DOACROSS_SINK;
16928 else if (strcmp ("source", p) == 0)
16929 dkind = OMP_CLAUSE_DOACROSS_SOURCE;
16930 else
16931 goto invalid_kind;
16932 break;
16934 while (1);
16936 c_parser_consume_token (parser);
16938 if (iterators
16939 && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
16940 || dkind == OMP_CLAUSE_DOACROSS_SINK))
16942 pop_scope ();
16943 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16944 dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
16945 iterators = NULL_TREE;
16948 if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
16950 c = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16951 OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
16952 OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
16953 OMP_CLAUSE_DECL (c) = NULL_TREE;
16954 OMP_CLAUSE_CHAIN (c) = list;
16955 parens.skip_until_found_close (parser);
16956 return c;
16959 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16960 goto resync_fail;
16962 if (dkind == OMP_CLAUSE_DOACROSS_SINK)
16963 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, true);
16964 else
16966 nl = c_parser_omp_variable_list (parser, clause_loc,
16967 OMP_CLAUSE_DEPEND, list);
16969 if (iterators)
16971 tree block = pop_scope ();
16972 if (iterators == error_mark_node)
16973 iterators = NULL_TREE;
16974 else
16975 TREE_VEC_ELT (iterators, 5) = block;
16978 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16980 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16981 if (iterators)
16982 OMP_CLAUSE_DECL (c)
16983 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16987 parens.skip_until_found_close (parser);
16988 return nl;
16990 invalid_kind:
16991 c_parser_error (parser, "invalid depend kind");
16992 resync_fail:
16993 parens.skip_until_found_close (parser);
16994 if (iterators)
16995 pop_scope ();
16996 return list;
16999 /* OpenMP 5.2:
17000 doacross ( source : )
17001 doacross ( source : omp_cur_iteration )
17003 doacross ( sink : vec )
17004 doacross ( sink : omp_cur_iteration - logical_iteration ) */
17006 static tree
17007 c_parser_omp_clause_doacross (c_parser *parser, tree list)
17009 location_t clause_loc = c_parser_peek_token (parser)->location;
17010 enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
17011 tree nl;
17012 const char *p;
17014 matching_parens parens;
17015 if (!parens.require_open (parser))
17016 return list;
17018 if (c_parser_next_token_is_not (parser, CPP_NAME))
17019 goto invalid_kind;
17021 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17022 if (strcmp ("sink", p) == 0)
17023 kind = OMP_CLAUSE_DOACROSS_SINK;
17024 else if (strcmp ("source", p) == 0)
17025 kind = OMP_CLAUSE_DOACROSS_SOURCE;
17026 else
17027 goto invalid_kind;
17029 c_parser_consume_token (parser);
17031 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
17032 goto resync_fail;
17034 if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
17036 if (c_parser_next_token_is (parser, CPP_NAME)
17037 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
17038 "omp_cur_iteration") == 0)
17039 c_parser_consume_token (parser);
17040 nl = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
17041 OMP_CLAUSE_DOACROSS_KIND (nl) = OMP_CLAUSE_DOACROSS_SOURCE;
17042 OMP_CLAUSE_DECL (nl) = NULL_TREE;
17043 OMP_CLAUSE_CHAIN (nl) = list;
17045 else
17046 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, false);
17048 parens.skip_until_found_close (parser);
17049 return nl;
17051 invalid_kind:
17052 c_parser_error (parser, "invalid doacross kind");
17053 resync_fail:
17054 parens.skip_until_found_close (parser);
17055 return list;
17058 /* OpenMP 4.0:
17059 map ( map-kind: variable-list )
17060 map ( variable-list )
17062 map-kind:
17063 alloc | to | from | tofrom
17065 OpenMP 4.5:
17066 map-kind:
17067 alloc | to | from | tofrom | release | delete
17069 map ( always [,] map-kind: variable-list )
17071 OpenMP 5.0:
17072 map ( [map-type-modifier[,] ...] map-kind: variable-list )
17074 map-type-modifier:
17075 always | close */
17077 static tree
17078 c_parser_omp_clause_map (c_parser *parser, tree list)
17080 location_t clause_loc = c_parser_peek_token (parser)->location;
17081 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
17082 tree nl, c;
17084 matching_parens parens;
17085 if (!parens.require_open (parser))
17086 return list;
17088 int pos = 1;
17089 int map_kind_pos = 0;
17090 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
17092 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
17094 map_kind_pos = pos;
17095 break;
17098 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
17099 pos++;
17100 pos++;
17103 int always_modifier = 0;
17104 int close_modifier = 0;
17105 for (int pos = 1; pos < map_kind_pos; ++pos)
17107 c_token *tok = c_parser_peek_token (parser);
17109 if (tok->type == CPP_COMMA)
17111 c_parser_consume_token (parser);
17112 continue;
17115 const char *p = IDENTIFIER_POINTER (tok->value);
17116 if (strcmp ("always", p) == 0)
17118 if (always_modifier)
17120 c_parser_error (parser, "too many %<always%> modifiers");
17121 parens.skip_until_found_close (parser);
17122 return list;
17124 always_modifier++;
17126 else if (strcmp ("close", p) == 0)
17128 if (close_modifier)
17130 c_parser_error (parser, "too many %<close%> modifiers");
17131 parens.skip_until_found_close (parser);
17132 return list;
17134 close_modifier++;
17136 else
17138 c_parser_error (parser, "%<#pragma omp target%> with "
17139 "modifier other than %<always%> or "
17140 "%<close%> on %<map%> clause");
17141 parens.skip_until_found_close (parser);
17142 return list;
17145 c_parser_consume_token (parser);
17148 if (c_parser_next_token_is (parser, CPP_NAME)
17149 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
17151 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17152 if (strcmp ("alloc", p) == 0)
17153 kind = GOMP_MAP_ALLOC;
17154 else if (strcmp ("to", p) == 0)
17155 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
17156 else if (strcmp ("from", p) == 0)
17157 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
17158 else if (strcmp ("tofrom", p) == 0)
17159 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
17160 else if (strcmp ("release", p) == 0)
17161 kind = GOMP_MAP_RELEASE;
17162 else if (strcmp ("delete", p) == 0)
17163 kind = GOMP_MAP_DELETE;
17164 else
17166 c_parser_error (parser, "invalid map kind");
17167 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17168 "expected %<)%>");
17169 return list;
17171 c_parser_consume_token (parser);
17172 c_parser_consume_token (parser);
17175 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
17176 true);
17178 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
17179 OMP_CLAUSE_SET_MAP_KIND (c, kind);
17181 parens.skip_until_found_close (parser);
17182 return nl;
17185 /* OpenMP 4.0:
17186 device ( expression )
17188 OpenMP 5.0:
17189 device ( [device-modifier :] integer-expression )
17191 device-modifier:
17192 ancestor | device_num */
17194 static tree
17195 c_parser_omp_clause_device (c_parser *parser, tree list)
17197 location_t clause_loc = c_parser_peek_token (parser)->location;
17198 location_t expr_loc;
17199 c_expr expr;
17200 tree c, t;
17201 bool ancestor = false;
17203 matching_parens parens;
17204 if (!parens.require_open (parser))
17205 return list;
17207 if (c_parser_next_token_is (parser, CPP_NAME)
17208 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
17210 c_token *tok = c_parser_peek_token (parser);
17211 const char *p = IDENTIFIER_POINTER (tok->value);
17212 if (strcmp ("ancestor", p) == 0)
17214 /* A requires directive with the reverse_offload clause must be
17215 specified. */
17216 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
17218 error_at (tok->location, "%<ancestor%> device modifier not "
17219 "preceded by %<requires%> directive "
17220 "with %<reverse_offload%> clause");
17221 parens.skip_until_found_close (parser);
17222 return list;
17224 ancestor = true;
17226 else if (strcmp ("device_num", p) == 0)
17228 else
17230 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
17231 parens.skip_until_found_close (parser);
17232 return list;
17234 c_parser_consume_token (parser);
17235 c_parser_consume_token (parser);
17238 expr_loc = c_parser_peek_token (parser)->location;
17239 expr = c_parser_expr_no_commas (parser, NULL);
17240 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17241 t = expr.value;
17242 t = c_fully_fold (t, false, NULL);
17244 parens.skip_until_found_close (parser);
17246 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
17248 c_parser_error (parser, "expected integer expression");
17249 return list;
17251 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
17253 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
17254 "%<1%>");
17255 return list;
17258 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
17260 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
17262 OMP_CLAUSE_DEVICE_ID (c) = t;
17263 OMP_CLAUSE_CHAIN (c) = list;
17264 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
17266 list = c;
17267 return list;
17270 /* OpenMP 4.0:
17271 dist_schedule ( static )
17272 dist_schedule ( static , expression ) */
17274 static tree
17275 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
17277 tree c, t = NULL_TREE;
17278 location_t loc = c_parser_peek_token (parser)->location;
17280 matching_parens parens;
17281 if (!parens.require_open (parser))
17282 return list;
17284 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
17286 c_parser_error (parser, "invalid dist_schedule kind");
17287 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17288 "expected %<)%>");
17289 return list;
17292 c_parser_consume_token (parser);
17293 if (c_parser_next_token_is (parser, CPP_COMMA))
17295 c_parser_consume_token (parser);
17297 location_t expr_loc = c_parser_peek_token (parser)->location;
17298 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17299 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17300 t = expr.value;
17301 t = c_fully_fold (t, false, NULL);
17302 parens.skip_until_found_close (parser);
17304 else
17305 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17306 "expected %<,%> or %<)%>");
17308 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
17309 "dist_schedule"); */
17310 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
17311 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
17312 if (t == error_mark_node)
17313 return list;
17315 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
17316 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
17317 OMP_CLAUSE_CHAIN (c) = list;
17318 return c;
17321 /* OpenMP 4.0:
17322 proc_bind ( proc-bind-kind )
17324 proc-bind-kind:
17325 primary | master | close | spread
17326 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
17328 static tree
17329 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
17331 location_t clause_loc = c_parser_peek_token (parser)->location;
17332 enum omp_clause_proc_bind_kind kind;
17333 tree c;
17335 matching_parens parens;
17336 if (!parens.require_open (parser))
17337 return list;
17339 if (c_parser_next_token_is (parser, CPP_NAME))
17341 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17342 if (strcmp ("primary", p) == 0)
17343 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
17344 else if (strcmp ("master", p) == 0)
17345 kind = OMP_CLAUSE_PROC_BIND_MASTER;
17346 else if (strcmp ("close", p) == 0)
17347 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
17348 else if (strcmp ("spread", p) == 0)
17349 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
17350 else
17351 goto invalid_kind;
17353 else
17354 goto invalid_kind;
17356 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
17357 c_parser_consume_token (parser);
17358 parens.skip_until_found_close (parser);
17359 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
17360 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
17361 OMP_CLAUSE_CHAIN (c) = list;
17362 return c;
17364 invalid_kind:
17365 c_parser_error (parser, "invalid proc_bind kind");
17366 parens.skip_until_found_close (parser);
17367 return list;
17370 /* OpenMP 5.0:
17371 device_type ( host | nohost | any ) */
17373 static tree
17374 c_parser_omp_clause_device_type (c_parser *parser, tree list)
17376 location_t clause_loc = c_parser_peek_token (parser)->location;
17377 enum omp_clause_device_type_kind kind;
17378 tree c;
17380 matching_parens parens;
17381 if (!parens.require_open (parser))
17382 return list;
17384 if (c_parser_next_token_is (parser, CPP_NAME))
17386 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17387 if (strcmp ("host", p) == 0)
17388 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
17389 else if (strcmp ("nohost", p) == 0)
17390 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
17391 else if (strcmp ("any", p) == 0)
17392 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
17393 else
17394 goto invalid_kind;
17396 else
17397 goto invalid_kind;
17399 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
17400 "device_type");
17401 c_parser_consume_token (parser);
17402 parens.skip_until_found_close (parser);
17403 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
17404 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
17405 OMP_CLAUSE_CHAIN (c) = list;
17406 return c;
17408 invalid_kind:
17409 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
17410 parens.skip_until_found_close (parser);
17411 return list;
17414 /* OpenMP 4.0:
17415 to ( variable-list ) */
17417 static tree
17418 c_parser_omp_clause_to (c_parser *parser, tree list)
17420 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
17423 /* OpenMP 4.0:
17424 from ( variable-list ) */
17426 static tree
17427 c_parser_omp_clause_from (c_parser *parser, tree list)
17429 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
17432 /* OpenMP 4.0:
17433 uniform ( variable-list ) */
17435 static tree
17436 c_parser_omp_clause_uniform (c_parser *parser, tree list)
17438 /* The clauses location. */
17439 location_t loc = c_parser_peek_token (parser)->location;
17441 matching_parens parens;
17442 if (parens.require_open (parser))
17444 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
17445 list);
17446 parens.skip_until_found_close (parser);
17448 return list;
17451 /* OpenMP 5.0:
17452 detach ( event-handle ) */
17454 static tree
17455 c_parser_omp_clause_detach (c_parser *parser, tree list)
17457 matching_parens parens;
17458 location_t clause_loc = c_parser_peek_token (parser)->location;
17460 if (!parens.require_open (parser))
17461 return list;
17463 if (c_parser_next_token_is_not (parser, CPP_NAME)
17464 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
17466 c_parser_error (parser, "expected identifier");
17467 parens.skip_until_found_close (parser);
17468 return list;
17471 tree t = lookup_name (c_parser_peek_token (parser)->value);
17472 if (t == NULL_TREE)
17474 undeclared_variable (c_parser_peek_token (parser)->location,
17475 c_parser_peek_token (parser)->value);
17476 parens.skip_until_found_close (parser);
17477 return list;
17479 c_parser_consume_token (parser);
17481 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
17482 if (!INTEGRAL_TYPE_P (type)
17483 || TREE_CODE (type) != ENUMERAL_TYPE
17484 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
17486 error_at (clause_loc, "%<detach%> clause event handle "
17487 "has type %qT rather than "
17488 "%<omp_event_handle_t%>",
17489 type);
17490 parens.skip_until_found_close (parser);
17491 return list;
17494 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
17495 OMP_CLAUSE_DECL (u) = t;
17496 OMP_CLAUSE_CHAIN (u) = list;
17497 parens.skip_until_found_close (parser);
17498 return u;
17501 /* Parse all OpenACC clauses. The set clauses allowed by the directive
17502 is a bitmask in MASK. Return the list of clauses found. */
17504 static tree
17505 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
17506 const char *where, bool finish_p = true)
17508 tree clauses = NULL;
17509 bool first = true;
17511 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17513 location_t here;
17514 pragma_omp_clause c_kind;
17515 const char *c_name;
17516 tree prev = clauses;
17518 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
17519 c_parser_consume_token (parser);
17521 here = c_parser_peek_token (parser)->location;
17522 c_kind = c_parser_omp_clause_name (parser);
17524 switch (c_kind)
17526 case PRAGMA_OACC_CLAUSE_ASYNC:
17527 clauses = c_parser_oacc_clause_async (parser, clauses);
17528 c_name = "async";
17529 break;
17530 case PRAGMA_OACC_CLAUSE_AUTO:
17531 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
17532 clauses);
17533 c_name = "auto";
17534 break;
17535 case PRAGMA_OACC_CLAUSE_ATTACH:
17536 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17537 c_name = "attach";
17538 break;
17539 case PRAGMA_OACC_CLAUSE_COLLAPSE:
17540 clauses = c_parser_omp_clause_collapse (parser, clauses);
17541 c_name = "collapse";
17542 break;
17543 case PRAGMA_OACC_CLAUSE_COPY:
17544 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17545 c_name = "copy";
17546 break;
17547 case PRAGMA_OACC_CLAUSE_COPYIN:
17548 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17549 c_name = "copyin";
17550 break;
17551 case PRAGMA_OACC_CLAUSE_COPYOUT:
17552 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17553 c_name = "copyout";
17554 break;
17555 case PRAGMA_OACC_CLAUSE_CREATE:
17556 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17557 c_name = "create";
17558 break;
17559 case PRAGMA_OACC_CLAUSE_DELETE:
17560 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17561 c_name = "delete";
17562 break;
17563 case PRAGMA_OMP_CLAUSE_DEFAULT:
17564 clauses = c_parser_omp_clause_default (parser, clauses, true);
17565 c_name = "default";
17566 break;
17567 case PRAGMA_OACC_CLAUSE_DETACH:
17568 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17569 c_name = "detach";
17570 break;
17571 case PRAGMA_OACC_CLAUSE_DEVICE:
17572 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17573 c_name = "device";
17574 break;
17575 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
17576 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
17577 c_name = "deviceptr";
17578 break;
17579 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
17580 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17581 c_name = "device_resident";
17582 break;
17583 case PRAGMA_OACC_CLAUSE_FINALIZE:
17584 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
17585 clauses);
17586 c_name = "finalize";
17587 break;
17588 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
17589 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
17590 c_name = "firstprivate";
17591 break;
17592 case PRAGMA_OACC_CLAUSE_GANG:
17593 c_name = "gang";
17594 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
17595 c_name, clauses);
17596 break;
17597 case PRAGMA_OACC_CLAUSE_HOST:
17598 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17599 c_name = "host";
17600 break;
17601 case PRAGMA_OACC_CLAUSE_IF:
17602 clauses = c_parser_omp_clause_if (parser, clauses, false);
17603 c_name = "if";
17604 break;
17605 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
17606 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
17607 clauses);
17608 c_name = "if_present";
17609 break;
17610 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
17611 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
17612 clauses);
17613 c_name = "independent";
17614 break;
17615 case PRAGMA_OACC_CLAUSE_LINK:
17616 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17617 c_name = "link";
17618 break;
17619 case PRAGMA_OACC_CLAUSE_NO_CREATE:
17620 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17621 c_name = "no_create";
17622 break;
17623 case PRAGMA_OACC_CLAUSE_NOHOST:
17624 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
17625 clauses);
17626 c_name = "nohost";
17627 break;
17628 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
17629 clauses = c_parser_oacc_single_int_clause (parser,
17630 OMP_CLAUSE_NUM_GANGS,
17631 clauses);
17632 c_name = "num_gangs";
17633 break;
17634 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
17635 clauses = c_parser_oacc_single_int_clause (parser,
17636 OMP_CLAUSE_NUM_WORKERS,
17637 clauses);
17638 c_name = "num_workers";
17639 break;
17640 case PRAGMA_OACC_CLAUSE_PRESENT:
17641 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17642 c_name = "present";
17643 break;
17644 case PRAGMA_OACC_CLAUSE_PRIVATE:
17645 clauses = c_parser_omp_clause_private (parser, clauses);
17646 c_name = "private";
17647 break;
17648 case PRAGMA_OACC_CLAUSE_REDUCTION:
17649 clauses
17650 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17651 false, clauses);
17652 c_name = "reduction";
17653 break;
17654 case PRAGMA_OACC_CLAUSE_SEQ:
17655 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
17656 clauses);
17657 c_name = "seq";
17658 break;
17659 case PRAGMA_OACC_CLAUSE_TILE:
17660 clauses = c_parser_oacc_clause_tile (parser, clauses);
17661 c_name = "tile";
17662 break;
17663 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
17664 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17665 c_name = "use_device";
17666 break;
17667 case PRAGMA_OACC_CLAUSE_VECTOR:
17668 c_name = "vector";
17669 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
17670 c_name, clauses);
17671 break;
17672 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
17673 clauses = c_parser_oacc_single_int_clause (parser,
17674 OMP_CLAUSE_VECTOR_LENGTH,
17675 clauses);
17676 c_name = "vector_length";
17677 break;
17678 case PRAGMA_OACC_CLAUSE_WAIT:
17679 clauses = c_parser_oacc_clause_wait (parser, clauses);
17680 c_name = "wait";
17681 break;
17682 case PRAGMA_OACC_CLAUSE_WORKER:
17683 c_name = "worker";
17684 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
17685 c_name, clauses);
17686 break;
17687 default:
17688 c_parser_error (parser, "expected %<#pragma acc%> clause");
17689 goto saw_error;
17692 first = false;
17694 if (((mask >> c_kind) & 1) == 0)
17696 /* Remove the invalid clause(s) from the list to avoid
17697 confusing the rest of the compiler. */
17698 clauses = prev;
17699 error_at (here, "%qs is not valid for %qs", c_name, where);
17703 saw_error:
17704 c_parser_skip_to_pragma_eol (parser);
17706 if (finish_p)
17707 return c_finish_omp_clauses (clauses, C_ORT_ACC);
17709 return clauses;
17712 /* Parse all OpenMP clauses. The set clauses allowed by the directive
17713 is a bitmask in MASK. Return the list of clauses found.
17714 FINISH_P set if c_finish_omp_clauses should be called.
17715 NESTED non-zero if clauses should be terminated by closing paren instead
17716 of end of pragma. If it is 2, additionally commas are required in between
17717 the clauses. */
17719 static tree
17720 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
17721 const char *where, bool finish_p = true,
17722 int nested = 0)
17724 tree clauses = NULL;
17725 bool first = true;
17727 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17729 location_t here;
17730 pragma_omp_clause c_kind;
17731 const char *c_name;
17732 tree prev = clauses;
17734 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
17735 break;
17737 if (!first || nested != 2)
17739 if (c_parser_next_token_is (parser, CPP_COMMA))
17740 c_parser_consume_token (parser);
17741 else if (nested == 2)
17742 error_at (c_parser_peek_token (parser)->location,
17743 "clauses in %<simd%> trait should be separated "
17744 "by %<,%>");
17747 here = c_parser_peek_token (parser)->location;
17748 c_kind = c_parser_omp_clause_name (parser);
17750 switch (c_kind)
17752 case PRAGMA_OMP_CLAUSE_BIND:
17753 clauses = c_parser_omp_clause_bind (parser, clauses);
17754 c_name = "bind";
17755 break;
17756 case PRAGMA_OMP_CLAUSE_COLLAPSE:
17757 clauses = c_parser_omp_clause_collapse (parser, clauses);
17758 c_name = "collapse";
17759 break;
17760 case PRAGMA_OMP_CLAUSE_COPYIN:
17761 clauses = c_parser_omp_clause_copyin (parser, clauses);
17762 c_name = "copyin";
17763 break;
17764 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
17765 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
17766 c_name = "copyprivate";
17767 break;
17768 case PRAGMA_OMP_CLAUSE_DEFAULT:
17769 clauses = c_parser_omp_clause_default (parser, clauses, false);
17770 c_name = "default";
17771 break;
17772 case PRAGMA_OMP_CLAUSE_DETACH:
17773 clauses = c_parser_omp_clause_detach (parser, clauses);
17774 c_name = "detach";
17775 break;
17776 case PRAGMA_OMP_CLAUSE_FILTER:
17777 clauses = c_parser_omp_clause_filter (parser, clauses);
17778 c_name = "filter";
17779 break;
17780 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
17781 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
17782 c_name = "firstprivate";
17783 break;
17784 case PRAGMA_OMP_CLAUSE_FINAL:
17785 clauses = c_parser_omp_clause_final (parser, clauses);
17786 c_name = "final";
17787 break;
17788 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
17789 clauses = c_parser_omp_clause_grainsize (parser, clauses);
17790 c_name = "grainsize";
17791 break;
17792 case PRAGMA_OMP_CLAUSE_HINT:
17793 clauses = c_parser_omp_clause_hint (parser, clauses);
17794 c_name = "hint";
17795 break;
17796 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
17797 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
17798 c_name = "defaultmap";
17799 break;
17800 case PRAGMA_OMP_CLAUSE_IF:
17801 clauses = c_parser_omp_clause_if (parser, clauses, true);
17802 c_name = "if";
17803 break;
17804 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
17805 clauses
17806 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
17807 true, clauses);
17808 c_name = "in_reduction";
17809 break;
17810 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
17811 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
17812 c_name = "lastprivate";
17813 break;
17814 case PRAGMA_OMP_CLAUSE_MERGEABLE:
17815 clauses = c_parser_omp_clause_mergeable (parser, clauses);
17816 c_name = "mergeable";
17817 break;
17818 case PRAGMA_OMP_CLAUSE_NOWAIT:
17819 clauses = c_parser_omp_clause_nowait (parser, clauses);
17820 c_name = "nowait";
17821 break;
17822 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
17823 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
17824 c_name = "num_tasks";
17825 break;
17826 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
17827 clauses = c_parser_omp_clause_num_threads (parser, clauses);
17828 c_name = "num_threads";
17829 break;
17830 case PRAGMA_OMP_CLAUSE_ORDER:
17831 clauses = c_parser_omp_clause_order (parser, clauses);
17832 c_name = "order";
17833 break;
17834 case PRAGMA_OMP_CLAUSE_ORDERED:
17835 clauses = c_parser_omp_clause_ordered (parser, clauses);
17836 c_name = "ordered";
17837 break;
17838 case PRAGMA_OMP_CLAUSE_PRIORITY:
17839 clauses = c_parser_omp_clause_priority (parser, clauses);
17840 c_name = "priority";
17841 break;
17842 case PRAGMA_OMP_CLAUSE_PRIVATE:
17843 clauses = c_parser_omp_clause_private (parser, clauses);
17844 c_name = "private";
17845 break;
17846 case PRAGMA_OMP_CLAUSE_REDUCTION:
17847 clauses
17848 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17849 true, clauses);
17850 c_name = "reduction";
17851 break;
17852 case PRAGMA_OMP_CLAUSE_SCHEDULE:
17853 clauses = c_parser_omp_clause_schedule (parser, clauses);
17854 c_name = "schedule";
17855 break;
17856 case PRAGMA_OMP_CLAUSE_SHARED:
17857 clauses = c_parser_omp_clause_shared (parser, clauses);
17858 c_name = "shared";
17859 break;
17860 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
17861 clauses
17862 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
17863 true, clauses);
17864 c_name = "task_reduction";
17865 break;
17866 case PRAGMA_OMP_CLAUSE_UNTIED:
17867 clauses = c_parser_omp_clause_untied (parser, clauses);
17868 c_name = "untied";
17869 break;
17870 case PRAGMA_OMP_CLAUSE_INBRANCH:
17871 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
17872 clauses);
17873 c_name = "inbranch";
17874 break;
17875 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
17876 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
17877 c_name = "nontemporal";
17878 break;
17879 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
17880 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
17881 clauses);
17882 c_name = "notinbranch";
17883 break;
17884 case PRAGMA_OMP_CLAUSE_PARALLEL:
17885 clauses
17886 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
17887 clauses);
17888 c_name = "parallel";
17889 if (!first)
17891 clause_not_first:
17892 error_at (here, "%qs must be the first clause of %qs",
17893 c_name, where);
17894 clauses = prev;
17896 break;
17897 case PRAGMA_OMP_CLAUSE_FOR:
17898 clauses
17899 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
17900 clauses);
17901 c_name = "for";
17902 if (!first)
17903 goto clause_not_first;
17904 break;
17905 case PRAGMA_OMP_CLAUSE_SECTIONS:
17906 clauses
17907 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17908 clauses);
17909 c_name = "sections";
17910 if (!first)
17911 goto clause_not_first;
17912 break;
17913 case PRAGMA_OMP_CLAUSE_TASKGROUP:
17914 clauses
17915 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17916 clauses);
17917 c_name = "taskgroup";
17918 if (!first)
17919 goto clause_not_first;
17920 break;
17921 case PRAGMA_OMP_CLAUSE_LINK:
17922 clauses
17923 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17924 c_name = "link";
17925 break;
17926 case PRAGMA_OMP_CLAUSE_TO:
17927 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17929 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17930 clauses);
17931 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
17932 OMP_CLAUSE_ENTER_TO (c) = 1;
17933 clauses = nl;
17935 else
17936 clauses = c_parser_omp_clause_to (parser, clauses);
17937 c_name = "to";
17938 break;
17939 case PRAGMA_OMP_CLAUSE_FROM:
17940 clauses = c_parser_omp_clause_from (parser, clauses);
17941 c_name = "from";
17942 break;
17943 case PRAGMA_OMP_CLAUSE_UNIFORM:
17944 clauses = c_parser_omp_clause_uniform (parser, clauses);
17945 c_name = "uniform";
17946 break;
17947 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17948 clauses = c_parser_omp_clause_num_teams (parser, clauses);
17949 c_name = "num_teams";
17950 break;
17951 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17952 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17953 c_name = "thread_limit";
17954 break;
17955 case PRAGMA_OMP_CLAUSE_ALIGNED:
17956 clauses = c_parser_omp_clause_aligned (parser, clauses);
17957 c_name = "aligned";
17958 break;
17959 case PRAGMA_OMP_CLAUSE_ALLOCATE:
17960 clauses = c_parser_omp_clause_allocate (parser, clauses);
17961 c_name = "allocate";
17962 break;
17963 case PRAGMA_OMP_CLAUSE_LINEAR:
17964 clauses = c_parser_omp_clause_linear (parser, clauses);
17965 c_name = "linear";
17966 break;
17967 case PRAGMA_OMP_CLAUSE_AFFINITY:
17968 clauses = c_parser_omp_clause_affinity (parser, clauses);
17969 c_name = "affinity";
17970 break;
17971 case PRAGMA_OMP_CLAUSE_DEPEND:
17972 clauses = c_parser_omp_clause_depend (parser, clauses);
17973 c_name = "depend";
17974 break;
17975 case PRAGMA_OMP_CLAUSE_DOACROSS:
17976 clauses = c_parser_omp_clause_doacross (parser, clauses);
17977 c_name = "doacross";
17978 break;
17979 case PRAGMA_OMP_CLAUSE_MAP:
17980 clauses = c_parser_omp_clause_map (parser, clauses);
17981 c_name = "map";
17982 break;
17983 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17984 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17985 c_name = "use_device_ptr";
17986 break;
17987 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17988 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17989 c_name = "use_device_addr";
17990 break;
17991 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17992 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17993 c_name = "has_device_addr";
17994 break;
17995 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17996 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17997 c_name = "is_device_ptr";
17998 break;
17999 case PRAGMA_OMP_CLAUSE_DEVICE:
18000 clauses = c_parser_omp_clause_device (parser, clauses);
18001 c_name = "device";
18002 break;
18003 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
18004 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
18005 c_name = "dist_schedule";
18006 break;
18007 case PRAGMA_OMP_CLAUSE_PROC_BIND:
18008 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
18009 c_name = "proc_bind";
18010 break;
18011 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
18012 clauses = c_parser_omp_clause_device_type (parser, clauses);
18013 c_name = "device_type";
18014 break;
18015 case PRAGMA_OMP_CLAUSE_SAFELEN:
18016 clauses = c_parser_omp_clause_safelen (parser, clauses);
18017 c_name = "safelen";
18018 break;
18019 case PRAGMA_OMP_CLAUSE_SIMDLEN:
18020 clauses = c_parser_omp_clause_simdlen (parser, clauses);
18021 c_name = "simdlen";
18022 break;
18023 case PRAGMA_OMP_CLAUSE_NOGROUP:
18024 clauses = c_parser_omp_clause_nogroup (parser, clauses);
18025 c_name = "nogroup";
18026 break;
18027 case PRAGMA_OMP_CLAUSE_THREADS:
18028 clauses
18029 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
18030 clauses);
18031 c_name = "threads";
18032 break;
18033 case PRAGMA_OMP_CLAUSE_SIMD:
18034 clauses
18035 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
18036 clauses);
18037 c_name = "simd";
18038 break;
18039 case PRAGMA_OMP_CLAUSE_ENTER:
18040 clauses
18041 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
18042 clauses);
18043 c_name = "enter";
18044 break;
18045 default:
18046 c_parser_error (parser, "expected %<#pragma omp%> clause");
18047 goto saw_error;
18050 first = false;
18052 if (((mask >> c_kind) & 1) == 0)
18054 /* Remove the invalid clause(s) from the list to avoid
18055 confusing the rest of the compiler. */
18056 clauses = prev;
18057 error_at (here, "%qs is not valid for %qs", c_name, where);
18061 saw_error:
18062 if (!nested)
18063 c_parser_skip_to_pragma_eol (parser);
18065 if (finish_p)
18067 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
18068 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
18069 return c_finish_omp_clauses (clauses, C_ORT_OMP);
18072 return clauses;
18075 /* OpenACC 2.0, OpenMP 2.5:
18076 structured-block:
18077 statement
18079 In practice, we're also interested in adding the statement to an
18080 outer node. So it is convenient if we work around the fact that
18081 c_parser_statement calls add_stmt. */
18083 static tree
18084 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
18086 tree stmt = push_stmt_list ();
18087 c_parser_statement (parser, if_p);
18088 return pop_stmt_list (stmt);
18091 /* OpenACC 2.0:
18092 # pragma acc cache (variable-list) new-line
18094 LOC is the location of the #pragma token.
18097 static tree
18098 c_parser_oacc_cache (location_t loc, c_parser *parser)
18100 tree stmt, clauses;
18102 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
18103 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
18105 c_parser_skip_to_pragma_eol (parser);
18107 stmt = make_node (OACC_CACHE);
18108 TREE_TYPE (stmt) = void_type_node;
18109 OACC_CACHE_CLAUSES (stmt) = clauses;
18110 SET_EXPR_LOCATION (stmt, loc);
18111 add_stmt (stmt);
18113 return stmt;
18116 /* OpenACC 2.0:
18117 # pragma acc data oacc-data-clause[optseq] new-line
18118 structured-block
18120 LOC is the location of the #pragma token.
18123 #define OACC_DATA_CLAUSE_MASK \
18124 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18126 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18127 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18128 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
18134 static tree
18135 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
18137 tree stmt, clauses, block;
18139 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
18140 "#pragma acc data");
18142 block = c_begin_omp_parallel ();
18143 add_stmt (c_parser_omp_structured_block (parser, if_p));
18145 stmt = c_finish_oacc_data (loc, clauses, block);
18147 return stmt;
18150 /* OpenACC 2.0:
18151 # pragma acc declare oacc-data-clause[optseq] new-line
18154 #define OACC_DECLARE_CLAUSE_MASK \
18155 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
18161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
18162 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
18164 static void
18165 c_parser_oacc_declare (c_parser *parser)
18167 location_t pragma_loc = c_parser_peek_token (parser)->location;
18168 tree clauses, stmt, t, decl;
18170 bool error = false;
18172 c_parser_consume_pragma (parser);
18174 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
18175 "#pragma acc declare");
18176 if (!clauses)
18178 error_at (pragma_loc,
18179 "no valid clauses specified in %<#pragma acc declare%>");
18180 return;
18183 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
18185 location_t loc = OMP_CLAUSE_LOCATION (t);
18186 decl = OMP_CLAUSE_DECL (t);
18187 if (!DECL_P (decl))
18189 error_at (loc, "array section in %<#pragma acc declare%>");
18190 error = true;
18191 continue;
18194 switch (OMP_CLAUSE_MAP_KIND (t))
18196 case GOMP_MAP_FIRSTPRIVATE_POINTER:
18197 case GOMP_MAP_ALLOC:
18198 case GOMP_MAP_TO:
18199 case GOMP_MAP_FORCE_DEVICEPTR:
18200 case GOMP_MAP_DEVICE_RESIDENT:
18201 break;
18203 case GOMP_MAP_LINK:
18204 if (!global_bindings_p ()
18205 && (TREE_STATIC (decl)
18206 || !DECL_EXTERNAL (decl)))
18208 error_at (loc,
18209 "%qD must be a global variable in "
18210 "%<#pragma acc declare link%>",
18211 decl);
18212 error = true;
18213 continue;
18215 break;
18217 default:
18218 if (global_bindings_p ())
18220 error_at (loc, "invalid OpenACC clause at file scope");
18221 error = true;
18222 continue;
18224 if (DECL_EXTERNAL (decl))
18226 error_at (loc,
18227 "invalid use of %<extern%> variable %qD "
18228 "in %<#pragma acc declare%>", decl);
18229 error = true;
18230 continue;
18232 else if (TREE_PUBLIC (decl))
18234 error_at (loc,
18235 "invalid use of %<global%> variable %qD "
18236 "in %<#pragma acc declare%>", decl);
18237 error = true;
18238 continue;
18240 break;
18243 if (!c_check_in_current_scope (decl))
18245 error_at (loc,
18246 "%qD must be a variable declared in the same scope as "
18247 "%<#pragma acc declare%>", decl);
18248 error = true;
18249 continue;
18252 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
18253 || lookup_attribute ("omp declare target link",
18254 DECL_ATTRIBUTES (decl)))
18256 error_at (loc, "variable %qD used more than once with "
18257 "%<#pragma acc declare%>", decl);
18258 error = true;
18259 continue;
18262 if (!error)
18264 tree id;
18266 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
18267 id = get_identifier ("omp declare target link");
18268 else
18269 id = get_identifier ("omp declare target");
18271 DECL_ATTRIBUTES (decl)
18272 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
18274 if (global_bindings_p ())
18276 symtab_node *node = symtab_node::get (decl);
18277 if (node != NULL)
18279 node->offloadable = 1;
18280 if (ENABLE_OFFLOADING)
18282 g->have_offload = true;
18283 if (is_a <varpool_node *> (node))
18284 vec_safe_push (offload_vars, decl);
18291 if (error || global_bindings_p ())
18292 return;
18294 stmt = make_node (OACC_DECLARE);
18295 TREE_TYPE (stmt) = void_type_node;
18296 OACC_DECLARE_CLAUSES (stmt) = clauses;
18297 SET_EXPR_LOCATION (stmt, pragma_loc);
18299 add_stmt (stmt);
18301 return;
18304 /* OpenACC 2.0:
18305 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
18309 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
18312 LOC is the location of the #pragma token.
18315 #define OACC_ENTER_DATA_CLAUSE_MASK \
18316 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18317 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18318 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18319 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18320 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18321 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18323 #define OACC_EXIT_DATA_CLAUSE_MASK \
18324 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18325 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18326 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18327 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
18328 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
18329 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
18330 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18332 static void
18333 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
18335 location_t loc = c_parser_peek_token (parser)->location;
18336 tree clauses, stmt;
18337 const char *p = "";
18339 c_parser_consume_pragma (parser);
18341 if (c_parser_next_token_is (parser, CPP_NAME))
18343 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18344 c_parser_consume_token (parser);
18347 if (strcmp (p, "data") != 0)
18349 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
18350 enter ? "enter" : "exit");
18351 parser->error = true;
18352 c_parser_skip_to_pragma_eol (parser);
18353 return;
18356 if (enter)
18357 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
18358 "#pragma acc enter data");
18359 else
18360 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
18361 "#pragma acc exit data");
18363 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
18365 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
18366 enter ? "enter" : "exit");
18367 return;
18370 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
18371 TREE_TYPE (stmt) = void_type_node;
18372 OMP_STANDALONE_CLAUSES (stmt) = clauses;
18373 SET_EXPR_LOCATION (stmt, loc);
18374 add_stmt (stmt);
18378 /* OpenACC 2.0:
18379 # pragma acc host_data oacc-data-clause[optseq] new-line
18380 structured-block
18383 #define OACC_HOST_DATA_CLAUSE_MASK \
18384 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
18385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
18388 static tree
18389 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
18391 tree stmt, clauses, block;
18393 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
18394 "#pragma acc host_data");
18396 block = c_begin_omp_parallel ();
18397 add_stmt (c_parser_omp_structured_block (parser, if_p));
18398 stmt = c_finish_oacc_host_data (loc, clauses, block);
18399 return stmt;
18403 /* OpenACC 2.0:
18405 # pragma acc loop oacc-loop-clause[optseq] new-line
18406 structured-block
18408 LOC is the location of the #pragma token.
18411 #define OACC_LOOP_CLAUSE_MASK \
18412 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
18413 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18414 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
18416 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
18417 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
18418 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
18419 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
18420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
18421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
18422 static tree
18423 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
18424 omp_clause_mask mask, tree *cclauses, bool *if_p)
18426 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
18428 strcat (p_name, " loop");
18429 mask |= OACC_LOOP_CLAUSE_MASK;
18431 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
18432 cclauses == NULL);
18433 if (cclauses)
18435 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
18436 if (*cclauses)
18437 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
18438 if (clauses)
18439 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
18442 tree block = c_begin_compound_stmt (true);
18443 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
18444 if_p);
18445 block = c_end_compound_stmt (loc, block, true);
18446 add_stmt (block);
18448 return stmt;
18451 /* OpenACC 2.0:
18452 # pragma acc kernels oacc-kernels-clause[optseq] new-line
18453 structured-block
18457 # pragma acc parallel oacc-parallel-clause[optseq] new-line
18458 structured-block
18460 OpenACC 2.6:
18462 # pragma acc serial oacc-serial-clause[optseq] new-line
18463 structured-block
18465 LOC is the location of the #pragma token.
18468 #define OACC_KERNELS_CLAUSE_MASK \
18469 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18476 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18477 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18478 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18479 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
18480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
18481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
18483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18485 #define OACC_PARALLEL_CLAUSE_MASK \
18486 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18487 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18488 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18489 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18490 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
18498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
18499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
18500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
18503 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18505 #define OACC_SERIAL_CLAUSE_MASK \
18506 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18514 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18515 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18516 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18517 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
18518 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18519 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18520 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18522 static tree
18523 c_parser_oacc_compute (location_t loc, c_parser *parser,
18524 enum pragma_kind p_kind, char *p_name, bool *if_p)
18526 omp_clause_mask mask;
18527 enum tree_code code;
18528 switch (p_kind)
18530 case PRAGMA_OACC_KERNELS:
18531 strcat (p_name, " kernels");
18532 mask = OACC_KERNELS_CLAUSE_MASK;
18533 code = OACC_KERNELS;
18534 break;
18535 case PRAGMA_OACC_PARALLEL:
18536 strcat (p_name, " parallel");
18537 mask = OACC_PARALLEL_CLAUSE_MASK;
18538 code = OACC_PARALLEL;
18539 break;
18540 case PRAGMA_OACC_SERIAL:
18541 strcat (p_name, " serial");
18542 mask = OACC_SERIAL_CLAUSE_MASK;
18543 code = OACC_SERIAL;
18544 break;
18545 default:
18546 gcc_unreachable ();
18549 if (c_parser_next_token_is (parser, CPP_NAME))
18551 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18552 if (strcmp (p, "loop") == 0)
18554 c_parser_consume_token (parser);
18555 tree block = c_begin_omp_parallel ();
18556 tree clauses;
18557 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
18558 return c_finish_omp_construct (loc, code, block, clauses);
18562 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
18564 tree block = c_begin_omp_parallel ();
18565 add_stmt (c_parser_omp_structured_block (parser, if_p));
18567 return c_finish_omp_construct (loc, code, block, clauses);
18570 /* OpenACC 2.0:
18571 # pragma acc routine oacc-routine-clause[optseq] new-line
18572 function-definition
18574 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
18577 #define OACC_ROUTINE_CLAUSE_MASK \
18578 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
18579 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
18580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
18581 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
18582 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
18584 /* Parse an OpenACC routine directive. For named directives, we apply
18585 immediately to the named function. For unnamed ones we then parse
18586 a declaration or definition, which must be for a function. */
18588 static void
18589 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
18591 gcc_checking_assert (context == pragma_external);
18593 oacc_routine_data data;
18594 data.error_seen = false;
18595 data.fndecl_seen = false;
18596 data.loc = c_parser_peek_token (parser)->location;
18598 c_parser_consume_pragma (parser);
18600 /* Look for optional '( name )'. */
18601 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
18603 c_parser_consume_token (parser); /* '(' */
18605 tree decl = NULL_TREE;
18606 c_token *name_token = c_parser_peek_token (parser);
18607 location_t name_loc = name_token->location;
18608 if (name_token->type == CPP_NAME
18609 && (name_token->id_kind == C_ID_ID
18610 || name_token->id_kind == C_ID_TYPENAME))
18612 decl = lookup_name (name_token->value);
18613 if (!decl)
18614 error_at (name_loc,
18615 "%qE has not been declared", name_token->value);
18616 c_parser_consume_token (parser);
18618 else
18619 c_parser_error (parser, "expected function name");
18621 if (!decl
18622 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
18624 c_parser_skip_to_pragma_eol (parser, false);
18625 return;
18628 data.clauses
18629 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
18630 "#pragma acc routine");
18631 /* The clauses are in reverse order; fix that to make later diagnostic
18632 emission easier. */
18633 data.clauses = nreverse (data.clauses);
18635 if (TREE_CODE (decl) != FUNCTION_DECL)
18637 error_at (name_loc, "%qD does not refer to a function", decl);
18638 return;
18641 c_finish_oacc_routine (&data, decl, false);
18643 else /* No optional '( name )'. */
18645 data.clauses
18646 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
18647 "#pragma acc routine");
18648 /* The clauses are in reverse order; fix that to make later diagnostic
18649 emission easier. */
18650 data.clauses = nreverse (data.clauses);
18652 /* Emit a helpful diagnostic if there's another pragma following this
18653 one. Also don't allow a static assertion declaration, as in the
18654 following we'll just parse a *single* "declaration or function
18655 definition", and the static assertion counts an one. */
18656 if (c_parser_next_token_is (parser, CPP_PRAGMA)
18657 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
18659 error_at (data.loc,
18660 "%<#pragma acc routine%> not immediately followed by"
18661 " function declaration or definition");
18662 /* ..., and then just keep going. */
18663 return;
18666 /* We only have to consider the pragma_external case here. */
18667 if (c_parser_next_token_is (parser, CPP_KEYWORD)
18668 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
18670 int ext = disable_extension_diagnostics ();
18672 c_parser_consume_token (parser);
18673 while (c_parser_next_token_is (parser, CPP_KEYWORD)
18674 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
18675 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
18676 NULL, NULL, false, NULL, &data);
18677 restore_extension_diagnostics (ext);
18679 else
18680 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
18681 NULL, NULL, false, NULL, &data);
18685 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
18686 IS_DEFN is true if we're applying it to the definition. */
18688 static void
18689 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
18690 bool is_defn)
18692 /* Keep going if we're in error reporting mode. */
18693 if (data->error_seen
18694 || fndecl == error_mark_node)
18695 return;
18697 if (data->fndecl_seen)
18699 error_at (data->loc,
18700 "%<#pragma acc routine%> not immediately followed by"
18701 " a single function declaration or definition");
18702 data->error_seen = true;
18703 return;
18705 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
18707 error_at (data->loc,
18708 "%<#pragma acc routine%> not immediately followed by"
18709 " function declaration or definition");
18710 data->error_seen = true;
18711 return;
18714 int compatible
18715 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
18716 "#pragma acc routine");
18717 if (compatible < 0)
18719 data->error_seen = true;
18720 return;
18722 if (compatible > 0)
18725 else
18727 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
18729 error_at (data->loc,
18730 TREE_USED (fndecl)
18731 ? G_("%<#pragma acc routine%> must be applied before use")
18732 : G_("%<#pragma acc routine%> must be applied before"
18733 " definition"));
18734 data->error_seen = true;
18735 return;
18738 /* Set the routine's level of parallelism. */
18739 tree dims = oacc_build_routine_dims (data->clauses);
18740 oacc_replace_fn_attrib (fndecl, dims);
18742 /* Add an "omp declare target" attribute. */
18743 DECL_ATTRIBUTES (fndecl)
18744 = tree_cons (get_identifier ("omp declare target"),
18745 data->clauses, DECL_ATTRIBUTES (fndecl));
18748 /* Remember that we've used this "#pragma acc routine". */
18749 data->fndecl_seen = true;
18752 /* OpenACC 2.0:
18753 # pragma acc update oacc-update-clause[optseq] new-line
18756 #define OACC_UPDATE_CLAUSE_MASK \
18757 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18758 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
18759 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
18760 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18761 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
18762 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18764 static void
18765 c_parser_oacc_update (c_parser *parser)
18767 location_t loc = c_parser_peek_token (parser)->location;
18769 c_parser_consume_pragma (parser);
18771 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
18772 "#pragma acc update");
18773 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
18775 error_at (loc,
18776 "%<#pragma acc update%> must contain at least one "
18777 "%<device%> or %<host%> or %<self%> clause");
18778 return;
18781 if (parser->error)
18782 return;
18784 tree stmt = make_node (OACC_UPDATE);
18785 TREE_TYPE (stmt) = void_type_node;
18786 OACC_UPDATE_CLAUSES (stmt) = clauses;
18787 SET_EXPR_LOCATION (stmt, loc);
18788 add_stmt (stmt);
18791 /* OpenACC 2.0:
18792 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18794 LOC is the location of the #pragma token.
18797 #define OACC_WAIT_CLAUSE_MASK \
18798 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18800 static tree
18801 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
18803 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
18805 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
18806 list = c_parser_oacc_wait_list (parser, loc, list);
18808 strcpy (p_name, " wait");
18809 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
18810 stmt = c_finish_oacc_wait (loc, list, clauses);
18811 add_stmt (stmt);
18813 return stmt;
18816 /* OpenMP 5.x:
18817 # pragma omp allocate (list) clauses
18819 OpenMP 5.0 clause:
18820 allocator (omp_allocator_handle_t expression)
18822 OpenMP 5.1 additional clause:
18823 align (constant-expression)] */
18825 static void
18826 c_parser_omp_allocate (location_t loc, c_parser *parser)
18828 tree alignment = NULL_TREE;
18829 tree allocator = NULL_TREE;
18830 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
18833 if (c_parser_next_token_is (parser, CPP_COMMA)
18834 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18835 c_parser_consume_token (parser);
18836 if (!c_parser_next_token_is (parser, CPP_NAME))
18837 break;
18838 matching_parens parens;
18839 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18840 c_parser_consume_token (parser);
18841 location_t expr_loc = c_parser_peek_token (parser)->location;
18842 if (strcmp ("align", p) != 0 && strcmp ("allocator", p) != 0)
18844 error_at (c_parser_peek_token (parser)->location,
18845 "expected %<allocator%> or %<align%>");
18846 break;
18848 if (!parens.require_open (parser))
18849 break;
18851 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18852 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18853 expr_loc = c_parser_peek_token (parser)->location;
18854 if (p[2] == 'i' && alignment)
18856 error_at (expr_loc, "too many %qs clauses", "align");
18857 break;
18859 else if (p[2] == 'i')
18861 alignment = c_fully_fold (expr.value, false, NULL);
18862 if (TREE_CODE (alignment) != INTEGER_CST
18863 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
18864 || tree_int_cst_sgn (alignment) != 1
18865 || !integer_pow2p (alignment))
18867 error_at (expr_loc, "%<align%> clause argument needs to be "
18868 "positive constant power of two integer "
18869 "expression");
18870 alignment = NULL_TREE;
18873 else if (allocator)
18875 error_at (expr_loc, "too many %qs clauses", "allocator");
18876 break;
18878 else
18880 allocator = c_fully_fold (expr.value, false, NULL);
18881 tree orig_type
18882 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
18883 orig_type = TYPE_MAIN_VARIANT (orig_type);
18884 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
18885 || TREE_CODE (orig_type) != ENUMERAL_TYPE
18886 || TYPE_NAME (orig_type)
18887 != get_identifier ("omp_allocator_handle_t"))
18889 error_at (expr_loc,
18890 "%<allocator%> clause allocator expression has type "
18891 "%qT rather than %<omp_allocator_handle_t%>",
18892 TREE_TYPE (allocator));
18893 allocator = NULL_TREE;
18896 parens.skip_until_found_close (parser);
18897 } while (true);
18898 c_parser_skip_to_pragma_eol (parser);
18900 if (allocator || alignment)
18901 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
18903 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18904 OMP_CLAUSE_ALLOCATE_ALIGN (c) = alignment;
18907 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
18910 /* OpenMP 2.5:
18911 # pragma omp atomic new-line
18912 expression-stmt
18914 expression-stmt:
18915 x binop= expr | x++ | ++x | x-- | --x
18916 binop:
18917 +, *, -, /, &, ^, |, <<, >>
18919 where x is an lvalue expression with scalar type.
18921 OpenMP 3.1:
18922 # pragma omp atomic new-line
18923 update-stmt
18925 # pragma omp atomic read new-line
18926 read-stmt
18928 # pragma omp atomic write new-line
18929 write-stmt
18931 # pragma omp atomic update new-line
18932 update-stmt
18934 # pragma omp atomic capture new-line
18935 capture-stmt
18937 # pragma omp atomic capture new-line
18938 capture-block
18940 read-stmt:
18941 v = x
18942 write-stmt:
18943 x = expr
18944 update-stmt:
18945 expression-stmt | x = x binop expr
18946 capture-stmt:
18947 v = expression-stmt
18948 capture-block:
18949 { v = x; update-stmt; } | { update-stmt; v = x; }
18951 OpenMP 4.0:
18952 update-stmt:
18953 expression-stmt | x = x binop expr | x = expr binop x
18954 capture-stmt:
18955 v = update-stmt
18956 capture-block:
18957 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18959 OpenMP 5.1:
18960 # pragma omp atomic compare new-line
18961 conditional-update-atomic
18963 # pragma omp atomic compare capture new-line
18964 conditional-update-capture-atomic
18966 conditional-update-atomic:
18967 cond-expr-stmt | cond-update-stmt
18968 cond-expr-stmt:
18969 x = expr ordop x ? expr : x;
18970 x = x ordop expr ? expr : x;
18971 x = x == e ? d : x;
18972 cond-update-stmt:
18973 if (expr ordop x) { x = expr; }
18974 if (x ordop expr) { x = expr; }
18975 if (x == e) { x = d; }
18976 ordop:
18977 <, >
18978 conditional-update-capture-atomic:
18979 v = cond-expr-stmt
18980 { v = x; cond-expr-stmt }
18981 { cond-expr-stmt v = x; }
18982 { v = x; cond-update-stmt }
18983 { cond-update-stmt v = x; }
18984 if (x == e) { x = d; } else { v = x; }
18985 { r = x == e; if (r) { x = d; } }
18986 { r = x == e; if (r) { x = d; } else { v = x; } }
18988 where x, r and v are lvalue expressions with scalar type,
18989 expr, e and d are expressions with scalar type and e might be
18990 the same as v.
18992 LOC is the location of the #pragma token. */
18994 static void
18995 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18997 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18998 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18999 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
19000 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
19001 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
19002 struct c_expr expr;
19003 location_t eloc;
19004 bool structured_block = false;
19005 bool swapped = false;
19006 bool non_lvalue_p;
19007 tree clauses = NULL_TREE;
19008 bool capture = false;
19009 bool compare = false;
19010 bool weak = false;
19011 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
19012 bool no_semicolon = false;
19013 bool extra_scope = false;
19015 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19017 if (c_parser_next_token_is (parser, CPP_COMMA)
19018 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
19019 c_parser_consume_token (parser);
19021 if (c_parser_next_token_is (parser, CPP_NAME))
19023 const char *p
19024 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19025 location_t cloc = c_parser_peek_token (parser)->location;
19026 enum tree_code new_code = ERROR_MARK;
19027 enum omp_memory_order new_memory_order
19028 = OMP_MEMORY_ORDER_UNSPECIFIED;
19029 bool new_capture = false;
19030 bool new_compare = false;
19031 bool new_weak = false;
19032 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
19034 if (!strcmp (p, "read"))
19035 new_code = OMP_ATOMIC_READ;
19036 else if (!strcmp (p, "write"))
19037 new_code = NOP_EXPR;
19038 else if (!strcmp (p, "update"))
19039 new_code = OMP_ATOMIC;
19040 else if (openacc && !strcmp (p, "capture"))
19041 new_code = OMP_ATOMIC_CAPTURE_NEW;
19042 else if (openacc)
19044 p = NULL;
19045 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
19046 "or %<capture%> clause");
19048 else if (!strcmp (p, "capture"))
19049 new_capture = true;
19050 else if (!strcmp (p, "compare"))
19051 new_compare = true;
19052 else if (!strcmp (p, "weak"))
19053 new_weak = true;
19054 else if (!strcmp (p, "fail"))
19056 matching_parens parens;
19058 c_parser_consume_token (parser);
19059 if (!parens.require_open (parser))
19060 continue;
19062 if (c_parser_next_token_is (parser, CPP_NAME))
19064 const char *q
19065 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19067 if (!strcmp (q, "seq_cst"))
19068 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
19069 else if (!strcmp (q, "acquire"))
19070 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
19071 else if (!strcmp (q, "relaxed"))
19072 new_fail = OMP_MEMORY_ORDER_RELAXED;
19075 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
19077 c_parser_consume_token (parser);
19078 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
19079 error_at (cloc, "too many %qs clauses", "fail");
19080 else
19081 fail = new_fail;
19083 else
19084 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
19085 "or %<relaxed%>");
19086 parens.skip_until_found_close (parser);
19087 continue;
19089 else if (!strcmp (p, "seq_cst"))
19090 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
19091 else if (!strcmp (p, "acq_rel"))
19092 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
19093 else if (!strcmp (p, "release"))
19094 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
19095 else if (!strcmp (p, "acquire"))
19096 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
19097 else if (!strcmp (p, "relaxed"))
19098 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
19099 else if (!strcmp (p, "hint"))
19101 c_parser_consume_token (parser);
19102 clauses = c_parser_omp_clause_hint (parser, clauses);
19103 continue;
19105 else
19107 p = NULL;
19108 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
19109 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
19110 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
19111 "%<relaxed%> or %<hint%> clause");
19113 if (p)
19115 if (new_code != ERROR_MARK)
19117 /* OpenACC permits 'update capture'. */
19118 if (openacc
19119 && code == OMP_ATOMIC
19120 && new_code == OMP_ATOMIC_CAPTURE_NEW)
19121 code = new_code;
19122 else if (code != ERROR_MARK)
19123 error_at (cloc, "too many atomic clauses");
19124 else
19125 code = new_code;
19127 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
19129 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
19130 error_at (cloc, "too many memory order clauses");
19131 else
19132 memory_order = new_memory_order;
19134 else if (new_capture)
19136 if (capture)
19137 error_at (cloc, "too many %qs clauses", "capture");
19138 else
19139 capture = true;
19141 else if (new_compare)
19143 if (compare)
19144 error_at (cloc, "too many %qs clauses", "compare");
19145 else
19146 compare = true;
19148 else if (new_weak)
19150 if (weak)
19151 error_at (cloc, "too many %qs clauses", "weak");
19152 else
19153 weak = true;
19155 c_parser_consume_token (parser);
19156 continue;
19159 break;
19161 c_parser_skip_to_pragma_eol (parser);
19163 if (code == ERROR_MARK)
19164 code = OMP_ATOMIC;
19165 if (capture)
19167 if (code != OMP_ATOMIC)
19168 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
19169 "clauses", "capture");
19170 else
19171 code = OMP_ATOMIC_CAPTURE_NEW;
19173 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
19175 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
19176 "clauses", "compare");
19177 compare = false;
19179 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
19181 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
19182 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
19184 if (weak && !compare)
19186 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
19187 weak = false;
19189 if (openacc)
19190 memory_order = OMP_MEMORY_ORDER_RELAXED;
19191 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
19193 omp_requires_mask
19194 = (enum omp_requires) (omp_requires_mask
19195 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
19196 switch ((enum omp_memory_order)
19197 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
19199 case OMP_MEMORY_ORDER_UNSPECIFIED:
19200 case OMP_MEMORY_ORDER_RELAXED:
19201 memory_order = OMP_MEMORY_ORDER_RELAXED;
19202 break;
19203 case OMP_MEMORY_ORDER_SEQ_CST:
19204 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
19205 break;
19206 case OMP_MEMORY_ORDER_ACQ_REL:
19207 switch (code)
19209 case OMP_ATOMIC_READ:
19210 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
19211 break;
19212 case NOP_EXPR: /* atomic write */
19213 memory_order = OMP_MEMORY_ORDER_RELEASE;
19214 break;
19215 default:
19216 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
19217 break;
19219 break;
19220 default:
19221 gcc_unreachable ();
19224 else
19225 switch (code)
19227 case OMP_ATOMIC_READ:
19228 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
19230 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
19231 "%<release%> clause");
19232 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
19234 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
19235 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
19236 break;
19237 case NOP_EXPR: /* atomic write */
19238 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
19240 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
19241 "%<acquire%> clause");
19242 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
19244 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
19245 memory_order = OMP_MEMORY_ORDER_RELEASE;
19246 break;
19247 default:
19248 break;
19250 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
19251 memory_order
19252 = (enum omp_memory_order) (memory_order
19253 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
19255 switch (code)
19257 case OMP_ATOMIC_READ:
19258 case NOP_EXPR: /* atomic write */
19259 v = c_parser_cast_expression (parser, NULL).value;
19260 non_lvalue_p = !lvalue_p (v);
19261 v = c_fully_fold (v, false, NULL, true);
19262 if (v == error_mark_node)
19263 goto saw_error;
19264 if (non_lvalue_p)
19265 v = non_lvalue (v);
19266 loc = c_parser_peek_token (parser)->location;
19267 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19268 goto saw_error;
19269 if (code == NOP_EXPR)
19271 lhs = c_parser_expression (parser).value;
19272 lhs = c_fully_fold (lhs, false, NULL);
19273 if (lhs == error_mark_node)
19274 goto saw_error;
19276 else
19278 lhs = c_parser_cast_expression (parser, NULL).value;
19279 non_lvalue_p = !lvalue_p (lhs);
19280 lhs = c_fully_fold (lhs, false, NULL, true);
19281 if (lhs == error_mark_node)
19282 goto saw_error;
19283 if (non_lvalue_p)
19284 lhs = non_lvalue (lhs);
19286 if (code == NOP_EXPR)
19288 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
19289 opcode. */
19290 code = OMP_ATOMIC;
19291 rhs = lhs;
19292 lhs = v;
19293 v = NULL_TREE;
19295 goto done;
19296 case OMP_ATOMIC_CAPTURE_NEW:
19297 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19299 c_parser_consume_token (parser);
19300 structured_block = true;
19302 else if (compare
19303 && c_parser_next_token_is_keyword (parser, RID_IF))
19304 break;
19305 else
19307 v = c_parser_cast_expression (parser, NULL).value;
19308 non_lvalue_p = !lvalue_p (v);
19309 v = c_fully_fold (v, false, NULL, true);
19310 if (v == error_mark_node)
19311 goto saw_error;
19312 if (non_lvalue_p)
19313 v = non_lvalue (v);
19314 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19315 goto saw_error;
19316 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
19318 eloc = c_parser_peek_token (parser)->location;
19319 error_at (eloc, "expected expression");
19320 goto saw_error;
19323 break;
19324 default:
19325 break;
19328 /* For structured_block case we don't know yet whether
19329 old or new x should be captured. */
19330 restart:
19331 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
19333 c_parser_consume_token (parser);
19335 matching_parens parens;
19336 if (!parens.require_open (parser))
19337 goto saw_error;
19338 eloc = c_parser_peek_token (parser)->location;
19339 c_expr cmp_expr;
19340 if (r)
19342 cmp_expr = c_parser_cast_expression (parser, NULL);
19343 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
19345 else
19346 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
19347 parens.skip_until_found_close (parser);
19348 if (cmp_expr.value == error_mark_node)
19349 goto saw_error;
19350 if (r)
19352 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
19353 goto bad_if;
19354 cmp_expr.value = rhs1;
19355 rhs1 = NULL_TREE;
19356 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
19358 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
19360 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
19362 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
19363 "expected %<==%> comparison in %<if%> condition");
19364 goto saw_error;
19366 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
19367 && TREE_CODE (cmp_expr.value) != LT_EXPR)
19369 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
19370 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
19371 "condition");
19372 goto saw_error;
19374 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19375 goto saw_error;
19377 extra_scope = true;
19378 eloc = c_parser_peek_token (parser)->location;
19379 expr = c_parser_cast_expression (parser, NULL);
19380 lhs = expr.value;
19381 expr = default_function_array_conversion (eloc, expr);
19382 unfolded_lhs = expr.value;
19383 lhs = c_fully_fold (lhs, false, NULL, true);
19384 orig_lhs = lhs;
19385 if (lhs == error_mark_node)
19386 goto saw_error;
19387 if (!lvalue_p (unfolded_lhs))
19388 lhs = non_lvalue (lhs);
19389 if (!c_parser_next_token_is (parser, CPP_EQ))
19391 c_parser_error (parser, "expected %<=%>");
19392 goto saw_error;
19394 c_parser_consume_token (parser);
19395 eloc = c_parser_peek_token (parser)->location;
19396 expr = c_parser_expr_no_commas (parser, NULL);
19397 rhs1 = expr.value;
19399 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
19400 goto saw_error;
19402 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
19403 goto saw_error;
19405 extra_scope = false;
19406 no_semicolon = true;
19408 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
19410 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
19412 opcode = COND_EXPR;
19413 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
19414 false, NULL, true);
19415 rhs1 = c_fully_fold (rhs1, false, NULL, true);
19417 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
19419 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
19420 ? MIN_EXPR : MAX_EXPR);
19421 rhs = c_fully_fold (rhs1, false, NULL, true);
19422 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
19423 false, NULL, true);
19425 else
19426 goto bad_if;
19428 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
19429 goto bad_if;
19430 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
19431 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
19433 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
19434 ? MAX_EXPR : MIN_EXPR);
19435 rhs = c_fully_fold (rhs1, false, NULL, true);
19436 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
19437 false, NULL, true);
19439 else
19441 bad_if:
19442 c_parser_error (parser,
19443 "invalid form of %<#pragma omp atomic compare%>");
19444 goto saw_error;
19447 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
19449 if (code != OMP_ATOMIC_CAPTURE_NEW
19450 || (structured_block && r == NULL_TREE)
19451 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
19453 eloc = c_parser_peek_token (parser)->location;
19454 error_at (eloc, "unexpected %<else%>");
19455 goto saw_error;
19458 c_parser_consume_token (parser);
19460 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19461 goto saw_error;
19463 extra_scope = true;
19464 v = c_parser_cast_expression (parser, NULL).value;
19465 non_lvalue_p = !lvalue_p (v);
19466 v = c_fully_fold (v, false, NULL, true);
19467 if (v == error_mark_node)
19468 goto saw_error;
19469 if (non_lvalue_p)
19470 v = non_lvalue (v);
19471 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19472 goto saw_error;
19474 expr = c_parser_expr_no_commas (parser, NULL);
19476 if (!c_tree_equal (expr.value, unfolded_lhs))
19477 goto bad_if;
19479 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
19480 goto saw_error;
19482 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
19483 goto saw_error;
19485 extra_scope = false;
19486 code = OMP_ATOMIC_CAPTURE_OLD;
19487 if (r == NULL_TREE)
19488 /* Signal to c_finish_omp_atomic that in
19489 if (x == e) { x = d; } else { v = x; }
19490 case the store to v should be conditional. */
19491 r = void_list_node;
19493 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
19495 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
19496 goto saw_error;
19498 else if (code == OMP_ATOMIC_CAPTURE_NEW
19499 && r != NULL_TREE
19500 && v == NULL_TREE)
19501 code = OMP_ATOMIC;
19502 goto stmt_done;
19504 eloc = c_parser_peek_token (parser)->location;
19505 expr = c_parser_cast_expression (parser, NULL);
19506 lhs = expr.value;
19507 expr = default_function_array_conversion (eloc, expr);
19508 unfolded_lhs = expr.value;
19509 lhs = c_fully_fold (lhs, false, NULL, true);
19510 orig_lhs = lhs;
19511 switch (TREE_CODE (lhs))
19513 invalid_compare:
19514 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
19515 /* FALLTHRU */
19516 case ERROR_MARK:
19517 saw_error:
19518 c_parser_skip_to_end_of_block_or_statement (parser);
19519 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19520 c_parser_consume_token (parser);
19521 if (structured_block)
19523 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19524 c_parser_consume_token (parser);
19525 else if (code == OMP_ATOMIC_CAPTURE_NEW)
19527 c_parser_skip_to_end_of_block_or_statement (parser);
19528 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19529 c_parser_consume_token (parser);
19532 return;
19534 case POSTINCREMENT_EXPR:
19535 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
19536 code = OMP_ATOMIC_CAPTURE_OLD;
19537 /* FALLTHROUGH */
19538 case PREINCREMENT_EXPR:
19539 lhs = TREE_OPERAND (lhs, 0);
19540 unfolded_lhs = NULL_TREE;
19541 opcode = PLUS_EXPR;
19542 rhs = integer_one_node;
19543 if (compare)
19544 goto invalid_compare;
19545 break;
19547 case POSTDECREMENT_EXPR:
19548 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
19549 code = OMP_ATOMIC_CAPTURE_OLD;
19550 /* FALLTHROUGH */
19551 case PREDECREMENT_EXPR:
19552 lhs = TREE_OPERAND (lhs, 0);
19553 unfolded_lhs = NULL_TREE;
19554 opcode = MINUS_EXPR;
19555 rhs = integer_one_node;
19556 if (compare)
19557 goto invalid_compare;
19558 break;
19560 case COMPOUND_EXPR:
19561 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
19562 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
19563 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
19564 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
19565 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
19566 (TREE_OPERAND (lhs, 1), 0), 0))))
19567 /* Undo effects of boolean_increment for post {in,de}crement. */
19568 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
19569 /* FALLTHRU */
19570 case MODIFY_EXPR:
19571 if (TREE_CODE (lhs) == MODIFY_EXPR
19572 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))))
19574 /* Undo effects of boolean_increment. */
19575 if (integer_onep (TREE_OPERAND (lhs, 1)))
19577 /* This is pre or post increment. */
19578 rhs = TREE_OPERAND (lhs, 1);
19579 lhs = TREE_OPERAND (lhs, 0);
19580 unfolded_lhs = NULL_TREE;
19581 opcode = NOP_EXPR;
19582 if (code == OMP_ATOMIC_CAPTURE_NEW
19583 && !structured_block
19584 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
19585 code = OMP_ATOMIC_CAPTURE_OLD;
19586 if (compare)
19587 goto invalid_compare;
19588 break;
19590 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
19591 && TREE_OPERAND (lhs, 0)
19592 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
19594 /* This is pre or post decrement. */
19595 rhs = TREE_OPERAND (lhs, 1);
19596 lhs = TREE_OPERAND (lhs, 0);
19597 unfolded_lhs = NULL_TREE;
19598 opcode = NOP_EXPR;
19599 if (code == OMP_ATOMIC_CAPTURE_NEW
19600 && !structured_block
19601 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
19602 code = OMP_ATOMIC_CAPTURE_OLD;
19603 if (compare)
19604 goto invalid_compare;
19605 break;
19608 /* FALLTHRU */
19609 default:
19610 if (!lvalue_p (unfolded_lhs))
19611 lhs = non_lvalue (lhs);
19612 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
19614 c_parser_error (parser, "expected %<=%>");
19615 goto saw_error;
19617 switch (c_parser_peek_token (parser)->type)
19619 case CPP_MULT_EQ:
19620 opcode = MULT_EXPR;
19621 break;
19622 case CPP_DIV_EQ:
19623 opcode = TRUNC_DIV_EXPR;
19624 break;
19625 case CPP_PLUS_EQ:
19626 opcode = PLUS_EXPR;
19627 break;
19628 case CPP_MINUS_EQ:
19629 opcode = MINUS_EXPR;
19630 break;
19631 case CPP_LSHIFT_EQ:
19632 opcode = LSHIFT_EXPR;
19633 break;
19634 case CPP_RSHIFT_EQ:
19635 opcode = RSHIFT_EXPR;
19636 break;
19637 case CPP_AND_EQ:
19638 opcode = BIT_AND_EXPR;
19639 break;
19640 case CPP_OR_EQ:
19641 opcode = BIT_IOR_EXPR;
19642 break;
19643 case CPP_XOR_EQ:
19644 opcode = BIT_XOR_EXPR;
19645 break;
19646 case CPP_EQ:
19647 c_parser_consume_token (parser);
19648 eloc = c_parser_peek_token (parser)->location;
19649 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
19650 rhs1 = expr.value;
19651 switch (TREE_CODE (rhs1))
19653 case MULT_EXPR:
19654 case TRUNC_DIV_EXPR:
19655 case RDIV_EXPR:
19656 case PLUS_EXPR:
19657 case MINUS_EXPR:
19658 case LSHIFT_EXPR:
19659 case RSHIFT_EXPR:
19660 case BIT_AND_EXPR:
19661 case BIT_IOR_EXPR:
19662 case BIT_XOR_EXPR:
19663 if (compare)
19664 break;
19665 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
19667 opcode = TREE_CODE (rhs1);
19668 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19669 true);
19670 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
19671 true);
19672 goto stmt_done;
19674 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
19676 opcode = TREE_CODE (rhs1);
19677 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
19678 true);
19679 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19680 true);
19681 swapped = !commutative_tree_code (opcode);
19682 goto stmt_done;
19684 break;
19685 case COND_EXPR:
19686 if (!compare)
19687 break;
19688 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
19689 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
19690 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
19691 break;
19692 if (!TREE_OPERAND (rhs1, 1))
19693 break;
19694 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
19695 break;
19696 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
19697 unfolded_lhs))
19699 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
19701 opcode = COND_EXPR;
19702 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
19703 0), 1),
19704 false, NULL, true);
19705 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
19706 NULL, true);
19707 goto stmt_done;
19709 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
19710 TREE_OPERAND (rhs1, 1)))
19712 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
19713 ? MIN_EXPR : MAX_EXPR);
19714 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19715 true);
19716 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
19717 0), 0),
19718 false, NULL, true);
19719 goto stmt_done;
19722 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
19723 break;
19724 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
19725 unfolded_lhs))
19727 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
19728 TREE_OPERAND (rhs1, 1)))
19730 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
19731 ? MAX_EXPR : MIN_EXPR);
19732 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19733 true);
19734 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
19735 0), 1),
19736 false, NULL, true);
19737 goto stmt_done;
19740 break;
19741 case EQ_EXPR:
19742 if (!compare
19743 || code != OMP_ATOMIC_CAPTURE_NEW
19744 || !structured_block
19745 || v
19746 || r)
19747 break;
19748 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
19749 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
19751 r = lhs;
19752 lhs = NULL_TREE;
19753 c_parser_consume_token (parser);
19754 goto restart;
19756 break;
19757 case ERROR_MARK:
19758 goto saw_error;
19759 default:
19760 break;
19762 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
19764 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
19766 code = OMP_ATOMIC_CAPTURE_OLD;
19767 v = lhs;
19768 lhs = NULL_TREE;
19769 expr = default_function_array_read_conversion (eloc, expr);
19770 unfolded_lhs1 = expr.value;
19771 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
19772 rhs1 = NULL_TREE;
19773 c_parser_consume_token (parser);
19774 goto restart;
19776 if (structured_block && !compare)
19778 opcode = NOP_EXPR;
19779 expr = default_function_array_read_conversion (eloc, expr);
19780 rhs = c_fully_fold (expr.value, false, NULL, true);
19781 rhs1 = NULL_TREE;
19782 goto stmt_done;
19785 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
19786 goto saw_error;
19787 default:
19788 c_parser_error (parser,
19789 "invalid operator for %<#pragma omp atomic%>");
19790 goto saw_error;
19793 /* Arrange to pass the location of the assignment operator to
19794 c_finish_omp_atomic. */
19795 loc = c_parser_peek_token (parser)->location;
19796 c_parser_consume_token (parser);
19797 eloc = c_parser_peek_token (parser)->location;
19798 expr = c_parser_expression (parser);
19799 expr = default_function_array_read_conversion (eloc, expr);
19800 rhs = expr.value;
19801 rhs = c_fully_fold (rhs, false, NULL, true);
19802 break;
19804 stmt_done:
19805 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
19807 if (!no_semicolon
19808 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
19809 goto saw_error;
19810 no_semicolon = false;
19811 v = c_parser_cast_expression (parser, NULL).value;
19812 non_lvalue_p = !lvalue_p (v);
19813 v = c_fully_fold (v, false, NULL, true);
19814 if (v == error_mark_node)
19815 goto saw_error;
19816 if (non_lvalue_p)
19817 v = non_lvalue (v);
19818 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19819 goto saw_error;
19820 eloc = c_parser_peek_token (parser)->location;
19821 expr = c_parser_cast_expression (parser, NULL);
19822 lhs1 = expr.value;
19823 expr = default_function_array_read_conversion (eloc, expr);
19824 unfolded_lhs1 = expr.value;
19825 lhs1 = c_fully_fold (lhs1, false, NULL, true);
19826 if (lhs1 == error_mark_node)
19827 goto saw_error;
19828 if (!lvalue_p (unfolded_lhs1))
19829 lhs1 = non_lvalue (lhs1);
19831 if (structured_block)
19833 if (!no_semicolon)
19834 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19835 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
19837 done:
19838 if (weak && opcode != COND_EXPR)
19840 error_at (loc, "%<weak%> clause requires atomic equality comparison");
19841 weak = false;
19843 if (unfolded_lhs && unfolded_lhs1
19844 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
19846 error ("%<#pragma omp atomic capture%> uses two different "
19847 "expressions for memory");
19848 stmt = error_mark_node;
19850 else
19851 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
19852 swapped, memory_order, weak);
19853 if (stmt != error_mark_node)
19854 add_stmt (stmt);
19856 if (!structured_block && !no_semicolon)
19857 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19861 /* OpenMP 2.5:
19862 # pragma omp barrier new-line
19865 static void
19866 c_parser_omp_barrier (c_parser *parser)
19868 location_t loc = c_parser_peek_token (parser)->location;
19869 c_parser_consume_pragma (parser);
19870 c_parser_skip_to_pragma_eol (parser);
19872 c_finish_omp_barrier (loc);
19875 /* OpenMP 2.5:
19876 # pragma omp critical [(name)] new-line
19877 structured-block
19879 OpenMP 4.5:
19880 # pragma omp critical [(name) [hint(expression)]] new-line
19882 LOC is the location of the #pragma itself. */
19884 #define OMP_CRITICAL_CLAUSE_MASK \
19885 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19887 static tree
19888 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
19890 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
19892 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19894 c_parser_consume_token (parser);
19895 if (c_parser_next_token_is (parser, CPP_NAME))
19897 name = c_parser_peek_token (parser)->value;
19898 c_parser_consume_token (parser);
19899 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
19901 else
19902 c_parser_error (parser, "expected identifier");
19904 if (c_parser_next_token_is (parser, CPP_COMMA)
19905 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
19906 c_parser_consume_token (parser);
19908 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
19909 "#pragma omp critical");
19910 stmt = c_parser_omp_structured_block (parser, if_p);
19911 return c_finish_omp_critical (loc, stmt, name, clauses);
19914 /* OpenMP 5.0:
19915 # pragma omp depobj ( depobj ) depobj-clause new-line
19917 depobj-clause:
19918 depend (dependence-type : locator)
19919 destroy
19920 update (dependence-type)
19922 dependence-type:
19925 inout
19926 mutexinout */
19928 static void
19929 c_parser_omp_depobj (c_parser *parser)
19931 location_t loc = c_parser_peek_token (parser)->location;
19932 c_parser_consume_pragma (parser);
19933 matching_parens parens;
19934 if (!parens.require_open (parser))
19936 c_parser_skip_to_pragma_eol (parser);
19937 return;
19940 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
19941 if (depobj != error_mark_node)
19943 if (!lvalue_p (depobj))
19945 error_at (EXPR_LOC_OR_LOC (depobj, loc),
19946 "%<depobj%> expression is not lvalue expression");
19947 depobj = error_mark_node;
19949 else
19951 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
19952 depobj, false);
19953 if (addr == error_mark_node)
19954 depobj = error_mark_node;
19955 else
19956 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
19957 addr, RO_UNARY_STAR);
19961 parens.skip_until_found_close (parser);
19962 tree clause = NULL_TREE;
19963 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
19964 if (c_parser_next_token_is (parser, CPP_COMMA))
19965 c_parser_consume_token (parser);
19966 location_t c_loc = c_parser_peek_token (parser)->location;
19967 if (c_parser_next_token_is (parser, CPP_NAME))
19969 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19971 c_parser_consume_token (parser);
19972 if (!strcmp ("depend", p))
19974 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19975 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19976 if (!clause)
19977 clause = error_mark_node;
19979 else if (!strcmp ("destroy", p))
19980 kind = OMP_CLAUSE_DEPEND_LAST;
19981 else if (!strcmp ("update", p))
19983 matching_parens c_parens;
19984 if (c_parens.require_open (parser))
19986 location_t c2_loc = c_parser_peek_token (parser)->location;
19987 if (c_parser_next_token_is (parser, CPP_NAME))
19989 const char *p2
19990 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19992 c_parser_consume_token (parser);
19993 if (!strcmp ("in", p2))
19994 kind = OMP_CLAUSE_DEPEND_IN;
19995 else if (!strcmp ("out", p2))
19996 kind = OMP_CLAUSE_DEPEND_OUT;
19997 else if (!strcmp ("inout", p2))
19998 kind = OMP_CLAUSE_DEPEND_INOUT;
19999 else if (!strcmp ("mutexinoutset", p2))
20000 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
20001 else if (!strcmp ("inoutset", p2))
20002 kind = OMP_CLAUSE_DEPEND_INOUTSET;
20004 if (kind == OMP_CLAUSE_DEPEND_INVALID)
20006 clause = error_mark_node;
20007 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
20008 "%<mutexinoutset%> or %<inoutset%>");
20010 c_parens.skip_until_found_close (parser);
20012 else
20013 clause = error_mark_node;
20016 if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
20018 clause = error_mark_node;
20019 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
20021 c_parser_skip_to_pragma_eol (parser);
20023 c_finish_omp_depobj (loc, depobj, kind, clause);
20027 /* OpenMP 2.5:
20028 # pragma omp flush flush-vars[opt] new-line
20030 flush-vars:
20031 ( variable-list )
20033 OpenMP 5.0:
20034 # pragma omp flush memory-order-clause new-line */
20036 static void
20037 c_parser_omp_flush (c_parser *parser)
20039 location_t loc = c_parser_peek_token (parser)->location;
20040 c_parser_consume_pragma (parser);
20041 enum memmodel mo = MEMMODEL_LAST;
20042 if (c_parser_next_token_is (parser, CPP_COMMA)
20043 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
20044 c_parser_consume_token (parser);
20045 if (c_parser_next_token_is (parser, CPP_NAME))
20047 const char *p
20048 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20050 if (!strcmp (p, "seq_cst"))
20051 mo = MEMMODEL_SEQ_CST;
20052 else if (!strcmp (p, "acq_rel"))
20053 mo = MEMMODEL_ACQ_REL;
20054 else if (!strcmp (p, "release"))
20055 mo = MEMMODEL_RELEASE;
20056 else if (!strcmp (p, "acquire"))
20057 mo = MEMMODEL_ACQUIRE;
20058 else
20059 error_at (c_parser_peek_token (parser)->location,
20060 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
20061 "%<acquire%>");
20062 c_parser_consume_token (parser);
20064 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20066 if (mo != MEMMODEL_LAST)
20067 error_at (c_parser_peek_token (parser)->location,
20068 "%<flush%> list specified together with memory order "
20069 "clause");
20070 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
20072 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20073 c_parser_error (parser, "expected %<(%> or end of line");
20074 c_parser_skip_to_pragma_eol (parser);
20076 c_finish_omp_flush (loc, mo);
20079 /* Parse an OpenMP structured block sequence. KIND is the corresponding
20080 separating directive. */
20082 static tree
20083 c_parser_omp_structured_block_sequence (c_parser *parser,
20084 enum pragma_kind kind)
20086 tree stmt = push_stmt_list ();
20087 c_parser_statement (parser, NULL);
20090 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20091 break;
20092 if (c_parser_next_token_is (parser, CPP_EOF))
20093 break;
20095 if (kind != PRAGMA_NONE
20096 && c_parser_peek_token (parser)->pragma_kind == kind)
20097 break;
20098 c_parser_statement (parser, NULL);
20100 while (1);
20101 return pop_stmt_list (stmt);
20104 /* OpenMP 5.0:
20106 scan-loop-body:
20107 { structured-block scan-directive structured-block } */
20109 static void
20110 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
20112 tree substmt;
20113 location_t loc;
20114 tree clauses = NULL_TREE;
20116 loc = c_parser_peek_token (parser)->location;
20117 if (!open_brace_parsed
20118 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20120 /* Avoid skipping until the end of the block. */
20121 parser->error = false;
20122 return;
20125 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
20126 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
20127 SET_EXPR_LOCATION (substmt, loc);
20128 add_stmt (substmt);
20130 loc = c_parser_peek_token (parser)->location;
20131 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
20133 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
20135 c_parser_consume_pragma (parser);
20137 if (c_parser_next_token_is (parser, CPP_COMMA))
20138 c_parser_consume_token (parser);
20140 if (c_parser_next_token_is (parser, CPP_NAME))
20142 const char *p
20143 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20144 if (strcmp (p, "inclusive") == 0)
20145 clause = OMP_CLAUSE_INCLUSIVE;
20146 else if (strcmp (p, "exclusive") == 0)
20147 clause = OMP_CLAUSE_EXCLUSIVE;
20149 if (clause != OMP_CLAUSE_ERROR)
20151 c_parser_consume_token (parser);
20152 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
20154 else
20155 c_parser_error (parser, "expected %<inclusive%> or "
20156 "%<exclusive%> clause");
20157 c_parser_skip_to_pragma_eol (parser);
20159 else
20160 error ("expected %<#pragma omp scan%>");
20162 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
20163 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
20164 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
20165 SET_EXPR_LOCATION (substmt, loc);
20166 add_stmt (substmt);
20168 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20169 "expected %<}%>");
20172 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
20173 The real trick here is to determine the loop control variable early
20174 so that we can push a new decl if necessary to make it private.
20175 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
20176 respectively. */
20178 static tree
20179 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
20180 tree clauses, tree *cclauses, bool *if_p)
20182 tree decl, cond, incr, body, init, stmt, cl;
20183 unsigned char save_in_statement;
20184 tree declv, condv, incrv, initv, ret = NULL_TREE;
20185 tree pre_body = NULL_TREE, this_pre_body;
20186 tree ordered_cl = NULL_TREE;
20187 bool fail = false, open_brace_parsed = false;
20188 int i, collapse = 1, ordered = 0, count, nbraces = 0;
20189 location_t for_loc;
20190 bool tiling = false;
20191 bool inscan = false;
20192 vec<tree, va_gc> *for_block = make_tree_vector ();
20194 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
20195 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
20196 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
20197 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
20199 tiling = true;
20200 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
20202 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
20203 && OMP_CLAUSE_ORDERED_EXPR (cl))
20205 ordered_cl = cl;
20206 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
20208 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
20209 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
20210 && (code == OMP_SIMD || code == OMP_FOR))
20211 inscan = true;
20213 if (ordered && ordered < collapse)
20215 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
20216 "%<ordered%> clause parameter is less than %<collapse%>");
20217 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
20218 = build_int_cst (NULL_TREE, collapse);
20219 ordered = collapse;
20222 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
20223 count = ordered ? ordered : collapse;
20225 declv = make_tree_vec (count);
20226 initv = make_tree_vec (count);
20227 condv = make_tree_vec (count);
20228 incrv = make_tree_vec (count);
20230 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
20232 c_parser_error (parser, "for statement expected");
20233 return NULL;
20235 for_loc = c_parser_peek_token (parser)->location;
20236 c_parser_consume_token (parser);
20238 /* Forbid break/continue in the loop initializer, condition, and
20239 increment expressions. */
20240 save_in_statement = in_statement;
20241 in_statement = IN_OMP_BLOCK;
20243 for (i = 0; i < count; i++)
20245 int bracecount = 0;
20247 matching_parens parens;
20248 if (!parens.require_open (parser))
20249 goto pop_scopes;
20251 /* Parse the initialization declaration or expression. */
20252 if (c_parser_next_tokens_start_declaration (parser))
20254 if (i > 0)
20255 vec_safe_push (for_block, c_begin_compound_stmt (true));
20256 this_pre_body = push_stmt_list ();
20257 c_in_omp_for = true;
20258 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
20259 c_in_omp_for = false;
20260 if (this_pre_body)
20262 this_pre_body = pop_stmt_list (this_pre_body);
20263 if (pre_body)
20265 tree t = pre_body;
20266 pre_body = push_stmt_list ();
20267 add_stmt (t);
20268 add_stmt (this_pre_body);
20269 pre_body = pop_stmt_list (pre_body);
20271 else
20272 pre_body = this_pre_body;
20274 decl = check_for_loop_decls (for_loc, flag_isoc99);
20275 if (decl == NULL)
20276 goto error_init;
20277 if (DECL_INITIAL (decl) == error_mark_node)
20278 decl = error_mark_node;
20279 init = decl;
20281 else if (c_parser_next_token_is (parser, CPP_NAME)
20282 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
20284 struct c_expr decl_exp;
20285 struct c_expr init_exp;
20286 location_t init_loc;
20288 decl_exp = c_parser_postfix_expression (parser);
20289 decl = decl_exp.value;
20291 c_parser_require (parser, CPP_EQ, "expected %<=%>");
20293 init_loc = c_parser_peek_token (parser)->location;
20294 init_exp = c_parser_expr_no_commas (parser, NULL);
20295 init_exp = default_function_array_read_conversion (init_loc,
20296 init_exp);
20297 c_in_omp_for = true;
20298 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
20299 NOP_EXPR, init_loc, init_exp.value,
20300 init_exp.original_type);
20301 c_in_omp_for = false;
20302 init = c_process_expr_stmt (init_loc, init);
20304 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
20306 else
20308 error_init:
20309 c_parser_error (parser,
20310 "expected iteration declaration or initialization");
20311 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
20312 "expected %<)%>");
20313 fail = true;
20314 goto parse_next;
20317 /* Parse the loop condition. */
20318 cond = NULL_TREE;
20319 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
20321 location_t cond_loc = c_parser_peek_token (parser)->location;
20322 c_in_omp_for = true;
20323 struct c_expr cond_expr
20324 = c_parser_binary_expression (parser, NULL, NULL_TREE);
20325 c_in_omp_for = false;
20327 cond = cond_expr.value;
20328 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
20329 switch (cond_expr.original_code)
20331 case GT_EXPR:
20332 case GE_EXPR:
20333 case LT_EXPR:
20334 case LE_EXPR:
20335 break;
20336 case NE_EXPR:
20337 if (code != OACC_LOOP)
20338 break;
20339 /* FALLTHRU. */
20340 default:
20341 /* Can't be cond = error_mark_node, because we want to preserve
20342 the location until c_finish_omp_for. */
20343 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
20344 break;
20346 protected_set_expr_location (cond, cond_loc);
20348 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
20350 /* Parse the increment expression. */
20351 incr = NULL_TREE;
20352 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
20354 location_t incr_loc = c_parser_peek_token (parser)->location;
20356 incr = c_process_expr_stmt (incr_loc,
20357 c_parser_expression (parser).value);
20359 parens.skip_until_found_close (parser);
20361 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
20362 fail = true;
20363 else
20365 TREE_VEC_ELT (declv, i) = decl;
20366 TREE_VEC_ELT (initv, i) = init;
20367 TREE_VEC_ELT (condv, i) = cond;
20368 TREE_VEC_ELT (incrv, i) = incr;
20371 parse_next:
20372 if (i == count - 1)
20373 break;
20375 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
20376 in between the collapsed for loops to be still considered perfectly
20377 nested. Hopefully the final version clarifies this.
20378 For now handle (multiple) {'s and empty statements. */
20381 if (c_parser_next_token_is_keyword (parser, RID_FOR))
20383 c_parser_consume_token (parser);
20384 break;
20386 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
20388 c_parser_consume_token (parser);
20389 bracecount++;
20391 else if (bracecount
20392 && c_parser_next_token_is (parser, CPP_SEMICOLON))
20393 c_parser_consume_token (parser);
20394 else
20396 c_parser_error (parser, "not enough perfectly nested loops");
20397 if (bracecount)
20399 open_brace_parsed = true;
20400 bracecount--;
20402 fail = true;
20403 count = 0;
20404 break;
20407 while (1);
20409 nbraces += bracecount;
20412 if (nbraces)
20413 if_p = NULL;
20415 in_statement = IN_OMP_FOR;
20416 body = push_stmt_list ();
20418 if (inscan)
20419 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
20420 else if (open_brace_parsed)
20422 location_t here = c_parser_peek_token (parser)->location;
20423 stmt = c_begin_compound_stmt (true);
20424 c_parser_compound_statement_nostart (parser);
20425 add_stmt (c_end_compound_stmt (here, stmt, true));
20427 else
20428 add_stmt (c_parser_c99_block_statement (parser, if_p));
20430 body = pop_stmt_list (body);
20431 in_statement = save_in_statement;
20433 while (nbraces)
20435 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20437 c_parser_consume_token (parser);
20438 nbraces--;
20440 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
20441 c_parser_consume_token (parser);
20442 else
20444 c_parser_error (parser, "collapsed loops not perfectly nested");
20445 while (nbraces)
20447 location_t here = c_parser_peek_token (parser)->location;
20448 stmt = c_begin_compound_stmt (true);
20449 add_stmt (body);
20450 c_parser_compound_statement_nostart (parser);
20451 body = c_end_compound_stmt (here, stmt, true);
20452 nbraces--;
20454 goto pop_scopes;
20458 /* Only bother calling c_finish_omp_for if we haven't already generated
20459 an error from the initialization parsing. */
20460 if (!fail)
20462 c_in_omp_for = true;
20463 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
20464 incrv, body, pre_body, true);
20465 c_in_omp_for = false;
20467 /* Check for iterators appearing in lb, b or incr expressions. */
20468 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
20469 stmt = NULL_TREE;
20471 if (stmt)
20473 add_stmt (stmt);
20475 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
20477 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
20478 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
20479 tree decl = TREE_OPERAND (init, 0);
20480 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
20481 gcc_assert (COMPARISON_CLASS_P (cond));
20482 gcc_assert (TREE_OPERAND (cond, 0) == decl);
20484 tree op0 = TREE_OPERAND (init, 1);
20485 if (!OMP_FOR_NON_RECTANGULAR (stmt)
20486 || TREE_CODE (op0) != TREE_VEC)
20487 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
20488 else
20490 TREE_VEC_ELT (op0, 1)
20491 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
20492 TREE_VEC_ELT (op0, 2)
20493 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
20496 tree op1 = TREE_OPERAND (cond, 1);
20497 if (!OMP_FOR_NON_RECTANGULAR (stmt)
20498 || TREE_CODE (op1) != TREE_VEC)
20499 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
20500 else
20502 TREE_VEC_ELT (op1, 1)
20503 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
20504 TREE_VEC_ELT (op1, 2)
20505 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
20509 if (cclauses != NULL
20510 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
20512 tree *c;
20513 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
20514 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
20515 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
20516 c = &OMP_CLAUSE_CHAIN (*c);
20517 else
20519 for (i = 0; i < count; i++)
20520 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
20521 break;
20522 if (i == count)
20523 c = &OMP_CLAUSE_CHAIN (*c);
20524 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
20526 error_at (loc,
20527 "iteration variable %qD should not be firstprivate",
20528 OMP_CLAUSE_DECL (*c));
20529 *c = OMP_CLAUSE_CHAIN (*c);
20531 else
20533 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
20534 tree l = *c;
20535 *c = OMP_CLAUSE_CHAIN (*c);
20536 if (code == OMP_SIMD)
20538 OMP_CLAUSE_CHAIN (l)
20539 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
20540 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
20542 else
20544 OMP_CLAUSE_CHAIN (l) = clauses;
20545 clauses = l;
20550 OMP_FOR_CLAUSES (stmt) = clauses;
20552 ret = stmt;
20554 pop_scopes:
20555 while (!for_block->is_empty ())
20557 /* FIXME diagnostics: LOC below should be the actual location of
20558 this particular for block. We need to build a list of
20559 locations to go along with FOR_BLOCK. */
20560 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
20561 add_stmt (stmt);
20563 release_tree_vector (for_block);
20564 return ret;
20567 /* Helper function for OpenMP parsing, split clauses and call
20568 finish_omp_clauses on each of the set of clauses afterwards. */
20570 static void
20571 omp_split_clauses (location_t loc, enum tree_code code,
20572 omp_clause_mask mask, tree clauses, tree *cclauses)
20574 int i;
20575 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
20576 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
20577 if (cclauses[i])
20578 cclauses[i] = c_finish_omp_clauses (cclauses[i],
20579 i == C_OMP_CLAUSE_SPLIT_TARGET
20580 ? C_ORT_OMP_TARGET : C_ORT_OMP);
20583 /* OpenMP 5.0:
20584 #pragma omp loop loop-clause[optseq] new-line
20585 for-loop
20587 LOC is the location of the #pragma token.
20590 #define OMP_LOOP_CLAUSE_MASK \
20591 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20592 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20593 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20594 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20595 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
20596 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20598 static tree
20599 c_parser_omp_loop (location_t loc, c_parser *parser,
20600 char *p_name, omp_clause_mask mask, tree *cclauses,
20601 bool *if_p)
20603 tree block, clauses, ret;
20605 strcat (p_name, " loop");
20606 mask |= OMP_LOOP_CLAUSE_MASK;
20608 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20609 if (cclauses)
20611 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
20612 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
20615 block = c_begin_compound_stmt (true);
20616 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
20617 block = c_end_compound_stmt (loc, block, true);
20618 add_stmt (block);
20620 return ret;
20623 /* OpenMP 4.0:
20624 #pragma omp simd simd-clause[optseq] new-line
20625 for-loop
20627 LOC is the location of the #pragma token.
20630 #define OMP_SIMD_CLAUSE_MASK \
20631 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
20632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
20633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20634 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
20635 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
20641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20643 static tree
20644 c_parser_omp_simd (location_t loc, c_parser *parser,
20645 char *p_name, omp_clause_mask mask, tree *cclauses,
20646 bool *if_p)
20648 tree block, clauses, ret;
20650 strcat (p_name, " simd");
20651 mask |= OMP_SIMD_CLAUSE_MASK;
20653 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20654 if (cclauses)
20656 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
20657 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
20660 block = c_begin_compound_stmt (true);
20661 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
20662 block = c_end_compound_stmt (loc, block, true);
20663 add_stmt (block);
20665 return ret;
20668 /* OpenMP 2.5:
20669 #pragma omp for for-clause[optseq] new-line
20670 for-loop
20672 OpenMP 4.0:
20673 #pragma omp for simd for-simd-clause[optseq] new-line
20674 for-loop
20676 LOC is the location of the #pragma token.
20679 #define OMP_FOR_CLAUSE_MASK \
20680 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20683 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20684 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20685 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
20686 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
20687 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20688 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
20689 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20690 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20692 static tree
20693 c_parser_omp_for (location_t loc, c_parser *parser,
20694 char *p_name, omp_clause_mask mask, tree *cclauses,
20695 bool *if_p)
20697 tree block, clauses, ret;
20699 strcat (p_name, " for");
20700 mask |= OMP_FOR_CLAUSE_MASK;
20701 /* parallel for{, simd} disallows nowait clause, but for
20702 target {teams distribute ,}parallel for{, simd} it should be accepted. */
20703 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
20704 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20705 /* Composite distribute parallel for{, simd} disallows ordered clause. */
20706 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20707 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
20709 if (c_parser_next_token_is (parser, CPP_NAME))
20711 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20713 if (strcmp (p, "simd") == 0)
20715 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20716 if (cclauses == NULL)
20717 cclauses = cclauses_buf;
20719 c_parser_consume_token (parser);
20720 if (!flag_openmp) /* flag_openmp_simd */
20721 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20722 if_p);
20723 block = c_begin_compound_stmt (true);
20724 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
20725 block = c_end_compound_stmt (loc, block, true);
20726 if (ret == NULL_TREE)
20727 return ret;
20728 ret = make_node (OMP_FOR);
20729 TREE_TYPE (ret) = void_type_node;
20730 OMP_FOR_BODY (ret) = block;
20731 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
20732 SET_EXPR_LOCATION (ret, loc);
20733 add_stmt (ret);
20734 return ret;
20737 if (!flag_openmp) /* flag_openmp_simd */
20739 c_parser_skip_to_pragma_eol (parser, false);
20740 return NULL_TREE;
20743 /* Composite distribute parallel for disallows linear clause. */
20744 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20745 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
20747 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20748 if (cclauses)
20750 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
20751 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
20754 block = c_begin_compound_stmt (true);
20755 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
20756 block = c_end_compound_stmt (loc, block, true);
20757 add_stmt (block);
20759 return ret;
20762 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
20763 omp_clause_mask, tree *, bool *);
20765 /* OpenMP 2.5:
20766 # pragma omp master new-line
20767 structured-block
20769 LOC is the location of the #pragma token.
20772 static tree
20773 c_parser_omp_master (location_t loc, c_parser *parser,
20774 char *p_name, omp_clause_mask mask, tree *cclauses,
20775 bool *if_p)
20777 tree block, clauses, ret;
20779 strcat (p_name, " master");
20781 if (c_parser_next_token_is (parser, CPP_NAME))
20783 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20785 if (strcmp (p, "taskloop") == 0)
20787 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20788 if (cclauses == NULL)
20789 cclauses = cclauses_buf;
20791 c_parser_consume_token (parser);
20792 if (!flag_openmp) /* flag_openmp_simd */
20793 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20794 if_p);
20795 block = c_begin_compound_stmt (true);
20796 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20797 if_p);
20798 block = c_end_compound_stmt (loc, block, true);
20799 if (ret == NULL_TREE)
20800 return ret;
20801 ret = c_finish_omp_master (loc, block);
20802 OMP_MASTER_COMBINED (ret) = 1;
20803 return ret;
20806 if (!flag_openmp) /* flag_openmp_simd */
20808 c_parser_skip_to_pragma_eol (parser, false);
20809 return NULL_TREE;
20812 if (cclauses)
20814 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
20815 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
20817 else
20818 c_parser_skip_to_pragma_eol (parser);
20820 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
20821 if_p));
20824 /* OpenMP 5.1:
20825 # pragma omp masked masked-clauses new-line
20826 structured-block
20828 LOC is the location of the #pragma token.
20831 #define OMP_MASKED_CLAUSE_MASK \
20832 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20834 static tree
20835 c_parser_omp_masked (location_t loc, c_parser *parser,
20836 char *p_name, omp_clause_mask mask, tree *cclauses,
20837 bool *if_p)
20839 tree block, clauses, ret;
20841 strcat (p_name, " masked");
20842 mask |= OMP_MASKED_CLAUSE_MASK;
20844 if (c_parser_next_token_is (parser, CPP_NAME))
20846 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20848 if (strcmp (p, "taskloop") == 0)
20850 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20851 if (cclauses == NULL)
20852 cclauses = cclauses_buf;
20854 c_parser_consume_token (parser);
20855 if (!flag_openmp) /* flag_openmp_simd */
20856 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20857 if_p);
20858 block = c_begin_compound_stmt (true);
20859 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20860 if_p);
20861 block = c_end_compound_stmt (loc, block, true);
20862 if (ret == NULL_TREE)
20863 return ret;
20864 ret = c_finish_omp_masked (loc, block,
20865 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
20866 OMP_MASKED_COMBINED (ret) = 1;
20867 return ret;
20870 if (!flag_openmp) /* flag_openmp_simd */
20872 c_parser_skip_to_pragma_eol (parser, false);
20873 return NULL_TREE;
20876 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20877 if (cclauses)
20879 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
20880 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
20883 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
20884 if_p),
20885 clauses);
20888 /* OpenMP 2.5:
20889 # pragma omp ordered new-line
20890 structured-block
20892 OpenMP 4.5:
20893 # pragma omp ordered ordered-clauses new-line
20894 structured-block
20896 # pragma omp ordered depend-clauses new-line
20898 OpenMP 5.2
20899 # pragma omp ordered doacross-clauses new-line */
20901 #define OMP_ORDERED_CLAUSE_MASK \
20902 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20905 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20906 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20907 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
20909 static bool
20910 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
20911 bool *if_p)
20913 location_t loc = c_parser_peek_token (parser)->location;
20914 c_parser_consume_pragma (parser);
20916 if (context != pragma_stmt && context != pragma_compound)
20918 c_parser_error (parser, "expected declaration specifiers");
20919 c_parser_skip_to_pragma_eol (parser, false);
20920 return false;
20923 int n = 1;
20924 if (c_parser_next_token_is (parser, CPP_COMMA))
20925 n = 2;
20927 if (c_parser_peek_nth_token (parser, n)->type == CPP_NAME)
20929 const char *p
20930 = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser, n)->value);
20932 if (!strcmp ("depend", p) || !strcmp ("doacross", p))
20934 if (!flag_openmp) /* flag_openmp_simd */
20936 c_parser_skip_to_pragma_eol (parser, false);
20937 return false;
20939 if (context == pragma_stmt)
20941 error_at (loc,
20942 "%<#pragma omp ordered%> with %qs clause may "
20943 "only be used in compound statements", p);
20944 c_parser_skip_to_pragma_eol (parser, false);
20945 return true;
20948 tree clauses
20949 = c_parser_omp_all_clauses (parser,
20950 OMP_ORDERED_DEPEND_CLAUSE_MASK,
20951 "#pragma omp ordered");
20952 c_finish_omp_ordered (loc, clauses, NULL_TREE);
20953 return false;
20957 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20958 "#pragma omp ordered");
20960 if (!flag_openmp /* flag_openmp_simd */
20961 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20962 return false;
20964 c_finish_omp_ordered (loc, clauses,
20965 c_parser_omp_structured_block (parser, if_p));
20966 return true;
20969 /* OpenMP 2.5:
20971 section-scope:
20972 { section-sequence }
20974 section-sequence:
20975 section-directive[opt] structured-block
20976 section-sequence section-directive structured-block
20978 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20980 SECTIONS_LOC is the location of the #pragma omp sections. */
20982 static tree
20983 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20985 tree stmt, substmt;
20986 bool error_suppress = false;
20987 location_t loc;
20989 loc = c_parser_peek_token (parser)->location;
20990 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20992 /* Avoid skipping until the end of the block. */
20993 parser->error = false;
20994 return NULL_TREE;
20997 stmt = push_stmt_list ();
20999 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
21001 substmt = c_parser_omp_structured_block_sequence (parser,
21002 PRAGMA_OMP_SECTION);
21003 substmt = build1 (OMP_SECTION, void_type_node, substmt);
21004 SET_EXPR_LOCATION (substmt, loc);
21005 add_stmt (substmt);
21008 while (1)
21010 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
21011 break;
21012 if (c_parser_next_token_is (parser, CPP_EOF))
21013 break;
21015 loc = c_parser_peek_token (parser)->location;
21016 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
21018 c_parser_consume_pragma (parser);
21019 c_parser_skip_to_pragma_eol (parser);
21020 error_suppress = false;
21022 else if (!error_suppress)
21024 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
21025 error_suppress = true;
21028 substmt = c_parser_omp_structured_block_sequence (parser,
21029 PRAGMA_OMP_SECTION);
21030 substmt = build1 (OMP_SECTION, void_type_node, substmt);
21031 SET_EXPR_LOCATION (substmt, loc);
21032 add_stmt (substmt);
21034 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
21035 "expected %<#pragma omp section%> or %<}%>");
21037 substmt = pop_stmt_list (stmt);
21039 stmt = make_node (OMP_SECTIONS);
21040 SET_EXPR_LOCATION (stmt, sections_loc);
21041 TREE_TYPE (stmt) = void_type_node;
21042 OMP_SECTIONS_BODY (stmt) = substmt;
21044 return add_stmt (stmt);
21047 /* OpenMP 2.5:
21048 # pragma omp sections sections-clause[optseq] newline
21049 sections-scope
21051 LOC is the location of the #pragma token.
21054 #define OMP_SECTIONS_CLAUSE_MASK \
21055 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21060 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21062 static tree
21063 c_parser_omp_sections (location_t loc, c_parser *parser,
21064 char *p_name, omp_clause_mask mask, tree *cclauses)
21066 tree block, clauses, ret;
21068 strcat (p_name, " sections");
21069 mask |= OMP_SECTIONS_CLAUSE_MASK;
21070 if (cclauses)
21071 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
21073 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21074 if (cclauses)
21076 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
21077 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
21080 block = c_begin_compound_stmt (true);
21081 ret = c_parser_omp_sections_scope (loc, parser);
21082 if (ret)
21083 OMP_SECTIONS_CLAUSES (ret) = clauses;
21084 block = c_end_compound_stmt (loc, block, true);
21085 add_stmt (block);
21087 return ret;
21090 /* OpenMP 2.5:
21091 # pragma omp parallel parallel-clause[optseq] new-line
21092 structured-block
21093 # pragma omp parallel for parallel-for-clause[optseq] new-line
21094 structured-block
21095 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
21096 structured-block
21098 OpenMP 4.0:
21099 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
21100 structured-block
21102 LOC is the location of the #pragma token.
21105 #define OMP_PARALLEL_CLAUSE_MASK \
21106 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21107 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21108 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21109 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21110 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21111 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
21112 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21113 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
21114 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21115 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
21117 static tree
21118 c_parser_omp_parallel (location_t loc, c_parser *parser,
21119 char *p_name, omp_clause_mask mask, tree *cclauses,
21120 bool *if_p)
21122 tree stmt, clauses, block;
21124 strcat (p_name, " parallel");
21125 mask |= OMP_PARALLEL_CLAUSE_MASK;
21126 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
21127 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
21128 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
21129 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
21131 if (c_parser_next_token_is_keyword (parser, RID_FOR))
21133 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21134 if (cclauses == NULL)
21135 cclauses = cclauses_buf;
21137 c_parser_consume_token (parser);
21138 if (!flag_openmp) /* flag_openmp_simd */
21139 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
21140 block = c_begin_omp_parallel ();
21141 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
21142 stmt
21143 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
21144 block);
21145 if (ret == NULL_TREE)
21146 return ret;
21147 OMP_PARALLEL_COMBINED (stmt) = 1;
21148 return stmt;
21150 /* When combined with distribute, parallel has to be followed by for.
21151 #pragma omp target parallel is allowed though. */
21152 else if (cclauses
21153 && (mask & (OMP_CLAUSE_MASK_1
21154 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
21156 error_at (loc, "expected %<for%> after %qs", p_name);
21157 c_parser_skip_to_pragma_eol (parser);
21158 return NULL_TREE;
21160 else if (c_parser_next_token_is (parser, CPP_NAME))
21162 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21163 if (cclauses == NULL && strcmp (p, "masked") == 0)
21165 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21166 cclauses = cclauses_buf;
21168 c_parser_consume_token (parser);
21169 if (!flag_openmp) /* flag_openmp_simd */
21170 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
21171 if_p);
21172 block = c_begin_omp_parallel ();
21173 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
21174 if_p);
21175 stmt = c_finish_omp_parallel (loc,
21176 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
21177 block);
21178 if (ret == NULL)
21179 return ret;
21180 /* masked does have just filter clause, but during gimplification
21181 isn't represented by a gimplification omp context, so for
21182 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
21183 so that
21184 #pragma omp parallel masked
21185 #pragma omp taskloop simd lastprivate (x)
21186 isn't confused with
21187 #pragma omp parallel masked taskloop simd lastprivate (x) */
21188 if (OMP_MASKED_COMBINED (ret))
21189 OMP_PARALLEL_COMBINED (stmt) = 1;
21190 return stmt;
21192 else if (cclauses == NULL && strcmp (p, "master") == 0)
21194 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21195 cclauses = cclauses_buf;
21197 c_parser_consume_token (parser);
21198 if (!flag_openmp) /* flag_openmp_simd */
21199 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
21200 if_p);
21201 block = c_begin_omp_parallel ();
21202 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
21203 if_p);
21204 stmt = c_finish_omp_parallel (loc,
21205 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
21206 block);
21207 if (ret == NULL)
21208 return ret;
21209 /* master doesn't have any clauses and during gimplification
21210 isn't represented by a gimplification omp context, so for
21211 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
21212 so that
21213 #pragma omp parallel master
21214 #pragma omp taskloop simd lastprivate (x)
21215 isn't confused with
21216 #pragma omp parallel master taskloop simd lastprivate (x) */
21217 if (OMP_MASTER_COMBINED (ret))
21218 OMP_PARALLEL_COMBINED (stmt) = 1;
21219 return stmt;
21221 else if (strcmp (p, "loop") == 0)
21223 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21224 if (cclauses == NULL)
21225 cclauses = cclauses_buf;
21227 c_parser_consume_token (parser);
21228 if (!flag_openmp) /* flag_openmp_simd */
21229 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
21230 if_p);
21231 block = c_begin_omp_parallel ();
21232 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
21233 if_p);
21234 stmt
21235 = c_finish_omp_parallel (loc,
21236 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
21237 block);
21238 if (ret == NULL_TREE)
21239 return ret;
21240 OMP_PARALLEL_COMBINED (stmt) = 1;
21241 return stmt;
21243 else if (!flag_openmp) /* flag_openmp_simd */
21245 c_parser_skip_to_pragma_eol (parser, false);
21246 return NULL_TREE;
21248 else if (cclauses == NULL && strcmp (p, "sections") == 0)
21250 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21251 cclauses = cclauses_buf;
21253 c_parser_consume_token (parser);
21254 block = c_begin_omp_parallel ();
21255 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
21256 stmt = c_finish_omp_parallel (loc,
21257 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
21258 block);
21259 OMP_PARALLEL_COMBINED (stmt) = 1;
21260 return stmt;
21263 else if (!flag_openmp) /* flag_openmp_simd */
21265 c_parser_skip_to_pragma_eol (parser, false);
21266 return NULL_TREE;
21269 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21270 if (cclauses)
21272 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
21273 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
21276 block = c_begin_omp_parallel ();
21277 c_parser_statement (parser, if_p);
21278 stmt = c_finish_omp_parallel (loc, clauses, block);
21280 return stmt;
21283 /* OpenMP 2.5:
21284 # pragma omp single single-clause[optseq] new-line
21285 structured-block
21287 LOC is the location of the #pragma.
21290 #define OMP_SINGLE_CLAUSE_MASK \
21291 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21292 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21293 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
21294 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21295 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21297 static tree
21298 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
21300 tree stmt = make_node (OMP_SINGLE);
21301 SET_EXPR_LOCATION (stmt, loc);
21302 TREE_TYPE (stmt) = void_type_node;
21304 OMP_SINGLE_CLAUSES (stmt)
21305 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
21306 "#pragma omp single");
21307 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
21309 return add_stmt (stmt);
21312 /* OpenMP 5.1:
21313 # pragma omp scope scope-clause[optseq] new-line
21314 structured-block
21316 LOC is the location of the #pragma.
21319 #define OMP_SCOPE_CLAUSE_MASK \
21320 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21321 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21322 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21323 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21324 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21326 static tree
21327 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
21329 tree stmt = make_node (OMP_SCOPE);
21330 SET_EXPR_LOCATION (stmt, loc);
21331 TREE_TYPE (stmt) = void_type_node;
21333 OMP_SCOPE_CLAUSES (stmt)
21334 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
21335 "#pragma omp scope");
21336 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
21338 return add_stmt (stmt);
21341 /* OpenMP 3.0:
21342 # pragma omp task task-clause[optseq] new-line
21344 LOC is the location of the #pragma.
21347 #define OMP_TASK_CLAUSE_MASK \
21348 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21356 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21357 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21358 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21360 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
21361 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
21363 static tree
21364 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
21366 tree clauses, block;
21368 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
21369 "#pragma omp task");
21371 block = c_begin_omp_task ();
21372 c_parser_statement (parser, if_p);
21373 return c_finish_omp_task (loc, clauses, block);
21376 /* OpenMP 3.0:
21377 # pragma omp taskwait new-line
21379 OpenMP 5.0:
21380 # pragma omp taskwait taskwait-clause[optseq] new-line
21383 #define OMP_TASKWAIT_CLAUSE_MASK \
21384 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21387 static void
21388 c_parser_omp_taskwait (c_parser *parser)
21390 location_t loc = c_parser_peek_token (parser)->location;
21391 c_parser_consume_pragma (parser);
21393 tree clauses
21394 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
21395 "#pragma omp taskwait");
21397 if (clauses)
21399 tree stmt = make_node (OMP_TASK);
21400 TREE_TYPE (stmt) = void_node;
21401 OMP_TASK_CLAUSES (stmt) = clauses;
21402 OMP_TASK_BODY (stmt) = NULL_TREE;
21403 SET_EXPR_LOCATION (stmt, loc);
21404 add_stmt (stmt);
21406 else
21407 c_finish_omp_taskwait (loc);
21410 /* OpenMP 3.1:
21411 # pragma omp taskyield new-line
21414 static void
21415 c_parser_omp_taskyield (c_parser *parser)
21417 location_t loc = c_parser_peek_token (parser)->location;
21418 c_parser_consume_pragma (parser);
21419 c_parser_skip_to_pragma_eol (parser);
21421 c_finish_omp_taskyield (loc);
21424 /* OpenMP 4.0:
21425 # pragma omp taskgroup new-line
21427 OpenMP 5.0:
21428 # pragma omp taskgroup taskgroup-clause[optseq] new-line
21431 #define OMP_TASKGROUP_CLAUSE_MASK \
21432 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21433 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
21435 static tree
21436 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
21438 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
21439 "#pragma omp taskgroup");
21441 tree body = c_parser_omp_structured_block (parser, if_p);
21442 return c_finish_omp_taskgroup (loc, body, clauses);
21445 /* OpenMP 4.0:
21446 # pragma omp cancel cancel-clause[optseq] new-line
21448 LOC is the location of the #pragma.
21451 #define OMP_CANCEL_CLAUSE_MASK \
21452 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
21453 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
21454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
21455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
21456 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
21458 static void
21459 c_parser_omp_cancel (c_parser *parser)
21461 location_t loc = c_parser_peek_token (parser)->location;
21463 c_parser_consume_pragma (parser);
21464 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
21465 "#pragma omp cancel");
21467 c_finish_omp_cancel (loc, clauses);
21470 /* OpenMP 4.0:
21471 # pragma omp cancellation point cancelpt-clause[optseq] new-line
21473 LOC is the location of the #pragma.
21476 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
21477 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
21478 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
21479 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
21480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
21482 static bool
21483 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
21485 location_t loc = c_parser_peek_token (parser)->location;
21486 tree clauses;
21487 bool point_seen = false;
21489 c_parser_consume_pragma (parser);
21490 if (c_parser_next_token_is (parser, CPP_NAME))
21492 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21493 if (strcmp (p, "point") == 0)
21495 c_parser_consume_token (parser);
21496 point_seen = true;
21499 if (!point_seen)
21501 c_parser_error (parser, "expected %<point%>");
21502 c_parser_skip_to_pragma_eol (parser);
21503 return false;
21506 if (context != pragma_compound)
21508 if (context == pragma_stmt)
21509 error_at (loc,
21510 "%<#pragma %s%> may only be used in compound statements",
21511 "omp cancellation point");
21512 else
21513 c_parser_error (parser, "expected declaration specifiers");
21514 c_parser_skip_to_pragma_eol (parser, false);
21515 return true;
21518 clauses
21519 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
21520 "#pragma omp cancellation point");
21522 c_finish_omp_cancellation_point (loc, clauses);
21523 return true;
21526 /* OpenMP 4.0:
21527 #pragma omp distribute distribute-clause[optseq] new-line
21528 for-loop */
21530 #define OMP_DISTRIBUTE_CLAUSE_MASK \
21531 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21532 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21533 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21534 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
21535 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21536 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
21539 static tree
21540 c_parser_omp_distribute (location_t loc, c_parser *parser,
21541 char *p_name, omp_clause_mask mask, tree *cclauses,
21542 bool *if_p)
21544 tree clauses, block, ret;
21546 strcat (p_name, " distribute");
21547 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
21549 if (c_parser_next_token_is (parser, CPP_NAME))
21551 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21552 bool simd = false;
21553 bool parallel = false;
21555 if (strcmp (p, "simd") == 0)
21556 simd = true;
21557 else
21558 parallel = strcmp (p, "parallel") == 0;
21559 if (parallel || simd)
21561 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21562 if (cclauses == NULL)
21563 cclauses = cclauses_buf;
21564 c_parser_consume_token (parser);
21565 if (!flag_openmp) /* flag_openmp_simd */
21567 if (simd)
21568 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21569 if_p);
21570 else
21571 return c_parser_omp_parallel (loc, parser, p_name, mask,
21572 cclauses, if_p);
21574 block = c_begin_compound_stmt (true);
21575 if (simd)
21576 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21577 if_p);
21578 else
21579 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
21580 if_p);
21581 block = c_end_compound_stmt (loc, block, true);
21582 if (ret == NULL)
21583 return ret;
21584 ret = make_node (OMP_DISTRIBUTE);
21585 TREE_TYPE (ret) = void_type_node;
21586 OMP_FOR_BODY (ret) = block;
21587 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
21588 SET_EXPR_LOCATION (ret, loc);
21589 add_stmt (ret);
21590 return ret;
21593 if (!flag_openmp) /* flag_openmp_simd */
21595 c_parser_skip_to_pragma_eol (parser, false);
21596 return NULL_TREE;
21599 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21600 if (cclauses)
21602 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
21603 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
21606 block = c_begin_compound_stmt (true);
21607 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
21608 if_p);
21609 block = c_end_compound_stmt (loc, block, true);
21610 add_stmt (block);
21612 return ret;
21615 /* OpenMP 4.0:
21616 # pragma omp teams teams-clause[optseq] new-line
21617 structured-block */
21619 #define OMP_TEAMS_CLAUSE_MASK \
21620 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21621 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21622 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21623 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21624 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
21625 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21626 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21627 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
21629 static tree
21630 c_parser_omp_teams (location_t loc, c_parser *parser,
21631 char *p_name, omp_clause_mask mask, tree *cclauses,
21632 bool *if_p)
21634 tree clauses, block, ret;
21636 strcat (p_name, " teams");
21637 mask |= OMP_TEAMS_CLAUSE_MASK;
21639 if (c_parser_next_token_is (parser, CPP_NAME))
21641 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21642 if (strcmp (p, "distribute") == 0)
21644 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21645 if (cclauses == NULL)
21646 cclauses = cclauses_buf;
21648 c_parser_consume_token (parser);
21649 if (!flag_openmp) /* flag_openmp_simd */
21650 return c_parser_omp_distribute (loc, parser, p_name, mask,
21651 cclauses, if_p);
21652 block = c_begin_omp_parallel ();
21653 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
21654 if_p);
21655 block = c_end_compound_stmt (loc, block, true);
21656 if (ret == NULL)
21657 return ret;
21658 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21659 ret = make_node (OMP_TEAMS);
21660 TREE_TYPE (ret) = void_type_node;
21661 OMP_TEAMS_CLAUSES (ret) = clauses;
21662 OMP_TEAMS_BODY (ret) = block;
21663 OMP_TEAMS_COMBINED (ret) = 1;
21664 SET_EXPR_LOCATION (ret, loc);
21665 return add_stmt (ret);
21667 else if (strcmp (p, "loop") == 0)
21669 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21670 if (cclauses == NULL)
21671 cclauses = cclauses_buf;
21673 c_parser_consume_token (parser);
21674 if (!flag_openmp) /* flag_openmp_simd */
21675 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
21676 if_p);
21677 block = c_begin_omp_parallel ();
21678 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
21679 block = c_end_compound_stmt (loc, block, true);
21680 if (ret == NULL)
21681 return ret;
21682 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21683 ret = make_node (OMP_TEAMS);
21684 TREE_TYPE (ret) = void_type_node;
21685 OMP_TEAMS_CLAUSES (ret) = clauses;
21686 OMP_TEAMS_BODY (ret) = block;
21687 OMP_TEAMS_COMBINED (ret) = 1;
21688 SET_EXPR_LOCATION (ret, loc);
21689 return add_stmt (ret);
21692 if (!flag_openmp) /* flag_openmp_simd */
21694 c_parser_skip_to_pragma_eol (parser, false);
21695 return NULL_TREE;
21698 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21699 if (cclauses)
21701 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
21702 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21705 tree stmt = make_node (OMP_TEAMS);
21706 TREE_TYPE (stmt) = void_type_node;
21707 OMP_TEAMS_CLAUSES (stmt) = clauses;
21708 block = c_begin_omp_parallel ();
21709 add_stmt (c_parser_omp_structured_block (parser, if_p));
21710 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21711 SET_EXPR_LOCATION (stmt, loc);
21713 return add_stmt (stmt);
21716 /* OpenMP 4.0:
21717 # pragma omp target data target-data-clause[optseq] new-line
21718 structured-block */
21720 #define OMP_TARGET_DATA_CLAUSE_MASK \
21721 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
21725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
21727 static tree
21728 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
21730 if (flag_openmp)
21731 omp_requires_mask
21732 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21734 tree clauses
21735 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
21736 "#pragma omp target data");
21737 c_omp_adjust_map_clauses (clauses, false);
21738 int map_seen = 0;
21739 for (tree *pc = &clauses; *pc;)
21741 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21742 switch (OMP_CLAUSE_MAP_KIND (*pc))
21744 case GOMP_MAP_TO:
21745 case GOMP_MAP_ALWAYS_TO:
21746 case GOMP_MAP_FROM:
21747 case GOMP_MAP_ALWAYS_FROM:
21748 case GOMP_MAP_TOFROM:
21749 case GOMP_MAP_ALWAYS_TOFROM:
21750 case GOMP_MAP_ALLOC:
21751 map_seen = 3;
21752 break;
21753 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21754 case GOMP_MAP_ALWAYS_POINTER:
21755 case GOMP_MAP_ATTACH_DETACH:
21756 break;
21757 default:
21758 map_seen |= 1;
21759 error_at (OMP_CLAUSE_LOCATION (*pc),
21760 "%<#pragma omp target data%> with map-type other "
21761 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21762 "on %<map%> clause");
21763 *pc = OMP_CLAUSE_CHAIN (*pc);
21764 continue;
21766 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
21767 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
21768 map_seen = 3;
21769 pc = &OMP_CLAUSE_CHAIN (*pc);
21772 if (map_seen != 3)
21774 if (map_seen == 0)
21775 error_at (loc,
21776 "%<#pragma omp target data%> must contain at least "
21777 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
21778 "clause");
21779 return NULL_TREE;
21782 tree stmt = make_node (OMP_TARGET_DATA);
21783 TREE_TYPE (stmt) = void_type_node;
21784 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
21785 keep_next_level ();
21786 tree block = c_begin_compound_stmt (true);
21787 add_stmt (c_parser_omp_structured_block (parser, if_p));
21788 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21790 SET_EXPR_LOCATION (stmt, loc);
21791 return add_stmt (stmt);
21794 /* OpenMP 4.0:
21795 # pragma omp target update target-update-clause[optseq] new-line */
21797 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
21798 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
21799 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21800 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21805 static bool
21806 c_parser_omp_target_update (location_t loc, c_parser *parser,
21807 enum pragma_context context)
21809 if (context == pragma_stmt)
21811 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21812 "omp target update");
21813 c_parser_skip_to_pragma_eol (parser, false);
21814 return true;
21817 tree clauses
21818 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
21819 "#pragma omp target update");
21820 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
21821 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
21823 error_at (loc,
21824 "%<#pragma omp target update%> must contain at least one "
21825 "%<from%> or %<to%> clauses");
21826 return false;
21829 if (flag_openmp)
21830 omp_requires_mask
21831 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21833 tree stmt = make_node (OMP_TARGET_UPDATE);
21834 TREE_TYPE (stmt) = void_type_node;
21835 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
21836 SET_EXPR_LOCATION (stmt, loc);
21837 add_stmt (stmt);
21838 return false;
21841 /* OpenMP 4.5:
21842 # pragma omp target enter data target-data-clause[optseq] new-line */
21844 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21845 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21848 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21849 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21851 static bool
21852 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
21853 enum pragma_context context)
21855 bool data_seen = false;
21856 if (c_parser_next_token_is (parser, CPP_NAME))
21858 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21859 if (strcmp (p, "data") == 0)
21861 c_parser_consume_token (parser);
21862 data_seen = true;
21865 if (!data_seen)
21867 c_parser_error (parser, "expected %<data%>");
21868 c_parser_skip_to_pragma_eol (parser);
21869 return false;
21872 if (context == pragma_stmt)
21874 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21875 "omp target enter data");
21876 c_parser_skip_to_pragma_eol (parser, false);
21877 return true;
21880 if (flag_openmp)
21881 omp_requires_mask
21882 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21884 tree clauses
21885 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
21886 "#pragma omp target enter data");
21887 c_omp_adjust_map_clauses (clauses, false);
21888 int map_seen = 0;
21889 for (tree *pc = &clauses; *pc;)
21891 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21892 switch (OMP_CLAUSE_MAP_KIND (*pc))
21894 case GOMP_MAP_TO:
21895 case GOMP_MAP_ALWAYS_TO:
21896 case GOMP_MAP_ALLOC:
21897 map_seen = 3;
21898 break;
21899 case GOMP_MAP_TOFROM:
21900 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
21901 map_seen = 3;
21902 break;
21903 case GOMP_MAP_ALWAYS_TOFROM:
21904 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
21905 map_seen = 3;
21906 break;
21907 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21908 case GOMP_MAP_ALWAYS_POINTER:
21909 case GOMP_MAP_ATTACH_DETACH:
21910 break;
21911 default:
21912 map_seen |= 1;
21913 error_at (OMP_CLAUSE_LOCATION (*pc),
21914 "%<#pragma omp target enter data%> with map-type other "
21915 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21916 *pc = OMP_CLAUSE_CHAIN (*pc);
21917 continue;
21919 pc = &OMP_CLAUSE_CHAIN (*pc);
21922 if (map_seen != 3)
21924 if (map_seen == 0)
21925 error_at (loc,
21926 "%<#pragma omp target enter data%> must contain at least "
21927 "one %<map%> clause");
21928 return true;
21931 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
21932 TREE_TYPE (stmt) = void_type_node;
21933 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
21934 SET_EXPR_LOCATION (stmt, loc);
21935 add_stmt (stmt);
21936 return true;
21939 /* OpenMP 4.5:
21940 # pragma omp target exit data target-data-clause[optseq] new-line */
21942 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21943 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21944 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21945 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21946 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21947 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21949 static bool
21950 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
21951 enum pragma_context context)
21953 bool data_seen = false;
21954 if (c_parser_next_token_is (parser, CPP_NAME))
21956 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21957 if (strcmp (p, "data") == 0)
21959 c_parser_consume_token (parser);
21960 data_seen = true;
21963 if (!data_seen)
21965 c_parser_error (parser, "expected %<data%>");
21966 c_parser_skip_to_pragma_eol (parser);
21967 return false;
21970 if (context == pragma_stmt)
21972 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21973 "omp target exit data");
21974 c_parser_skip_to_pragma_eol (parser, false);
21975 return true;
21978 if (flag_openmp)
21979 omp_requires_mask
21980 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21982 tree clauses
21983 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21984 "#pragma omp target exit data");
21985 c_omp_adjust_map_clauses (clauses, false);
21986 int map_seen = 0;
21987 for (tree *pc = &clauses; *pc;)
21989 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21990 switch (OMP_CLAUSE_MAP_KIND (*pc))
21992 case GOMP_MAP_FROM:
21993 case GOMP_MAP_ALWAYS_FROM:
21994 case GOMP_MAP_RELEASE:
21995 case GOMP_MAP_DELETE:
21996 map_seen = 3;
21997 break;
21998 case GOMP_MAP_TOFROM:
21999 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
22000 map_seen = 3;
22001 break;
22002 case GOMP_MAP_ALWAYS_TOFROM:
22003 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
22004 map_seen = 3;
22005 break;
22006 case GOMP_MAP_FIRSTPRIVATE_POINTER:
22007 case GOMP_MAP_ALWAYS_POINTER:
22008 case GOMP_MAP_ATTACH_DETACH:
22009 break;
22010 default:
22011 map_seen |= 1;
22012 error_at (OMP_CLAUSE_LOCATION (*pc),
22013 "%<#pragma omp target exit data%> with map-type other "
22014 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
22015 "on %<map%> clause");
22016 *pc = OMP_CLAUSE_CHAIN (*pc);
22017 continue;
22019 pc = &OMP_CLAUSE_CHAIN (*pc);
22022 if (map_seen != 3)
22024 if (map_seen == 0)
22025 error_at (loc,
22026 "%<#pragma omp target exit data%> must contain at least one "
22027 "%<map%> clause");
22028 return true;
22031 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
22032 TREE_TYPE (stmt) = void_type_node;
22033 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
22034 SET_EXPR_LOCATION (stmt, loc);
22035 add_stmt (stmt);
22036 return true;
22039 /* OpenMP 4.0:
22040 # pragma omp target target-clause[optseq] new-line
22041 structured-block */
22043 #define OMP_TARGET_CLAUSE_MASK \
22044 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
22045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
22046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22047 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
22048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
22049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22051 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
22053 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
22054 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
22055 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
22056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
22058 static bool
22059 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
22061 location_t loc = c_parser_peek_token (parser)->location;
22062 c_parser_consume_pragma (parser);
22063 tree *pc = NULL, stmt, block;
22065 if (context != pragma_stmt && context != pragma_compound)
22067 c_parser_error (parser, "expected declaration specifiers");
22068 c_parser_skip_to_pragma_eol (parser);
22069 return false;
22072 if (flag_openmp)
22073 omp_requires_mask
22074 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
22076 if (c_parser_next_token_is (parser, CPP_NAME))
22078 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22079 enum tree_code ccode = ERROR_MARK;
22081 if (strcmp (p, "teams") == 0)
22082 ccode = OMP_TEAMS;
22083 else if (strcmp (p, "parallel") == 0)
22084 ccode = OMP_PARALLEL;
22085 else if (strcmp (p, "simd") == 0)
22086 ccode = OMP_SIMD;
22087 if (ccode != ERROR_MARK)
22089 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
22090 char p_name[sizeof ("#pragma omp target teams distribute "
22091 "parallel for simd")];
22093 c_parser_consume_token (parser);
22094 strcpy (p_name, "#pragma omp target");
22095 if (!flag_openmp) /* flag_openmp_simd */
22097 tree stmt;
22098 switch (ccode)
22100 case OMP_TEAMS:
22101 stmt = c_parser_omp_teams (loc, parser, p_name,
22102 OMP_TARGET_CLAUSE_MASK,
22103 cclauses, if_p);
22104 break;
22105 case OMP_PARALLEL:
22106 stmt = c_parser_omp_parallel (loc, parser, p_name,
22107 OMP_TARGET_CLAUSE_MASK,
22108 cclauses, if_p);
22109 break;
22110 case OMP_SIMD:
22111 stmt = c_parser_omp_simd (loc, parser, p_name,
22112 OMP_TARGET_CLAUSE_MASK,
22113 cclauses, if_p);
22114 break;
22115 default:
22116 gcc_unreachable ();
22118 return stmt != NULL_TREE;
22120 keep_next_level ();
22121 tree block = c_begin_compound_stmt (true), ret;
22122 switch (ccode)
22124 case OMP_TEAMS:
22125 ret = c_parser_omp_teams (loc, parser, p_name,
22126 OMP_TARGET_CLAUSE_MASK, cclauses,
22127 if_p);
22128 break;
22129 case OMP_PARALLEL:
22130 ret = c_parser_omp_parallel (loc, parser, p_name,
22131 OMP_TARGET_CLAUSE_MASK, cclauses,
22132 if_p);
22133 break;
22134 case OMP_SIMD:
22135 ret = c_parser_omp_simd (loc, parser, p_name,
22136 OMP_TARGET_CLAUSE_MASK, cclauses,
22137 if_p);
22138 break;
22139 default:
22140 gcc_unreachable ();
22142 block = c_end_compound_stmt (loc, block, true);
22143 if (ret == NULL_TREE)
22144 return false;
22145 if (ccode == OMP_TEAMS)
22146 /* For combined target teams, ensure the num_teams and
22147 thread_limit clause expressions are evaluated on the host,
22148 before entering the target construct. */
22149 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
22150 c; c = OMP_CLAUSE_CHAIN (c))
22151 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
22152 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
22153 for (int i = 0;
22154 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
22155 if (OMP_CLAUSE_OPERAND (c, i)
22156 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
22158 tree expr = OMP_CLAUSE_OPERAND (c, i);
22159 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
22160 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
22161 expr, NULL_TREE, NULL_TREE);
22162 add_stmt (expr);
22163 OMP_CLAUSE_OPERAND (c, i) = expr;
22164 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
22165 OMP_CLAUSE_FIRSTPRIVATE);
22166 OMP_CLAUSE_DECL (tc) = tmp;
22167 OMP_CLAUSE_CHAIN (tc)
22168 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
22169 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
22171 tree stmt = make_node (OMP_TARGET);
22172 TREE_TYPE (stmt) = void_type_node;
22173 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
22174 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
22175 OMP_TARGET_BODY (stmt) = block;
22176 OMP_TARGET_COMBINED (stmt) = 1;
22177 SET_EXPR_LOCATION (stmt, loc);
22178 add_stmt (stmt);
22179 pc = &OMP_TARGET_CLAUSES (stmt);
22180 goto check_clauses;
22182 else if (!flag_openmp) /* flag_openmp_simd */
22184 c_parser_skip_to_pragma_eol (parser, false);
22185 return false;
22187 else if (strcmp (p, "data") == 0)
22189 c_parser_consume_token (parser);
22190 c_parser_omp_target_data (loc, parser, if_p);
22191 return true;
22193 else if (strcmp (p, "enter") == 0)
22195 c_parser_consume_token (parser);
22196 return c_parser_omp_target_enter_data (loc, parser, context);
22198 else if (strcmp (p, "exit") == 0)
22200 c_parser_consume_token (parser);
22201 return c_parser_omp_target_exit_data (loc, parser, context);
22203 else if (strcmp (p, "update") == 0)
22205 c_parser_consume_token (parser);
22206 return c_parser_omp_target_update (loc, parser, context);
22209 if (!flag_openmp) /* flag_openmp_simd */
22211 c_parser_skip_to_pragma_eol (parser, false);
22212 return false;
22215 stmt = make_node (OMP_TARGET);
22216 TREE_TYPE (stmt) = void_type_node;
22218 OMP_TARGET_CLAUSES (stmt)
22219 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
22220 "#pragma omp target", false);
22221 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
22222 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
22224 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
22225 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
22226 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
22227 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
22228 OMP_CLAUSE_CHAIN (c) = nc;
22230 OMP_TARGET_CLAUSES (stmt)
22231 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
22232 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
22234 pc = &OMP_TARGET_CLAUSES (stmt);
22235 keep_next_level ();
22236 block = c_begin_compound_stmt (true);
22237 add_stmt (c_parser_omp_structured_block (parser, if_p));
22238 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
22240 SET_EXPR_LOCATION (stmt, loc);
22241 add_stmt (stmt);
22243 check_clauses:
22244 while (*pc)
22246 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
22247 switch (OMP_CLAUSE_MAP_KIND (*pc))
22249 case GOMP_MAP_TO:
22250 case GOMP_MAP_ALWAYS_TO:
22251 case GOMP_MAP_FROM:
22252 case GOMP_MAP_ALWAYS_FROM:
22253 case GOMP_MAP_TOFROM:
22254 case GOMP_MAP_ALWAYS_TOFROM:
22255 case GOMP_MAP_ALLOC:
22256 case GOMP_MAP_FIRSTPRIVATE_POINTER:
22257 case GOMP_MAP_ALWAYS_POINTER:
22258 case GOMP_MAP_ATTACH_DETACH:
22259 break;
22260 default:
22261 error_at (OMP_CLAUSE_LOCATION (*pc),
22262 "%<#pragma omp target%> with map-type other "
22263 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
22264 "on %<map%> clause");
22265 *pc = OMP_CLAUSE_CHAIN (*pc);
22266 continue;
22268 pc = &OMP_CLAUSE_CHAIN (*pc);
22270 cfun->has_omp_target = true;
22271 return true;
22274 /* OpenMP 4.0:
22275 # pragma omp declare simd declare-simd-clauses[optseq] new-line
22277 OpenMP 5.0:
22278 # pragma omp declare variant (identifier) match(context-selector) new-line
22281 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
22282 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
22283 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22284 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
22285 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
22286 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
22287 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
22289 static void
22290 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
22292 c_token *token = c_parser_peek_token (parser);
22293 gcc_assert (token->type == CPP_NAME);
22294 tree kind = token->value;
22295 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
22296 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
22298 auto_vec<c_token> clauses;
22299 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22301 c_token *token = c_parser_peek_token (parser);
22302 if (token->type == CPP_EOF)
22304 c_parser_skip_to_pragma_eol (parser);
22305 return;
22307 clauses.safe_push (*token);
22308 c_parser_consume_token (parser);
22310 clauses.safe_push (*c_parser_peek_token (parser));
22311 c_parser_skip_to_pragma_eol (parser);
22313 while (c_parser_next_token_is (parser, CPP_PRAGMA))
22315 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
22316 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
22317 || c_parser_peek_2nd_token (parser)->value != kind)
22319 error ("%<#pragma omp declare %s%> must be followed by "
22320 "function declaration or definition or another "
22321 "%<#pragma omp declare %s%>",
22322 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
22323 return;
22325 c_parser_consume_pragma (parser);
22326 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22328 c_token *token = c_parser_peek_token (parser);
22329 if (token->type == CPP_EOF)
22331 c_parser_skip_to_pragma_eol (parser);
22332 return;
22334 clauses.safe_push (*token);
22335 c_parser_consume_token (parser);
22337 clauses.safe_push (*c_parser_peek_token (parser));
22338 c_parser_skip_to_pragma_eol (parser);
22341 /* Make sure nothing tries to read past the end of the tokens. */
22342 c_token eof_token;
22343 memset (&eof_token, 0, sizeof (eof_token));
22344 eof_token.type = CPP_EOF;
22345 clauses.safe_push (eof_token);
22346 clauses.safe_push (eof_token);
22348 switch (context)
22350 case pragma_external:
22351 if (c_parser_next_token_is (parser, CPP_KEYWORD)
22352 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
22354 int ext = disable_extension_diagnostics ();
22356 c_parser_consume_token (parser);
22357 while (c_parser_next_token_is (parser, CPP_KEYWORD)
22358 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
22359 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
22360 NULL, &clauses);
22361 restore_extension_diagnostics (ext);
22363 else
22364 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
22365 NULL, &clauses);
22366 break;
22367 case pragma_struct:
22368 case pragma_param:
22369 case pragma_stmt:
22370 error ("%<#pragma omp declare %s%> must be followed by "
22371 "function declaration or definition",
22372 IDENTIFIER_POINTER (kind));
22373 break;
22374 case pragma_compound:
22375 if (c_parser_next_token_is (parser, CPP_KEYWORD)
22376 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
22378 int ext = disable_extension_diagnostics ();
22380 c_parser_consume_token (parser);
22381 while (c_parser_next_token_is (parser, CPP_KEYWORD)
22382 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
22383 if (c_parser_next_tokens_start_declaration (parser))
22385 c_parser_declaration_or_fndef (parser, true, true, true, true,
22386 true, NULL, &clauses);
22387 restore_extension_diagnostics (ext);
22388 break;
22390 restore_extension_diagnostics (ext);
22392 else if (c_parser_next_tokens_start_declaration (parser))
22394 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
22395 NULL, &clauses);
22396 break;
22398 error ("%<#pragma omp declare %s%> must be followed by "
22399 "function declaration or definition",
22400 IDENTIFIER_POINTER (kind));
22401 break;
22402 default:
22403 gcc_unreachable ();
22407 static const char *const omp_construct_selectors[] = {
22408 "simd", "target", "teams", "parallel", "for", NULL };
22409 static const char *const omp_device_selectors[] = {
22410 "kind", "isa", "arch", NULL };
22411 static const char *const omp_implementation_selectors[] = {
22412 "vendor", "extension", "atomic_default_mem_order", "unified_address",
22413 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
22414 static const char *const omp_user_selectors[] = {
22415 "condition", NULL };
22417 /* OpenMP 5.0:
22419 trait-selector:
22420 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
22422 trait-score:
22423 score(score-expression) */
22425 static tree
22426 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
22428 tree ret = NULL_TREE;
22431 tree selector;
22432 if (c_parser_next_token_is (parser, CPP_KEYWORD)
22433 || c_parser_next_token_is (parser, CPP_NAME))
22434 selector = c_parser_peek_token (parser)->value;
22435 else
22437 c_parser_error (parser, "expected trait selector name");
22438 return error_mark_node;
22441 tree properties = NULL_TREE;
22442 const char *const *selectors = NULL;
22443 bool allow_score = true;
22444 bool allow_user = false;
22445 int property_limit = 0;
22446 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
22447 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
22448 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
22449 switch (IDENTIFIER_POINTER (set)[0])
22451 case 'c': /* construct */
22452 selectors = omp_construct_selectors;
22453 allow_score = false;
22454 property_limit = 1;
22455 property_kind = CTX_PROPERTY_SIMD;
22456 break;
22457 case 'd': /* device */
22458 selectors = omp_device_selectors;
22459 allow_score = false;
22460 allow_user = true;
22461 property_limit = 3;
22462 property_kind = CTX_PROPERTY_NAME_LIST;
22463 break;
22464 case 'i': /* implementation */
22465 selectors = omp_implementation_selectors;
22466 allow_user = true;
22467 property_limit = 3;
22468 property_kind = CTX_PROPERTY_NAME_LIST;
22469 break;
22470 case 'u': /* user */
22471 selectors = omp_user_selectors;
22472 property_limit = 1;
22473 property_kind = CTX_PROPERTY_EXPR;
22474 break;
22475 default:
22476 gcc_unreachable ();
22478 for (int i = 0; ; i++)
22480 if (selectors[i] == NULL)
22482 if (allow_user)
22484 property_kind = CTX_PROPERTY_USER;
22485 break;
22487 else
22489 error_at (c_parser_peek_token (parser)->location,
22490 "selector %qs not allowed for context selector "
22491 "set %qs", IDENTIFIER_POINTER (selector),
22492 IDENTIFIER_POINTER (set));
22493 c_parser_consume_token (parser);
22494 return error_mark_node;
22497 if (i == property_limit)
22498 property_kind = CTX_PROPERTY_NONE;
22499 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
22500 break;
22502 if (property_kind == CTX_PROPERTY_NAME_LIST
22503 && IDENTIFIER_POINTER (set)[0] == 'i'
22504 && strcmp (IDENTIFIER_POINTER (selector),
22505 "atomic_default_mem_order") == 0)
22506 property_kind = CTX_PROPERTY_ID;
22508 c_parser_consume_token (parser);
22510 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22512 if (property_kind == CTX_PROPERTY_NONE)
22514 error_at (c_parser_peek_token (parser)->location,
22515 "selector %qs does not accept any properties",
22516 IDENTIFIER_POINTER (selector));
22517 return error_mark_node;
22520 matching_parens parens;
22521 parens.require_open (parser);
22523 c_token *token = c_parser_peek_token (parser);
22524 if (allow_score
22525 && c_parser_next_token_is (parser, CPP_NAME)
22526 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
22527 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
22529 c_parser_consume_token (parser);
22531 matching_parens parens2;
22532 parens2.require_open (parser);
22533 tree score = c_parser_expr_no_commas (parser, NULL).value;
22534 parens2.skip_until_found_close (parser);
22535 c_parser_require (parser, CPP_COLON, "expected %<:%>");
22536 if (score != error_mark_node)
22538 mark_exp_read (score);
22539 score = c_fully_fold (score, false, NULL);
22540 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
22541 || TREE_CODE (score) != INTEGER_CST)
22542 error_at (token->location, "score argument must be "
22543 "constant integer expression");
22544 else if (tree_int_cst_sgn (score) < 0)
22545 error_at (token->location, "score argument must be "
22546 "non-negative");
22547 else
22548 properties = tree_cons (get_identifier (" score"),
22549 score, properties);
22551 token = c_parser_peek_token (parser);
22554 switch (property_kind)
22556 tree t;
22557 case CTX_PROPERTY_USER:
22560 t = c_parser_expr_no_commas (parser, NULL).value;
22561 if (TREE_CODE (t) == STRING_CST)
22562 properties = tree_cons (NULL_TREE, t, properties);
22563 else if (t != error_mark_node)
22565 mark_exp_read (t);
22566 t = c_fully_fold (t, false, NULL);
22567 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
22568 || !tree_fits_shwi_p (t))
22569 error_at (token->location, "property must be "
22570 "constant integer expression or string "
22571 "literal");
22572 else
22573 properties = tree_cons (NULL_TREE, t, properties);
22575 else
22576 return error_mark_node;
22578 if (c_parser_next_token_is (parser, CPP_COMMA))
22579 c_parser_consume_token (parser);
22580 else
22581 break;
22583 while (1);
22584 break;
22585 case CTX_PROPERTY_ID:
22586 if (c_parser_next_token_is (parser, CPP_KEYWORD)
22587 || c_parser_next_token_is (parser, CPP_NAME))
22589 tree prop = c_parser_peek_token (parser)->value;
22590 c_parser_consume_token (parser);
22591 properties = tree_cons (prop, NULL_TREE, properties);
22593 else
22595 c_parser_error (parser, "expected identifier");
22596 return error_mark_node;
22598 break;
22599 case CTX_PROPERTY_NAME_LIST:
22602 tree prop = NULL_TREE, value = NULL_TREE;
22603 if (c_parser_next_token_is (parser, CPP_KEYWORD)
22604 || c_parser_next_token_is (parser, CPP_NAME))
22606 prop = c_parser_peek_token (parser)->value;
22607 c_parser_consume_token (parser);
22609 else if (c_parser_next_token_is (parser, CPP_STRING))
22610 value = c_parser_string_literal (parser, false,
22611 false).value;
22612 else
22614 c_parser_error (parser, "expected identifier or "
22615 "string literal");
22616 return error_mark_node;
22619 properties = tree_cons (prop, value, properties);
22621 if (c_parser_next_token_is (parser, CPP_COMMA))
22622 c_parser_consume_token (parser);
22623 else
22624 break;
22626 while (1);
22627 break;
22628 case CTX_PROPERTY_EXPR:
22629 t = c_parser_expr_no_commas (parser, NULL).value;
22630 if (t != error_mark_node)
22632 mark_exp_read (t);
22633 t = c_fully_fold (t, false, NULL);
22634 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
22635 || !tree_fits_shwi_p (t))
22636 error_at (token->location, "property must be "
22637 "constant integer expression");
22638 else
22639 properties = tree_cons (NULL_TREE, t, properties);
22641 else
22642 return error_mark_node;
22643 break;
22644 case CTX_PROPERTY_SIMD:
22645 if (parms == NULL_TREE)
22647 error_at (token->location, "properties for %<simd%> "
22648 "selector may not be specified in "
22649 "%<metadirective%>");
22650 return error_mark_node;
22652 tree c;
22653 c = c_parser_omp_all_clauses (parser,
22654 OMP_DECLARE_SIMD_CLAUSE_MASK,
22655 "simd", true, 2);
22656 c = c_omp_declare_simd_clauses_to_numbers (parms
22657 == error_mark_node
22658 ? NULL_TREE : parms,
22660 properties = c;
22661 break;
22662 default:
22663 gcc_unreachable ();
22666 parens.skip_until_found_close (parser);
22667 properties = nreverse (properties);
22669 else if (property_kind == CTX_PROPERTY_NAME_LIST
22670 || property_kind == CTX_PROPERTY_ID
22671 || property_kind == CTX_PROPERTY_EXPR)
22673 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
22674 return error_mark_node;
22677 ret = tree_cons (selector, properties, ret);
22679 if (c_parser_next_token_is (parser, CPP_COMMA))
22680 c_parser_consume_token (parser);
22681 else
22682 break;
22684 while (1);
22686 return nreverse (ret);
22689 /* OpenMP 5.0:
22691 trait-set-selector[,trait-set-selector[,...]]
22693 trait-set-selector:
22694 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
22696 trait-set-selector-name:
22697 constructor
22698 device
22699 implementation
22700 user */
22702 static tree
22703 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
22705 tree ret = NULL_TREE;
22708 const char *setp = "";
22709 if (c_parser_next_token_is (parser, CPP_NAME))
22710 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22711 switch (setp[0])
22713 case 'c':
22714 if (strcmp (setp, "construct") == 0)
22715 setp = NULL;
22716 break;
22717 case 'd':
22718 if (strcmp (setp, "device") == 0)
22719 setp = NULL;
22720 break;
22721 case 'i':
22722 if (strcmp (setp, "implementation") == 0)
22723 setp = NULL;
22724 break;
22725 case 'u':
22726 if (strcmp (setp, "user") == 0)
22727 setp = NULL;
22728 break;
22729 default:
22730 break;
22732 if (setp)
22734 c_parser_error (parser, "expected %<construct%>, %<device%>, "
22735 "%<implementation%> or %<user%>");
22736 return error_mark_node;
22739 tree set = c_parser_peek_token (parser)->value;
22740 c_parser_consume_token (parser);
22742 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22743 return error_mark_node;
22745 matching_braces braces;
22746 if (!braces.require_open (parser))
22747 return error_mark_node;
22749 tree selectors = c_parser_omp_context_selector (parser, set, parms);
22750 if (selectors == error_mark_node)
22751 ret = error_mark_node;
22752 else if (ret != error_mark_node)
22753 ret = tree_cons (set, selectors, ret);
22755 braces.skip_until_found_close (parser);
22757 if (c_parser_next_token_is (parser, CPP_COMMA))
22758 c_parser_consume_token (parser);
22759 else
22760 break;
22762 while (1);
22764 if (ret == error_mark_node)
22765 return ret;
22766 return nreverse (ret);
22769 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
22770 that into "omp declare variant base" attribute. */
22772 static void
22773 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
22775 matching_parens parens;
22776 if (!parens.require_open (parser))
22778 fail:
22779 c_parser_skip_to_pragma_eol (parser, false);
22780 return;
22783 if (c_parser_next_token_is_not (parser, CPP_NAME)
22784 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22786 c_parser_error (parser, "expected identifier");
22787 goto fail;
22790 c_token *token = c_parser_peek_token (parser);
22791 tree variant = lookup_name (token->value);
22793 if (variant == NULL_TREE)
22795 undeclared_variable (token->location, token->value);
22796 variant = error_mark_node;
22799 c_parser_consume_token (parser);
22801 parens.require_close (parser);
22803 if (c_parser_next_token_is (parser, CPP_COMMA)
22804 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22805 c_parser_consume_token (parser);
22807 const char *clause = "";
22808 location_t match_loc = c_parser_peek_token (parser)->location;
22809 if (c_parser_next_token_is (parser, CPP_NAME))
22810 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22811 if (strcmp (clause, "match"))
22813 c_parser_error (parser, "expected %<match%>");
22814 goto fail;
22817 c_parser_consume_token (parser);
22819 if (!parens.require_open (parser))
22820 goto fail;
22822 if (parms == NULL_TREE)
22823 parms = error_mark_node;
22825 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
22826 if (ctx == error_mark_node)
22827 goto fail;
22828 ctx = omp_check_context_selector (match_loc, ctx);
22829 if (ctx != error_mark_node && variant != error_mark_node)
22831 if (TREE_CODE (variant) != FUNCTION_DECL)
22833 error_at (token->location, "variant %qD is not a function", variant);
22834 variant = error_mark_node;
22836 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
22837 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
22839 error_at (token->location, "variant %qD and base %qD have "
22840 "incompatible types", variant, fndecl);
22841 variant = error_mark_node;
22843 else if (fndecl_built_in_p (variant)
22844 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22845 "__builtin_", strlen ("__builtin_")) == 0
22846 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22847 "__sync_", strlen ("__sync_")) == 0
22848 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22849 "__atomic_", strlen ("__atomic_")) == 0))
22851 error_at (token->location, "variant %qD is a built-in", variant);
22852 variant = error_mark_node;
22854 if (variant != error_mark_node)
22856 C_DECL_USED (variant) = 1;
22857 tree construct = omp_get_context_selector (ctx, "construct", NULL);
22858 omp_mark_declare_variant (match_loc, variant, construct);
22859 if (omp_context_selector_matches (ctx))
22861 tree attr
22862 = tree_cons (get_identifier ("omp declare variant base"),
22863 build_tree_list (variant, ctx),
22864 DECL_ATTRIBUTES (fndecl));
22865 DECL_ATTRIBUTES (fndecl) = attr;
22870 parens.require_close (parser);
22871 c_parser_skip_to_pragma_eol (parser);
22874 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22875 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22876 or "omp declare variant base" attribute. */
22878 static void
22879 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
22880 vec<c_token> *pclauses)
22882 vec<c_token> &clauses = *pclauses;
22884 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22885 indicates error has been reported and CPP_PRAGMA that
22886 c_finish_omp_declare_simd has already processed the tokens. */
22887 if (clauses.exists () && clauses[0].type == CPP_EOF)
22888 return;
22889 const char *kind = "simd";
22890 if (clauses.exists ()
22891 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
22892 kind = IDENTIFIER_POINTER (clauses[0].value);
22893 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
22894 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
22896 error ("%<#pragma omp declare %s%> not immediately followed by "
22897 "a function declaration or definition", kind);
22898 clauses[0].type = CPP_EOF;
22899 return;
22901 if (clauses.exists () && clauses[0].type != CPP_NAME)
22903 error_at (DECL_SOURCE_LOCATION (fndecl),
22904 "%<#pragma omp declare %s%> not immediately followed by "
22905 "a single function declaration or definition", kind);
22906 clauses[0].type = CPP_EOF;
22907 return;
22910 if (parms == NULL_TREE)
22911 parms = DECL_ARGUMENTS (fndecl);
22913 unsigned int tokens_avail = parser->tokens_avail;
22914 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22916 parser->tokens = clauses.address ();
22917 parser->tokens_avail = clauses.length ();
22919 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22920 while (parser->tokens_avail > 3)
22922 c_token *token = c_parser_peek_token (parser);
22923 gcc_assert (token->type == CPP_NAME
22924 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
22925 c_parser_consume_token (parser);
22926 parser->in_pragma = true;
22928 if (strcmp (kind, "simd") == 0)
22930 tree c;
22931 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
22932 "#pragma omp declare simd");
22933 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
22934 if (c != NULL_TREE)
22935 c = tree_cons (NULL_TREE, c, NULL_TREE);
22936 c = build_tree_list (get_identifier ("omp declare simd"), c);
22937 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
22938 DECL_ATTRIBUTES (fndecl) = c;
22940 else
22942 gcc_assert (strcmp (kind, "variant") == 0);
22943 c_finish_omp_declare_variant (parser, fndecl, parms);
22947 parser->tokens = &parser->tokens_buf[0];
22948 parser->tokens_avail = tokens_avail;
22949 if (clauses.exists ())
22950 clauses[0].type = CPP_PRAGMA;
22954 /* OpenMP 4.0:
22955 # pragma omp declare target new-line
22956 declarations and definitions
22957 # pragma omp end declare target new-line
22959 OpenMP 4.5:
22960 # pragma omp declare target ( extended-list ) new-line
22962 # pragma omp declare target declare-target-clauses[seq] new-line */
22964 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22965 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22966 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22967 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22968 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22970 static void
22971 c_parser_omp_declare_target (c_parser *parser)
22973 tree clauses = NULL_TREE;
22974 int device_type = 0;
22975 bool only_device_type = true;
22976 if (c_parser_next_token_is (parser, CPP_NAME)
22977 || (c_parser_next_token_is (parser, CPP_COMMA)
22978 && c_parser_peek_2nd_token (parser)->type == CPP_NAME))
22979 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
22980 "#pragma omp declare target");
22981 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22983 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
22984 clauses);
22985 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22986 c_parser_skip_to_pragma_eol (parser);
22988 else
22990 c_parser_skip_to_pragma_eol (parser);
22991 c_omp_declare_target_attr attr = { -1 };
22992 vec_safe_push (current_omp_declare_target_attribute, attr);
22993 return;
22995 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22996 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22997 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22998 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
23000 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
23001 continue;
23002 tree t = OMP_CLAUSE_DECL (c), id;
23003 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
23004 tree at2 = lookup_attribute ("omp declare target link",
23005 DECL_ATTRIBUTES (t));
23006 only_device_type = false;
23007 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
23009 id = get_identifier ("omp declare target link");
23010 std::swap (at1, at2);
23012 else
23013 id = get_identifier ("omp declare target");
23014 if (at2)
23016 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
23017 error_at (OMP_CLAUSE_LOCATION (c),
23018 "%qD specified both in declare target %<link%> and %qs"
23019 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
23020 else
23021 error_at (OMP_CLAUSE_LOCATION (c),
23022 "%qD specified both in declare target %<link%> and "
23023 "%<to%> or %<enter%> clauses", t);
23024 continue;
23026 if (!at1)
23028 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
23029 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
23030 continue;
23032 symtab_node *node = symtab_node::get (t);
23033 if (node != NULL)
23035 node->offloadable = 1;
23036 if (ENABLE_OFFLOADING)
23038 g->have_offload = true;
23039 if (is_a <varpool_node *> (node))
23040 vec_safe_push (offload_vars, t);
23044 if (TREE_CODE (t) != FUNCTION_DECL)
23045 continue;
23046 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
23048 tree at3 = lookup_attribute ("omp declare target host",
23049 DECL_ATTRIBUTES (t));
23050 if (at3 == NULL_TREE)
23052 id = get_identifier ("omp declare target host");
23053 DECL_ATTRIBUTES (t)
23054 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
23057 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
23059 tree at3 = lookup_attribute ("omp declare target nohost",
23060 DECL_ATTRIBUTES (t));
23061 if (at3 == NULL_TREE)
23063 id = get_identifier ("omp declare target nohost");
23064 DECL_ATTRIBUTES (t)
23065 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
23069 if (device_type && only_device_type)
23070 error_at (OMP_CLAUSE_LOCATION (clauses),
23071 "directive with only %<device_type%> clause");
23074 /* OpenMP 5.1
23075 #pragma omp begin assumes clauses[optseq] new-line
23077 #pragma omp begin declare target clauses[optseq] new-line */
23079 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
23080 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)
23082 static void
23083 c_parser_omp_begin (c_parser *parser)
23085 const char *p = "";
23086 c_parser_consume_pragma (parser);
23087 if (c_parser_next_token_is (parser, CPP_NAME))
23088 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23089 if (strcmp (p, "declare") == 0)
23091 c_parser_consume_token (parser);
23092 p = "";
23093 if (c_parser_next_token_is (parser, CPP_NAME))
23094 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23095 if (strcmp (p, "target") == 0)
23097 c_parser_consume_token (parser);
23098 tree clauses
23099 = c_parser_omp_all_clauses (parser,
23100 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
23101 "#pragma omp begin declare target");
23102 int device_type = 0;
23103 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
23104 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
23105 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
23106 c_omp_declare_target_attr attr = { device_type };
23107 vec_safe_push (current_omp_declare_target_attribute, attr);
23109 else
23111 c_parser_error (parser, "expected %<target%>");
23112 c_parser_skip_to_pragma_eol (parser);
23115 else if (strcmp (p, "assumes") == 0)
23117 c_parser_consume_token (parser);
23118 c_parser_omp_assumption_clauses (parser, false);
23119 current_omp_begin_assumes++;
23121 else
23123 c_parser_error (parser, "expected %<declare target%> or %<assumes%>");
23124 c_parser_skip_to_pragma_eol (parser);
23128 /* OpenMP 4.0
23129 #pragma omp end declare target
23131 OpenMP 5.1
23132 #pragma omp end assumes */
23134 static void
23135 c_parser_omp_end (c_parser *parser)
23137 location_t loc = c_parser_peek_token (parser)->location;
23138 const char *p = "";
23139 c_parser_consume_pragma (parser);
23140 if (c_parser_next_token_is (parser, CPP_NAME))
23141 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23142 if (strcmp (p, "declare") == 0)
23144 c_parser_consume_token (parser);
23145 if (c_parser_next_token_is (parser, CPP_NAME)
23146 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
23147 "target") == 0)
23148 c_parser_consume_token (parser);
23149 else
23151 c_parser_error (parser, "expected %<target%>");
23152 c_parser_skip_to_pragma_eol (parser);
23153 return;
23155 c_parser_skip_to_pragma_eol (parser);
23156 if (!vec_safe_length (current_omp_declare_target_attribute))
23157 error_at (loc, "%<#pragma omp end declare target%> without "
23158 "corresponding %<#pragma omp declare target%> or "
23159 "%<#pragma omp begin declare target%>");
23160 else
23161 current_omp_declare_target_attribute->pop ();
23163 else if (strcmp (p, "assumes") == 0)
23165 c_parser_consume_token (parser);
23166 c_parser_skip_to_pragma_eol (parser);
23167 if (!current_omp_begin_assumes)
23168 error_at (loc, "%qs without corresponding %qs",
23169 "#pragma omp end assumes", "#pragma omp begin assumes");
23170 else
23171 current_omp_begin_assumes--;
23173 else
23175 c_parser_error (parser, "expected %<declare%> or %<assumes%>");
23176 c_parser_skip_to_pragma_eol (parser);
23180 /* OpenMP 4.0
23181 #pragma omp declare reduction (reduction-id : typename-list : expression) \
23182 initializer-clause[opt] new-line
23184 initializer-clause:
23185 initializer (omp_priv = initializer)
23186 initializer (function-name (argument-list)) */
23188 static void
23189 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
23191 unsigned int tokens_avail = 0, i;
23192 vec<tree> types = vNULL;
23193 vec<c_token> clauses = vNULL;
23194 enum tree_code reduc_code = ERROR_MARK;
23195 tree reduc_id = NULL_TREE;
23196 tree type;
23197 location_t rloc = c_parser_peek_token (parser)->location;
23199 if (context == pragma_struct || context == pragma_param)
23201 error ("%<#pragma omp declare reduction%> not at file or block scope");
23202 goto fail;
23205 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
23206 goto fail;
23208 switch (c_parser_peek_token (parser)->type)
23210 case CPP_PLUS:
23211 reduc_code = PLUS_EXPR;
23212 break;
23213 case CPP_MULT:
23214 reduc_code = MULT_EXPR;
23215 break;
23216 case CPP_MINUS:
23217 reduc_code = MINUS_EXPR;
23218 break;
23219 case CPP_AND:
23220 reduc_code = BIT_AND_EXPR;
23221 break;
23222 case CPP_XOR:
23223 reduc_code = BIT_XOR_EXPR;
23224 break;
23225 case CPP_OR:
23226 reduc_code = BIT_IOR_EXPR;
23227 break;
23228 case CPP_AND_AND:
23229 reduc_code = TRUTH_ANDIF_EXPR;
23230 break;
23231 case CPP_OR_OR:
23232 reduc_code = TRUTH_ORIF_EXPR;
23233 break;
23234 case CPP_NAME:
23235 const char *p;
23236 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23237 if (strcmp (p, "min") == 0)
23239 reduc_code = MIN_EXPR;
23240 break;
23242 if (strcmp (p, "max") == 0)
23244 reduc_code = MAX_EXPR;
23245 break;
23247 reduc_id = c_parser_peek_token (parser)->value;
23248 break;
23249 default:
23250 c_parser_error (parser,
23251 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
23252 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
23253 goto fail;
23256 tree orig_reduc_id, reduc_decl;
23257 orig_reduc_id = reduc_id;
23258 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
23259 reduc_decl = c_omp_reduction_decl (reduc_id);
23260 c_parser_consume_token (parser);
23262 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
23263 goto fail;
23265 while (true)
23267 location_t loc = c_parser_peek_token (parser)->location;
23268 struct c_type_name *ctype = c_parser_type_name (parser);
23269 if (ctype != NULL)
23271 type = groktypename (ctype, NULL, NULL);
23272 if (type == error_mark_node)
23274 else if ((INTEGRAL_TYPE_P (type)
23275 || TREE_CODE (type) == REAL_TYPE
23276 || TREE_CODE (type) == COMPLEX_TYPE)
23277 && orig_reduc_id == NULL_TREE)
23278 error_at (loc, "predeclared arithmetic type in "
23279 "%<#pragma omp declare reduction%>");
23280 else if (TREE_CODE (type) == FUNCTION_TYPE
23281 || TREE_CODE (type) == ARRAY_TYPE)
23282 error_at (loc, "function or array type in "
23283 "%<#pragma omp declare reduction%>");
23284 else if (TYPE_ATOMIC (type))
23285 error_at (loc, "%<_Atomic%> qualified type in "
23286 "%<#pragma omp declare reduction%>");
23287 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
23288 error_at (loc, "const, volatile or restrict qualified type in "
23289 "%<#pragma omp declare reduction%>");
23290 else
23292 tree t;
23293 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
23294 if (comptypes (TREE_PURPOSE (t), type))
23296 error_at (loc, "redeclaration of %qs "
23297 "%<#pragma omp declare reduction%> for "
23298 "type %qT",
23299 IDENTIFIER_POINTER (reduc_id)
23300 + sizeof ("omp declare reduction ") - 1,
23301 type);
23302 location_t ploc
23303 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
23304 0));
23305 error_at (ploc, "previous %<#pragma omp declare "
23306 "reduction%>");
23307 break;
23309 if (t == NULL_TREE)
23310 types.safe_push (type);
23312 if (c_parser_next_token_is (parser, CPP_COMMA))
23313 c_parser_consume_token (parser);
23314 else
23315 break;
23317 else
23318 break;
23321 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
23322 || types.is_empty ())
23324 fail:
23325 clauses.release ();
23326 types.release ();
23327 while (true)
23329 c_token *token = c_parser_peek_token (parser);
23330 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
23331 break;
23332 c_parser_consume_token (parser);
23334 c_parser_skip_to_pragma_eol (parser);
23335 return;
23338 if (types.length () > 1)
23340 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23342 c_token *token = c_parser_peek_token (parser);
23343 if (token->type == CPP_EOF)
23344 goto fail;
23345 clauses.safe_push (*token);
23346 c_parser_consume_token (parser);
23348 clauses.safe_push (*c_parser_peek_token (parser));
23349 c_parser_skip_to_pragma_eol (parser);
23351 /* Make sure nothing tries to read past the end of the tokens. */
23352 c_token eof_token;
23353 memset (&eof_token, 0, sizeof (eof_token));
23354 eof_token.type = CPP_EOF;
23355 clauses.safe_push (eof_token);
23356 clauses.safe_push (eof_token);
23359 int errs = errorcount;
23360 FOR_EACH_VEC_ELT (types, i, type)
23362 tokens_avail = parser->tokens_avail;
23363 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
23364 if (!clauses.is_empty ())
23366 parser->tokens = clauses.address ();
23367 parser->tokens_avail = clauses.length ();
23368 parser->in_pragma = true;
23371 bool nested = current_function_decl != NULL_TREE;
23372 if (nested)
23373 c_push_function_context ();
23374 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
23375 reduc_id, default_function_type);
23376 current_function_decl = fndecl;
23377 allocate_struct_function (fndecl, true);
23378 push_scope ();
23379 tree stmt = push_stmt_list ();
23380 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
23381 warn about these. */
23382 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
23383 get_identifier ("omp_out"), type);
23384 DECL_ARTIFICIAL (omp_out) = 1;
23385 DECL_CONTEXT (omp_out) = fndecl;
23386 pushdecl (omp_out);
23387 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
23388 get_identifier ("omp_in"), type);
23389 DECL_ARTIFICIAL (omp_in) = 1;
23390 DECL_CONTEXT (omp_in) = fndecl;
23391 pushdecl (omp_in);
23392 struct c_expr combiner = c_parser_expression (parser);
23393 struct c_expr initializer;
23394 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
23395 bool bad = false;
23396 initializer.set_error ();
23397 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
23398 bad = true;
23399 else if (c_parser_next_token_is (parser, CPP_COMMA)
23400 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23401 c_parser_consume_token (parser);
23402 if (!bad
23403 && (c_parser_next_token_is (parser, CPP_NAME)
23404 && strcmp (IDENTIFIER_POINTER
23405 (c_parser_peek_token (parser)->value),
23406 "initializer") == 0))
23408 c_parser_consume_token (parser);
23409 pop_scope ();
23410 push_scope ();
23411 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
23412 get_identifier ("omp_priv"), type);
23413 DECL_ARTIFICIAL (omp_priv) = 1;
23414 DECL_INITIAL (omp_priv) = error_mark_node;
23415 DECL_CONTEXT (omp_priv) = fndecl;
23416 pushdecl (omp_priv);
23417 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
23418 get_identifier ("omp_orig"), type);
23419 DECL_ARTIFICIAL (omp_orig) = 1;
23420 DECL_CONTEXT (omp_orig) = fndecl;
23421 pushdecl (omp_orig);
23422 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
23423 bad = true;
23424 else if (!c_parser_next_token_is (parser, CPP_NAME))
23426 c_parser_error (parser, "expected %<omp_priv%> or "
23427 "function-name");
23428 bad = true;
23430 else if (strcmp (IDENTIFIER_POINTER
23431 (c_parser_peek_token (parser)->value),
23432 "omp_priv") != 0)
23434 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
23435 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
23437 c_parser_error (parser, "expected function-name %<(%>");
23438 bad = true;
23440 else
23441 initializer = c_parser_postfix_expression (parser);
23442 if (initializer.value
23443 && TREE_CODE (initializer.value) == CALL_EXPR)
23445 int j;
23446 tree c = initializer.value;
23447 for (j = 0; j < call_expr_nargs (c); j++)
23449 tree a = CALL_EXPR_ARG (c, j);
23450 STRIP_NOPS (a);
23451 if (TREE_CODE (a) == ADDR_EXPR
23452 && TREE_OPERAND (a, 0) == omp_priv)
23453 break;
23455 if (j == call_expr_nargs (c))
23456 error ("one of the initializer call arguments should be "
23457 "%<&omp_priv%>");
23460 else
23462 c_parser_consume_token (parser);
23463 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
23464 bad = true;
23465 else
23467 tree st = push_stmt_list ();
23468 location_t loc = c_parser_peek_token (parser)->location;
23469 rich_location richloc (line_table, loc);
23470 start_init (omp_priv, NULL_TREE, false, false, &richloc);
23471 struct c_expr init = c_parser_initializer (parser, omp_priv);
23472 finish_init ();
23473 finish_decl (omp_priv, loc, init.value,
23474 init.original_type, NULL_TREE);
23475 pop_stmt_list (st);
23478 if (!bad
23479 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
23480 bad = true;
23483 if (!bad)
23485 c_parser_skip_to_pragma_eol (parser);
23487 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
23488 DECL_INITIAL (reduc_decl));
23489 DECL_INITIAL (reduc_decl) = t;
23490 DECL_SOURCE_LOCATION (omp_out) = rloc;
23491 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
23492 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
23493 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
23494 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
23495 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
23496 if (omp_priv)
23498 DECL_SOURCE_LOCATION (omp_priv) = rloc;
23499 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
23500 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
23501 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
23502 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
23503 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
23504 walk_tree (&DECL_INITIAL (omp_priv),
23505 c_check_omp_declare_reduction_r,
23506 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
23510 pop_stmt_list (stmt);
23511 pop_scope ();
23512 if (cfun->language != NULL)
23514 ggc_free (cfun->language);
23515 cfun->language = NULL;
23517 set_cfun (NULL);
23518 current_function_decl = NULL_TREE;
23519 if (nested)
23520 c_pop_function_context ();
23522 if (!clauses.is_empty ())
23524 parser->tokens = &parser->tokens_buf[0];
23525 parser->tokens_avail = tokens_avail;
23527 if (bad)
23528 goto fail;
23529 if (errs != errorcount)
23530 break;
23533 clauses.release ();
23534 types.release ();
23538 /* OpenMP 4.0
23539 #pragma omp declare simd declare-simd-clauses[optseq] new-line
23540 #pragma omp declare reduction (reduction-id : typename-list : expression) \
23541 initializer-clause[opt] new-line
23542 #pragma omp declare target new-line
23544 OpenMP 5.0
23545 #pragma omp declare variant (identifier) match (context-selector) */
23547 static bool
23548 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
23550 c_parser_consume_pragma (parser);
23551 if (c_parser_next_token_is (parser, CPP_NAME))
23553 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23554 if (strcmp (p, "simd") == 0)
23556 /* c_parser_consume_token (parser); done in
23557 c_parser_omp_declare_simd. */
23558 c_parser_omp_declare_simd (parser, context);
23559 return true;
23561 if (strcmp (p, "reduction") == 0)
23563 c_parser_consume_token (parser);
23564 c_parser_omp_declare_reduction (parser, context);
23565 return false;
23567 if (!flag_openmp) /* flag_openmp_simd */
23569 c_parser_skip_to_pragma_eol (parser, false);
23570 return false;
23572 if (strcmp (p, "target") == 0)
23574 c_parser_consume_token (parser);
23575 c_parser_omp_declare_target (parser);
23576 return false;
23578 if (strcmp (p, "variant") == 0)
23580 /* c_parser_consume_token (parser); done in
23581 c_parser_omp_declare_simd. */
23582 c_parser_omp_declare_simd (parser, context);
23583 return true;
23587 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
23588 "%<target%> or %<variant%>");
23589 c_parser_skip_to_pragma_eol (parser);
23590 return false;
23593 /* OpenMP 5.0
23594 #pragma omp requires clauses[optseq] new-line */
23596 static void
23597 c_parser_omp_requires (c_parser *parser)
23599 enum omp_requires new_req = (enum omp_requires) 0;
23601 c_parser_consume_pragma (parser);
23603 location_t loc = c_parser_peek_token (parser)->location;
23604 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23606 if (c_parser_next_token_is (parser, CPP_COMMA)
23607 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23608 c_parser_consume_token (parser);
23610 if (c_parser_next_token_is (parser, CPP_NAME))
23612 const char *p
23613 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23614 location_t cloc = c_parser_peek_token (parser)->location;
23615 enum omp_requires this_req = (enum omp_requires) 0;
23617 if (!strcmp (p, "unified_address"))
23618 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
23619 else if (!strcmp (p, "unified_shared_memory"))
23620 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
23621 else if (!strcmp (p, "dynamic_allocators"))
23622 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
23623 else if (!strcmp (p, "reverse_offload"))
23624 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
23625 else if (!strcmp (p, "atomic_default_mem_order"))
23627 c_parser_consume_token (parser);
23629 matching_parens parens;
23630 if (parens.require_open (parser))
23632 if (c_parser_next_token_is (parser, CPP_NAME))
23634 tree v = c_parser_peek_token (parser)->value;
23635 p = IDENTIFIER_POINTER (v);
23637 if (!strcmp (p, "seq_cst"))
23638 this_req
23639 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
23640 else if (!strcmp (p, "relaxed"))
23641 this_req
23642 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
23643 else if (!strcmp (p, "acq_rel"))
23644 this_req
23645 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
23647 if (this_req == 0)
23649 error_at (c_parser_peek_token (parser)->location,
23650 "expected %<seq_cst%>, %<relaxed%> or "
23651 "%<acq_rel%>");
23652 switch (c_parser_peek_token (parser)->type)
23654 case CPP_EOF:
23655 case CPP_PRAGMA_EOL:
23656 case CPP_CLOSE_PAREN:
23657 break;
23658 default:
23659 if (c_parser_peek_2nd_token (parser)->type
23660 == CPP_CLOSE_PAREN)
23661 c_parser_consume_token (parser);
23662 break;
23665 else
23666 c_parser_consume_token (parser);
23668 parens.skip_until_found_close (parser);
23669 if (this_req == 0)
23671 c_parser_skip_to_pragma_eol (parser, false);
23672 return;
23675 p = NULL;
23677 else
23679 error_at (cloc, "expected %<unified_address%>, "
23680 "%<unified_shared_memory%>, "
23681 "%<dynamic_allocators%>, "
23682 "%<reverse_offload%> "
23683 "or %<atomic_default_mem_order%> clause");
23684 c_parser_skip_to_pragma_eol (parser, false);
23685 return;
23687 if (p)
23688 c_parser_consume_token (parser);
23689 if (this_req)
23691 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
23693 if ((this_req & new_req) != 0)
23694 error_at (cloc, "too many %qs clauses", p);
23695 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
23696 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
23697 error_at (cloc, "%qs clause used lexically after first "
23698 "target construct or offloading API", p);
23700 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
23702 error_at (cloc, "too many %qs clauses",
23703 "atomic_default_mem_order");
23704 this_req = (enum omp_requires) 0;
23706 else if ((omp_requires_mask
23707 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
23709 error_at (cloc, "more than one %<atomic_default_mem_order%>"
23710 " clause in a single compilation unit");
23711 this_req
23712 = (enum omp_requires)
23713 (omp_requires_mask
23714 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
23716 else if ((omp_requires_mask
23717 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
23718 error_at (cloc, "%<atomic_default_mem_order%> clause used "
23719 "lexically after first %<atomic%> construct "
23720 "without memory order clause");
23721 new_req = (enum omp_requires) (new_req | this_req);
23722 omp_requires_mask
23723 = (enum omp_requires) (omp_requires_mask | this_req);
23724 continue;
23727 break;
23729 c_parser_skip_to_pragma_eol (parser);
23731 if (new_req == 0)
23732 error_at (loc, "%<pragma omp requires%> requires at least one clause");
23735 /* Helper function for c_parser_omp_taskloop.
23736 Disallow zero sized or potentially zero sized task reductions. */
23738 static tree
23739 c_finish_taskloop_clauses (tree clauses)
23741 tree *pc = &clauses;
23742 for (tree c = clauses; c; c = *pc)
23744 bool remove = false;
23745 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
23747 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
23748 if (integer_zerop (TYPE_SIZE_UNIT (type)))
23750 error_at (OMP_CLAUSE_LOCATION (c),
23751 "zero sized type %qT in %<reduction%> clause", type);
23752 remove = true;
23754 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
23756 error_at (OMP_CLAUSE_LOCATION (c),
23757 "variable sized type %qT in %<reduction%> clause",
23758 type);
23759 remove = true;
23762 if (remove)
23763 *pc = OMP_CLAUSE_CHAIN (c);
23764 else
23765 pc = &OMP_CLAUSE_CHAIN (c);
23767 return clauses;
23770 /* OpenMP 4.5:
23771 #pragma omp taskloop taskloop-clause[optseq] new-line
23772 for-loop
23774 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
23775 for-loop */
23777 #define OMP_TASKLOOP_CLAUSE_MASK \
23778 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23779 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23780 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23781 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23782 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
23784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
23785 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23786 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23787 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
23791 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
23796 static tree
23797 c_parser_omp_taskloop (location_t loc, c_parser *parser,
23798 char *p_name, omp_clause_mask mask, tree *cclauses,
23799 bool *if_p)
23801 tree clauses, block, ret;
23803 strcat (p_name, " taskloop");
23804 mask |= OMP_TASKLOOP_CLAUSE_MASK;
23805 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
23806 clause. */
23807 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
23808 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
23810 if (c_parser_next_token_is (parser, CPP_NAME))
23812 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23814 if (strcmp (p, "simd") == 0)
23816 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23817 if (cclauses == NULL)
23818 cclauses = cclauses_buf;
23819 c_parser_consume_token (parser);
23820 if (!flag_openmp) /* flag_openmp_simd */
23821 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23822 if_p);
23823 block = c_begin_compound_stmt (true);
23824 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
23825 block = c_end_compound_stmt (loc, block, true);
23826 if (ret == NULL)
23827 return ret;
23828 ret = make_node (OMP_TASKLOOP);
23829 TREE_TYPE (ret) = void_type_node;
23830 OMP_FOR_BODY (ret) = block;
23831 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
23832 OMP_FOR_CLAUSES (ret)
23833 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
23834 SET_EXPR_LOCATION (ret, loc);
23835 add_stmt (ret);
23836 return ret;
23839 if (!flag_openmp) /* flag_openmp_simd */
23841 c_parser_skip_to_pragma_eol (parser, false);
23842 return NULL_TREE;
23845 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23846 if (cclauses)
23848 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
23849 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
23852 clauses = c_finish_taskloop_clauses (clauses);
23853 block = c_begin_compound_stmt (true);
23854 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
23855 block = c_end_compound_stmt (loc, block, true);
23856 add_stmt (block);
23858 return ret;
23861 /* OpenMP 5.1
23862 #pragma omp nothing new-line */
23864 static void
23865 c_parser_omp_nothing (c_parser *parser)
23867 c_parser_consume_pragma (parser);
23868 c_parser_skip_to_pragma_eol (parser);
23871 /* OpenMP 5.1
23872 #pragma omp error clauses[optseq] new-line */
23874 static bool
23875 c_parser_omp_error (c_parser *parser, enum pragma_context context)
23877 int at_compilation = -1;
23878 int severity_fatal = -1;
23879 tree message = NULL_TREE;
23880 bool bad = false;
23881 location_t loc = c_parser_peek_token (parser)->location;
23883 c_parser_consume_pragma (parser);
23885 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23887 if (c_parser_next_token_is (parser, CPP_COMMA)
23888 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23889 c_parser_consume_token (parser);
23891 if (!c_parser_next_token_is (parser, CPP_NAME))
23892 break;
23894 const char *p
23895 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23896 location_t cloc = c_parser_peek_token (parser)->location;
23897 static const char *args[] = {
23898 "execution", "compilation", "warning", "fatal"
23900 int *v = NULL;
23901 int idx = 0, n = -1;
23902 tree m = NULL_TREE;
23904 if (!strcmp (p, "at"))
23905 v = &at_compilation;
23906 else if (!strcmp (p, "severity"))
23908 v = &severity_fatal;
23909 idx += 2;
23911 else if (strcmp (p, "message"))
23913 error_at (cloc,
23914 "expected %<at%>, %<severity%> or %<message%> clause");
23915 c_parser_skip_to_pragma_eol (parser, false);
23916 return false;
23919 c_parser_consume_token (parser);
23921 matching_parens parens;
23922 if (parens.require_open (parser))
23924 if (v == NULL)
23926 location_t expr_loc = c_parser_peek_token (parser)->location;
23927 c_expr expr = c_parser_expr_no_commas (parser, NULL);
23928 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
23929 m = convert (const_string_type_node, expr.value);
23930 m = c_fully_fold (m, false, NULL);
23932 else
23934 if (c_parser_next_token_is (parser, CPP_NAME))
23936 tree val = c_parser_peek_token (parser)->value;
23937 const char *q = IDENTIFIER_POINTER (val);
23939 if (!strcmp (q, args[idx]))
23940 n = 0;
23941 else if (!strcmp (q, args[idx + 1]))
23942 n = 1;
23944 if (n == -1)
23946 error_at (c_parser_peek_token (parser)->location,
23947 "expected %qs or %qs", args[idx], args[idx + 1]);
23948 bad = true;
23949 switch (c_parser_peek_token (parser)->type)
23951 case CPP_EOF:
23952 case CPP_PRAGMA_EOL:
23953 case CPP_CLOSE_PAREN:
23954 break;
23955 default:
23956 if (c_parser_peek_2nd_token (parser)->type
23957 == CPP_CLOSE_PAREN)
23958 c_parser_consume_token (parser);
23959 break;
23962 else
23963 c_parser_consume_token (parser);
23966 parens.skip_until_found_close (parser);
23968 if (v == NULL)
23970 if (message)
23972 error_at (cloc, "too many %qs clauses", p);
23973 bad = true;
23975 else
23976 message = m;
23978 else if (n != -1)
23980 if (*v != -1)
23982 error_at (cloc, "too many %qs clauses", p);
23983 bad = true;
23985 else
23986 *v = n;
23989 else
23990 bad = true;
23992 c_parser_skip_to_pragma_eol (parser);
23993 if (bad)
23994 return true;
23996 if (at_compilation == -1)
23997 at_compilation = 1;
23998 if (severity_fatal == -1)
23999 severity_fatal = 1;
24000 if (!at_compilation)
24002 if (context != pragma_compound)
24004 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
24005 "may only be used in compound statements");
24006 return true;
24008 tree fndecl
24009 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
24010 : BUILT_IN_GOMP_WARNING);
24011 if (!message)
24012 message = build_zero_cst (const_string_type_node);
24013 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
24014 build_all_ones_cst (size_type_node));
24015 add_stmt (stmt);
24016 return true;
24018 const char *msg = NULL;
24019 if (message)
24021 msg = c_getstr (message);
24022 if (msg == NULL)
24023 msg = _("<message unknown at compile time>");
24025 if (msg)
24026 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
24027 "%<pragma omp error%> encountered: %s", msg);
24028 else
24029 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
24030 "%<pragma omp error%> encountered");
24031 return false;
24034 /* Assumption clauses:
24035 OpenMP 5.1
24036 absent (directive-name-list)
24037 contains (directive-name-list)
24038 holds (expression)
24039 no_openmp
24040 no_openmp_routines
24041 no_parallelism */
24043 static void
24044 c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
24046 bool no_openmp = false;
24047 bool no_openmp_routines = false;
24048 bool no_parallelism = false;
24049 bitmap_head absent_head, contains_head;
24051 bitmap_obstack_initialize (NULL);
24052 bitmap_initialize (&absent_head, &bitmap_default_obstack);
24053 bitmap_initialize (&contains_head, &bitmap_default_obstack);
24055 if (c_parser_next_token_is (parser, CPP_PRAGMA_EOL))
24056 error_at (c_parser_peek_token (parser)->location,
24057 "expected at least one assumption clause");
24059 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
24061 if (c_parser_next_token_is (parser, CPP_COMMA)
24062 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
24063 c_parser_consume_token (parser);
24065 if (!c_parser_next_token_is (parser, CPP_NAME))
24066 break;
24068 const char *p
24069 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
24070 location_t cloc = c_parser_peek_token (parser)->location;
24072 if (!strcmp (p, "no_openmp"))
24074 c_parser_consume_token (parser);
24075 if (no_openmp)
24076 error_at (cloc, "too many %qs clauses", "no_openmp");
24077 no_openmp = true;
24079 else if (!strcmp (p, "no_openmp_routines"))
24081 c_parser_consume_token (parser);
24082 if (no_openmp_routines)
24083 error_at (cloc, "too many %qs clauses", "no_openmp_routines");
24084 no_openmp_routines = true;
24086 else if (!strcmp (p, "no_parallelism"))
24088 c_parser_consume_token (parser);
24089 if (no_parallelism)
24090 error_at (cloc, "too many %qs clauses", "no_parallelism");
24091 no_parallelism = true;
24093 else if (!strcmp (p, "holds"))
24095 c_parser_consume_token (parser);
24096 matching_parens parens;
24097 if (parens.require_open (parser))
24099 location_t eloc = c_parser_peek_token (parser)->location;
24100 c_expr expr = c_parser_expr_no_commas (parser, NULL);
24101 tree t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
24102 t = c_objc_common_truthvalue_conversion (eloc, t);
24103 t = c_fully_fold (t, false, NULL);
24104 if (is_assume && t != error_mark_node)
24106 tree fn = build_call_expr_internal_loc (eloc, IFN_ASSUME,
24107 void_type_node, 1,
24109 add_stmt (fn);
24111 parens.skip_until_found_close (parser);
24114 else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
24116 c_parser_consume_token (parser);
24117 matching_parens parens;
24118 if (parens.require_open (parser))
24122 const char *directive[3] = {};
24123 int i;
24124 location_t dloc = c_parser_peek_token (parser)->location;
24125 for (i = 0; i < 3; i++)
24127 tree id;
24128 if (c_parser_peek_nth_token (parser, i + 1)->type
24129 == CPP_NAME)
24130 id = c_parser_peek_nth_token (parser, i + 1)->value;
24131 else if (c_parser_peek_nth_token (parser, i + 1)->keyword
24132 != RID_MAX)
24134 enum rid rid
24135 = c_parser_peek_nth_token (parser, i + 1)->keyword;
24136 id = ridpointers[rid];
24138 else
24139 break;
24140 directive[i] = IDENTIFIER_POINTER (id);
24142 if (i == 0)
24143 error_at (dloc, "expected directive name");
24144 else
24146 const struct c_omp_directive *dir
24147 = c_omp_categorize_directive (directive[0],
24148 directive[1],
24149 directive[2]);
24150 if (dir == NULL
24151 || dir->kind == C_OMP_DIR_DECLARATIVE
24152 || dir->kind == C_OMP_DIR_INFORMATIONAL
24153 || dir->id == PRAGMA_OMP_END
24154 || (!dir->second && directive[1])
24155 || (!dir->third && directive[2]))
24156 error_at (dloc, "unknown OpenMP directive name in "
24157 "%qs clause argument", p);
24158 else
24160 int id = dir - c_omp_directives;
24161 if (bitmap_bit_p (p[0] == 'a' ? &contains_head
24162 : &absent_head, id))
24163 error_at (dloc, "%<%s%s%s%s%s%> directive "
24164 "mentioned in both %<absent%> and "
24165 "%<contains%> clauses",
24166 directive[0],
24167 directive[1] ? " " : "",
24168 directive[1] ? directive[1] : "",
24169 directive[2] ? " " : "",
24170 directive[2] ? directive[2] : "");
24171 else if (!bitmap_set_bit (p[0] == 'a'
24172 ? &absent_head
24173 : &contains_head, id))
24174 error_at (dloc, "%<%s%s%s%s%s%> directive "
24175 "mentioned multiple times in %qs "
24176 "clauses",
24177 directive[0],
24178 directive[1] ? " " : "",
24179 directive[1] ? directive[1] : "",
24180 directive[2] ? " " : "",
24181 directive[2] ? directive[2] : "", p);
24183 for (; i; --i)
24184 c_parser_consume_token (parser);
24186 if (c_parser_next_token_is (parser, CPP_COMMA))
24187 c_parser_consume_token (parser);
24188 else
24189 break;
24191 while (1);
24192 parens.skip_until_found_close (parser);
24195 else if (startswith (p, "ext_"))
24197 warning_at (cloc, 0, "unknown assumption clause %qs", p);
24198 c_parser_consume_token (parser);
24199 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
24201 matching_parens parens;
24202 parens.consume_open (parser);
24203 c_parser_balanced_token_sequence (parser);
24204 parens.require_close (parser);
24207 else
24209 c_parser_consume_token (parser);
24210 error_at (cloc, "expected assumption clause");
24211 break;
24214 c_parser_skip_to_pragma_eol (parser);
24217 /* OpenMP 5.1
24218 #pragma omp assume clauses[optseq] new-line */
24220 static void
24221 c_parser_omp_assume (c_parser *parser, bool *if_p)
24223 c_parser_omp_assumption_clauses (parser, true);
24224 add_stmt (c_parser_omp_structured_block (parser, if_p));
24227 /* OpenMP 5.1
24228 #pragma omp assumes clauses[optseq] new-line */
24230 static void
24231 c_parser_omp_assumes (c_parser *parser)
24233 c_parser_consume_pragma (parser);
24234 c_parser_omp_assumption_clauses (parser, false);
24237 /* Main entry point to parsing most OpenMP pragmas. */
24239 static void
24240 c_parser_omp_construct (c_parser *parser, bool *if_p)
24242 enum pragma_kind p_kind;
24243 location_t loc;
24244 tree stmt;
24245 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
24246 omp_clause_mask mask (0);
24248 loc = c_parser_peek_token (parser)->location;
24249 p_kind = c_parser_peek_token (parser)->pragma_kind;
24250 c_parser_consume_pragma (parser);
24252 switch (p_kind)
24254 case PRAGMA_OACC_ATOMIC:
24255 c_parser_omp_atomic (loc, parser, true);
24256 return;
24257 case PRAGMA_OACC_CACHE:
24258 strcpy (p_name, "#pragma acc");
24259 stmt = c_parser_oacc_cache (loc, parser);
24260 break;
24261 case PRAGMA_OACC_DATA:
24262 stmt = c_parser_oacc_data (loc, parser, if_p);
24263 break;
24264 case PRAGMA_OACC_HOST_DATA:
24265 stmt = c_parser_oacc_host_data (loc, parser, if_p);
24266 break;
24267 case PRAGMA_OACC_KERNELS:
24268 case PRAGMA_OACC_PARALLEL:
24269 case PRAGMA_OACC_SERIAL:
24270 strcpy (p_name, "#pragma acc");
24271 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
24272 break;
24273 case PRAGMA_OACC_LOOP:
24274 strcpy (p_name, "#pragma acc");
24275 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
24276 break;
24277 case PRAGMA_OACC_WAIT:
24278 strcpy (p_name, "#pragma wait");
24279 stmt = c_parser_oacc_wait (loc, parser, p_name);
24280 break;
24281 case PRAGMA_OMP_ALLOCATE:
24282 c_parser_omp_allocate (loc, parser);
24283 return;
24284 case PRAGMA_OMP_ATOMIC:
24285 c_parser_omp_atomic (loc, parser, false);
24286 return;
24287 case PRAGMA_OMP_CRITICAL:
24288 stmt = c_parser_omp_critical (loc, parser, if_p);
24289 break;
24290 case PRAGMA_OMP_DISTRIBUTE:
24291 strcpy (p_name, "#pragma omp");
24292 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
24293 break;
24294 case PRAGMA_OMP_FOR:
24295 strcpy (p_name, "#pragma omp");
24296 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
24297 break;
24298 case PRAGMA_OMP_LOOP:
24299 strcpy (p_name, "#pragma omp");
24300 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
24301 break;
24302 case PRAGMA_OMP_MASKED:
24303 strcpy (p_name, "#pragma omp");
24304 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
24305 break;
24306 case PRAGMA_OMP_MASTER:
24307 strcpy (p_name, "#pragma omp");
24308 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
24309 break;
24310 case PRAGMA_OMP_PARALLEL:
24311 strcpy (p_name, "#pragma omp");
24312 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
24313 break;
24314 case PRAGMA_OMP_SCOPE:
24315 stmt = c_parser_omp_scope (loc, parser, if_p);
24316 break;
24317 case PRAGMA_OMP_SECTIONS:
24318 strcpy (p_name, "#pragma omp");
24319 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
24320 break;
24321 case PRAGMA_OMP_SIMD:
24322 strcpy (p_name, "#pragma omp");
24323 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
24324 break;
24325 case PRAGMA_OMP_SINGLE:
24326 stmt = c_parser_omp_single (loc, parser, if_p);
24327 break;
24328 case PRAGMA_OMP_TASK:
24329 stmt = c_parser_omp_task (loc, parser, if_p);
24330 break;
24331 case PRAGMA_OMP_TASKGROUP:
24332 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
24333 break;
24334 case PRAGMA_OMP_TASKLOOP:
24335 strcpy (p_name, "#pragma omp");
24336 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
24337 break;
24338 case PRAGMA_OMP_TEAMS:
24339 strcpy (p_name, "#pragma omp");
24340 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
24341 break;
24342 case PRAGMA_OMP_ASSUME:
24343 c_parser_omp_assume (parser, if_p);
24344 return;
24345 default:
24346 gcc_unreachable ();
24349 if (stmt && stmt != error_mark_node)
24350 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
24354 /* OpenMP 2.5:
24355 # pragma omp threadprivate (variable-list) */
24357 static void
24358 c_parser_omp_threadprivate (c_parser *parser)
24360 tree vars, t;
24361 location_t loc;
24363 c_parser_consume_pragma (parser);
24364 loc = c_parser_peek_token (parser)->location;
24365 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
24367 /* Mark every variable in VARS to be assigned thread local storage. */
24368 for (t = vars; t; t = TREE_CHAIN (t))
24370 tree v = TREE_PURPOSE (t);
24372 /* FIXME diagnostics: Ideally we should keep individual
24373 locations for all the variables in the var list to make the
24374 following errors more precise. Perhaps
24375 c_parser_omp_var_list_parens() should construct a list of
24376 locations to go along with the var list. */
24378 /* If V had already been marked threadprivate, it doesn't matter
24379 whether it had been used prior to this point. */
24380 if (!VAR_P (v))
24381 error_at (loc, "%qD is not a variable", v);
24382 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
24383 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
24384 else if (! is_global_var (v))
24385 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
24386 else if (TREE_TYPE (v) == error_mark_node)
24388 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
24389 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
24390 else
24392 if (! DECL_THREAD_LOCAL_P (v))
24394 set_decl_tls_model (v, decl_default_tls_model (v));
24395 /* If rtl has been already set for this var, call
24396 make_decl_rtl once again, so that encode_section_info
24397 has a chance to look at the new decl flags. */
24398 if (DECL_RTL_SET_P (v))
24399 make_decl_rtl (v);
24401 C_DECL_THREADPRIVATE_P (v) = 1;
24405 c_parser_skip_to_pragma_eol (parser);
24408 /* Parse a transaction attribute (GCC Extension).
24410 transaction-attribute:
24411 gnu-attributes
24412 attribute-specifier
24415 static tree
24416 c_parser_transaction_attributes (c_parser *parser)
24418 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
24419 return c_parser_gnu_attributes (parser);
24421 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
24422 return NULL_TREE;
24423 return c_parser_std_attribute_specifier (parser, true);
24426 /* Parse a __transaction_atomic or __transaction_relaxed statement
24427 (GCC Extension).
24429 transaction-statement:
24430 __transaction_atomic transaction-attribute[opt] compound-statement
24431 __transaction_relaxed compound-statement
24433 Note that the only valid attribute is: "outer".
24436 static tree
24437 c_parser_transaction (c_parser *parser, enum rid keyword)
24439 unsigned int old_in = parser->in_transaction;
24440 unsigned int this_in = 1, new_in;
24441 location_t loc = c_parser_peek_token (parser)->location;
24442 tree stmt, attrs;
24444 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
24445 || keyword == RID_TRANSACTION_RELAXED)
24446 && c_parser_next_token_is_keyword (parser, keyword));
24447 c_parser_consume_token (parser);
24449 if (keyword == RID_TRANSACTION_RELAXED)
24450 this_in |= TM_STMT_ATTR_RELAXED;
24451 else
24453 attrs = c_parser_transaction_attributes (parser);
24454 if (attrs)
24455 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
24458 /* Keep track if we're in the lexical scope of an outer transaction. */
24459 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
24461 parser->in_transaction = new_in;
24462 stmt = c_parser_compound_statement (parser);
24463 parser->in_transaction = old_in;
24465 if (flag_tm)
24466 stmt = c_finish_transaction (loc, stmt, this_in);
24467 else
24468 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
24469 "%<__transaction_atomic%> without transactional memory support enabled"
24470 : "%<__transaction_relaxed %> "
24471 "without transactional memory support enabled"));
24473 return stmt;
24476 /* Parse a __transaction_atomic or __transaction_relaxed expression
24477 (GCC Extension).
24479 transaction-expression:
24480 __transaction_atomic ( expression )
24481 __transaction_relaxed ( expression )
24484 static struct c_expr
24485 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
24487 struct c_expr ret;
24488 unsigned int old_in = parser->in_transaction;
24489 unsigned int this_in = 1;
24490 location_t loc = c_parser_peek_token (parser)->location;
24491 tree attrs;
24493 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
24494 || keyword == RID_TRANSACTION_RELAXED)
24495 && c_parser_next_token_is_keyword (parser, keyword));
24496 c_parser_consume_token (parser);
24498 if (keyword == RID_TRANSACTION_RELAXED)
24499 this_in |= TM_STMT_ATTR_RELAXED;
24500 else
24502 attrs = c_parser_transaction_attributes (parser);
24503 if (attrs)
24504 this_in |= parse_tm_stmt_attr (attrs, 0);
24507 parser->in_transaction = this_in;
24508 matching_parens parens;
24509 if (parens.require_open (parser))
24511 tree expr = c_parser_expression (parser).value;
24512 ret.original_type = TREE_TYPE (expr);
24513 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
24514 if (this_in & TM_STMT_ATTR_RELAXED)
24515 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
24516 SET_EXPR_LOCATION (ret.value, loc);
24517 ret.original_code = TRANSACTION_EXPR;
24518 ret.m_decimal = 0;
24519 if (!parens.require_close (parser))
24521 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
24522 goto error;
24525 else
24527 error:
24528 ret.set_error ();
24529 ret.original_code = ERROR_MARK;
24530 ret.original_type = NULL;
24532 parser->in_transaction = old_in;
24534 if (!flag_tm)
24535 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
24536 "%<__transaction_atomic%> without transactional memory support enabled"
24537 : "%<__transaction_relaxed %> "
24538 "without transactional memory support enabled"));
24540 set_c_expr_source_range (&ret, loc, loc);
24542 return ret;
24545 /* Parse a __transaction_cancel statement (GCC Extension).
24547 transaction-cancel-statement:
24548 __transaction_cancel transaction-attribute[opt] ;
24550 Note that the only valid attribute is "outer".
24553 static tree
24554 c_parser_transaction_cancel (c_parser *parser)
24556 location_t loc = c_parser_peek_token (parser)->location;
24557 tree attrs;
24558 bool is_outer = false;
24560 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
24561 c_parser_consume_token (parser);
24563 attrs = c_parser_transaction_attributes (parser);
24564 if (attrs)
24565 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
24567 if (!flag_tm)
24569 error_at (loc, "%<__transaction_cancel%> without "
24570 "transactional memory support enabled");
24571 goto ret_error;
24573 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
24575 error_at (loc, "%<__transaction_cancel%> within a "
24576 "%<__transaction_relaxed%>");
24577 goto ret_error;
24579 else if (is_outer)
24581 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
24582 && !is_tm_may_cancel_outer (current_function_decl))
24584 error_at (loc, "outer %<__transaction_cancel%> not "
24585 "within outer %<__transaction_atomic%> or "
24586 "a %<transaction_may_cancel_outer%> function");
24587 goto ret_error;
24590 else if (parser->in_transaction == 0)
24592 error_at (loc, "%<__transaction_cancel%> not within "
24593 "%<__transaction_atomic%>");
24594 goto ret_error;
24597 return add_stmt (build_tm_abort_call (loc, is_outer));
24599 ret_error:
24600 return build1 (NOP_EXPR, void_type_node, error_mark_node);
24603 /* Parse a single source file. */
24605 void
24606 c_parse_file (void)
24608 /* Use local storage to begin. If the first token is a pragma, parse it.
24609 If it is #pragma GCC pch_preprocess, then this will load a PCH file
24610 which will cause garbage collection. */
24611 c_parser tparser;
24613 memset (&tparser, 0, sizeof tparser);
24614 tparser.translate_strings_p = true;
24615 tparser.tokens = &tparser.tokens_buf[0];
24616 the_parser = &tparser;
24618 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
24619 c_parser_pragma_pch_preprocess (&tparser);
24620 else
24621 c_common_no_more_pch ();
24623 the_parser = ggc_alloc<c_parser> ();
24624 *the_parser = tparser;
24625 if (tparser.tokens == &tparser.tokens_buf[0])
24626 the_parser->tokens = &the_parser->tokens_buf[0];
24628 /* Initialize EH, if we've been told to do so. */
24629 if (flag_exceptions)
24630 using_eh_for_cleanups ();
24632 c_parser_translation_unit (the_parser);
24633 the_parser = NULL;
24636 /* Parse the body of a function declaration marked with "__RTL".
24638 The RTL parser works on the level of characters read from a
24639 FILE *, whereas c_parser works at the level of tokens.
24640 Square this circle by consuming all of the tokens up to and
24641 including the closing brace, recording the start/end of the RTL
24642 fragment, and reopening the file and re-reading the relevant
24643 lines within the RTL parser.
24645 This requires the opening and closing braces of the C function
24646 to be on separate lines from the RTL they wrap.
24648 Take ownership of START_WITH_PASS, if non-NULL. */
24650 location_t
24651 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
24653 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
24655 free (start_with_pass);
24656 return c_parser_peek_token (parser)->location;
24659 location_t start_loc = c_parser_peek_token (parser)->location;
24661 /* Consume all tokens, up to the closing brace, handling
24662 matching pairs of braces in the rtl dump. */
24663 int num_open_braces = 1;
24664 while (1)
24666 switch (c_parser_peek_token (parser)->type)
24668 case CPP_OPEN_BRACE:
24669 num_open_braces++;
24670 break;
24671 case CPP_CLOSE_BRACE:
24672 if (--num_open_braces == 0)
24673 goto found_closing_brace;
24674 break;
24675 case CPP_EOF:
24676 error_at (start_loc, "no closing brace");
24677 free (start_with_pass);
24678 return c_parser_peek_token (parser)->location;
24679 default:
24680 break;
24682 c_parser_consume_token (parser);
24685 found_closing_brace:
24686 /* At the closing brace; record its location. */
24687 location_t end_loc = c_parser_peek_token (parser)->location;
24689 /* Consume the closing brace. */
24690 c_parser_consume_token (parser);
24692 /* Invoke the RTL parser. */
24693 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
24695 free (start_with_pass);
24696 return end_loc;
24699 /* Run the backend on the cfun created above, transferring ownership of
24700 START_WITH_PASS. */
24701 run_rtl_passes (start_with_pass);
24702 return end_loc;
24705 #include "gt-c-c-parser.h"