Add emergency dump after an ICE
[official-gcc.git] / gcc / c / c-parser.c
bloba8bc301ffadf4ef566b0b6653555be4df65d4a55
1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2020 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_UNIQUE_PTR
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 "memmodel.h"
72 #include "c-family/known-headers.h"
74 /* We need to walk over decls with incomplete struct/union/enum types
75 after parsing the whole translation unit.
76 In finish_decl(), if the decl is static, has incomplete
77 struct/union/enum type, it is appended to incomplete_record_decls.
78 In c_parser_translation_unit(), we iterate over incomplete_record_decls
79 and report error if any of the decls are still incomplete. */
81 vec<tree> incomplete_record_decls;
83 void
84 set_c_expr_source_range (c_expr *expr,
85 location_t start, location_t finish)
87 expr->src_range.m_start = start;
88 expr->src_range.m_finish = finish;
89 if (expr->value)
90 set_source_range (expr->value, start, finish);
93 void
94 set_c_expr_source_range (c_expr *expr,
95 source_range src_range)
97 expr->src_range = src_range;
98 if (expr->value)
99 set_source_range (expr->value, src_range);
103 /* Initialization routine for this file. */
105 void
106 c_parse_init (void)
108 /* The only initialization required is of the reserved word
109 identifiers. */
110 unsigned int i;
111 tree id;
112 int mask = 0;
114 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
115 the c_token structure. */
116 gcc_assert (RID_MAX <= 255);
118 mask |= D_CXXONLY;
119 if (!flag_isoc99)
120 mask |= D_C99;
121 if (flag_no_asm)
123 mask |= D_ASM | D_EXT;
124 if (!flag_isoc99)
125 mask |= D_EXT89;
127 if (!c_dialect_objc ())
128 mask |= D_OBJC | D_CXX_OBJC;
130 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
131 for (i = 0; i < num_c_common_reswords; i++)
133 /* If a keyword is disabled, do not enter it into the table
134 and so create a canonical spelling that isn't a keyword. */
135 if (c_common_reswords[i].disable & mask)
137 if (warn_cxx_compat
138 && (c_common_reswords[i].disable & D_CXXWARN))
140 id = get_identifier (c_common_reswords[i].word);
141 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
142 C_IS_RESERVED_WORD (id) = 1;
144 continue;
147 id = get_identifier (c_common_reswords[i].word);
148 C_SET_RID_CODE (id, c_common_reswords[i].rid);
149 C_IS_RESERVED_WORD (id) = 1;
150 ridpointers [(int) c_common_reswords[i].rid] = id;
153 for (i = 0; i < NUM_INT_N_ENTS; i++)
155 /* We always create the symbols but they aren't always supported. */
156 char name[50];
157 sprintf (name, "__int%d", int_n_data[i].bitsize);
158 id = get_identifier (name);
159 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
160 C_IS_RESERVED_WORD (id) = 1;
162 sprintf (name, "__int%d__", int_n_data[i].bitsize);
163 id = get_identifier (name);
164 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
165 C_IS_RESERVED_WORD (id) = 1;
169 /* A parser structure recording information about the state and
170 context of parsing. Includes lexer information with up to two
171 tokens of look-ahead; more are not needed for C. */
172 struct GTY(()) c_parser {
173 /* The look-ahead tokens. */
174 c_token * GTY((skip)) tokens;
175 /* Buffer for look-ahead tokens. */
176 c_token tokens_buf[4];
177 /* How many look-ahead tokens are available (0 - 4, or
178 more if parsing from pre-lexed tokens). */
179 unsigned int tokens_avail;
180 /* Raw look-ahead tokens, used only for checking in Objective-C
181 whether '[[' starts attributes. */
182 vec<c_token, va_gc> *raw_tokens;
183 /* The number of raw look-ahead tokens that have since been fully
184 lexed. */
185 unsigned int raw_tokens_used;
186 /* True if a syntax error is being recovered from; false otherwise.
187 c_parser_error sets this flag. It should clear this flag when
188 enough tokens have been consumed to recover from the error. */
189 BOOL_BITFIELD error : 1;
190 /* True if we're processing a pragma, and shouldn't automatically
191 consume CPP_PRAGMA_EOL. */
192 BOOL_BITFIELD in_pragma : 1;
193 /* True if we're parsing the outermost block of an if statement. */
194 BOOL_BITFIELD in_if_block : 1;
195 /* True if we want to lex a translated, joined string (for an
196 initial #pragma pch_preprocess). Otherwise the parser is
197 responsible for concatenating strings and translating to the
198 execution character set as needed. */
199 BOOL_BITFIELD lex_joined_string : 1;
200 /* True if, when the parser is concatenating string literals, it
201 should translate them to the execution character set (false
202 inside attributes). */
203 BOOL_BITFIELD translate_strings_p : 1;
205 /* Objective-C specific parser/lexer information. */
207 /* True if we are in a context where the Objective-C "PQ" keywords
208 are considered keywords. */
209 BOOL_BITFIELD objc_pq_context : 1;
210 /* True if we are parsing a (potential) Objective-C foreach
211 statement. This is set to true after we parsed 'for (' and while
212 we wait for 'in' or ';' to decide if it's a standard C for loop or an
213 Objective-C foreach loop. */
214 BOOL_BITFIELD objc_could_be_foreach_context : 1;
215 /* The following flag is needed to contextualize Objective-C lexical
216 analysis. In some cases (e.g., 'int NSObject;'), it is
217 undesirable to bind an identifier to an Objective-C class, even
218 if a class with that name exists. */
219 BOOL_BITFIELD objc_need_raw_identifier : 1;
220 /* Nonzero if we're processing a __transaction statement. The value
221 is 1 | TM_STMT_ATTR_*. */
222 unsigned int in_transaction : 4;
223 /* True if we are in a context where the Objective-C "Property attribute"
224 keywords are valid. */
225 BOOL_BITFIELD objc_property_attr_context : 1;
227 /* Whether we have just seen/constructed a string-literal. Set when
228 returning a string-literal from c_parser_string_literal. Reset
229 in consume_token. Useful when we get a parse error and see an
230 unknown token, which could have been a string-literal constant
231 macro. */
232 BOOL_BITFIELD seen_string_literal : 1;
234 /* Location of the last consumed token. */
235 location_t last_token_location;
238 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
240 c_token *
241 c_parser_tokens_buf (c_parser *parser, unsigned n)
243 return &parser->tokens_buf[n];
246 /* Return the error state of PARSER. */
248 bool
249 c_parser_error (c_parser *parser)
251 return parser->error;
254 /* Set the error state of PARSER to ERR. */
256 void
257 c_parser_set_error (c_parser *parser, bool err)
259 parser->error = err;
263 /* The actual parser and external interface. ??? Does this need to be
264 garbage-collected? */
266 static GTY (()) c_parser *the_parser;
268 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
269 context-sensitive postprocessing of the token is not done. */
271 static void
272 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
274 timevar_push (TV_LEX);
276 if (raw || vec_safe_length (parser->raw_tokens) == 0)
278 token->type = c_lex_with_flags (&token->value, &token->location,
279 &token->flags,
280 (parser->lex_joined_string
281 ? 0 : C_LEX_STRING_NO_JOIN));
282 token->id_kind = C_ID_NONE;
283 token->keyword = RID_MAX;
284 token->pragma_kind = PRAGMA_NONE;
286 else
288 /* Use a token previously lexed as a raw look-ahead token, and
289 complete the processing on it. */
290 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
291 ++parser->raw_tokens_used;
292 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
294 vec_free (parser->raw_tokens);
295 parser->raw_tokens_used = 0;
299 if (raw)
300 goto out;
302 switch (token->type)
304 case CPP_NAME:
306 tree decl;
308 bool objc_force_identifier = parser->objc_need_raw_identifier;
309 if (c_dialect_objc ())
310 parser->objc_need_raw_identifier = false;
312 if (C_IS_RESERVED_WORD (token->value))
314 enum rid rid_code = C_RID_CODE (token->value);
316 if (rid_code == RID_CXX_COMPAT_WARN)
318 warning_at (token->location,
319 OPT_Wc___compat,
320 "identifier %qE conflicts with C++ keyword",
321 token->value);
323 else if (rid_code >= RID_FIRST_ADDR_SPACE
324 && rid_code <= RID_LAST_ADDR_SPACE)
326 addr_space_t as;
327 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
328 targetm.addr_space.diagnose_usage (as, token->location);
329 token->id_kind = C_ID_ADDRSPACE;
330 token->keyword = rid_code;
331 break;
333 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
335 /* We found an Objective-C "pq" keyword (in, out,
336 inout, bycopy, byref, oneway). They need special
337 care because the interpretation depends on the
338 context. */
339 if (parser->objc_pq_context)
341 token->type = CPP_KEYWORD;
342 token->keyword = rid_code;
343 break;
345 else if (parser->objc_could_be_foreach_context
346 && rid_code == RID_IN)
348 /* We are in Objective-C, inside a (potential)
349 foreach context (which means after having
350 parsed 'for (', but before having parsed ';'),
351 and we found 'in'. We consider it the keyword
352 which terminates the declaration at the
353 beginning of a foreach-statement. Note that
354 this means you can't use 'in' for anything else
355 in that context; in particular, in Objective-C
356 you can't use 'in' as the name of the running
357 variable in a C for loop. We could potentially
358 try to add code here to disambiguate, but it
359 seems a reasonable limitation. */
360 token->type = CPP_KEYWORD;
361 token->keyword = rid_code;
362 break;
364 /* Else, "pq" keywords outside of the "pq" context are
365 not keywords, and we fall through to the code for
366 normal tokens. */
368 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
370 /* We found an Objective-C "property attribute"
371 keyword (getter, setter, readonly, etc). These are
372 only valid in the property context. */
373 if (parser->objc_property_attr_context)
375 token->type = CPP_KEYWORD;
376 token->keyword = rid_code;
377 break;
379 /* Else they are not special keywords.
382 else if (c_dialect_objc ()
383 && (OBJC_IS_AT_KEYWORD (rid_code)
384 || OBJC_IS_CXX_KEYWORD (rid_code)))
386 /* We found one of the Objective-C "@" keywords (defs,
387 selector, synchronized, etc) or one of the
388 Objective-C "cxx" keywords (class, private,
389 protected, public, try, catch, throw) without a
390 preceding '@' sign. Do nothing and fall through to
391 the code for normal tokens (in C++ we would still
392 consider the CXX ones keywords, but not in C). */
395 else
397 token->type = CPP_KEYWORD;
398 token->keyword = rid_code;
399 break;
403 decl = lookup_name (token->value);
404 if (decl)
406 if (TREE_CODE (decl) == TYPE_DECL)
408 token->id_kind = C_ID_TYPENAME;
409 break;
412 else if (c_dialect_objc ())
414 tree objc_interface_decl = objc_is_class_name (token->value);
415 /* Objective-C class names are in the same namespace as
416 variables and typedefs, and hence are shadowed by local
417 declarations. */
418 if (objc_interface_decl
419 && (!objc_force_identifier || global_bindings_p ()))
421 token->value = objc_interface_decl;
422 token->id_kind = C_ID_CLASSNAME;
423 break;
426 token->id_kind = C_ID_ID;
428 break;
429 case CPP_AT_NAME:
430 /* This only happens in Objective-C; it must be a keyword. */
431 token->type = CPP_KEYWORD;
432 switch (C_RID_CODE (token->value))
434 /* Replace 'class' with '@class', 'private' with '@private',
435 etc. This prevents confusion with the C++ keyword
436 'class', and makes the tokens consistent with other
437 Objective-C 'AT' keywords. For example '@class' is
438 reported as RID_AT_CLASS which is consistent with
439 '@synchronized', which is reported as
440 RID_AT_SYNCHRONIZED.
442 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
443 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
444 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
445 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
446 case RID_THROW: token->keyword = RID_AT_THROW; break;
447 case RID_TRY: token->keyword = RID_AT_TRY; break;
448 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
449 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
450 default: token->keyword = C_RID_CODE (token->value);
452 break;
453 case CPP_COLON:
454 case CPP_COMMA:
455 case CPP_CLOSE_PAREN:
456 case CPP_SEMICOLON:
457 /* These tokens may affect the interpretation of any identifiers
458 following, if doing Objective-C. */
459 if (c_dialect_objc ())
460 parser->objc_need_raw_identifier = false;
461 break;
462 case CPP_PRAGMA:
463 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
464 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
465 token->value = NULL;
466 break;
467 default:
468 break;
470 out:
471 timevar_pop (TV_LEX);
474 /* Return a pointer to the next token from PARSER, reading it in if
475 necessary. */
477 c_token *
478 c_parser_peek_token (c_parser *parser)
480 if (parser->tokens_avail == 0)
482 c_lex_one_token (parser, &parser->tokens[0]);
483 parser->tokens_avail = 1;
485 return &parser->tokens[0];
488 /* Return a pointer to the next-but-one token from PARSER, reading it
489 in if necessary. The next token is already read in. */
491 c_token *
492 c_parser_peek_2nd_token (c_parser *parser)
494 if (parser->tokens_avail >= 2)
495 return &parser->tokens[1];
496 gcc_assert (parser->tokens_avail == 1);
497 gcc_assert (parser->tokens[0].type != CPP_EOF);
498 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
499 c_lex_one_token (parser, &parser->tokens[1]);
500 parser->tokens_avail = 2;
501 return &parser->tokens[1];
504 /* Return a pointer to the Nth token from PARSER, reading it
505 in if necessary. The N-1th token is already read in. */
507 c_token *
508 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
510 /* N is 1-based, not zero-based. */
511 gcc_assert (n > 0);
513 if (parser->tokens_avail >= n)
514 return &parser->tokens[n - 1];
515 gcc_assert (parser->tokens_avail == n - 1);
516 c_lex_one_token (parser, &parser->tokens[n - 1]);
517 parser->tokens_avail = n;
518 return &parser->tokens[n - 1];
521 /* Return a pointer to the Nth token from PARSER, reading it in as a
522 raw look-ahead token if necessary. The N-1th token is already read
523 in. Raw look-ahead tokens remain available for when the non-raw
524 functions above are called. */
526 c_token *
527 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
529 /* N is 1-based, not zero-based. */
530 gcc_assert (n > 0);
532 if (parser->tokens_avail >= n)
533 return &parser->tokens[n - 1];
534 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
535 unsigned int raw_avail
536 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
537 gcc_assert (raw_avail >= n - 1);
538 if (raw_avail >= n)
539 return &(*parser->raw_tokens)[parser->raw_tokens_used
540 + n - 1 - parser->tokens_avail];
541 vec_safe_reserve (parser->raw_tokens, 1);
542 parser->raw_tokens->quick_grow (raw_len + 1);
543 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
544 return &(*parser->raw_tokens)[raw_len];
547 bool
548 c_keyword_starts_typename (enum rid keyword)
550 switch (keyword)
552 case RID_UNSIGNED:
553 case RID_LONG:
554 case RID_SHORT:
555 case RID_SIGNED:
556 case RID_COMPLEX:
557 case RID_INT:
558 case RID_CHAR:
559 case RID_FLOAT:
560 case RID_DOUBLE:
561 case RID_VOID:
562 case RID_DFLOAT32:
563 case RID_DFLOAT64:
564 case RID_DFLOAT128:
565 CASE_RID_FLOATN_NX:
566 case RID_BOOL:
567 case RID_ENUM:
568 case RID_STRUCT:
569 case RID_UNION:
570 case RID_TYPEOF:
571 case RID_CONST:
572 case RID_ATOMIC:
573 case RID_VOLATILE:
574 case RID_RESTRICT:
575 case RID_ATTRIBUTE:
576 case RID_FRACT:
577 case RID_ACCUM:
578 case RID_SAT:
579 case RID_AUTO_TYPE:
580 case RID_ALIGNAS:
581 return true;
582 default:
583 if (keyword >= RID_FIRST_INT_N
584 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
585 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
586 return true;
587 return false;
591 /* Return true if TOKEN can start a type name,
592 false otherwise. */
593 bool
594 c_token_starts_typename (c_token *token)
596 switch (token->type)
598 case CPP_NAME:
599 switch (token->id_kind)
601 case C_ID_ID:
602 return false;
603 case C_ID_ADDRSPACE:
604 return true;
605 case C_ID_TYPENAME:
606 return true;
607 case C_ID_CLASSNAME:
608 gcc_assert (c_dialect_objc ());
609 return true;
610 default:
611 gcc_unreachable ();
613 case CPP_KEYWORD:
614 return c_keyword_starts_typename (token->keyword);
615 case CPP_LESS:
616 if (c_dialect_objc ())
617 return true;
618 return false;
619 default:
620 return false;
624 /* Return true if the next token from PARSER can start a type name,
625 false otherwise. LA specifies how to do lookahead in order to
626 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
628 static inline bool
629 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
631 c_token *token = c_parser_peek_token (parser);
632 if (c_token_starts_typename (token))
633 return true;
635 /* Try a bit harder to detect an unknown typename. */
636 if (la != cla_prefer_id
637 && token->type == CPP_NAME
638 && token->id_kind == C_ID_ID
640 /* Do not try too hard when we could have "object in array". */
641 && !parser->objc_could_be_foreach_context
643 && (la == cla_prefer_type
644 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
645 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
647 /* Only unknown identifiers. */
648 && !lookup_name (token->value))
649 return true;
651 return false;
654 /* Return true if TOKEN is a type qualifier, false otherwise. */
655 static bool
656 c_token_is_qualifier (c_token *token)
658 switch (token->type)
660 case CPP_NAME:
661 switch (token->id_kind)
663 case C_ID_ADDRSPACE:
664 return true;
665 default:
666 return false;
668 case CPP_KEYWORD:
669 switch (token->keyword)
671 case RID_CONST:
672 case RID_VOLATILE:
673 case RID_RESTRICT:
674 case RID_ATTRIBUTE:
675 case RID_ATOMIC:
676 return true;
677 default:
678 return false;
680 case CPP_LESS:
681 return false;
682 default:
683 gcc_unreachable ();
687 /* Return true if the next token from PARSER is a type qualifier,
688 false otherwise. */
689 static inline bool
690 c_parser_next_token_is_qualifier (c_parser *parser)
692 c_token *token = c_parser_peek_token (parser);
693 return c_token_is_qualifier (token);
696 /* Return true if TOKEN can start declaration specifiers (not
697 including standard attributes), false otherwise. */
698 static bool
699 c_token_starts_declspecs (c_token *token)
701 switch (token->type)
703 case CPP_NAME:
704 switch (token->id_kind)
706 case C_ID_ID:
707 return false;
708 case C_ID_ADDRSPACE:
709 return true;
710 case C_ID_TYPENAME:
711 return true;
712 case C_ID_CLASSNAME:
713 gcc_assert (c_dialect_objc ());
714 return true;
715 default:
716 gcc_unreachable ();
718 case CPP_KEYWORD:
719 switch (token->keyword)
721 case RID_STATIC:
722 case RID_EXTERN:
723 case RID_REGISTER:
724 case RID_TYPEDEF:
725 case RID_INLINE:
726 case RID_NORETURN:
727 case RID_AUTO:
728 case RID_THREAD:
729 case RID_UNSIGNED:
730 case RID_LONG:
731 case RID_SHORT:
732 case RID_SIGNED:
733 case RID_COMPLEX:
734 case RID_INT:
735 case RID_CHAR:
736 case RID_FLOAT:
737 case RID_DOUBLE:
738 case RID_VOID:
739 case RID_DFLOAT32:
740 case RID_DFLOAT64:
741 case RID_DFLOAT128:
742 CASE_RID_FLOATN_NX:
743 case RID_BOOL:
744 case RID_ENUM:
745 case RID_STRUCT:
746 case RID_UNION:
747 case RID_TYPEOF:
748 case RID_CONST:
749 case RID_VOLATILE:
750 case RID_RESTRICT:
751 case RID_ATTRIBUTE:
752 case RID_FRACT:
753 case RID_ACCUM:
754 case RID_SAT:
755 case RID_ALIGNAS:
756 case RID_ATOMIC:
757 case RID_AUTO_TYPE:
758 return true;
759 default:
760 if (token->keyword >= RID_FIRST_INT_N
761 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
762 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
763 return true;
764 return false;
766 case CPP_LESS:
767 if (c_dialect_objc ())
768 return true;
769 return false;
770 default:
771 return false;
776 /* Return true if TOKEN can start declaration specifiers (not
777 including standard attributes) or a static assertion, false
778 otherwise. */
779 static bool
780 c_token_starts_declaration (c_token *token)
782 if (c_token_starts_declspecs (token)
783 || token->keyword == RID_STATIC_ASSERT)
784 return true;
785 else
786 return false;
789 /* Return true if the next token from PARSER can start declaration
790 specifiers (not including standard attributes), false
791 otherwise. */
792 bool
793 c_parser_next_token_starts_declspecs (c_parser *parser)
795 c_token *token = c_parser_peek_token (parser);
797 /* In Objective-C, a classname normally starts a declspecs unless it
798 is immediately followed by a dot. In that case, it is the
799 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
800 setter/getter on the class. c_token_starts_declspecs() can't
801 differentiate between the two cases because it only checks the
802 current token, so we have a special check here. */
803 if (c_dialect_objc ()
804 && token->type == CPP_NAME
805 && token->id_kind == C_ID_CLASSNAME
806 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
807 return false;
809 return c_token_starts_declspecs (token);
812 /* Return true if the next tokens from PARSER can start declaration
813 specifiers (not including standard attributes) or a static
814 assertion, false otherwise. */
815 bool
816 c_parser_next_tokens_start_declaration (c_parser *parser)
818 c_token *token = c_parser_peek_token (parser);
820 /* Same as above. */
821 if (c_dialect_objc ()
822 && token->type == CPP_NAME
823 && token->id_kind == C_ID_CLASSNAME
824 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
825 return false;
827 /* Labels do not start declarations. */
828 if (token->type == CPP_NAME
829 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
830 return false;
832 if (c_token_starts_declaration (token))
833 return true;
835 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
836 return true;
838 return false;
841 /* Consume the next token from PARSER. */
843 void
844 c_parser_consume_token (c_parser *parser)
846 gcc_assert (parser->tokens_avail >= 1);
847 gcc_assert (parser->tokens[0].type != CPP_EOF);
848 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
849 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
850 parser->last_token_location = parser->tokens[0].location;
851 if (parser->tokens != &parser->tokens_buf[0])
852 parser->tokens++;
853 else if (parser->tokens_avail >= 2)
855 parser->tokens[0] = parser->tokens[1];
856 if (parser->tokens_avail >= 3)
858 parser->tokens[1] = parser->tokens[2];
859 if (parser->tokens_avail >= 4)
860 parser->tokens[2] = parser->tokens[3];
863 parser->tokens_avail--;
864 parser->seen_string_literal = false;
867 /* Expect the current token to be a #pragma. Consume it and remember
868 that we've begun parsing a pragma. */
870 static void
871 c_parser_consume_pragma (c_parser *parser)
873 gcc_assert (!parser->in_pragma);
874 gcc_assert (parser->tokens_avail >= 1);
875 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
876 if (parser->tokens != &parser->tokens_buf[0])
877 parser->tokens++;
878 else if (parser->tokens_avail >= 2)
880 parser->tokens[0] = parser->tokens[1];
881 if (parser->tokens_avail >= 3)
882 parser->tokens[1] = parser->tokens[2];
884 parser->tokens_avail--;
885 parser->in_pragma = true;
888 /* Update the global input_location from TOKEN. */
889 static inline void
890 c_parser_set_source_position_from_token (c_token *token)
892 if (token->type != CPP_EOF)
894 input_location = token->location;
898 /* Helper function for c_parser_error.
899 Having peeked a token of kind TOK1_KIND that might signify
900 a conflict marker, peek successor tokens to determine
901 if we actually do have a conflict marker.
902 Specifically, we consider a run of 7 '<', '=' or '>' characters
903 at the start of a line as a conflict marker.
904 These come through the lexer as three pairs and a single,
905 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
906 If it returns true, *OUT_LOC is written to with the location/range
907 of the marker. */
909 static bool
910 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
911 location_t *out_loc)
913 c_token *token2 = c_parser_peek_2nd_token (parser);
914 if (token2->type != tok1_kind)
915 return false;
916 c_token *token3 = c_parser_peek_nth_token (parser, 3);
917 if (token3->type != tok1_kind)
918 return false;
919 c_token *token4 = c_parser_peek_nth_token (parser, 4);
920 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
921 return false;
923 /* It must be at the start of the line. */
924 location_t start_loc = c_parser_peek_token (parser)->location;
925 if (LOCATION_COLUMN (start_loc) != 1)
926 return false;
928 /* We have a conflict marker. Construct a location of the form:
929 <<<<<<<
930 ^~~~~~~
931 with start == caret, finishing at the end of the marker. */
932 location_t finish_loc = get_finish (token4->location);
933 *out_loc = make_location (start_loc, start_loc, finish_loc);
935 return true;
938 /* Issue a diagnostic of the form
939 FILE:LINE: MESSAGE before TOKEN
940 where TOKEN is the next token in the input stream of PARSER.
941 MESSAGE (specified by the caller) is usually of the form "expected
942 OTHER-TOKEN".
944 Use RICHLOC as the location of the diagnostic.
946 Do not issue a diagnostic if still recovering from an error.
948 Return true iff an error was actually emitted.
950 ??? This is taken from the C++ parser, but building up messages in
951 this way is not i18n-friendly and some other approach should be
952 used. */
954 static bool
955 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
956 rich_location *richloc)
958 c_token *token = c_parser_peek_token (parser);
959 if (parser->error)
960 return false;
961 parser->error = true;
962 if (!gmsgid)
963 return false;
965 /* If this is actually a conflict marker, report it as such. */
966 if (token->type == CPP_LSHIFT
967 || token->type == CPP_RSHIFT
968 || token->type == CPP_EQ_EQ)
970 location_t loc;
971 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
973 error_at (loc, "version control conflict marker in file");
974 return true;
978 /* If we were parsing a string-literal and there is an unknown name
979 token right after, then check to see if that could also have been
980 a literal string by checking the name against a list of known
981 standard string literal constants defined in header files. If
982 there is one, then add that as an hint to the error message. */
983 auto_diagnostic_group d;
984 name_hint h;
985 if (parser->seen_string_literal && token->type == CPP_NAME)
987 tree name = token->value;
988 const char *token_name = IDENTIFIER_POINTER (name);
989 const char *header_hint
990 = get_c_stdlib_header_for_string_macro_name (token_name);
991 if (header_hint != NULL)
992 h = name_hint (NULL, new suggest_missing_header (token->location,
993 token_name,
994 header_hint));
997 c_parse_error (gmsgid,
998 /* Because c_parse_error does not understand
999 CPP_KEYWORD, keywords are treated like
1000 identifiers. */
1001 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1002 /* ??? The C parser does not save the cpp flags of a
1003 token, we need to pass 0 here and we will not get
1004 the source spelling of some tokens but rather the
1005 canonical spelling. */
1006 token->value, /*flags=*/0, richloc);
1007 return true;
1010 /* As c_parser_error_richloc, but issue the message at the
1011 location of PARSER's next token, or at input_location
1012 if the next token is EOF. */
1014 bool
1015 c_parser_error (c_parser *parser, const char *gmsgid)
1017 c_token *token = c_parser_peek_token (parser);
1018 c_parser_set_source_position_from_token (token);
1019 rich_location richloc (line_table, input_location);
1020 return c_parser_error_richloc (parser, gmsgid, &richloc);
1023 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1024 This class is for tracking such a matching pair of symbols.
1025 In particular, it tracks the location of the first token,
1026 so that if the second token is missing, we can highlight the
1027 location of the first token when notifying the user about the
1028 problem. */
1030 template <typename traits_t>
1031 class token_pair
1033 public:
1034 /* token_pair's ctor. */
1035 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1037 /* If the next token is the opening symbol for this pair, consume it and
1038 return true.
1039 Otherwise, issue an error and return false.
1040 In either case, record the location of the opening token. */
1042 bool require_open (c_parser *parser)
1044 c_token *token = c_parser_peek_token (parser);
1045 if (token)
1046 m_open_loc = token->location;
1048 return c_parser_require (parser, traits_t::open_token_type,
1049 traits_t::open_gmsgid);
1052 /* Consume the next token from PARSER, recording its location as
1053 that of the opening token within the pair. */
1055 void consume_open (c_parser *parser)
1057 c_token *token = c_parser_peek_token (parser);
1058 gcc_assert (token->type == traits_t::open_token_type);
1059 m_open_loc = token->location;
1060 c_parser_consume_token (parser);
1063 /* If the next token is the closing symbol for this pair, consume it
1064 and return true.
1065 Otherwise, issue an error, highlighting the location of the
1066 corresponding opening token, and return false. */
1068 bool require_close (c_parser *parser) const
1070 return c_parser_require (parser, traits_t::close_token_type,
1071 traits_t::close_gmsgid, m_open_loc);
1074 /* Like token_pair::require_close, except that tokens will be skipped
1075 until the desired token is found. An error message is still produced
1076 if the next token is not as expected. */
1078 void skip_until_found_close (c_parser *parser) const
1080 c_parser_skip_until_found (parser, traits_t::close_token_type,
1081 traits_t::close_gmsgid, m_open_loc);
1084 private:
1085 location_t m_open_loc;
1088 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1090 struct matching_paren_traits
1092 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1093 static const char * const open_gmsgid;
1094 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1095 static const char * const close_gmsgid;
1098 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1099 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1101 /* "matching_parens" is a token_pair<T> class for tracking matching
1102 pairs of parentheses. */
1104 typedef token_pair<matching_paren_traits> matching_parens;
1106 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1108 struct matching_brace_traits
1110 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1111 static const char * const open_gmsgid;
1112 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1113 static const char * const close_gmsgid;
1116 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1117 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1119 /* "matching_braces" is a token_pair<T> class for tracking matching
1120 pairs of braces. */
1122 typedef token_pair<matching_brace_traits> matching_braces;
1124 /* Get a description of the matching symbol to TYPE e.g. "(" for
1125 CPP_CLOSE_PAREN. */
1127 static const char *
1128 get_matching_symbol (enum cpp_ttype type)
1130 switch (type)
1132 default:
1133 gcc_unreachable ();
1134 return "";
1135 case CPP_CLOSE_PAREN:
1136 return "(";
1137 case CPP_CLOSE_BRACE:
1138 return "{";
1142 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1143 issue the error MSGID. If MSGID is NULL then a message has already
1144 been produced and no message will be produced this time. Returns
1145 true if found, false otherwise.
1147 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1148 within any error as the location of an "opening" token matching
1149 the close token TYPE (e.g. the location of the '(' when TYPE is
1150 CPP_CLOSE_PAREN).
1152 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1153 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1154 attempt to generate a fix-it hint for the problem.
1155 Otherwise msgid describes multiple token types (e.g.
1156 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1157 generate a fix-it hint. */
1159 bool
1160 c_parser_require (c_parser *parser,
1161 enum cpp_ttype type,
1162 const char *msgid,
1163 location_t matching_location,
1164 bool type_is_unique)
1166 if (c_parser_next_token_is (parser, type))
1168 c_parser_consume_token (parser);
1169 return true;
1171 else
1173 location_t next_token_loc = c_parser_peek_token (parser)->location;
1174 gcc_rich_location richloc (next_token_loc);
1176 /* Potentially supply a fix-it hint, suggesting to add the
1177 missing token immediately after the *previous* token.
1178 This may move the primary location within richloc. */
1179 if (!parser->error && type_is_unique)
1180 maybe_suggest_missing_token_insertion (&richloc, type,
1181 parser->last_token_location);
1183 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1184 Attempt to consolidate diagnostics by printing it as a
1185 secondary range within the main diagnostic. */
1186 bool added_matching_location = false;
1187 if (matching_location != UNKNOWN_LOCATION)
1188 added_matching_location
1189 = richloc.add_location_if_nearby (matching_location);
1191 if (c_parser_error_richloc (parser, msgid, &richloc))
1192 /* If we weren't able to consolidate matching_location, then
1193 print it as a secondary diagnostic. */
1194 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1195 inform (matching_location, "to match this %qs",
1196 get_matching_symbol (type));
1198 return false;
1202 /* If the next token is the indicated keyword, consume it. Otherwise,
1203 issue the error MSGID. Returns true if found, false otherwise. */
1205 static bool
1206 c_parser_require_keyword (c_parser *parser,
1207 enum rid keyword,
1208 const char *msgid)
1210 if (c_parser_next_token_is_keyword (parser, keyword))
1212 c_parser_consume_token (parser);
1213 return true;
1215 else
1217 c_parser_error (parser, msgid);
1218 return false;
1222 /* Like c_parser_require, except that tokens will be skipped until the
1223 desired token is found. An error message is still produced if the
1224 next token is not as expected. If MSGID is NULL then a message has
1225 already been produced and no message will be produced this
1226 time.
1228 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1229 within any error as the location of an "opening" token matching
1230 the close token TYPE (e.g. the location of the '(' when TYPE is
1231 CPP_CLOSE_PAREN). */
1233 void
1234 c_parser_skip_until_found (c_parser *parser,
1235 enum cpp_ttype type,
1236 const char *msgid,
1237 location_t matching_location)
1239 unsigned nesting_depth = 0;
1241 if (c_parser_require (parser, type, msgid, matching_location))
1242 return;
1244 /* Skip tokens until the desired token is found. */
1245 while (true)
1247 /* Peek at the next token. */
1248 c_token *token = c_parser_peek_token (parser);
1249 /* If we've reached the token we want, consume it and stop. */
1250 if (token->type == type && !nesting_depth)
1252 c_parser_consume_token (parser);
1253 break;
1256 /* If we've run out of tokens, stop. */
1257 if (token->type == CPP_EOF)
1258 return;
1259 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1260 return;
1261 if (token->type == CPP_OPEN_BRACE
1262 || token->type == CPP_OPEN_PAREN
1263 || token->type == CPP_OPEN_SQUARE)
1264 ++nesting_depth;
1265 else if (token->type == CPP_CLOSE_BRACE
1266 || token->type == CPP_CLOSE_PAREN
1267 || token->type == CPP_CLOSE_SQUARE)
1269 if (nesting_depth-- == 0)
1270 break;
1272 /* Consume this token. */
1273 c_parser_consume_token (parser);
1275 parser->error = false;
1278 /* Skip tokens until the end of a parameter is found, but do not
1279 consume the comma, semicolon or closing delimiter. */
1281 static void
1282 c_parser_skip_to_end_of_parameter (c_parser *parser)
1284 unsigned nesting_depth = 0;
1286 while (true)
1288 c_token *token = c_parser_peek_token (parser);
1289 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1290 && !nesting_depth)
1291 break;
1292 /* If we've run out of tokens, stop. */
1293 if (token->type == CPP_EOF)
1294 return;
1295 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1296 return;
1297 if (token->type == CPP_OPEN_BRACE
1298 || token->type == CPP_OPEN_PAREN
1299 || token->type == CPP_OPEN_SQUARE)
1300 ++nesting_depth;
1301 else if (token->type == CPP_CLOSE_BRACE
1302 || token->type == CPP_CLOSE_PAREN
1303 || token->type == CPP_CLOSE_SQUARE)
1305 if (nesting_depth-- == 0)
1306 break;
1308 /* Consume this token. */
1309 c_parser_consume_token (parser);
1311 parser->error = false;
1314 /* Expect to be at the end of the pragma directive and consume an
1315 end of line marker. */
1317 static void
1318 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1320 gcc_assert (parser->in_pragma);
1321 parser->in_pragma = false;
1323 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1324 c_parser_error (parser, "expected end of line");
1326 cpp_ttype token_type;
1329 c_token *token = c_parser_peek_token (parser);
1330 token_type = token->type;
1331 if (token_type == CPP_EOF)
1332 break;
1333 c_parser_consume_token (parser);
1335 while (token_type != CPP_PRAGMA_EOL);
1337 parser->error = false;
1340 /* Skip tokens until we have consumed an entire block, or until we
1341 have consumed a non-nested ';'. */
1343 static void
1344 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1346 unsigned nesting_depth = 0;
1347 bool save_error = parser->error;
1349 while (true)
1351 c_token *token;
1353 /* Peek at the next token. */
1354 token = c_parser_peek_token (parser);
1356 switch (token->type)
1358 case CPP_EOF:
1359 return;
1361 case CPP_PRAGMA_EOL:
1362 if (parser->in_pragma)
1363 return;
1364 break;
1366 case CPP_SEMICOLON:
1367 /* If the next token is a ';', we have reached the
1368 end of the statement. */
1369 if (!nesting_depth)
1371 /* Consume the ';'. */
1372 c_parser_consume_token (parser);
1373 goto finished;
1375 break;
1377 case CPP_CLOSE_BRACE:
1378 /* If the next token is a non-nested '}', then we have
1379 reached the end of the current block. */
1380 if (nesting_depth == 0 || --nesting_depth == 0)
1382 c_parser_consume_token (parser);
1383 goto finished;
1385 break;
1387 case CPP_OPEN_BRACE:
1388 /* If it the next token is a '{', then we are entering a new
1389 block. Consume the entire block. */
1390 ++nesting_depth;
1391 break;
1393 case CPP_PRAGMA:
1394 /* If we see a pragma, consume the whole thing at once. We
1395 have some safeguards against consuming pragmas willy-nilly.
1396 Normally, we'd expect to be here with parser->error set,
1397 which disables these safeguards. But it's possible to get
1398 here for secondary error recovery, after parser->error has
1399 been cleared. */
1400 c_parser_consume_pragma (parser);
1401 c_parser_skip_to_pragma_eol (parser);
1402 parser->error = save_error;
1403 continue;
1405 default:
1406 break;
1409 c_parser_consume_token (parser);
1412 finished:
1413 parser->error = false;
1416 /* CPP's options (initialized by c-opts.c). */
1417 extern cpp_options *cpp_opts;
1419 /* Save the warning flags which are controlled by __extension__. */
1421 static inline int
1422 disable_extension_diagnostics (void)
1424 int ret = (pedantic
1425 | (warn_pointer_arith << 1)
1426 | (warn_traditional << 2)
1427 | (flag_iso << 3)
1428 | (warn_long_long << 4)
1429 | (warn_cxx_compat << 5)
1430 | (warn_overlength_strings << 6)
1431 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1432 play tricks to properly restore it. */
1433 | ((warn_c90_c99_compat == 1) << 7)
1434 | ((warn_c90_c99_compat == -1) << 8)
1435 /* Similarly for warn_c99_c11_compat. */
1436 | ((warn_c99_c11_compat == 1) << 9)
1437 | ((warn_c99_c11_compat == -1) << 10)
1438 /* Similarly for warn_c11_c2x_compat. */
1439 | ((warn_c11_c2x_compat == 1) << 11)
1440 | ((warn_c11_c2x_compat == -1) << 12)
1442 cpp_opts->cpp_pedantic = pedantic = 0;
1443 warn_pointer_arith = 0;
1444 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1445 flag_iso = 0;
1446 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1447 warn_cxx_compat = 0;
1448 warn_overlength_strings = 0;
1449 warn_c90_c99_compat = 0;
1450 warn_c99_c11_compat = 0;
1451 warn_c11_c2x_compat = 0;
1452 return ret;
1455 /* Restore the warning flags which are controlled by __extension__.
1456 FLAGS is the return value from disable_extension_diagnostics. */
1458 static inline void
1459 restore_extension_diagnostics (int flags)
1461 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1462 warn_pointer_arith = (flags >> 1) & 1;
1463 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1464 flag_iso = (flags >> 3) & 1;
1465 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1466 warn_cxx_compat = (flags >> 5) & 1;
1467 warn_overlength_strings = (flags >> 6) & 1;
1468 /* See above for why is this needed. */
1469 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1470 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1471 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1474 /* Helper data structure for parsing #pragma acc routine. */
1475 struct oacc_routine_data {
1476 bool error_seen; /* Set if error has been reported. */
1477 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1478 tree clauses;
1479 location_t loc;
1482 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1483 unsigned int);
1484 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1485 static void c_parser_external_declaration (c_parser *);
1486 static void c_parser_asm_definition (c_parser *);
1487 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1488 bool, bool, tree *, vec<c_token>,
1489 bool have_attrs = false,
1490 tree attrs = NULL,
1491 struct oacc_routine_data * = NULL,
1492 bool * = NULL);
1493 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1494 static void c_parser_static_assert_declaration (c_parser *);
1495 static struct c_typespec c_parser_enum_specifier (c_parser *);
1496 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1497 static tree c_parser_struct_declaration (c_parser *);
1498 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1499 static tree c_parser_alignas_specifier (c_parser *);
1500 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1501 c_dtr_syn, bool *);
1502 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1503 bool,
1504 struct c_declarator *);
1505 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1506 bool);
1507 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1508 tree, bool);
1509 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1510 static tree c_parser_simple_asm_expr (c_parser *);
1511 static tree c_parser_gnu_attributes (c_parser *);
1512 static struct c_expr c_parser_initializer (c_parser *);
1513 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1514 struct obstack *);
1515 static void c_parser_initelt (c_parser *, struct obstack *);
1516 static void c_parser_initval (c_parser *, struct c_expr *,
1517 struct obstack *);
1518 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1519 static location_t c_parser_compound_statement_nostart (c_parser *);
1520 static void c_parser_label (c_parser *);
1521 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1522 static void c_parser_statement_after_labels (c_parser *, bool *,
1523 vec<tree> * = NULL);
1524 static tree c_parser_c99_block_statement (c_parser *, bool *,
1525 location_t * = NULL);
1526 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1527 static void c_parser_switch_statement (c_parser *, bool *);
1528 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1529 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1530 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1531 static tree c_parser_asm_statement (c_parser *);
1532 static tree c_parser_asm_operands (c_parser *);
1533 static tree c_parser_asm_goto_operands (c_parser *);
1534 static tree c_parser_asm_clobbers (c_parser *);
1535 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1536 tree = NULL_TREE);
1537 static struct c_expr c_parser_conditional_expression (c_parser *,
1538 struct c_expr *, tree);
1539 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1540 tree);
1541 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1542 static struct c_expr c_parser_unary_expression (c_parser *);
1543 static struct c_expr c_parser_sizeof_expression (c_parser *);
1544 static struct c_expr c_parser_alignof_expression (c_parser *);
1545 static struct c_expr c_parser_postfix_expression (c_parser *);
1546 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1547 struct c_type_name *,
1548 location_t);
1549 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1550 location_t loc,
1551 struct c_expr);
1552 static tree c_parser_transaction (c_parser *, enum rid);
1553 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1554 static tree c_parser_transaction_cancel (c_parser *);
1555 static struct c_expr c_parser_expression (c_parser *);
1556 static struct c_expr c_parser_expression_conv (c_parser *);
1557 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1558 vec<tree, va_gc> **, location_t *,
1559 tree *, vec<location_t> *,
1560 unsigned int * = NULL);
1561 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1563 static void c_parser_oacc_declare (c_parser *);
1564 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1565 static void c_parser_oacc_update (c_parser *);
1566 static void c_parser_omp_construct (c_parser *, bool *);
1567 static void c_parser_omp_threadprivate (c_parser *);
1568 static void c_parser_omp_barrier (c_parser *);
1569 static void c_parser_omp_depobj (c_parser *);
1570 static void c_parser_omp_flush (c_parser *);
1571 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1572 tree, tree *, bool *);
1573 static void c_parser_omp_taskwait (c_parser *);
1574 static void c_parser_omp_taskyield (c_parser *);
1575 static void c_parser_omp_cancel (c_parser *);
1577 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1578 pragma_stmt, pragma_compound };
1579 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1580 static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1581 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1582 static void c_parser_omp_end_declare_target (c_parser *);
1583 static void c_parser_omp_declare (c_parser *, enum pragma_context);
1584 static void c_parser_omp_requires (c_parser *);
1585 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1586 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1588 /* These Objective-C parser functions are only ever called when
1589 compiling Objective-C. */
1590 static void c_parser_objc_class_definition (c_parser *, tree);
1591 static void c_parser_objc_class_instance_variables (c_parser *);
1592 static void c_parser_objc_class_declaration (c_parser *);
1593 static void c_parser_objc_alias_declaration (c_parser *);
1594 static void c_parser_objc_protocol_definition (c_parser *, tree);
1595 static bool c_parser_objc_method_type (c_parser *);
1596 static void c_parser_objc_method_definition (c_parser *);
1597 static void c_parser_objc_methodprotolist (c_parser *);
1598 static void c_parser_objc_methodproto (c_parser *);
1599 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1600 static tree c_parser_objc_type_name (c_parser *);
1601 static tree c_parser_objc_protocol_refs (c_parser *);
1602 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1603 static void c_parser_objc_synchronized_statement (c_parser *);
1604 static tree c_parser_objc_selector (c_parser *);
1605 static tree c_parser_objc_selector_arg (c_parser *);
1606 static tree c_parser_objc_receiver (c_parser *);
1607 static tree c_parser_objc_message_args (c_parser *);
1608 static tree c_parser_objc_keywordexpr (c_parser *);
1609 static void c_parser_objc_at_property_declaration (c_parser *);
1610 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1611 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1612 static bool c_parser_objc_diagnose_bad_element_prefix
1613 (c_parser *, struct c_declspecs *);
1614 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1616 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1618 translation-unit:
1619 external-declarations
1621 external-declarations:
1622 external-declaration
1623 external-declarations external-declaration
1625 GNU extensions:
1627 translation-unit:
1628 empty
1631 static void
1632 c_parser_translation_unit (c_parser *parser)
1634 if (c_parser_next_token_is (parser, CPP_EOF))
1636 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1637 "ISO C forbids an empty translation unit");
1639 else
1641 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1642 mark_valid_location_for_stdc_pragma (false);
1645 ggc_collect ();
1646 c_parser_external_declaration (parser);
1647 obstack_free (&parser_obstack, obstack_position);
1649 while (c_parser_next_token_is_not (parser, CPP_EOF));
1652 unsigned int i;
1653 tree decl;
1654 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1655 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1656 error ("storage size of %q+D isn%'t known", decl);
1658 if (current_omp_declare_target_attribute)
1660 if (!errorcount)
1661 error ("%<#pragma omp declare target%> without corresponding "
1662 "%<#pragma omp end declare target%>");
1663 current_omp_declare_target_attribute = 0;
1667 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1669 external-declaration:
1670 function-definition
1671 declaration
1673 GNU extensions:
1675 external-declaration:
1676 asm-definition
1678 __extension__ external-declaration
1680 Objective-C:
1682 external-declaration:
1683 objc-class-definition
1684 objc-class-declaration
1685 objc-alias-declaration
1686 objc-protocol-definition
1687 objc-method-definition
1688 @end
1691 static void
1692 c_parser_external_declaration (c_parser *parser)
1694 int ext;
1695 switch (c_parser_peek_token (parser)->type)
1697 case CPP_KEYWORD:
1698 switch (c_parser_peek_token (parser)->keyword)
1700 case RID_EXTENSION:
1701 ext = disable_extension_diagnostics ();
1702 c_parser_consume_token (parser);
1703 c_parser_external_declaration (parser);
1704 restore_extension_diagnostics (ext);
1705 break;
1706 case RID_ASM:
1707 c_parser_asm_definition (parser);
1708 break;
1709 case RID_AT_INTERFACE:
1710 case RID_AT_IMPLEMENTATION:
1711 gcc_assert (c_dialect_objc ());
1712 c_parser_objc_class_definition (parser, NULL_TREE);
1713 break;
1714 case RID_AT_CLASS:
1715 gcc_assert (c_dialect_objc ());
1716 c_parser_objc_class_declaration (parser);
1717 break;
1718 case RID_AT_ALIAS:
1719 gcc_assert (c_dialect_objc ());
1720 c_parser_objc_alias_declaration (parser);
1721 break;
1722 case RID_AT_PROTOCOL:
1723 gcc_assert (c_dialect_objc ());
1724 c_parser_objc_protocol_definition (parser, NULL_TREE);
1725 break;
1726 case RID_AT_PROPERTY:
1727 gcc_assert (c_dialect_objc ());
1728 c_parser_objc_at_property_declaration (parser);
1729 break;
1730 case RID_AT_SYNTHESIZE:
1731 gcc_assert (c_dialect_objc ());
1732 c_parser_objc_at_synthesize_declaration (parser);
1733 break;
1734 case RID_AT_DYNAMIC:
1735 gcc_assert (c_dialect_objc ());
1736 c_parser_objc_at_dynamic_declaration (parser);
1737 break;
1738 case RID_AT_END:
1739 gcc_assert (c_dialect_objc ());
1740 c_parser_consume_token (parser);
1741 objc_finish_implementation ();
1742 break;
1743 default:
1744 goto decl_or_fndef;
1746 break;
1747 case CPP_SEMICOLON:
1748 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1749 "ISO C does not allow extra %<;%> outside of a function");
1750 c_parser_consume_token (parser);
1751 break;
1752 case CPP_PRAGMA:
1753 mark_valid_location_for_stdc_pragma (true);
1754 c_parser_pragma (parser, pragma_external, NULL);
1755 mark_valid_location_for_stdc_pragma (false);
1756 break;
1757 case CPP_PLUS:
1758 case CPP_MINUS:
1759 if (c_dialect_objc ())
1761 c_parser_objc_method_definition (parser);
1762 break;
1764 /* Else fall through, and yield a syntax error trying to parse
1765 as a declaration or function definition. */
1766 /* FALLTHRU */
1767 default:
1768 decl_or_fndef:
1769 /* A declaration or a function definition (or, in Objective-C,
1770 an @interface or @protocol with prefix attributes). We can
1771 only tell which after parsing the declaration specifiers, if
1772 any, and the first declarator. */
1773 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
1774 NULL, vNULL);
1775 break;
1779 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
1780 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1782 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1784 static void
1785 add_debug_begin_stmt (location_t loc)
1787 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1788 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1789 return;
1791 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1792 SET_EXPR_LOCATION (stmt, loc);
1793 add_stmt (stmt);
1796 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1797 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1798 is accepted; otherwise (old-style parameter declarations) only other
1799 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1800 assertion is accepted; otherwise (old-style parameter declarations)
1801 it is not. If NESTED is true, we are inside a function or parsing
1802 old-style parameter declarations; any functions encountered are
1803 nested functions and declaration specifiers are required; otherwise
1804 we are at top level and functions are normal functions and
1805 declaration specifiers may be optional. If EMPTY_OK is true, empty
1806 declarations are OK (subject to all other constraints); otherwise
1807 (old-style parameter declarations) they are diagnosed. If
1808 START_ATTR_OK is true, the declaration specifiers may start with
1809 attributes (GNU or standard); otherwise they may not.
1810 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1811 declaration when parsing an Objective-C foreach statement.
1812 FALLTHRU_ATTR_P is used to signal whether this function parsed
1813 "__attribute__((fallthrough));". ATTRS are any standard attributes
1814 parsed in the caller (in contexts where such attributes had to be
1815 parsed to determine whether what follows is a declaration or a
1816 statement); HAVE_ATTRS says whether there were any such attributes
1817 (even empty).
1819 declaration:
1820 declaration-specifiers init-declarator-list[opt] ;
1821 static_assert-declaration
1823 function-definition:
1824 declaration-specifiers[opt] declarator declaration-list[opt]
1825 compound-statement
1827 declaration-list:
1828 declaration
1829 declaration-list declaration
1831 init-declarator-list:
1832 init-declarator
1833 init-declarator-list , init-declarator
1835 init-declarator:
1836 declarator simple-asm-expr[opt] gnu-attributes[opt]
1837 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1839 GNU extensions:
1841 nested-function-definition:
1842 declaration-specifiers declarator declaration-list[opt]
1843 compound-statement
1845 attribute ;
1847 Objective-C:
1848 gnu-attributes objc-class-definition
1849 gnu-attributes objc-category-definition
1850 gnu-attributes objc-protocol-definition
1852 The simple-asm-expr and gnu-attributes are GNU extensions.
1854 This function does not handle __extension__; that is handled in its
1855 callers. ??? Following the old parser, __extension__ may start
1856 external declarations, declarations in functions and declarations
1857 at the start of "for" loops, but not old-style parameter
1858 declarations.
1860 C99 requires declaration specifiers in a function definition; the
1861 absence is diagnosed through the diagnosis of implicit int. In GNU
1862 C we also allow but diagnose declarations without declaration
1863 specifiers, but only at top level (elsewhere they conflict with
1864 other syntax).
1866 In Objective-C, declarations of the looping variable in a foreach
1867 statement are exceptionally terminated by 'in' (for example, 'for
1868 (NSObject *object in array) { ... }').
1870 OpenMP:
1872 declaration:
1873 threadprivate-directive
1875 GIMPLE:
1877 gimple-function-definition:
1878 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1879 declaration-list[opt] compound-statement
1881 rtl-function-definition:
1882 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1883 declaration-list[opt] compound-statement */
1885 static void
1886 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1887 bool static_assert_ok, bool empty_ok,
1888 bool nested, bool start_attr_ok,
1889 tree *objc_foreach_object_declaration,
1890 vec<c_token> omp_declare_simd_clauses,
1891 bool have_attrs, tree attrs,
1892 struct oacc_routine_data *oacc_routine_data,
1893 bool *fallthru_attr_p)
1895 struct c_declspecs *specs;
1896 tree prefix_attrs;
1897 tree all_prefix_attrs;
1898 bool diagnosed_no_specs = false;
1899 location_t here = c_parser_peek_token (parser)->location;
1901 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1903 if (static_assert_ok
1904 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1906 c_parser_static_assert_declaration (parser);
1907 return;
1909 specs = build_null_declspecs ();
1911 /* Handle any standard attributes parsed in the caller. */
1912 if (have_attrs)
1914 declspecs_add_attrs (here, specs, attrs);
1915 specs->non_std_attrs_seen_p = false;
1918 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1919 if (c_parser_peek_token (parser)->type == CPP_NAME
1920 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1921 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1922 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1923 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1925 tree name = c_parser_peek_token (parser)->value;
1927 /* Issue a warning about NAME being an unknown type name, perhaps
1928 with some kind of hint.
1929 If the user forgot a "struct" etc, suggest inserting
1930 it. Otherwise, attempt to look for misspellings. */
1931 gcc_rich_location richloc (here);
1932 if (tag_exists_p (RECORD_TYPE, name))
1934 /* This is not C++ with its implicit typedef. */
1935 richloc.add_fixit_insert_before ("struct ");
1936 error_at (&richloc,
1937 "unknown type name %qE;"
1938 " use %<struct%> keyword to refer to the type",
1939 name);
1941 else if (tag_exists_p (UNION_TYPE, name))
1943 richloc.add_fixit_insert_before ("union ");
1944 error_at (&richloc,
1945 "unknown type name %qE;"
1946 " use %<union%> keyword to refer to the type",
1947 name);
1949 else if (tag_exists_p (ENUMERAL_TYPE, name))
1951 richloc.add_fixit_insert_before ("enum ");
1952 error_at (&richloc,
1953 "unknown type name %qE;"
1954 " use %<enum%> keyword to refer to the type",
1955 name);
1957 else
1959 auto_diagnostic_group d;
1960 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1961 here);
1962 if (const char *suggestion = hint.suggestion ())
1964 richloc.add_fixit_replace (suggestion);
1965 error_at (&richloc,
1966 "unknown type name %qE; did you mean %qs?",
1967 name, suggestion);
1969 else
1970 error_at (here, "unknown type name %qE", name);
1973 /* Parse declspecs normally to get a correct pointer type, but avoid
1974 a further "fails to be a type name" error. Refuse nested functions
1975 since it is not how the user likely wants us to recover. */
1976 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1977 c_parser_peek_token (parser)->keyword = RID_VOID;
1978 c_parser_peek_token (parser)->value = error_mark_node;
1979 fndef_ok = !nested;
1982 /* When there are standard attributes at the start of the
1983 declaration (to apply to the entity being declared), an
1984 init-declarator-list or function definition must be present. */
1985 if (c_parser_nth_token_starts_std_attributes (parser, 1))
1986 have_attrs = true;
1988 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1989 true, true, start_attr_ok, true, cla_nonabstract_decl);
1990 if (parser->error)
1992 c_parser_skip_to_end_of_block_or_statement (parser);
1993 return;
1995 if (nested && !specs->declspecs_seen_p)
1997 c_parser_error (parser, "expected declaration specifiers");
1998 c_parser_skip_to_end_of_block_or_statement (parser);
1999 return;
2002 finish_declspecs (specs);
2003 bool auto_type_p = specs->typespec_word == cts_auto_type;
2004 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2006 if (auto_type_p)
2007 error_at (here, "%<__auto_type%> in empty declaration");
2008 else if (specs->typespec_kind == ctsk_none
2009 && attribute_fallthrough_p (specs->attrs))
2011 if (fallthru_attr_p != NULL)
2012 *fallthru_attr_p = true;
2013 if (nested)
2015 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2016 void_type_node, 0);
2017 add_stmt (fn);
2019 else
2020 pedwarn (here, OPT_Wattributes,
2021 "%<fallthrough%> attribute at top level");
2023 else if (empty_ok && !(have_attrs
2024 && specs->non_std_attrs_seen_p))
2025 shadow_tag (specs);
2026 else
2028 shadow_tag_warned (specs, 1);
2029 pedwarn (here, 0, "empty declaration");
2031 c_parser_consume_token (parser);
2032 if (oacc_routine_data)
2033 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2034 return;
2037 /* Provide better error recovery. Note that a type name here is usually
2038 better diagnosed as a redeclaration. */
2039 if (empty_ok
2040 && specs->typespec_kind == ctsk_tagdef
2041 && c_parser_next_token_starts_declspecs (parser)
2042 && !c_parser_next_token_is (parser, CPP_NAME))
2044 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2045 parser->error = false;
2046 shadow_tag_warned (specs, 1);
2047 return;
2049 else if (c_dialect_objc () && !auto_type_p)
2051 /* Prefix attributes are an error on method decls. */
2052 switch (c_parser_peek_token (parser)->type)
2054 case CPP_PLUS:
2055 case CPP_MINUS:
2056 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2057 return;
2058 if (specs->attrs)
2060 warning_at (c_parser_peek_token (parser)->location,
2061 OPT_Wattributes,
2062 "prefix attributes are ignored for methods");
2063 specs->attrs = NULL_TREE;
2065 if (fndef_ok)
2066 c_parser_objc_method_definition (parser);
2067 else
2068 c_parser_objc_methodproto (parser);
2069 return;
2070 break;
2071 default:
2072 break;
2074 /* This is where we parse 'attributes @interface ...',
2075 'attributes @implementation ...', 'attributes @protocol ...'
2076 (where attributes could be, for example, __attribute__
2077 ((deprecated)).
2079 switch (c_parser_peek_token (parser)->keyword)
2081 case RID_AT_INTERFACE:
2083 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2084 return;
2085 c_parser_objc_class_definition (parser, specs->attrs);
2086 return;
2088 break;
2089 case RID_AT_IMPLEMENTATION:
2091 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2092 return;
2093 if (specs->attrs)
2095 warning_at (c_parser_peek_token (parser)->location,
2096 OPT_Wattributes,
2097 "prefix attributes are ignored for implementations");
2098 specs->attrs = NULL_TREE;
2100 c_parser_objc_class_definition (parser, NULL_TREE);
2101 return;
2103 break;
2104 case RID_AT_PROTOCOL:
2106 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2107 return;
2108 c_parser_objc_protocol_definition (parser, specs->attrs);
2109 return;
2111 break;
2112 case RID_AT_ALIAS:
2113 case RID_AT_CLASS:
2114 case RID_AT_END:
2115 case RID_AT_PROPERTY:
2116 if (specs->attrs)
2118 c_parser_error (parser, "unexpected attribute");
2119 specs->attrs = NULL;
2121 break;
2122 default:
2123 break;
2126 else if (attribute_fallthrough_p (specs->attrs))
2127 warning_at (here, OPT_Wattributes,
2128 "%<fallthrough%> attribute not followed by %<;%>");
2130 pending_xref_error ();
2131 prefix_attrs = specs->attrs;
2132 all_prefix_attrs = prefix_attrs;
2133 specs->attrs = NULL_TREE;
2134 while (true)
2136 struct c_declarator *declarator;
2137 bool dummy = false;
2138 timevar_id_t tv;
2139 tree fnbody = NULL_TREE;
2140 /* Declaring either one or more declarators (in which case we
2141 should diagnose if there were no declaration specifiers) or a
2142 function definition (in which case the diagnostic for
2143 implicit int suffices). */
2144 declarator = c_parser_declarator (parser,
2145 specs->typespec_kind != ctsk_none,
2146 C_DTR_NORMAL, &dummy);
2147 if (declarator == NULL)
2149 if (omp_declare_simd_clauses.exists ())
2150 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2151 omp_declare_simd_clauses);
2152 if (oacc_routine_data)
2153 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2154 c_parser_skip_to_end_of_block_or_statement (parser);
2155 return;
2157 if (auto_type_p && declarator->kind != cdk_id)
2159 error_at (here,
2160 "%<__auto_type%> requires a plain identifier"
2161 " as declarator");
2162 c_parser_skip_to_end_of_block_or_statement (parser);
2163 return;
2165 if (c_parser_next_token_is (parser, CPP_EQ)
2166 || c_parser_next_token_is (parser, CPP_COMMA)
2167 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2168 || c_parser_next_token_is_keyword (parser, RID_ASM)
2169 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2170 || c_parser_next_token_is_keyword (parser, RID_IN))
2172 tree asm_name = NULL_TREE;
2173 tree postfix_attrs = NULL_TREE;
2174 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2176 diagnosed_no_specs = true;
2177 pedwarn (here, 0, "data definition has no type or storage class");
2179 /* Having seen a data definition, there cannot now be a
2180 function definition. */
2181 fndef_ok = false;
2182 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2183 asm_name = c_parser_simple_asm_expr (parser);
2184 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2186 postfix_attrs = c_parser_gnu_attributes (parser);
2187 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2189 /* This means there is an attribute specifier after
2190 the declarator in a function definition. Provide
2191 some more information for the user. */
2192 error_at (here, "attributes should be specified before the "
2193 "declarator in a function definition");
2194 c_parser_skip_to_end_of_block_or_statement (parser);
2195 return;
2198 if (c_parser_next_token_is (parser, CPP_EQ))
2200 tree d;
2201 struct c_expr init;
2202 location_t init_loc;
2203 c_parser_consume_token (parser);
2204 if (auto_type_p)
2206 init_loc = c_parser_peek_token (parser)->location;
2207 rich_location richloc (line_table, init_loc);
2208 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2209 /* A parameter is initialized, which is invalid. Don't
2210 attempt to instrument the initializer. */
2211 int flag_sanitize_save = flag_sanitize;
2212 if (nested && !empty_ok)
2213 flag_sanitize = 0;
2214 init = c_parser_expr_no_commas (parser, NULL);
2215 flag_sanitize = flag_sanitize_save;
2216 if (TREE_CODE (init.value) == COMPONENT_REF
2217 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2218 error_at (here,
2219 "%<__auto_type%> used with a bit-field"
2220 " initializer");
2221 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2222 tree init_type = TREE_TYPE (init.value);
2223 /* As with typeof, remove all qualifiers from atomic types. */
2224 if (init_type != error_mark_node && TYPE_ATOMIC (init_type))
2225 init_type
2226 = c_build_qualified_type (init_type, TYPE_UNQUALIFIED);
2227 bool vm_type = variably_modified_type_p (init_type,
2228 NULL_TREE);
2229 if (vm_type)
2230 init.value = save_expr (init.value);
2231 finish_init ();
2232 specs->typespec_kind = ctsk_typeof;
2233 specs->locations[cdw_typedef] = init_loc;
2234 specs->typedef_p = true;
2235 specs->type = init_type;
2236 if (vm_type)
2238 bool maybe_const = true;
2239 tree type_expr = c_fully_fold (init.value, false,
2240 &maybe_const);
2241 specs->expr_const_operands &= maybe_const;
2242 if (specs->expr)
2243 specs->expr = build2 (COMPOUND_EXPR,
2244 TREE_TYPE (type_expr),
2245 specs->expr, type_expr);
2246 else
2247 specs->expr = type_expr;
2249 d = start_decl (declarator, specs, true,
2250 chainon (postfix_attrs, all_prefix_attrs));
2251 if (!d)
2252 d = error_mark_node;
2253 if (omp_declare_simd_clauses.exists ())
2254 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2255 omp_declare_simd_clauses);
2257 else
2259 /* The declaration of the variable is in effect while
2260 its initializer is parsed. */
2261 d = start_decl (declarator, specs, true,
2262 chainon (postfix_attrs, all_prefix_attrs));
2263 if (!d)
2264 d = error_mark_node;
2265 if (omp_declare_simd_clauses.exists ())
2266 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2267 omp_declare_simd_clauses);
2268 init_loc = c_parser_peek_token (parser)->location;
2269 rich_location richloc (line_table, init_loc);
2270 start_init (d, asm_name, global_bindings_p (), &richloc);
2271 /* A parameter is initialized, which is invalid. Don't
2272 attempt to instrument the initializer. */
2273 int flag_sanitize_save = flag_sanitize;
2274 if (TREE_CODE (d) == PARM_DECL)
2275 flag_sanitize = 0;
2276 init = c_parser_initializer (parser);
2277 flag_sanitize = flag_sanitize_save;
2278 finish_init ();
2280 if (oacc_routine_data)
2281 c_finish_oacc_routine (oacc_routine_data, d, false);
2282 if (d != error_mark_node)
2284 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2285 finish_decl (d, init_loc, init.value,
2286 init.original_type, asm_name);
2289 else
2291 if (auto_type_p)
2293 error_at (here,
2294 "%<__auto_type%> requires an initialized "
2295 "data declaration");
2296 c_parser_skip_to_end_of_block_or_statement (parser);
2297 return;
2299 tree d = start_decl (declarator, specs, false,
2300 chainon (postfix_attrs,
2301 all_prefix_attrs));
2302 if (d
2303 && TREE_CODE (d) == FUNCTION_DECL
2304 && DECL_ARGUMENTS (d) == NULL_TREE
2305 && DECL_INITIAL (d) == NULL_TREE)
2307 /* Find the innermost declarator that is neither cdk_id
2308 nor cdk_attrs. */
2309 const struct c_declarator *decl = declarator;
2310 const struct c_declarator *last_non_id_attrs = NULL;
2312 while (decl)
2313 switch (decl->kind)
2315 case cdk_array:
2316 case cdk_function:
2317 case cdk_pointer:
2318 last_non_id_attrs = decl;
2319 decl = decl->declarator;
2320 break;
2322 case cdk_attrs:
2323 decl = decl->declarator;
2324 break;
2326 case cdk_id:
2327 decl = 0;
2328 break;
2330 default:
2331 gcc_unreachable ();
2334 /* If it exists and is cdk_function, use its parameters. */
2335 if (last_non_id_attrs
2336 && last_non_id_attrs->kind == cdk_function)
2337 DECL_ARGUMENTS (d) = last_non_id_attrs->u.arg_info->parms;
2339 if (omp_declare_simd_clauses.exists ())
2341 tree parms = NULL_TREE;
2342 if (d && TREE_CODE (d) == FUNCTION_DECL)
2344 struct c_declarator *ce = declarator;
2345 while (ce != NULL)
2346 if (ce->kind == cdk_function)
2348 parms = ce->u.arg_info->parms;
2349 break;
2351 else
2352 ce = ce->declarator;
2354 if (parms)
2355 temp_store_parm_decls (d, parms);
2356 c_finish_omp_declare_simd (parser, d, parms,
2357 omp_declare_simd_clauses);
2358 if (parms)
2359 temp_pop_parm_decls ();
2361 if (oacc_routine_data)
2362 c_finish_oacc_routine (oacc_routine_data, d, false);
2363 if (d)
2364 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2365 NULL_TREE, asm_name);
2367 if (c_parser_next_token_is_keyword (parser, RID_IN))
2369 if (d)
2370 *objc_foreach_object_declaration = d;
2371 else
2372 *objc_foreach_object_declaration = error_mark_node;
2375 if (c_parser_next_token_is (parser, CPP_COMMA))
2377 if (auto_type_p)
2379 error_at (here,
2380 "%<__auto_type%> may only be used with"
2381 " a single declarator");
2382 c_parser_skip_to_end_of_block_or_statement (parser);
2383 return;
2385 c_parser_consume_token (parser);
2386 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2387 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2388 prefix_attrs);
2389 else
2390 all_prefix_attrs = prefix_attrs;
2391 continue;
2393 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2395 c_parser_consume_token (parser);
2396 return;
2398 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2400 /* This can only happen in Objective-C: we found the
2401 'in' that terminates the declaration inside an
2402 Objective-C foreach statement. Do not consume the
2403 token, so that the caller can use it to determine
2404 that this indeed is a foreach context. */
2405 return;
2407 else
2409 c_parser_error (parser, "expected %<,%> or %<;%>");
2410 c_parser_skip_to_end_of_block_or_statement (parser);
2411 return;
2414 else if (auto_type_p)
2416 error_at (here,
2417 "%<__auto_type%> requires an initialized data declaration");
2418 c_parser_skip_to_end_of_block_or_statement (parser);
2419 return;
2421 else if (!fndef_ok)
2423 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2424 "%<asm%> or %<__attribute__%>");
2425 c_parser_skip_to_end_of_block_or_statement (parser);
2426 return;
2428 /* Function definition (nested or otherwise). */
2429 if (nested)
2431 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2432 c_push_function_context ();
2434 if (!start_function (specs, declarator, all_prefix_attrs))
2436 /* At this point we've consumed:
2437 declaration-specifiers declarator
2438 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2439 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2440 but the
2441 declaration-specifiers declarator
2442 aren't grokkable as a function definition, so we have
2443 an error. */
2444 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2445 if (c_parser_next_token_starts_declspecs (parser))
2447 /* If we have
2448 declaration-specifiers declarator decl-specs
2449 then assume we have a missing semicolon, which would
2450 give us:
2451 declaration-specifiers declarator decl-specs
2454 <~~~~~~~~~ declaration ~~~~~~~~~~>
2455 Use c_parser_require to get an error with a fix-it hint. */
2456 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2457 parser->error = false;
2459 else
2461 /* This can appear in many cases looking nothing like a
2462 function definition, so we don't give a more specific
2463 error suggesting there was one. */
2464 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2465 "or %<__attribute__%>");
2467 if (nested)
2468 c_pop_function_context ();
2469 break;
2472 if (DECL_DECLARED_INLINE_P (current_function_decl))
2473 tv = TV_PARSE_INLINE;
2474 else
2475 tv = TV_PARSE_FUNC;
2476 auto_timevar at (g_timer, tv);
2478 /* Parse old-style parameter declarations. ??? Attributes are
2479 not allowed to start declaration specifiers here because of a
2480 syntax conflict between a function declaration with attribute
2481 suffix and a function definition with an attribute prefix on
2482 first old-style parameter declaration. Following the old
2483 parser, they are not accepted on subsequent old-style
2484 parameter declarations either. However, there is no
2485 ambiguity after the first declaration, nor indeed on the
2486 first as long as we don't allow postfix attributes after a
2487 declarator with a nonempty identifier list in a definition;
2488 and postfix attributes have never been accepted here in
2489 function definitions either. */
2490 while (c_parser_next_token_is_not (parser, CPP_EOF)
2491 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2492 c_parser_declaration_or_fndef (parser, false, false, false,
2493 true, false, NULL, vNULL);
2494 store_parm_decls ();
2495 if (omp_declare_simd_clauses.exists ())
2496 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2497 omp_declare_simd_clauses);
2498 if (oacc_routine_data)
2499 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2500 location_t startloc = c_parser_peek_token (parser)->location;
2501 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2502 = startloc;
2503 location_t endloc = startloc;
2505 /* If the definition was marked with __RTL, use the RTL parser now,
2506 consuming the function body. */
2507 if (specs->declspec_il == cdil_rtl)
2509 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2511 /* Normally, store_parm_decls sets next_is_function_body,
2512 anticipating a function body. We need a push_scope/pop_scope
2513 pair to flush out this state, or subsequent function parsing
2514 will go wrong. */
2515 push_scope ();
2516 pop_scope ();
2518 finish_function (endloc);
2519 return;
2521 /* If the definition was marked with __GIMPLE then parse the
2522 function body as GIMPLE. */
2523 else if (specs->declspec_il != cdil_none)
2525 bool saved = in_late_binary_op;
2526 in_late_binary_op = true;
2527 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2528 specs->declspec_il,
2529 specs->entry_bb_count);
2530 in_late_binary_op = saved;
2532 else
2533 fnbody = c_parser_compound_statement (parser, &endloc);
2534 tree fndecl = current_function_decl;
2535 if (nested)
2537 tree decl = current_function_decl;
2538 /* Mark nested functions as needing static-chain initially.
2539 lower_nested_functions will recompute it but the
2540 DECL_STATIC_CHAIN flag is also used before that happens,
2541 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2542 DECL_STATIC_CHAIN (decl) = 1;
2543 add_stmt (fnbody);
2544 finish_function (endloc);
2545 c_pop_function_context ();
2546 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2548 else
2550 if (fnbody)
2551 add_stmt (fnbody);
2552 finish_function (endloc);
2554 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2555 if (specs->declspec_il != cdil_none)
2556 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2558 break;
2562 /* Parse an asm-definition (asm() outside a function body). This is a
2563 GNU extension.
2565 asm-definition:
2566 simple-asm-expr ;
2569 static void
2570 c_parser_asm_definition (c_parser *parser)
2572 tree asm_str = c_parser_simple_asm_expr (parser);
2573 if (asm_str)
2574 symtab->finalize_toplevel_asm (asm_str);
2575 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2578 /* Parse a static assertion (C11 6.7.10).
2580 static_assert-declaration:
2581 static_assert-declaration-no-semi ;
2584 static void
2585 c_parser_static_assert_declaration (c_parser *parser)
2587 c_parser_static_assert_declaration_no_semi (parser);
2588 if (parser->error
2589 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2590 c_parser_skip_to_end_of_block_or_statement (parser);
2593 /* Parse a static assertion (C11 6.7.10), without the trailing
2594 semicolon.
2596 static_assert-declaration-no-semi:
2597 _Static_assert ( constant-expression , string-literal )
2599 C2X:
2600 static_assert-declaration-no-semi:
2601 _Static_assert ( constant-expression )
2604 static void
2605 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2607 location_t assert_loc, value_loc;
2608 tree value;
2609 tree string = NULL_TREE;
2611 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2612 assert_loc = c_parser_peek_token (parser)->location;
2613 if (flag_isoc99)
2614 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2615 "ISO C99 does not support %<_Static_assert%>");
2616 else
2617 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2618 "ISO C90 does not support %<_Static_assert%>");
2619 c_parser_consume_token (parser);
2620 matching_parens parens;
2621 if (!parens.require_open (parser))
2622 return;
2623 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2624 value = c_parser_expr_no_commas (parser, NULL).value;
2625 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2626 if (c_parser_next_token_is (parser, CPP_COMMA))
2628 c_parser_consume_token (parser);
2629 switch (c_parser_peek_token (parser)->type)
2631 case CPP_STRING:
2632 case CPP_STRING16:
2633 case CPP_STRING32:
2634 case CPP_WSTRING:
2635 case CPP_UTF8STRING:
2636 string = c_parser_string_literal (parser, false, true).value;
2637 break;
2638 default:
2639 c_parser_error (parser, "expected string literal");
2640 return;
2643 else if (flag_isoc11)
2644 /* If pedantic for pre-C11, the use of _Static_assert itself will
2645 have been diagnosed, so do not also diagnose the use of this
2646 new C2X feature of _Static_assert. */
2647 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2648 "ISO C11 does not support omitting the string in "
2649 "%<_Static_assert%>");
2650 parens.require_close (parser);
2652 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2654 error_at (value_loc, "expression in static assertion is not an integer");
2655 return;
2657 if (TREE_CODE (value) != INTEGER_CST)
2659 value = c_fully_fold (value, false, NULL);
2660 /* Strip no-op conversions. */
2661 STRIP_TYPE_NOPS (value);
2662 if (TREE_CODE (value) == INTEGER_CST)
2663 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2664 "is not an integer constant expression");
2666 if (TREE_CODE (value) != INTEGER_CST)
2668 error_at (value_loc, "expression in static assertion is not constant");
2669 return;
2671 constant_expression_warning (value);
2672 if (integer_zerop (value))
2674 if (string)
2675 error_at (assert_loc, "static assertion failed: %E", string);
2676 else
2677 error_at (assert_loc, "static assertion failed");
2681 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2682 6.7, C11 6.7), adding them to SPECS (which may already include some).
2683 Storage class specifiers are accepted iff SCSPEC_OK; type
2684 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2685 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2686 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2687 addition to the syntax shown, standard attributes are accepted at
2688 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2689 unlike gnu-attributes, they are not accepted in the middle of the
2690 list. (This combines various different syntax productions in the C
2691 standard, and in some cases gnu-attributes and standard attributes
2692 at the start may already have been parsed before this function is
2693 called.)
2695 declaration-specifiers:
2696 storage-class-specifier declaration-specifiers[opt]
2697 type-specifier declaration-specifiers[opt]
2698 type-qualifier declaration-specifiers[opt]
2699 function-specifier declaration-specifiers[opt]
2700 alignment-specifier declaration-specifiers[opt]
2702 Function specifiers (inline) are from C99, and are currently
2703 handled as storage class specifiers, as is __thread. Alignment
2704 specifiers are from C11.
2706 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2707 storage-class-specifier:
2708 typedef
2709 extern
2710 static
2711 auto
2712 register
2713 _Thread_local
2715 (_Thread_local is new in C11.)
2717 C99 6.7.4, C11 6.7.4:
2718 function-specifier:
2719 inline
2720 _Noreturn
2722 (_Noreturn is new in C11.)
2724 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2725 type-specifier:
2726 void
2727 char
2728 short
2730 long
2731 float
2732 double
2733 signed
2734 unsigned
2735 _Bool
2736 _Complex
2737 [_Imaginary removed in C99 TC2]
2738 struct-or-union-specifier
2739 enum-specifier
2740 typedef-name
2741 atomic-type-specifier
2743 (_Bool and _Complex are new in C99.)
2744 (atomic-type-specifier is new in C11.)
2746 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2748 type-qualifier:
2749 const
2750 restrict
2751 volatile
2752 address-space-qualifier
2753 _Atomic
2755 (restrict is new in C99.)
2756 (_Atomic is new in C11.)
2758 GNU extensions:
2760 declaration-specifiers:
2761 gnu-attributes declaration-specifiers[opt]
2763 type-qualifier:
2764 address-space
2766 address-space:
2767 identifier recognized by the target
2769 storage-class-specifier:
2770 __thread
2772 type-specifier:
2773 typeof-specifier
2774 __auto_type
2775 __intN
2776 _Decimal32
2777 _Decimal64
2778 _Decimal128
2779 _Fract
2780 _Accum
2781 _Sat
2783 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2784 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2786 atomic-type-specifier
2787 _Atomic ( type-name )
2789 Objective-C:
2791 type-specifier:
2792 class-name objc-protocol-refs[opt]
2793 typedef-name objc-protocol-refs
2794 objc-protocol-refs
2797 void
2798 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2799 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2800 bool alignspec_ok, bool auto_type_ok,
2801 bool start_std_attr_ok, bool end_std_attr_ok,
2802 enum c_lookahead_kind la)
2804 bool attrs_ok = start_attr_ok;
2805 bool seen_type = specs->typespec_kind != ctsk_none;
2807 if (!typespec_ok)
2808 gcc_assert (la == cla_prefer_id);
2810 if (start_std_attr_ok
2811 && c_parser_nth_token_starts_std_attributes (parser, 1))
2813 gcc_assert (!specs->non_std_attrs_seen_p);
2814 location_t loc = c_parser_peek_token (parser)->location;
2815 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2816 declspecs_add_attrs (loc, specs, attrs);
2817 specs->non_std_attrs_seen_p = false;
2820 while (c_parser_next_token_is (parser, CPP_NAME)
2821 || c_parser_next_token_is (parser, CPP_KEYWORD)
2822 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2824 struct c_typespec t;
2825 tree attrs;
2826 tree align;
2827 location_t loc = c_parser_peek_token (parser)->location;
2829 /* If we cannot accept a type, exit if the next token must start
2830 one. Also, if we already have seen a tagged definition,
2831 a typename would be an error anyway and likely the user
2832 has simply forgotten a semicolon, so we exit. */
2833 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2834 && c_parser_next_tokens_start_typename (parser, la)
2835 && !c_parser_next_token_is_qualifier (parser)
2836 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2837 break;
2839 if (c_parser_next_token_is (parser, CPP_NAME))
2841 c_token *name_token = c_parser_peek_token (parser);
2842 tree value = name_token->value;
2843 c_id_kind kind = name_token->id_kind;
2845 if (kind == C_ID_ADDRSPACE)
2847 addr_space_t as
2848 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2849 declspecs_add_addrspace (name_token->location, specs, as);
2850 c_parser_consume_token (parser);
2851 attrs_ok = true;
2852 continue;
2855 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2857 /* If we cannot accept a type, and the next token must start one,
2858 exit. Do the same if we already have seen a tagged definition,
2859 since it would be an error anyway and likely the user has simply
2860 forgotten a semicolon. */
2861 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2862 break;
2864 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2865 a C_ID_CLASSNAME. */
2866 c_parser_consume_token (parser);
2867 seen_type = true;
2868 attrs_ok = true;
2869 if (kind == C_ID_ID)
2871 error_at (loc, "unknown type name %qE", value);
2872 t.kind = ctsk_typedef;
2873 t.spec = error_mark_node;
2875 else if (kind == C_ID_TYPENAME
2876 && (!c_dialect_objc ()
2877 || c_parser_next_token_is_not (parser, CPP_LESS)))
2879 t.kind = ctsk_typedef;
2880 /* For a typedef name, record the meaning, not the name.
2881 In case of 'foo foo, bar;'. */
2882 t.spec = lookup_name (value);
2884 else
2886 tree proto = NULL_TREE;
2887 gcc_assert (c_dialect_objc ());
2888 t.kind = ctsk_objc;
2889 if (c_parser_next_token_is (parser, CPP_LESS))
2890 proto = c_parser_objc_protocol_refs (parser);
2891 t.spec = objc_get_protocol_qualified_type (value, proto);
2893 t.expr = NULL_TREE;
2894 t.expr_const_operands = true;
2895 declspecs_add_type (name_token->location, specs, t);
2896 continue;
2898 if (c_parser_next_token_is (parser, CPP_LESS))
2900 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2901 nisse@lysator.liu.se. */
2902 tree proto;
2903 gcc_assert (c_dialect_objc ());
2904 if (!typespec_ok || seen_type)
2905 break;
2906 proto = c_parser_objc_protocol_refs (parser);
2907 t.kind = ctsk_objc;
2908 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2909 t.expr = NULL_TREE;
2910 t.expr_const_operands = true;
2911 declspecs_add_type (loc, specs, t);
2912 continue;
2914 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2915 switch (c_parser_peek_token (parser)->keyword)
2917 case RID_STATIC:
2918 case RID_EXTERN:
2919 case RID_REGISTER:
2920 case RID_TYPEDEF:
2921 case RID_INLINE:
2922 case RID_NORETURN:
2923 case RID_AUTO:
2924 case RID_THREAD:
2925 if (!scspec_ok)
2926 goto out;
2927 attrs_ok = true;
2928 /* TODO: Distinguish between function specifiers (inline, noreturn)
2929 and storage class specifiers, either here or in
2930 declspecs_add_scspec. */
2931 declspecs_add_scspec (loc, specs,
2932 c_parser_peek_token (parser)->value);
2933 c_parser_consume_token (parser);
2934 break;
2935 case RID_AUTO_TYPE:
2936 if (!auto_type_ok)
2937 goto out;
2938 /* Fall through. */
2939 case RID_UNSIGNED:
2940 case RID_LONG:
2941 case RID_SHORT:
2942 case RID_SIGNED:
2943 case RID_COMPLEX:
2944 case RID_INT:
2945 case RID_CHAR:
2946 case RID_FLOAT:
2947 case RID_DOUBLE:
2948 case RID_VOID:
2949 case RID_DFLOAT32:
2950 case RID_DFLOAT64:
2951 case RID_DFLOAT128:
2952 CASE_RID_FLOATN_NX:
2953 case RID_BOOL:
2954 case RID_FRACT:
2955 case RID_ACCUM:
2956 case RID_SAT:
2957 case RID_INT_N_0:
2958 case RID_INT_N_1:
2959 case RID_INT_N_2:
2960 case RID_INT_N_3:
2961 if (!typespec_ok)
2962 goto out;
2963 attrs_ok = true;
2964 seen_type = true;
2965 if (c_dialect_objc ())
2966 parser->objc_need_raw_identifier = true;
2967 t.kind = ctsk_resword;
2968 t.spec = c_parser_peek_token (parser)->value;
2969 t.expr = NULL_TREE;
2970 t.expr_const_operands = true;
2971 declspecs_add_type (loc, specs, t);
2972 c_parser_consume_token (parser);
2973 break;
2974 case RID_ENUM:
2975 if (!typespec_ok)
2976 goto out;
2977 attrs_ok = true;
2978 seen_type = true;
2979 t = c_parser_enum_specifier (parser);
2980 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2981 declspecs_add_type (loc, specs, t);
2982 break;
2983 case RID_STRUCT:
2984 case RID_UNION:
2985 if (!typespec_ok)
2986 goto out;
2987 attrs_ok = true;
2988 seen_type = true;
2989 t = c_parser_struct_or_union_specifier (parser);
2990 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2991 declspecs_add_type (loc, specs, t);
2992 break;
2993 case RID_TYPEOF:
2994 /* ??? The old parser rejected typeof after other type
2995 specifiers, but is a syntax error the best way of
2996 handling this? */
2997 if (!typespec_ok || seen_type)
2998 goto out;
2999 attrs_ok = true;
3000 seen_type = true;
3001 t = c_parser_typeof_specifier (parser);
3002 declspecs_add_type (loc, specs, t);
3003 break;
3004 case RID_ATOMIC:
3005 /* C parser handling of Objective-C constructs needs
3006 checking for correct lvalue-to-rvalue conversions, and
3007 the code in build_modify_expr handling various
3008 Objective-C cases, and that in build_unary_op handling
3009 Objective-C cases for increment / decrement, also needs
3010 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3011 and objc_types_are_equivalent may also need updates. */
3012 if (c_dialect_objc ())
3013 sorry ("%<_Atomic%> in Objective-C");
3014 if (flag_isoc99)
3015 pedwarn_c99 (loc, OPT_Wpedantic,
3016 "ISO C99 does not support the %<_Atomic%> qualifier");
3017 else
3018 pedwarn_c99 (loc, OPT_Wpedantic,
3019 "ISO C90 does not support the %<_Atomic%> qualifier");
3020 attrs_ok = true;
3021 tree value;
3022 value = c_parser_peek_token (parser)->value;
3023 c_parser_consume_token (parser);
3024 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3026 /* _Atomic ( type-name ). */
3027 seen_type = true;
3028 c_parser_consume_token (parser);
3029 struct c_type_name *type = c_parser_type_name (parser);
3030 t.kind = ctsk_typeof;
3031 t.spec = error_mark_node;
3032 t.expr = NULL_TREE;
3033 t.expr_const_operands = true;
3034 if (type != NULL)
3035 t.spec = groktypename (type, &t.expr,
3036 &t.expr_const_operands);
3037 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3038 "expected %<)%>");
3039 if (t.spec != error_mark_node)
3041 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3042 error_at (loc, "%<_Atomic%>-qualified array type");
3043 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3044 error_at (loc, "%<_Atomic%>-qualified function type");
3045 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3046 error_at (loc, "%<_Atomic%> applied to a qualified type");
3047 else
3048 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3050 declspecs_add_type (loc, specs, t);
3052 else
3053 declspecs_add_qual (loc, specs, value);
3054 break;
3055 case RID_CONST:
3056 case RID_VOLATILE:
3057 case RID_RESTRICT:
3058 attrs_ok = true;
3059 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3060 c_parser_consume_token (parser);
3061 break;
3062 case RID_ATTRIBUTE:
3063 if (!attrs_ok)
3064 goto out;
3065 attrs = c_parser_gnu_attributes (parser);
3066 declspecs_add_attrs (loc, specs, attrs);
3067 break;
3068 case RID_ALIGNAS:
3069 if (!alignspec_ok)
3070 goto out;
3071 align = c_parser_alignas_specifier (parser);
3072 declspecs_add_alignas (loc, specs, align);
3073 break;
3074 case RID_GIMPLE:
3075 if (! flag_gimple)
3076 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3077 c_parser_consume_token (parser);
3078 specs->declspec_il = cdil_gimple;
3079 specs->locations[cdw_gimple] = loc;
3080 c_parser_gimple_or_rtl_pass_list (parser, specs);
3081 break;
3082 case RID_RTL:
3083 c_parser_consume_token (parser);
3084 specs->declspec_il = cdil_rtl;
3085 specs->locations[cdw_rtl] = loc;
3086 c_parser_gimple_or_rtl_pass_list (parser, specs);
3087 break;
3088 default:
3089 goto out;
3092 out:
3093 if (end_std_attr_ok
3094 && c_parser_nth_token_starts_std_attributes (parser, 1))
3095 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3098 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3100 enum-specifier:
3101 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3102 gnu-attributes[opt]
3103 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3104 gnu-attributes[opt]
3105 enum gnu-attributes[opt] identifier
3107 The form with trailing comma is new in C99. The forms with
3108 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3109 without commas in the syntax (assignment expressions, not just
3110 conditional expressions); assignment expressions will be diagnosed
3111 as non-constant.
3113 enumerator-list:
3114 enumerator
3115 enumerator-list , enumerator
3117 enumerator:
3118 enumeration-constant attribute-specifier-sequence[opt]
3119 enumeration-constant attribute-specifier-sequence[opt]
3120 = constant-expression
3122 GNU Extensions:
3124 enumerator:
3125 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3126 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3127 = constant-expression
3131 static struct c_typespec
3132 c_parser_enum_specifier (c_parser *parser)
3134 struct c_typespec ret;
3135 bool have_std_attrs;
3136 tree std_attrs = NULL_TREE;
3137 tree attrs;
3138 tree ident = NULL_TREE;
3139 location_t enum_loc;
3140 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3141 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3142 c_parser_consume_token (parser);
3143 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3144 if (have_std_attrs)
3145 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3146 attrs = c_parser_gnu_attributes (parser);
3147 enum_loc = c_parser_peek_token (parser)->location;
3148 /* Set the location in case we create a decl now. */
3149 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3150 if (c_parser_next_token_is (parser, CPP_NAME))
3152 ident = c_parser_peek_token (parser)->value;
3153 ident_loc = c_parser_peek_token (parser)->location;
3154 enum_loc = ident_loc;
3155 c_parser_consume_token (parser);
3157 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3159 /* Parse an enum definition. */
3160 struct c_enum_contents the_enum;
3161 tree type;
3162 tree postfix_attrs;
3163 /* We chain the enumerators in reverse order, then put them in
3164 forward order at the end. */
3165 tree values;
3166 timevar_push (TV_PARSE_ENUM);
3167 type = start_enum (enum_loc, &the_enum, ident);
3168 values = NULL_TREE;
3169 c_parser_consume_token (parser);
3170 while (true)
3172 tree enum_id;
3173 tree enum_value;
3174 tree enum_decl;
3175 bool seen_comma;
3176 c_token *token;
3177 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3178 location_t decl_loc, value_loc;
3179 if (c_parser_next_token_is_not (parser, CPP_NAME))
3181 /* Give a nicer error for "enum {}". */
3182 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3183 && !parser->error)
3185 error_at (c_parser_peek_token (parser)->location,
3186 "empty enum is invalid");
3187 parser->error = true;
3189 else
3190 c_parser_error (parser, "expected identifier");
3191 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3192 values = error_mark_node;
3193 break;
3195 token = c_parser_peek_token (parser);
3196 enum_id = token->value;
3197 /* Set the location in case we create a decl now. */
3198 c_parser_set_source_position_from_token (token);
3199 decl_loc = value_loc = token->location;
3200 c_parser_consume_token (parser);
3201 /* Parse any specified attributes. */
3202 tree std_attrs = NULL_TREE;
3203 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3204 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3205 tree enum_attrs = chainon (std_attrs,
3206 c_parser_gnu_attributes (parser));
3207 if (c_parser_next_token_is (parser, CPP_EQ))
3209 c_parser_consume_token (parser);
3210 value_loc = c_parser_peek_token (parser)->location;
3211 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3213 else
3214 enum_value = NULL_TREE;
3215 enum_decl = build_enumerator (decl_loc, value_loc,
3216 &the_enum, enum_id, enum_value);
3217 if (enum_attrs)
3218 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3219 TREE_CHAIN (enum_decl) = values;
3220 values = enum_decl;
3221 seen_comma = false;
3222 if (c_parser_next_token_is (parser, CPP_COMMA))
3224 comma_loc = c_parser_peek_token (parser)->location;
3225 seen_comma = true;
3226 c_parser_consume_token (parser);
3228 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3230 if (seen_comma)
3231 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3232 "comma at end of enumerator list");
3233 c_parser_consume_token (parser);
3234 break;
3236 if (!seen_comma)
3238 c_parser_error (parser, "expected %<,%> or %<}%>");
3239 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3240 values = error_mark_node;
3241 break;
3244 postfix_attrs = c_parser_gnu_attributes (parser);
3245 ret.spec = finish_enum (type, nreverse (values),
3246 chainon (std_attrs,
3247 chainon (attrs, postfix_attrs)));
3248 ret.kind = ctsk_tagdef;
3249 ret.expr = NULL_TREE;
3250 ret.expr_const_operands = true;
3251 timevar_pop (TV_PARSE_ENUM);
3252 return ret;
3254 else if (!ident)
3256 c_parser_error (parser, "expected %<{%>");
3257 ret.spec = error_mark_node;
3258 ret.kind = ctsk_tagref;
3259 ret.expr = NULL_TREE;
3260 ret.expr_const_operands = true;
3261 return ret;
3263 /* Attributes may only appear when the members are defined or in
3264 certain forward declarations (treat enum forward declarations in
3265 GNU C analogously to struct and union forward declarations in
3266 standard C). */
3267 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3268 c_parser_error (parser, "expected %<;%>");
3269 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3270 std_attrs);
3271 /* In ISO C, enumerated types can be referred to only if already
3272 defined. */
3273 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3275 gcc_assert (ident);
3276 pedwarn (enum_loc, OPT_Wpedantic,
3277 "ISO C forbids forward references to %<enum%> types");
3279 return ret;
3282 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3284 struct-or-union-specifier:
3285 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3286 identifier[opt] { struct-contents } gnu-attributes[opt]
3287 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3288 identifier
3290 struct-contents:
3291 struct-declaration-list
3293 struct-declaration-list:
3294 struct-declaration ;
3295 struct-declaration-list struct-declaration ;
3297 GNU extensions:
3299 struct-contents:
3300 empty
3301 struct-declaration
3302 struct-declaration-list struct-declaration
3304 struct-declaration-list:
3305 struct-declaration-list ;
3308 (Note that in the syntax here, unlike that in ISO C, the semicolons
3309 are included here rather than in struct-declaration, in order to
3310 describe the syntax with extra semicolons and missing semicolon at
3311 end.)
3313 Objective-C:
3315 struct-declaration-list:
3316 @defs ( class-name )
3318 (Note this does not include a trailing semicolon, but can be
3319 followed by further declarations, and gets a pedwarn-if-pedantic
3320 when followed by a semicolon.) */
3322 static struct c_typespec
3323 c_parser_struct_or_union_specifier (c_parser *parser)
3325 struct c_typespec ret;
3326 bool have_std_attrs;
3327 tree std_attrs = NULL_TREE;
3328 tree attrs;
3329 tree ident = NULL_TREE;
3330 location_t struct_loc;
3331 location_t ident_loc = UNKNOWN_LOCATION;
3332 enum tree_code code;
3333 switch (c_parser_peek_token (parser)->keyword)
3335 case RID_STRUCT:
3336 code = RECORD_TYPE;
3337 break;
3338 case RID_UNION:
3339 code = UNION_TYPE;
3340 break;
3341 default:
3342 gcc_unreachable ();
3344 struct_loc = c_parser_peek_token (parser)->location;
3345 c_parser_consume_token (parser);
3346 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3347 if (have_std_attrs)
3348 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3349 attrs = c_parser_gnu_attributes (parser);
3351 /* Set the location in case we create a decl now. */
3352 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3354 if (c_parser_next_token_is (parser, CPP_NAME))
3356 ident = c_parser_peek_token (parser)->value;
3357 ident_loc = c_parser_peek_token (parser)->location;
3358 struct_loc = ident_loc;
3359 c_parser_consume_token (parser);
3361 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3363 /* Parse a struct or union definition. Start the scope of the
3364 tag before parsing components. */
3365 class c_struct_parse_info *struct_info;
3366 tree type = start_struct (struct_loc, code, ident, &struct_info);
3367 tree postfix_attrs;
3368 /* We chain the components in reverse order, then put them in
3369 forward order at the end. Each struct-declaration may
3370 declare multiple components (comma-separated), so we must use
3371 chainon to join them, although when parsing each
3372 struct-declaration we can use TREE_CHAIN directly.
3374 The theory behind all this is that there will be more
3375 semicolon separated fields than comma separated fields, and
3376 so we'll be minimizing the number of node traversals required
3377 by chainon. */
3378 tree contents;
3379 timevar_push (TV_PARSE_STRUCT);
3380 contents = NULL_TREE;
3381 c_parser_consume_token (parser);
3382 /* Handle the Objective-C @defs construct,
3383 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3384 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3386 tree name;
3387 gcc_assert (c_dialect_objc ());
3388 c_parser_consume_token (parser);
3389 matching_parens parens;
3390 if (!parens.require_open (parser))
3391 goto end_at_defs;
3392 if (c_parser_next_token_is (parser, CPP_NAME)
3393 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3395 name = c_parser_peek_token (parser)->value;
3396 c_parser_consume_token (parser);
3398 else
3400 c_parser_error (parser, "expected class name");
3401 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3402 goto end_at_defs;
3404 parens.skip_until_found_close (parser);
3405 contents = nreverse (objc_get_class_ivars (name));
3407 end_at_defs:
3408 /* Parse the struct-declarations and semicolons. Problems with
3409 semicolons are diagnosed here; empty structures are diagnosed
3410 elsewhere. */
3411 while (true)
3413 tree decls;
3414 /* Parse any stray semicolon. */
3415 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3417 location_t semicolon_loc
3418 = c_parser_peek_token (parser)->location;
3419 gcc_rich_location richloc (semicolon_loc);
3420 richloc.add_fixit_remove ();
3421 pedwarn (&richloc, OPT_Wpedantic,
3422 "extra semicolon in struct or union specified");
3423 c_parser_consume_token (parser);
3424 continue;
3426 /* Stop if at the end of the struct or union contents. */
3427 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3429 c_parser_consume_token (parser);
3430 break;
3432 /* Accept #pragmas at struct scope. */
3433 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3435 c_parser_pragma (parser, pragma_struct, NULL);
3436 continue;
3438 /* Parse some comma-separated declarations, but not the
3439 trailing semicolon if any. */
3440 decls = c_parser_struct_declaration (parser);
3441 contents = chainon (decls, contents);
3442 /* If no semicolon follows, either we have a parse error or
3443 are at the end of the struct or union and should
3444 pedwarn. */
3445 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3446 c_parser_consume_token (parser);
3447 else
3449 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3450 pedwarn (c_parser_peek_token (parser)->location, 0,
3451 "no semicolon at end of struct or union");
3452 else if (parser->error
3453 || !c_parser_next_token_starts_declspecs (parser))
3455 c_parser_error (parser, "expected %<;%>");
3456 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3457 break;
3460 /* If we come here, we have already emitted an error
3461 for an expected `;', identifier or `(', and we also
3462 recovered already. Go on with the next field. */
3465 postfix_attrs = c_parser_gnu_attributes (parser);
3466 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3467 chainon (std_attrs,
3468 chainon (attrs, postfix_attrs)),
3469 struct_info);
3470 ret.kind = ctsk_tagdef;
3471 ret.expr = NULL_TREE;
3472 ret.expr_const_operands = true;
3473 timevar_pop (TV_PARSE_STRUCT);
3474 return ret;
3476 else if (!ident)
3478 c_parser_error (parser, "expected %<{%>");
3479 ret.spec = error_mark_node;
3480 ret.kind = ctsk_tagref;
3481 ret.expr = NULL_TREE;
3482 ret.expr_const_operands = true;
3483 return ret;
3485 /* Attributes may only appear when the members are defined or in
3486 certain forward declarations. */
3487 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3488 c_parser_error (parser, "expected %<;%>");
3489 /* ??? Existing practice is that GNU attributes are ignored after
3490 the struct or union keyword when not defining the members. */
3491 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3492 return ret;
3495 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3496 *without* the trailing semicolon.
3498 struct-declaration:
3499 attribute-specifier-sequence[opt] specifier-qualifier-list
3500 attribute-specifier-sequence[opt] struct-declarator-list
3501 static_assert-declaration-no-semi
3503 specifier-qualifier-list:
3504 type-specifier specifier-qualifier-list[opt]
3505 type-qualifier specifier-qualifier-list[opt]
3506 alignment-specifier specifier-qualifier-list[opt]
3507 gnu-attributes specifier-qualifier-list[opt]
3509 struct-declarator-list:
3510 struct-declarator
3511 struct-declarator-list , gnu-attributes[opt] struct-declarator
3513 struct-declarator:
3514 declarator gnu-attributes[opt]
3515 declarator[opt] : constant-expression gnu-attributes[opt]
3517 GNU extensions:
3519 struct-declaration:
3520 __extension__ struct-declaration
3521 specifier-qualifier-list
3523 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3524 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3525 any expression without commas in the syntax (assignment
3526 expressions, not just conditional expressions); assignment
3527 expressions will be diagnosed as non-constant. */
3529 static tree
3530 c_parser_struct_declaration (c_parser *parser)
3532 struct c_declspecs *specs;
3533 tree prefix_attrs;
3534 tree all_prefix_attrs;
3535 tree decls;
3536 location_t decl_loc;
3537 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3539 int ext;
3540 tree decl;
3541 ext = disable_extension_diagnostics ();
3542 c_parser_consume_token (parser);
3543 decl = c_parser_struct_declaration (parser);
3544 restore_extension_diagnostics (ext);
3545 return decl;
3547 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3549 c_parser_static_assert_declaration_no_semi (parser);
3550 return NULL_TREE;
3552 specs = build_null_declspecs ();
3553 decl_loc = c_parser_peek_token (parser)->location;
3554 /* Strictly by the standard, we shouldn't allow _Alignas here,
3555 but it appears to have been intended to allow it there, so
3556 we're keeping it as it is until WG14 reaches a conclusion
3557 of N1731.
3558 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3559 c_parser_declspecs (parser, specs, false, true, true,
3560 true, false, true, true, cla_nonabstract_decl);
3561 if (parser->error)
3562 return NULL_TREE;
3563 if (!specs->declspecs_seen_p)
3565 c_parser_error (parser, "expected specifier-qualifier-list");
3566 return NULL_TREE;
3568 finish_declspecs (specs);
3569 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3570 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3572 tree ret;
3573 if (specs->typespec_kind == ctsk_none)
3575 pedwarn (decl_loc, OPT_Wpedantic,
3576 "ISO C forbids member declarations with no members");
3577 shadow_tag_warned (specs, pedantic);
3578 ret = NULL_TREE;
3580 else
3582 /* Support for unnamed structs or unions as members of
3583 structs or unions (which is [a] useful and [b] supports
3584 MS P-SDK). */
3585 tree attrs = NULL;
3587 ret = grokfield (c_parser_peek_token (parser)->location,
3588 build_id_declarator (NULL_TREE), specs,
3589 NULL_TREE, &attrs);
3590 if (ret)
3591 decl_attributes (&ret, attrs, 0);
3593 return ret;
3596 /* Provide better error recovery. Note that a type name here is valid,
3597 and will be treated as a field name. */
3598 if (specs->typespec_kind == ctsk_tagdef
3599 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3600 && c_parser_next_token_starts_declspecs (parser)
3601 && !c_parser_next_token_is (parser, CPP_NAME))
3603 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3604 parser->error = false;
3605 return NULL_TREE;
3608 pending_xref_error ();
3609 prefix_attrs = specs->attrs;
3610 all_prefix_attrs = prefix_attrs;
3611 specs->attrs = NULL_TREE;
3612 decls = NULL_TREE;
3613 while (true)
3615 /* Declaring one or more declarators or un-named bit-fields. */
3616 struct c_declarator *declarator;
3617 bool dummy = false;
3618 if (c_parser_next_token_is (parser, CPP_COLON))
3619 declarator = build_id_declarator (NULL_TREE);
3620 else
3621 declarator = c_parser_declarator (parser,
3622 specs->typespec_kind != ctsk_none,
3623 C_DTR_NORMAL, &dummy);
3624 if (declarator == NULL)
3626 c_parser_skip_to_end_of_block_or_statement (parser);
3627 break;
3629 if (c_parser_next_token_is (parser, CPP_COLON)
3630 || c_parser_next_token_is (parser, CPP_COMMA)
3631 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3632 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3633 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3635 tree postfix_attrs = NULL_TREE;
3636 tree width = NULL_TREE;
3637 tree d;
3638 if (c_parser_next_token_is (parser, CPP_COLON))
3640 c_parser_consume_token (parser);
3641 width = c_parser_expr_no_commas (parser, NULL).value;
3643 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3644 postfix_attrs = c_parser_gnu_attributes (parser);
3645 d = grokfield (c_parser_peek_token (parser)->location,
3646 declarator, specs, width, &all_prefix_attrs);
3647 decl_attributes (&d, chainon (postfix_attrs,
3648 all_prefix_attrs), 0);
3649 DECL_CHAIN (d) = decls;
3650 decls = d;
3651 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3652 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3653 prefix_attrs);
3654 else
3655 all_prefix_attrs = prefix_attrs;
3656 if (c_parser_next_token_is (parser, CPP_COMMA))
3657 c_parser_consume_token (parser);
3658 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3659 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3661 /* Semicolon consumed in caller. */
3662 break;
3664 else
3666 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3667 break;
3670 else
3672 c_parser_error (parser,
3673 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3674 "%<__attribute__%>");
3675 break;
3678 return decls;
3681 /* Parse a typeof specifier (a GNU extension).
3683 typeof-specifier:
3684 typeof ( expression )
3685 typeof ( type-name )
3688 static struct c_typespec
3689 c_parser_typeof_specifier (c_parser *parser)
3691 struct c_typespec ret;
3692 ret.kind = ctsk_typeof;
3693 ret.spec = error_mark_node;
3694 ret.expr = NULL_TREE;
3695 ret.expr_const_operands = true;
3696 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3697 c_parser_consume_token (parser);
3698 c_inhibit_evaluation_warnings++;
3699 in_typeof++;
3700 matching_parens parens;
3701 if (!parens.require_open (parser))
3703 c_inhibit_evaluation_warnings--;
3704 in_typeof--;
3705 return ret;
3707 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3709 struct c_type_name *type = c_parser_type_name (parser);
3710 c_inhibit_evaluation_warnings--;
3711 in_typeof--;
3712 if (type != NULL)
3714 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3715 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3718 else
3720 bool was_vm;
3721 location_t here = c_parser_peek_token (parser)->location;
3722 struct c_expr expr = c_parser_expression (parser);
3723 c_inhibit_evaluation_warnings--;
3724 in_typeof--;
3725 if (TREE_CODE (expr.value) == COMPONENT_REF
3726 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3727 error_at (here, "%<typeof%> applied to a bit-field");
3728 mark_exp_read (expr.value);
3729 ret.spec = TREE_TYPE (expr.value);
3730 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3731 /* This is returned with the type so that when the type is
3732 evaluated, this can be evaluated. */
3733 if (was_vm)
3734 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3735 pop_maybe_used (was_vm);
3736 /* For use in macros such as those in <stdatomic.h>, remove all
3737 qualifiers from atomic types. (const can be an issue for more macros
3738 using typeof than just the <stdatomic.h> ones.) */
3739 if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec))
3740 ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED);
3742 parens.skip_until_found_close (parser);
3743 return ret;
3746 /* Parse an alignment-specifier.
3748 C11 6.7.5:
3750 alignment-specifier:
3751 _Alignas ( type-name )
3752 _Alignas ( constant-expression )
3755 static tree
3756 c_parser_alignas_specifier (c_parser * parser)
3758 tree ret = error_mark_node;
3759 location_t loc = c_parser_peek_token (parser)->location;
3760 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3761 c_parser_consume_token (parser);
3762 if (flag_isoc99)
3763 pedwarn_c99 (loc, OPT_Wpedantic,
3764 "ISO C99 does not support %<_Alignas%>");
3765 else
3766 pedwarn_c99 (loc, OPT_Wpedantic,
3767 "ISO C90 does not support %<_Alignas%>");
3768 matching_parens parens;
3769 if (!parens.require_open (parser))
3770 return ret;
3771 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3773 struct c_type_name *type = c_parser_type_name (parser);
3774 if (type != NULL)
3775 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3776 false, true, 1);
3778 else
3779 ret = c_parser_expr_no_commas (parser, NULL).value;
3780 parens.skip_until_found_close (parser);
3781 return ret;
3784 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3785 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3786 a typedef name may be redeclared; otherwise it may not. KIND
3787 indicates which kind of declarator is wanted. Returns a valid
3788 declarator except in the case of a syntax error in which case NULL is
3789 returned. *SEEN_ID is set to true if an identifier being declared is
3790 seen; this is used to diagnose bad forms of abstract array declarators
3791 and to determine whether an identifier list is syntactically permitted.
3793 declarator:
3794 pointer[opt] direct-declarator
3796 direct-declarator:
3797 identifier
3798 ( gnu-attributes[opt] declarator )
3799 direct-declarator array-declarator
3800 direct-declarator ( parameter-type-list )
3801 direct-declarator ( identifier-list[opt] )
3803 pointer:
3804 * type-qualifier-list[opt]
3805 * type-qualifier-list[opt] pointer
3807 type-qualifier-list:
3808 type-qualifier
3809 gnu-attributes
3810 type-qualifier-list type-qualifier
3811 type-qualifier-list gnu-attributes
3813 array-declarator:
3814 [ type-qualifier-list[opt] assignment-expression[opt] ]
3815 [ static type-qualifier-list[opt] assignment-expression ]
3816 [ type-qualifier-list static assignment-expression ]
3817 [ type-qualifier-list[opt] * ]
3819 parameter-type-list:
3820 parameter-list
3821 parameter-list , ...
3823 parameter-list:
3824 parameter-declaration
3825 parameter-list , parameter-declaration
3827 parameter-declaration:
3828 declaration-specifiers declarator gnu-attributes[opt]
3829 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3831 identifier-list:
3832 identifier
3833 identifier-list , identifier
3835 abstract-declarator:
3836 pointer
3837 pointer[opt] direct-abstract-declarator
3839 direct-abstract-declarator:
3840 ( gnu-attributes[opt] abstract-declarator )
3841 direct-abstract-declarator[opt] array-declarator
3842 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3844 GNU extensions:
3846 direct-declarator:
3847 direct-declarator ( parameter-forward-declarations
3848 parameter-type-list[opt] )
3850 direct-abstract-declarator:
3851 direct-abstract-declarator[opt] ( parameter-forward-declarations
3852 parameter-type-list[opt] )
3854 parameter-forward-declarations:
3855 parameter-list ;
3856 parameter-forward-declarations parameter-list ;
3858 The uses of gnu-attributes shown above are GNU extensions.
3860 Some forms of array declarator are not included in C99 in the
3861 syntax for abstract declarators; these are disallowed elsewhere.
3862 This may be a defect (DR#289).
3864 This function also accepts an omitted abstract declarator as being
3865 an abstract declarator, although not part of the formal syntax. */
3867 struct c_declarator *
3868 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3869 bool *seen_id)
3871 /* Parse any initial pointer part. */
3872 if (c_parser_next_token_is (parser, CPP_MULT))
3874 struct c_declspecs *quals_attrs = build_null_declspecs ();
3875 struct c_declarator *inner;
3876 c_parser_consume_token (parser);
3877 c_parser_declspecs (parser, quals_attrs, false, false, true,
3878 false, false, true, false, cla_prefer_id);
3879 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3880 if (inner == NULL)
3881 return NULL;
3882 else
3883 return make_pointer_declarator (quals_attrs, inner);
3885 /* Now we have a direct declarator, direct abstract declarator or
3886 nothing (which counts as a direct abstract declarator here). */
3887 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3890 /* Parse a direct declarator or direct abstract declarator; arguments
3891 as c_parser_declarator. */
3893 static struct c_declarator *
3894 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3895 bool *seen_id)
3897 /* The direct declarator must start with an identifier (possibly
3898 omitted) or a parenthesized declarator (possibly abstract). In
3899 an ordinary declarator, initial parentheses must start a
3900 parenthesized declarator. In an abstract declarator or parameter
3901 declarator, they could start a parenthesized declarator or a
3902 parameter list. To tell which, the open parenthesis and any
3903 following gnu-attributes must be read. If a declaration
3904 specifier or standard attributes follow, then it is a parameter
3905 list; if the specifier is a typedef name, there might be an
3906 ambiguity about redeclaring it, which is resolved in the
3907 direction of treating it as a typedef name. If a close
3908 parenthesis follows, it is also an empty parameter list, as the
3909 syntax does not permit empty abstract declarators. Otherwise, it
3910 is a parenthesized declarator (in which case the analysis may be
3911 repeated inside it, recursively).
3913 ??? There is an ambiguity in a parameter declaration "int
3914 (__attribute__((foo)) x)", where x is not a typedef name: it
3915 could be an abstract declarator for a function, or declare x with
3916 parentheses. The proper resolution of this ambiguity needs
3917 documenting. At present we follow an accident of the old
3918 parser's implementation, whereby the first parameter must have
3919 some declaration specifiers other than just gnu-attributes. Thus as
3920 a parameter declaration it is treated as a parenthesized
3921 parameter named x, and as an abstract declarator it is
3922 rejected.
3924 ??? Also following the old parser, gnu-attributes inside an empty
3925 parameter list are ignored, making it a list not yielding a
3926 prototype, rather than giving an error or making it have one
3927 parameter with implicit type int.
3929 ??? Also following the old parser, typedef names may be
3930 redeclared in declarators, but not Objective-C class names. */
3932 if (kind != C_DTR_ABSTRACT
3933 && c_parser_next_token_is (parser, CPP_NAME)
3934 && ((type_seen_p
3935 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3936 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3937 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3939 struct c_declarator *inner
3940 = build_id_declarator (c_parser_peek_token (parser)->value);
3941 *seen_id = true;
3942 inner->id_loc = c_parser_peek_token (parser)->location;
3943 c_parser_consume_token (parser);
3944 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3945 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3946 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3949 if (kind != C_DTR_NORMAL
3950 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3951 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3953 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3954 inner->id_loc = c_parser_peek_token (parser)->location;
3955 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3958 /* Either we are at the end of an abstract declarator, or we have
3959 parentheses. */
3961 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3963 tree attrs;
3964 struct c_declarator *inner;
3965 c_parser_consume_token (parser);
3966 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3967 RID_ATTRIBUTE);
3968 attrs = c_parser_gnu_attributes (parser);
3969 if (kind != C_DTR_NORMAL
3970 && (c_parser_next_token_starts_declspecs (parser)
3971 || (!have_gnu_attrs
3972 && c_parser_nth_token_starts_std_attributes (parser, 1))
3973 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3975 struct c_arg_info *args
3976 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3977 attrs, have_gnu_attrs);
3978 if (args == NULL)
3979 return NULL;
3980 else
3982 inner = build_id_declarator (NULL_TREE);
3983 if (!(args->types
3984 && args->types != error_mark_node
3985 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
3986 && c_parser_nth_token_starts_std_attributes (parser, 1))
3988 tree std_attrs
3989 = c_parser_std_attribute_specifier_sequence (parser);
3990 if (std_attrs)
3991 inner = build_attrs_declarator (std_attrs, inner);
3993 inner = build_function_declarator (args, inner);
3994 return c_parser_direct_declarator_inner (parser, *seen_id,
3995 inner);
3998 /* A parenthesized declarator. */
3999 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4000 if (inner != NULL && attrs != NULL)
4001 inner = build_attrs_declarator (attrs, inner);
4002 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4004 c_parser_consume_token (parser);
4005 if (inner == NULL)
4006 return NULL;
4007 else
4008 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4010 else
4012 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4013 "expected %<)%>");
4014 return NULL;
4017 else
4019 if (kind == C_DTR_NORMAL)
4021 c_parser_error (parser, "expected identifier or %<(%>");
4022 return NULL;
4024 else
4025 return build_id_declarator (NULL_TREE);
4029 /* Parse part of a direct declarator or direct abstract declarator,
4030 given that some (in INNER) has already been parsed; ID_PRESENT is
4031 true if an identifier is present, false for an abstract
4032 declarator. */
4034 static struct c_declarator *
4035 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4036 struct c_declarator *inner)
4038 /* Parse a sequence of array declarators and parameter lists. */
4039 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4040 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4042 location_t brace_loc = c_parser_peek_token (parser)->location;
4043 struct c_declarator *declarator;
4044 struct c_declspecs *quals_attrs = build_null_declspecs ();
4045 bool static_seen;
4046 bool star_seen;
4047 struct c_expr dimen;
4048 dimen.value = NULL_TREE;
4049 dimen.original_code = ERROR_MARK;
4050 dimen.original_type = NULL_TREE;
4051 c_parser_consume_token (parser);
4052 c_parser_declspecs (parser, quals_attrs, false, false, true,
4053 false, false, false, false, cla_prefer_id);
4054 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4055 if (static_seen)
4056 c_parser_consume_token (parser);
4057 if (static_seen && !quals_attrs->declspecs_seen_p)
4058 c_parser_declspecs (parser, quals_attrs, false, false, true,
4059 false, false, false, false, cla_prefer_id);
4060 if (!quals_attrs->declspecs_seen_p)
4061 quals_attrs = NULL;
4062 /* If "static" is present, there must be an array dimension.
4063 Otherwise, there may be a dimension, "*", or no
4064 dimension. */
4065 if (static_seen)
4067 star_seen = false;
4068 dimen = c_parser_expr_no_commas (parser, NULL);
4070 else
4072 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4074 dimen.value = NULL_TREE;
4075 star_seen = false;
4077 else if (c_parser_next_token_is (parser, CPP_MULT))
4079 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4081 dimen.value = NULL_TREE;
4082 star_seen = true;
4083 c_parser_consume_token (parser);
4085 else
4087 star_seen = false;
4088 dimen = c_parser_expr_no_commas (parser, NULL);
4091 else
4093 star_seen = false;
4094 dimen = c_parser_expr_no_commas (parser, NULL);
4097 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4098 c_parser_consume_token (parser);
4099 else
4101 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4102 "expected %<]%>");
4103 return NULL;
4105 if (dimen.value)
4106 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4107 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4108 static_seen, star_seen);
4109 if (declarator == NULL)
4110 return NULL;
4111 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4113 tree std_attrs
4114 = c_parser_std_attribute_specifier_sequence (parser);
4115 if (std_attrs)
4116 inner = build_attrs_declarator (std_attrs, inner);
4118 inner = set_array_declarator_inner (declarator, inner);
4119 return c_parser_direct_declarator_inner (parser, id_present, inner);
4121 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4123 tree attrs;
4124 struct c_arg_info *args;
4125 c_parser_consume_token (parser);
4126 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4127 RID_ATTRIBUTE);
4128 attrs = c_parser_gnu_attributes (parser);
4129 args = c_parser_parms_declarator (parser, id_present, attrs,
4130 have_gnu_attrs);
4131 if (args == NULL)
4132 return NULL;
4133 else
4135 if (!(args->types
4136 && args->types != error_mark_node
4137 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4138 && c_parser_nth_token_starts_std_attributes (parser, 1))
4140 tree std_attrs
4141 = c_parser_std_attribute_specifier_sequence (parser);
4142 if (std_attrs)
4143 inner = build_attrs_declarator (std_attrs, inner);
4145 inner = build_function_declarator (args, inner);
4146 return c_parser_direct_declarator_inner (parser, id_present, inner);
4149 return inner;
4152 /* Parse a parameter list or identifier list, including the closing
4153 parenthesis but not the opening one. ATTRS are the gnu-attributes
4154 at the start of the list. ID_LIST_OK is true if an identifier list
4155 is acceptable; such a list must not have attributes at the start.
4156 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4157 attributes) were present (in which case standard attributes cannot
4158 occur). */
4160 static struct c_arg_info *
4161 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4162 bool have_gnu_attrs)
4164 push_scope ();
4165 declare_parm_level ();
4166 /* If the list starts with an identifier, it is an identifier list.
4167 Otherwise, it is either a prototype list or an empty list. */
4168 if (id_list_ok
4169 && !attrs
4170 && c_parser_next_token_is (parser, CPP_NAME)
4171 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4173 /* Look ahead to detect typos in type names. */
4174 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4175 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4176 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4177 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4178 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4180 tree list = NULL_TREE, *nextp = &list;
4181 while (c_parser_next_token_is (parser, CPP_NAME)
4182 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4184 *nextp = build_tree_list (NULL_TREE,
4185 c_parser_peek_token (parser)->value);
4186 nextp = & TREE_CHAIN (*nextp);
4187 c_parser_consume_token (parser);
4188 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4189 break;
4190 c_parser_consume_token (parser);
4191 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4193 c_parser_error (parser, "expected identifier");
4194 break;
4197 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4199 struct c_arg_info *ret = build_arg_info ();
4200 ret->types = list;
4201 c_parser_consume_token (parser);
4202 pop_scope ();
4203 return ret;
4205 else
4207 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4208 "expected %<)%>");
4209 pop_scope ();
4210 return NULL;
4213 else
4215 struct c_arg_info *ret
4216 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4217 pop_scope ();
4218 return ret;
4222 /* Parse a parameter list (possibly empty), including the closing
4223 parenthesis but not the opening one. ATTRS are the gnu-attributes
4224 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4225 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4226 which means standard attributes cannot start the list. EXPR is
4227 NULL or an expression that needs to be evaluated for the side
4228 effects of array size expressions in the parameters. */
4230 static struct c_arg_info *
4231 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4232 bool have_gnu_attrs)
4234 bool bad_parm = false;
4236 /* ??? Following the old parser, forward parameter declarations may
4237 use abstract declarators, and if no real parameter declarations
4238 follow the forward declarations then this is not diagnosed. Also
4239 note as above that gnu-attributes are ignored as the only contents of
4240 the parentheses, or as the only contents after forward
4241 declarations. */
4242 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4244 struct c_arg_info *ret = build_arg_info ();
4245 c_parser_consume_token (parser);
4246 return ret;
4248 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4250 struct c_arg_info *ret = build_arg_info ();
4252 if (flag_allow_parameterless_variadic_functions)
4254 /* F (...) is allowed. */
4255 ret->types = NULL_TREE;
4257 else
4259 /* Suppress -Wold-style-definition for this case. */
4260 ret->types = error_mark_node;
4261 error_at (c_parser_peek_token (parser)->location,
4262 "ISO C requires a named argument before %<...%>");
4264 c_parser_consume_token (parser);
4265 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4267 c_parser_consume_token (parser);
4268 return ret;
4270 else
4272 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4273 "expected %<)%>");
4274 return NULL;
4277 /* Nonempty list of parameters, either terminated with semicolon
4278 (forward declarations; recurse) or with close parenthesis (normal
4279 function) or with ", ... )" (variadic function). */
4280 while (true)
4282 /* Parse a parameter. */
4283 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4284 have_gnu_attrs);
4285 attrs = NULL_TREE;
4286 have_gnu_attrs = false;
4287 if (parm == NULL)
4288 bad_parm = true;
4289 else
4290 push_parm_decl (parm, &expr);
4291 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4293 tree new_attrs;
4294 c_parser_consume_token (parser);
4295 mark_forward_parm_decls ();
4296 bool new_have_gnu_attrs
4297 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4298 new_attrs = c_parser_gnu_attributes (parser);
4299 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4300 new_have_gnu_attrs);
4302 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4304 c_parser_consume_token (parser);
4305 if (bad_parm)
4306 return NULL;
4307 else
4308 return get_parm_info (false, expr);
4310 if (!c_parser_require (parser, CPP_COMMA,
4311 "expected %<;%>, %<,%> or %<)%>",
4312 UNKNOWN_LOCATION, false))
4314 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4315 return NULL;
4317 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4319 c_parser_consume_token (parser);
4320 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4322 c_parser_consume_token (parser);
4323 if (bad_parm)
4324 return NULL;
4325 else
4326 return get_parm_info (true, expr);
4328 else
4330 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4331 "expected %<)%>");
4332 return NULL;
4338 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4339 start of the declaration if it is the first parameter;
4340 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4341 empty) there. */
4343 static struct c_parm *
4344 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4345 bool have_gnu_attrs)
4347 struct c_declspecs *specs;
4348 struct c_declarator *declarator;
4349 tree prefix_attrs;
4350 tree postfix_attrs = NULL_TREE;
4351 bool dummy = false;
4353 /* Accept #pragmas between parameter declarations. */
4354 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4355 c_parser_pragma (parser, pragma_param, NULL);
4357 if (!c_parser_next_token_starts_declspecs (parser)
4358 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4360 c_token *token = c_parser_peek_token (parser);
4361 if (parser->error)
4362 return NULL;
4363 c_parser_set_source_position_from_token (token);
4364 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4366 auto_diagnostic_group d;
4367 name_hint hint = lookup_name_fuzzy (token->value,
4368 FUZZY_LOOKUP_TYPENAME,
4369 token->location);
4370 if (const char *suggestion = hint.suggestion ())
4372 gcc_rich_location richloc (token->location);
4373 richloc.add_fixit_replace (suggestion);
4374 error_at (&richloc,
4375 "unknown type name %qE; did you mean %qs?",
4376 token->value, suggestion);
4378 else
4379 error_at (token->location, "unknown type name %qE", token->value);
4380 parser->error = true;
4382 /* ??? In some Objective-C cases '...' isn't applicable so there
4383 should be a different message. */
4384 else
4385 c_parser_error (parser,
4386 "expected declaration specifiers or %<...%>");
4387 c_parser_skip_to_end_of_parameter (parser);
4388 return NULL;
4391 location_t start_loc = c_parser_peek_token (parser)->location;
4393 specs = build_null_declspecs ();
4394 if (attrs)
4396 declspecs_add_attrs (input_location, specs, attrs);
4397 attrs = NULL_TREE;
4399 c_parser_declspecs (parser, specs, true, true, true, true, false,
4400 !have_gnu_attrs, true, cla_nonabstract_decl);
4401 finish_declspecs (specs);
4402 pending_xref_error ();
4403 prefix_attrs = specs->attrs;
4404 specs->attrs = NULL_TREE;
4405 declarator = c_parser_declarator (parser,
4406 specs->typespec_kind != ctsk_none,
4407 C_DTR_PARM, &dummy);
4408 if (declarator == NULL)
4410 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4411 return NULL;
4413 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4414 postfix_attrs = c_parser_gnu_attributes (parser);
4416 /* Generate a location for the parameter, ranging from the start of the
4417 initial token to the end of the final token.
4419 If we have a identifier, then use it for the caret location, e.g.
4421 extern int callee (int one, int (*two)(int, int), float three);
4422 ~~~~~~^~~~~~~~~~~~~~
4424 otherwise, reuse the start location for the caret location e.g.:
4426 extern int callee (int one, int (*)(int, int), float three);
4427 ^~~~~~~~~~~~~~~~~
4429 location_t end_loc = parser->last_token_location;
4431 /* Find any cdk_id declarator; determine if we have an identifier. */
4432 c_declarator *id_declarator = declarator;
4433 while (id_declarator && id_declarator->kind != cdk_id)
4434 id_declarator = id_declarator->declarator;
4435 location_t caret_loc = (id_declarator->u.id.id
4436 ? id_declarator->id_loc
4437 : start_loc);
4438 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4440 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4441 declarator, param_loc);
4444 /* Parse a string literal in an asm expression. It should not be
4445 translated, and wide string literals are an error although
4446 permitted by the syntax. This is a GNU extension.
4448 asm-string-literal:
4449 string-literal
4452 static tree
4453 c_parser_asm_string_literal (c_parser *parser)
4455 tree str;
4456 int save_flag = warn_overlength_strings;
4457 warn_overlength_strings = 0;
4458 str = c_parser_string_literal (parser, false, false).value;
4459 warn_overlength_strings = save_flag;
4460 return str;
4463 /* Parse a simple asm expression. This is used in restricted
4464 contexts, where a full expression with inputs and outputs does not
4465 make sense. This is a GNU extension.
4467 simple-asm-expr:
4468 asm ( asm-string-literal )
4471 static tree
4472 c_parser_simple_asm_expr (c_parser *parser)
4474 tree str;
4475 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4476 c_parser_consume_token (parser);
4477 matching_parens parens;
4478 if (!parens.require_open (parser))
4479 return NULL_TREE;
4480 str = c_parser_asm_string_literal (parser);
4481 if (!parens.require_close (parser))
4483 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4484 return NULL_TREE;
4486 return str;
4489 static tree
4490 c_parser_gnu_attribute_any_word (c_parser *parser)
4492 tree attr_name = NULL_TREE;
4494 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4496 /* ??? See comment above about what keywords are accepted here. */
4497 bool ok;
4498 switch (c_parser_peek_token (parser)->keyword)
4500 case RID_STATIC:
4501 case RID_UNSIGNED:
4502 case RID_LONG:
4503 case RID_CONST:
4504 case RID_EXTERN:
4505 case RID_REGISTER:
4506 case RID_TYPEDEF:
4507 case RID_SHORT:
4508 case RID_INLINE:
4509 case RID_NORETURN:
4510 case RID_VOLATILE:
4511 case RID_SIGNED:
4512 case RID_AUTO:
4513 case RID_RESTRICT:
4514 case RID_COMPLEX:
4515 case RID_THREAD:
4516 case RID_INT:
4517 case RID_CHAR:
4518 case RID_FLOAT:
4519 case RID_DOUBLE:
4520 case RID_VOID:
4521 case RID_DFLOAT32:
4522 case RID_DFLOAT64:
4523 case RID_DFLOAT128:
4524 CASE_RID_FLOATN_NX:
4525 case RID_BOOL:
4526 case RID_FRACT:
4527 case RID_ACCUM:
4528 case RID_SAT:
4529 case RID_TRANSACTION_ATOMIC:
4530 case RID_TRANSACTION_CANCEL:
4531 case RID_ATOMIC:
4532 case RID_AUTO_TYPE:
4533 case RID_INT_N_0:
4534 case RID_INT_N_1:
4535 case RID_INT_N_2:
4536 case RID_INT_N_3:
4537 ok = true;
4538 break;
4539 default:
4540 ok = false;
4541 break;
4543 if (!ok)
4544 return NULL_TREE;
4546 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4547 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4549 else if (c_parser_next_token_is (parser, CPP_NAME))
4550 attr_name = c_parser_peek_token (parser)->value;
4552 return attr_name;
4555 /* Parse attribute arguments. This is a common form of syntax
4556 covering all currently valid GNU and standard attributes.
4558 gnu-attribute-arguments:
4559 identifier
4560 identifier , nonempty-expr-list
4561 expr-list
4563 where the "identifier" must not be declared as a type. ??? Why not
4564 allow identifiers declared as types to start the arguments? */
4566 static tree
4567 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4568 bool require_string, bool allow_empty_args)
4570 vec<tree, va_gc> *expr_list;
4571 tree attr_args;
4572 /* Parse the attribute contents. If they start with an
4573 identifier which is followed by a comma or close
4574 parenthesis, then the arguments start with that
4575 identifier; otherwise they are an expression list.
4576 In objective-c the identifier may be a classname. */
4577 if (c_parser_next_token_is (parser, CPP_NAME)
4578 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4579 || (c_dialect_objc ()
4580 && c_parser_peek_token (parser)->id_kind
4581 == C_ID_CLASSNAME))
4582 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4583 || (c_parser_peek_2nd_token (parser)->type
4584 == CPP_CLOSE_PAREN))
4585 && (takes_identifier
4586 || (c_dialect_objc ()
4587 && c_parser_peek_token (parser)->id_kind
4588 == C_ID_CLASSNAME)))
4590 tree arg1 = c_parser_peek_token (parser)->value;
4591 c_parser_consume_token (parser);
4592 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4593 attr_args = build_tree_list (NULL_TREE, arg1);
4594 else
4596 tree tree_list;
4597 c_parser_consume_token (parser);
4598 expr_list = c_parser_expr_list (parser, false, true,
4599 NULL, NULL, NULL, NULL);
4600 tree_list = build_tree_list_vec (expr_list);
4601 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4602 release_tree_vector (expr_list);
4605 else
4607 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4609 if (!allow_empty_args)
4610 error_at (c_parser_peek_token (parser)->location,
4611 "parentheses must be omitted if "
4612 "attribute argument list is empty");
4613 attr_args = NULL_TREE;
4615 else if (require_string)
4617 /* The only valid argument for this attribute is a string
4618 literal. Handle this specially here to avoid accepting
4619 string literals with excess parentheses. */
4620 tree string = c_parser_string_literal (parser, false, true).value;
4621 attr_args = build_tree_list (NULL_TREE, string);
4623 else
4625 expr_list = c_parser_expr_list (parser, false, true,
4626 NULL, NULL, NULL, NULL);
4627 attr_args = build_tree_list_vec (expr_list);
4628 release_tree_vector (expr_list);
4631 return attr_args;
4634 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4636 gnu-attributes:
4637 empty
4638 gnu-attributes gnu-attribute
4640 gnu-attribute:
4641 __attribute__ ( ( gnu-attribute-list ) )
4643 gnu-attribute-list:
4644 gnu-attrib
4645 gnu-attribute_list , gnu-attrib
4647 gnu-attrib:
4648 empty
4649 any-word
4650 any-word ( gnu-attribute-arguments )
4652 where "any-word" may be any identifier (including one declared as a
4653 type), a reserved word storage class specifier, type specifier or
4654 type qualifier. ??? This still leaves out most reserved keywords
4655 (following the old parser), shouldn't we include them?
4656 When EXPECT_COMMA is true, expect the attribute to be preceded
4657 by a comma and fail if it isn't.
4658 When EMPTY_OK is true, allow and consume any number of consecutive
4659 commas with no attributes in between. */
4661 static tree
4662 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4663 bool expect_comma = false, bool empty_ok = true)
4665 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4666 if (!comma_first
4667 && !c_parser_next_token_is (parser, CPP_NAME)
4668 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4669 return NULL_TREE;
4671 while (c_parser_next_token_is (parser, CPP_COMMA))
4673 c_parser_consume_token (parser);
4674 if (!empty_ok)
4675 return attrs;
4678 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4679 if (attr_name == NULL_TREE)
4680 return NULL_TREE;
4682 attr_name = canonicalize_attr_name (attr_name);
4683 c_parser_consume_token (parser);
4685 tree attr;
4686 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4688 if (expect_comma && !comma_first)
4690 /* A comma is missing between the last attribute on the chain
4691 and this one. */
4692 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4693 "expected %<)%>");
4694 return error_mark_node;
4696 attr = build_tree_list (attr_name, NULL_TREE);
4697 /* Add this attribute to the list. */
4698 attrs = chainon (attrs, attr);
4699 return attrs;
4701 c_parser_consume_token (parser);
4703 tree attr_args
4704 = c_parser_attribute_arguments (parser,
4705 attribute_takes_identifier_p (attr_name),
4706 false, true);
4708 attr = build_tree_list (attr_name, attr_args);
4709 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4710 c_parser_consume_token (parser);
4711 else
4713 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4714 "expected %<)%>");
4715 return error_mark_node;
4718 if (expect_comma && !comma_first)
4720 /* A comma is missing between the last attribute on the chain
4721 and this one. */
4722 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4723 "expected %<)%>");
4724 return error_mark_node;
4727 /* Add this attribute to the list. */
4728 attrs = chainon (attrs, attr);
4729 return attrs;
4732 static tree
4733 c_parser_gnu_attributes (c_parser *parser)
4735 tree attrs = NULL_TREE;
4736 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4738 bool save_translate_strings_p = parser->translate_strings_p;
4739 parser->translate_strings_p = false;
4740 /* Consume the `__attribute__' keyword. */
4741 c_parser_consume_token (parser);
4742 /* Look for the two `(' tokens. */
4743 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4745 parser->translate_strings_p = save_translate_strings_p;
4746 return attrs;
4748 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4750 parser->translate_strings_p = save_translate_strings_p;
4751 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4752 return attrs;
4754 /* Parse the attribute list. Require a comma between successive
4755 (possibly empty) attributes. */
4756 for (bool expect_comma = false; ; expect_comma = true)
4758 /* Parse a single attribute. */
4759 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4760 if (attr == error_mark_node)
4761 return attrs;
4762 if (!attr)
4763 break;
4764 attrs = attr;
4767 /* Look for the two `)' tokens. */
4768 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4769 c_parser_consume_token (parser);
4770 else
4772 parser->translate_strings_p = save_translate_strings_p;
4773 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4774 "expected %<)%>");
4775 return attrs;
4777 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4778 c_parser_consume_token (parser);
4779 else
4781 parser->translate_strings_p = save_translate_strings_p;
4782 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4783 "expected %<)%>");
4784 return attrs;
4786 parser->translate_strings_p = save_translate_strings_p;
4789 return attrs;
4792 /* Parse an optional balanced token sequence.
4794 balanced-token-sequence:
4795 balanced-token
4796 balanced-token-sequence balanced-token
4798 balanced-token:
4799 ( balanced-token-sequence[opt] )
4800 [ balanced-token-sequence[opt] ]
4801 { balanced-token-sequence[opt] }
4802 any token other than ()[]{}
4805 static void
4806 c_parser_balanced_token_sequence (c_parser *parser)
4808 while (true)
4810 c_token *token = c_parser_peek_token (parser);
4811 switch (token->type)
4813 case CPP_OPEN_BRACE:
4815 matching_braces braces;
4816 braces.consume_open (parser);
4817 c_parser_balanced_token_sequence (parser);
4818 braces.require_close (parser);
4819 break;
4822 case CPP_OPEN_PAREN:
4824 matching_parens parens;
4825 parens.consume_open (parser);
4826 c_parser_balanced_token_sequence (parser);
4827 parens.require_close (parser);
4828 break;
4831 case CPP_OPEN_SQUARE:
4832 c_parser_consume_token (parser);
4833 c_parser_balanced_token_sequence (parser);
4834 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4835 break;
4837 case CPP_CLOSE_BRACE:
4838 case CPP_CLOSE_PAREN:
4839 case CPP_CLOSE_SQUARE:
4840 case CPP_EOF:
4841 return;
4843 default:
4844 c_parser_consume_token (parser);
4845 break;
4850 /* Parse standard (C2X) attributes (including GNU attributes in the
4851 gnu:: namespace).
4853 attribute-specifier-sequence:
4854 attribute-specifier-sequence[opt] attribute-specifier
4856 attribute-specifier:
4857 [ [ attribute-list ] ]
4859 attribute-list:
4860 attribute[opt]
4861 attribute-list, attribute[opt]
4863 attribute:
4864 attribute-token attribute-argument-clause[opt]
4866 attribute-token:
4867 standard-attribute
4868 attribute-prefixed-token
4870 standard-attribute:
4871 identifier
4873 attribute-prefixed-token:
4874 attribute-prefix :: identifier
4876 attribute-prefix:
4877 identifier
4879 attribute-argument-clause:
4880 ( balanced-token-sequence[opt] )
4882 Keywords are accepted as identifiers for this purpose.
4885 static tree
4886 c_parser_std_attribute (c_parser *parser, bool for_tm)
4888 c_token *token = c_parser_peek_token (parser);
4889 tree ns, name, attribute;
4891 /* Parse the attribute-token. */
4892 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4894 c_parser_error (parser, "expected identifier");
4895 return error_mark_node;
4897 name = canonicalize_attr_name (token->value);
4898 c_parser_consume_token (parser);
4899 if (c_parser_next_token_is (parser, CPP_SCOPE))
4901 ns = name;
4902 c_parser_consume_token (parser);
4903 token = c_parser_peek_token (parser);
4904 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4906 c_parser_error (parser, "expected identifier");
4907 return error_mark_node;
4909 name = canonicalize_attr_name (token->value);
4910 c_parser_consume_token (parser);
4912 else
4913 ns = NULL_TREE;
4914 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4916 /* Parse the arguments, if any. */
4917 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4918 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4919 goto out;
4921 location_t open_loc = c_parser_peek_token (parser)->location;
4922 matching_parens parens;
4923 parens.consume_open (parser);
4924 if ((as && as->max_length == 0)
4925 /* Special-case the transactional-memory attribute "outer",
4926 which is specially handled but not registered as an
4927 attribute, to avoid allowing arbitrary balanced token
4928 sequences as arguments. */
4929 || is_attribute_p ("outer", name))
4931 error_at (open_loc, "%qE attribute does not take any arguments", name);
4932 parens.skip_until_found_close (parser);
4933 return error_mark_node;
4935 if (as)
4937 bool takes_identifier
4938 = (ns != NULL_TREE
4939 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4940 && attribute_takes_identifier_p (name));
4941 bool require_string
4942 = (ns == NULL_TREE
4943 && strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0);
4944 TREE_VALUE (attribute)
4945 = c_parser_attribute_arguments (parser, takes_identifier,
4946 require_string, false);
4948 else
4949 c_parser_balanced_token_sequence (parser);
4950 parens.require_close (parser);
4952 out:
4953 if (ns == NULL_TREE && !for_tm && !as && !is_attribute_p ("nodiscard", name))
4955 /* An attribute with standard syntax and no namespace specified
4956 is a constraint violation if it is not one of the known
4957 standard attributes (of which nodiscard is the only one
4958 without a handler in GCC). Diagnose it here with a pedwarn
4959 and then discard it to prevent a duplicate warning later. */
4960 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4961 name);
4962 return error_mark_node;
4964 return attribute;
4967 static tree
4968 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4970 bool seen_deprecated = false;
4971 bool seen_fallthrough = false;
4972 bool seen_maybe_unused = false;
4973 location_t loc = c_parser_peek_token (parser)->location;
4974 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4975 return NULL_TREE;
4976 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4978 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4979 return NULL_TREE;
4981 if (!for_tm)
4982 pedwarn_c11 (loc, OPT_Wpedantic,
4983 "ISO C does not support %<[[]]%> attributes before C2X");
4984 tree attributes = NULL_TREE;
4985 while (true)
4987 c_token *token = c_parser_peek_token (parser);
4988 if (token->type == CPP_CLOSE_SQUARE)
4989 break;
4990 if (token->type == CPP_COMMA)
4992 c_parser_consume_token (parser);
4993 continue;
4995 tree attribute = c_parser_std_attribute (parser, for_tm);
4996 if (attribute != error_mark_node)
4998 bool duplicate = false;
4999 tree name = get_attribute_name (attribute);
5000 tree ns = get_attribute_namespace (attribute);
5001 if (ns == NULL_TREE)
5003 /* Some standard attributes may appear at most once in
5004 each attribute list. Diagnose duplicates and remove
5005 them from the list to avoid subsequent diagnostics
5006 such as the more general one for multiple
5007 "fallthrough" attributes in the same place (including
5008 in separate attribute lists in the same attribute
5009 specifier sequence, which is not a constraint
5010 violation). */
5011 if (is_attribute_p ("deprecated", name))
5013 if (seen_deprecated)
5015 error ("attribute %<deprecated%> can appear at most "
5016 "once in an attribute-list");
5017 duplicate = true;
5019 seen_deprecated = true;
5021 else if (is_attribute_p ("fallthrough", name))
5023 if (seen_fallthrough)
5025 error ("attribute %<fallthrough%> can appear at most "
5026 "once in an attribute-list");
5027 duplicate = true;
5029 seen_fallthrough = true;
5031 else if (is_attribute_p ("maybe_unused", name))
5033 if (seen_maybe_unused)
5035 error ("attribute %<maybe_unused%> can appear at most "
5036 "once in an attribute-list");
5037 duplicate = true;
5039 seen_maybe_unused = true;
5042 if (!duplicate)
5044 TREE_CHAIN (attribute) = attributes;
5045 attributes = attribute;
5048 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5049 break;
5051 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5052 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5053 return nreverse (attributes);
5056 /* Look past an optional balanced token sequence of raw look-ahead
5057 tokens starting with the *Nth token. *N is updated to point to the
5058 following token. Return true if such a sequence was found, false
5059 if the tokens parsed were not balanced. */
5061 static bool
5062 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5064 while (true)
5066 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5067 switch (token->type)
5069 case CPP_OPEN_BRACE:
5071 ++*n;
5072 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5074 token = c_parser_peek_nth_token_raw (parser, *n);
5075 if (token->type == CPP_CLOSE_BRACE)
5076 ++*n;
5077 else
5078 return false;
5080 else
5081 return false;
5082 break;
5085 case CPP_OPEN_PAREN:
5087 ++*n;
5088 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5090 token = c_parser_peek_nth_token_raw (parser, *n);
5091 if (token->type == CPP_CLOSE_PAREN)
5092 ++*n;
5093 else
5094 return false;
5096 else
5097 return false;
5098 break;
5101 case CPP_OPEN_SQUARE:
5103 ++*n;
5104 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5106 token = c_parser_peek_nth_token_raw (parser, *n);
5107 if (token->type == CPP_CLOSE_SQUARE)
5108 ++*n;
5109 else
5110 return false;
5112 else
5113 return false;
5114 break;
5117 case CPP_CLOSE_BRACE:
5118 case CPP_CLOSE_PAREN:
5119 case CPP_CLOSE_SQUARE:
5120 case CPP_EOF:
5121 return true;
5123 default:
5124 ++*n;
5125 break;
5130 /* Return whether standard attributes start with the Nth token. */
5132 static bool
5133 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5135 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5136 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5137 return false;
5138 /* In C, '[[' must start attributes. In Objective-C, we need to
5139 check whether '[[' is matched by ']]'. */
5140 if (!c_dialect_objc ())
5141 return true;
5142 n += 2;
5143 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5144 return false;
5145 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5146 if (token->type != CPP_CLOSE_SQUARE)
5147 return false;
5148 token = c_parser_peek_nth_token_raw (parser, n + 1);
5149 return token->type == CPP_CLOSE_SQUARE;
5152 static tree
5153 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5155 tree attributes = NULL_TREE;
5158 tree attrs = c_parser_std_attribute_specifier (parser, false);
5159 attributes = chainon (attributes, attrs);
5161 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5162 return attributes;
5165 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5166 says whether alignment specifiers are OK (only in cases that might
5167 be the type name of a compound literal).
5169 type-name:
5170 specifier-qualifier-list abstract-declarator[opt]
5173 struct c_type_name *
5174 c_parser_type_name (c_parser *parser, bool alignas_ok)
5176 struct c_declspecs *specs = build_null_declspecs ();
5177 struct c_declarator *declarator;
5178 struct c_type_name *ret;
5179 bool dummy = false;
5180 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5181 false, true, cla_prefer_type);
5182 if (!specs->declspecs_seen_p)
5184 c_parser_error (parser, "expected specifier-qualifier-list");
5185 return NULL;
5187 if (specs->type != error_mark_node)
5189 pending_xref_error ();
5190 finish_declspecs (specs);
5192 declarator = c_parser_declarator (parser,
5193 specs->typespec_kind != ctsk_none,
5194 C_DTR_ABSTRACT, &dummy);
5195 if (declarator == NULL)
5196 return NULL;
5197 ret = XOBNEW (&parser_obstack, struct c_type_name);
5198 ret->specs = specs;
5199 ret->declarator = declarator;
5200 return ret;
5203 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5205 initializer:
5206 assignment-expression
5207 { initializer-list }
5208 { initializer-list , }
5210 initializer-list:
5211 designation[opt] initializer
5212 initializer-list , designation[opt] initializer
5214 designation:
5215 designator-list =
5217 designator-list:
5218 designator
5219 designator-list designator
5221 designator:
5222 array-designator
5223 . identifier
5225 array-designator:
5226 [ constant-expression ]
5228 GNU extensions:
5230 initializer:
5233 designation:
5234 array-designator
5235 identifier :
5237 array-designator:
5238 [ constant-expression ... constant-expression ]
5240 Any expression without commas is accepted in the syntax for the
5241 constant-expressions, with non-constant expressions rejected later.
5243 This function is only used for top-level initializers; for nested
5244 ones, see c_parser_initval. */
5246 static struct c_expr
5247 c_parser_initializer (c_parser *parser)
5249 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5250 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5251 else
5253 struct c_expr ret;
5254 location_t loc = c_parser_peek_token (parser)->location;
5255 ret = c_parser_expr_no_commas (parser, NULL);
5256 if (TREE_CODE (ret.value) != STRING_CST
5257 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5258 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5259 return ret;
5263 /* The location of the last comma within the current initializer list,
5264 or UNKNOWN_LOCATION if not within one. */
5266 location_t last_init_list_comma;
5268 /* Parse a braced initializer list. TYPE is the type specified for a
5269 compound literal, and NULL_TREE for other initializers and for
5270 nested braced lists. NESTED_P is true for nested braced lists,
5271 false for the list of a compound literal or the list that is the
5272 top-level initializer in a declaration. */
5274 static struct c_expr
5275 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5276 struct obstack *outer_obstack)
5278 struct c_expr ret;
5279 struct obstack braced_init_obstack;
5280 location_t brace_loc = c_parser_peek_token (parser)->location;
5281 gcc_obstack_init (&braced_init_obstack);
5282 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5283 matching_braces braces;
5284 braces.consume_open (parser);
5285 if (nested_p)
5287 finish_implicit_inits (brace_loc, outer_obstack);
5288 push_init_level (brace_loc, 0, &braced_init_obstack);
5290 else
5291 really_start_incremental_init (type);
5292 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5294 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5296 else
5298 /* Parse a non-empty initializer list, possibly with a trailing
5299 comma. */
5300 while (true)
5302 c_parser_initelt (parser, &braced_init_obstack);
5303 if (parser->error)
5304 break;
5305 if (c_parser_next_token_is (parser, CPP_COMMA))
5307 last_init_list_comma = c_parser_peek_token (parser)->location;
5308 c_parser_consume_token (parser);
5310 else
5311 break;
5312 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5313 break;
5316 c_token *next_tok = c_parser_peek_token (parser);
5317 if (next_tok->type != CPP_CLOSE_BRACE)
5319 ret.set_error ();
5320 ret.original_code = ERROR_MARK;
5321 ret.original_type = NULL;
5322 braces.skip_until_found_close (parser);
5323 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5324 obstack_free (&braced_init_obstack, NULL);
5325 return ret;
5327 location_t close_loc = next_tok->location;
5328 c_parser_consume_token (parser);
5329 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5330 obstack_free (&braced_init_obstack, NULL);
5331 set_c_expr_source_range (&ret, brace_loc, close_loc);
5332 return ret;
5335 /* Parse a nested initializer, including designators. */
5337 static void
5338 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5340 /* Parse any designator or designator list. A single array
5341 designator may have the subsequent "=" omitted in GNU C, but a
5342 longer list or a structure member designator may not. */
5343 if (c_parser_next_token_is (parser, CPP_NAME)
5344 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5346 /* Old-style structure member designator. */
5347 set_init_label (c_parser_peek_token (parser)->location,
5348 c_parser_peek_token (parser)->value,
5349 c_parser_peek_token (parser)->location,
5350 braced_init_obstack);
5351 /* Use the colon as the error location. */
5352 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5353 "obsolete use of designated initializer with %<:%>");
5354 c_parser_consume_token (parser);
5355 c_parser_consume_token (parser);
5357 else
5359 /* des_seen is 0 if there have been no designators, 1 if there
5360 has been a single array designator and 2 otherwise. */
5361 int des_seen = 0;
5362 /* Location of a designator. */
5363 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5364 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5365 || c_parser_next_token_is (parser, CPP_DOT))
5367 int des_prev = des_seen;
5368 if (!des_seen)
5369 des_loc = c_parser_peek_token (parser)->location;
5370 if (des_seen < 2)
5371 des_seen++;
5372 if (c_parser_next_token_is (parser, CPP_DOT))
5374 des_seen = 2;
5375 c_parser_consume_token (parser);
5376 if (c_parser_next_token_is (parser, CPP_NAME))
5378 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5379 c_parser_peek_token (parser)->location,
5380 braced_init_obstack);
5381 c_parser_consume_token (parser);
5383 else
5385 struct c_expr init;
5386 init.set_error ();
5387 init.original_code = ERROR_MARK;
5388 init.original_type = NULL;
5389 c_parser_error (parser, "expected identifier");
5390 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5391 process_init_element (input_location, init, false,
5392 braced_init_obstack);
5393 return;
5396 else
5398 tree first, second;
5399 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5400 location_t array_index_loc = UNKNOWN_LOCATION;
5401 /* ??? Following the old parser, [ objc-receiver
5402 objc-message-args ] is accepted as an initializer,
5403 being distinguished from a designator by what follows
5404 the first assignment expression inside the square
5405 brackets, but after a first array designator a
5406 subsequent square bracket is for Objective-C taken to
5407 start an expression, using the obsolete form of
5408 designated initializer without '=', rather than
5409 possibly being a second level of designation: in LALR
5410 terms, the '[' is shifted rather than reducing
5411 designator to designator-list. */
5412 if (des_prev == 1 && c_dialect_objc ())
5414 des_seen = des_prev;
5415 break;
5417 if (des_prev == 0 && c_dialect_objc ())
5419 /* This might be an array designator or an
5420 Objective-C message expression. If the former,
5421 continue parsing here; if the latter, parse the
5422 remainder of the initializer given the starting
5423 primary-expression. ??? It might make sense to
5424 distinguish when des_prev == 1 as well; see
5425 previous comment. */
5426 tree rec, args;
5427 struct c_expr mexpr;
5428 c_parser_consume_token (parser);
5429 if (c_parser_peek_token (parser)->type == CPP_NAME
5430 && ((c_parser_peek_token (parser)->id_kind
5431 == C_ID_TYPENAME)
5432 || (c_parser_peek_token (parser)->id_kind
5433 == C_ID_CLASSNAME)))
5435 /* Type name receiver. */
5436 tree id = c_parser_peek_token (parser)->value;
5437 c_parser_consume_token (parser);
5438 rec = objc_get_class_reference (id);
5439 goto parse_message_args;
5441 first = c_parser_expr_no_commas (parser, NULL).value;
5442 mark_exp_read (first);
5443 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5444 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5445 goto array_desig_after_first;
5446 /* Expression receiver. So far only one part
5447 without commas has been parsed; there might be
5448 more of the expression. */
5449 rec = first;
5450 while (c_parser_next_token_is (parser, CPP_COMMA))
5452 struct c_expr next;
5453 location_t comma_loc, exp_loc;
5454 comma_loc = c_parser_peek_token (parser)->location;
5455 c_parser_consume_token (parser);
5456 exp_loc = c_parser_peek_token (parser)->location;
5457 next = c_parser_expr_no_commas (parser, NULL);
5458 next = convert_lvalue_to_rvalue (exp_loc, next,
5459 true, true);
5460 rec = build_compound_expr (comma_loc, rec, next.value);
5462 parse_message_args:
5463 /* Now parse the objc-message-args. */
5464 args = c_parser_objc_message_args (parser);
5465 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5466 "expected %<]%>");
5467 mexpr.value
5468 = objc_build_message_expr (rec, args);
5469 mexpr.original_code = ERROR_MARK;
5470 mexpr.original_type = NULL;
5471 /* Now parse and process the remainder of the
5472 initializer, starting with this message
5473 expression as a primary-expression. */
5474 c_parser_initval (parser, &mexpr, braced_init_obstack);
5475 return;
5477 c_parser_consume_token (parser);
5478 array_index_loc = c_parser_peek_token (parser)->location;
5479 first = c_parser_expr_no_commas (parser, NULL).value;
5480 mark_exp_read (first);
5481 array_desig_after_first:
5482 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5484 ellipsis_loc = c_parser_peek_token (parser)->location;
5485 c_parser_consume_token (parser);
5486 second = c_parser_expr_no_commas (parser, NULL).value;
5487 mark_exp_read (second);
5489 else
5490 second = NULL_TREE;
5491 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5493 c_parser_consume_token (parser);
5494 set_init_index (array_index_loc, first, second,
5495 braced_init_obstack);
5496 if (second)
5497 pedwarn (ellipsis_loc, OPT_Wpedantic,
5498 "ISO C forbids specifying range of elements to initialize");
5500 else
5501 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5502 "expected %<]%>");
5505 if (des_seen >= 1)
5507 if (c_parser_next_token_is (parser, CPP_EQ))
5509 pedwarn_c90 (des_loc, OPT_Wpedantic,
5510 "ISO C90 forbids specifying subobject "
5511 "to initialize");
5512 c_parser_consume_token (parser);
5514 else
5516 if (des_seen == 1)
5517 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5518 "obsolete use of designated initializer without %<=%>");
5519 else
5521 struct c_expr init;
5522 init.set_error ();
5523 init.original_code = ERROR_MARK;
5524 init.original_type = NULL;
5525 c_parser_error (parser, "expected %<=%>");
5526 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5527 process_init_element (input_location, init, false,
5528 braced_init_obstack);
5529 return;
5534 c_parser_initval (parser, NULL, braced_init_obstack);
5537 /* Parse a nested initializer; as c_parser_initializer but parses
5538 initializers within braced lists, after any designators have been
5539 applied. If AFTER is not NULL then it is an Objective-C message
5540 expression which is the primary-expression starting the
5541 initializer. */
5543 static void
5544 c_parser_initval (c_parser *parser, struct c_expr *after,
5545 struct obstack * braced_init_obstack)
5547 struct c_expr init;
5548 gcc_assert (!after || c_dialect_objc ());
5549 location_t loc = c_parser_peek_token (parser)->location;
5551 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5552 init = c_parser_braced_init (parser, NULL_TREE, true,
5553 braced_init_obstack);
5554 else
5556 init = c_parser_expr_no_commas (parser, after);
5557 if (init.value != NULL_TREE
5558 && TREE_CODE (init.value) != STRING_CST
5559 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5560 init = convert_lvalue_to_rvalue (loc, init, true, true);
5562 process_init_element (loc, init, false, braced_init_obstack);
5565 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5566 C99 6.8.2, C11 6.8.2).
5568 compound-statement:
5569 { block-item-list[opt] }
5570 { label-declarations block-item-list }
5572 block-item-list:
5573 block-item
5574 block-item-list block-item
5576 block-item:
5577 nested-declaration
5578 statement
5580 nested-declaration:
5581 declaration
5583 GNU extensions:
5585 compound-statement:
5586 { label-declarations block-item-list }
5588 nested-declaration:
5589 __extension__ nested-declaration
5590 nested-function-definition
5592 label-declarations:
5593 label-declaration
5594 label-declarations label-declaration
5596 label-declaration:
5597 __label__ identifier-list ;
5599 Allowing the mixing of declarations and code is new in C99. The
5600 GNU syntax also permits (not shown above) labels at the end of
5601 compound statements, which yield an error. We don't allow labels
5602 on declarations; this might seem like a natural extension, but
5603 there would be a conflict between gnu-attributes on the label and
5604 prefix gnu-attributes on the declaration. ??? The syntax follows the
5605 old parser in requiring something after label declarations.
5606 Although they are erroneous if the labels declared aren't defined,
5607 is it useful for the syntax to be this way?
5609 OpenACC:
5611 block-item:
5612 openacc-directive
5614 openacc-directive:
5615 update-directive
5617 OpenMP:
5619 block-item:
5620 openmp-directive
5622 openmp-directive:
5623 barrier-directive
5624 flush-directive
5625 taskwait-directive
5626 taskyield-directive
5627 cancel-directive
5628 cancellation-point-directive */
5630 static tree
5631 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5633 tree stmt;
5634 location_t brace_loc;
5635 brace_loc = c_parser_peek_token (parser)->location;
5636 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5638 /* Ensure a scope is entered and left anyway to avoid confusion
5639 if we have just prepared to enter a function body. */
5640 stmt = c_begin_compound_stmt (true);
5641 c_end_compound_stmt (brace_loc, stmt, true);
5642 return error_mark_node;
5644 stmt = c_begin_compound_stmt (true);
5645 location_t end_loc = c_parser_compound_statement_nostart (parser);
5646 if (endlocp)
5647 *endlocp = end_loc;
5649 return c_end_compound_stmt (brace_loc, stmt, true);
5652 /* Parse a compound statement except for the opening brace. This is
5653 used for parsing both compound statements and statement expressions
5654 (which follow different paths to handling the opening). */
5656 static location_t
5657 c_parser_compound_statement_nostart (c_parser *parser)
5659 bool last_stmt = false;
5660 bool last_label = false;
5661 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5662 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5663 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5665 location_t endloc = c_parser_peek_token (parser)->location;
5666 add_debug_begin_stmt (endloc);
5667 c_parser_consume_token (parser);
5668 return endloc;
5670 mark_valid_location_for_stdc_pragma (true);
5671 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5673 /* Read zero or more forward-declarations for labels that nested
5674 functions can jump to. */
5675 mark_valid_location_for_stdc_pragma (false);
5676 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5678 label_loc = c_parser_peek_token (parser)->location;
5679 c_parser_consume_token (parser);
5680 /* Any identifiers, including those declared as type names,
5681 are OK here. */
5682 while (true)
5684 tree label;
5685 if (c_parser_next_token_is_not (parser, CPP_NAME))
5687 c_parser_error (parser, "expected identifier");
5688 break;
5690 label
5691 = declare_label (c_parser_peek_token (parser)->value);
5692 C_DECLARED_LABEL_FLAG (label) = 1;
5693 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5694 c_parser_consume_token (parser);
5695 if (c_parser_next_token_is (parser, CPP_COMMA))
5696 c_parser_consume_token (parser);
5697 else
5698 break;
5700 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5702 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5704 /* We must now have at least one statement, label or declaration. */
5705 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5707 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5708 c_parser_error (parser, "expected declaration or statement");
5709 location_t endloc = c_parser_peek_token (parser)->location;
5710 c_parser_consume_token (parser);
5711 return endloc;
5713 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5715 location_t loc = c_parser_peek_token (parser)->location;
5716 loc = expansion_point_location_if_in_system_header (loc);
5717 /* Standard attributes may start a statement or a declaration. */
5718 bool have_std_attrs
5719 = c_parser_nth_token_starts_std_attributes (parser, 1);
5720 tree std_attrs = NULL_TREE;
5721 if (have_std_attrs)
5722 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5723 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5724 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5725 || (c_parser_next_token_is (parser, CPP_NAME)
5726 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5728 c_warn_unused_attributes (std_attrs);
5729 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5730 label_loc = c_parser_peek_2nd_token (parser)->location;
5731 else
5732 label_loc = c_parser_peek_token (parser)->location;
5733 last_label = true;
5734 last_stmt = false;
5735 mark_valid_location_for_stdc_pragma (false);
5736 c_parser_label (parser);
5738 else if (!last_label
5739 && (c_parser_next_tokens_start_declaration (parser)
5740 || (have_std_attrs
5741 && c_parser_next_token_is (parser, CPP_SEMICOLON))))
5743 last_label = false;
5744 mark_valid_location_for_stdc_pragma (false);
5745 bool fallthru_attr_p = false;
5746 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5747 true, true, true, NULL,
5748 vNULL, have_std_attrs, std_attrs,
5749 NULL, &fallthru_attr_p);
5750 if (last_stmt && !fallthru_attr_p)
5751 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5752 "ISO C90 forbids mixed declarations and code");
5753 last_stmt = fallthru_attr_p;
5755 else if (!last_label
5756 && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5758 /* __extension__ can start a declaration, but is also an
5759 unary operator that can start an expression. Consume all
5760 but the last of a possible series of __extension__ to
5761 determine which. If standard attributes have already
5762 been seen, it must start a statement, not a declaration,
5763 but standard attributes starting a declaration may appear
5764 after __extension__. */
5765 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5766 && (c_parser_peek_2nd_token (parser)->keyword
5767 == RID_EXTENSION))
5768 c_parser_consume_token (parser);
5769 if (!have_std_attrs
5770 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5771 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5773 int ext;
5774 ext = disable_extension_diagnostics ();
5775 c_parser_consume_token (parser);
5776 last_label = false;
5777 mark_valid_location_for_stdc_pragma (false);
5778 c_parser_declaration_or_fndef (parser, true, true, true, true,
5779 true, NULL, vNULL);
5780 /* Following the old parser, __extension__ does not
5781 disable this diagnostic. */
5782 restore_extension_diagnostics (ext);
5783 if (last_stmt)
5784 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5785 "ISO C90 forbids mixed declarations and code");
5786 last_stmt = false;
5788 else
5789 goto statement;
5791 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5793 if (have_std_attrs)
5794 c_parser_error (parser, "expected declaration or statement");
5795 /* External pragmas, and some omp pragmas, are not associated
5796 with regular c code, and so are not to be considered statements
5797 syntactically. This ensures that the user doesn't put them
5798 places that would turn into syntax errors if the directive
5799 were ignored. */
5800 if (c_parser_pragma (parser,
5801 last_label ? pragma_stmt : pragma_compound,
5802 NULL))
5803 last_label = false, last_stmt = true;
5805 else if (c_parser_next_token_is (parser, CPP_EOF))
5807 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5808 c_parser_error (parser, "expected declaration or statement");
5809 return c_parser_peek_token (parser)->location;
5811 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5813 if (parser->in_if_block)
5815 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5816 error_at (loc, "expected %<}%> before %<else%>");
5817 return c_parser_peek_token (parser)->location;
5819 else
5821 error_at (loc, "%<else%> without a previous %<if%>");
5822 c_parser_consume_token (parser);
5823 continue;
5826 else
5828 statement:
5829 c_warn_unused_attributes (std_attrs);
5830 last_label = false;
5831 last_stmt = true;
5832 mark_valid_location_for_stdc_pragma (false);
5833 c_parser_statement_after_labels (parser, NULL);
5836 parser->error = false;
5838 if (last_label)
5839 error_at (label_loc, "label at end of compound statement");
5840 location_t endloc = c_parser_peek_token (parser)->location;
5841 c_parser_consume_token (parser);
5842 /* Restore the value we started with. */
5843 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5844 return endloc;
5847 /* Parse all consecutive labels, possibly preceded by standard
5848 attributes. In this context, a statement is required, not a
5849 declaration, so attributes must be followed by a statement that is
5850 not just a semicolon. */
5852 static void
5853 c_parser_all_labels (c_parser *parser)
5855 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5857 tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5858 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5859 c_parser_error (parser, "expected statement");
5860 else
5861 c_warn_unused_attributes (std_attrs);
5863 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5864 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5865 || (c_parser_next_token_is (parser, CPP_NAME)
5866 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5867 c_parser_label (parser);
5870 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5872 label:
5873 identifier : gnu-attributes[opt]
5874 case constant-expression :
5875 default :
5877 GNU extensions:
5879 label:
5880 case constant-expression ... constant-expression :
5882 The use of gnu-attributes on labels is a GNU extension. The syntax in
5883 GNU C accepts any expressions without commas, non-constant
5884 expressions being rejected later. Any standard
5885 attribute-specifier-sequence before the first label has been parsed
5886 in the caller, to distinguish statements from declarations. Any
5887 attribute-specifier-sequence after the label is parsed in this
5888 function. */
5890 static void
5891 c_parser_label (c_parser *parser)
5893 location_t loc1 = c_parser_peek_token (parser)->location;
5894 tree label = NULL_TREE;
5896 /* Remember whether this case or a user-defined label is allowed to fall
5897 through to. */
5898 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5900 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5902 tree exp1, exp2;
5903 c_parser_consume_token (parser);
5904 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5905 if (c_parser_next_token_is (parser, CPP_COLON))
5907 c_parser_consume_token (parser);
5908 label = do_case (loc1, exp1, NULL_TREE);
5910 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5912 c_parser_consume_token (parser);
5913 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5914 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5915 label = do_case (loc1, exp1, exp2);
5917 else
5918 c_parser_error (parser, "expected %<:%> or %<...%>");
5920 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5922 c_parser_consume_token (parser);
5923 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5924 label = do_case (loc1, NULL_TREE, NULL_TREE);
5926 else
5928 tree name = c_parser_peek_token (parser)->value;
5929 tree tlab;
5930 tree attrs;
5931 location_t loc2 = c_parser_peek_token (parser)->location;
5932 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5933 c_parser_consume_token (parser);
5934 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5935 c_parser_consume_token (parser);
5936 attrs = c_parser_gnu_attributes (parser);
5937 tlab = define_label (loc2, name);
5938 if (tlab)
5940 decl_attributes (&tlab, attrs, 0);
5941 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5944 if (label)
5946 if (TREE_CODE (label) == LABEL_EXPR)
5947 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5948 else
5949 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5951 /* Standard attributes are only allowed here if they start a
5952 statement, not a declaration (including the case of an
5953 attribute-declaration with only attributes). */
5954 bool have_std_attrs
5955 = c_parser_nth_token_starts_std_attributes (parser, 1);
5956 tree std_attrs = NULL_TREE;
5957 if (have_std_attrs)
5958 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5960 /* Allow '__attribute__((fallthrough));'. */
5961 if (!have_std_attrs
5962 && c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5964 location_t loc = c_parser_peek_token (parser)->location;
5965 tree attrs = c_parser_gnu_attributes (parser);
5966 if (attribute_fallthrough_p (attrs))
5968 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5970 tree fn = build_call_expr_internal_loc (loc,
5971 IFN_FALLTHROUGH,
5972 void_type_node, 0);
5973 add_stmt (fn);
5975 else
5976 warning_at (loc, OPT_Wattributes, "%<fallthrough%> attribute "
5977 "not followed by %<;%>");
5979 else if (attrs != NULL_TREE)
5980 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
5981 " can be applied to a null statement");
5983 if (c_parser_next_tokens_start_declaration (parser)
5984 || (have_std_attrs
5985 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5987 error_at (c_parser_peek_token (parser)->location,
5988 "a label can only be part of a statement and "
5989 "a declaration is not a statement");
5990 c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
5991 /*static_assert_ok*/ true,
5992 /*empty_ok*/ true, /*nested*/ true,
5993 /*start_attr_ok*/ true, NULL,
5994 vNULL, have_std_attrs, std_attrs);
5996 else if (std_attrs)
5997 /* Nonempty attributes on the following statement are ignored. */
5998 c_warn_unused_attributes (std_attrs);
6002 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
6004 statement:
6005 labeled-statement
6006 attribute-specifier-sequence[opt] compound-statement
6007 expression-statement
6008 attribute-specifier-sequence[opt] selection-statement
6009 attribute-specifier-sequence[opt] iteration-statement
6010 attribute-specifier-sequence[opt] jump-statement
6012 labeled-statement:
6013 attribute-specifier-sequence[opt] label statement
6015 expression-statement:
6016 expression[opt] ;
6017 attribute-specifier-sequence expression ;
6019 selection-statement:
6020 if-statement
6021 switch-statement
6023 iteration-statement:
6024 while-statement
6025 do-statement
6026 for-statement
6028 jump-statement:
6029 goto identifier ;
6030 continue ;
6031 break ;
6032 return expression[opt] ;
6034 GNU extensions:
6036 statement:
6037 attribute-specifier-sequence[opt] asm-statement
6039 jump-statement:
6040 goto * expression ;
6042 expression-statement:
6043 gnu-attributes ;
6045 Objective-C:
6047 statement:
6048 attribute-specifier-sequence[opt] objc-throw-statement
6049 attribute-specifier-sequence[opt] objc-try-catch-statement
6050 attribute-specifier-sequence[opt] objc-synchronized-statement
6052 objc-throw-statement:
6053 @throw expression ;
6054 @throw ;
6056 OpenACC:
6058 statement:
6059 attribute-specifier-sequence[opt] openacc-construct
6061 openacc-construct:
6062 parallel-construct
6063 kernels-construct
6064 data-construct
6065 loop-construct
6067 parallel-construct:
6068 parallel-directive structured-block
6070 kernels-construct:
6071 kernels-directive structured-block
6073 data-construct:
6074 data-directive structured-block
6076 loop-construct:
6077 loop-directive structured-block
6079 OpenMP:
6081 statement:
6082 attribute-specifier-sequence[opt] openmp-construct
6084 openmp-construct:
6085 parallel-construct
6086 for-construct
6087 simd-construct
6088 for-simd-construct
6089 sections-construct
6090 single-construct
6091 parallel-for-construct
6092 parallel-for-simd-construct
6093 parallel-sections-construct
6094 master-construct
6095 critical-construct
6096 atomic-construct
6097 ordered-construct
6099 parallel-construct:
6100 parallel-directive structured-block
6102 for-construct:
6103 for-directive iteration-statement
6105 simd-construct:
6106 simd-directive iteration-statements
6108 for-simd-construct:
6109 for-simd-directive iteration-statements
6111 sections-construct:
6112 sections-directive section-scope
6114 single-construct:
6115 single-directive structured-block
6117 parallel-for-construct:
6118 parallel-for-directive iteration-statement
6120 parallel-for-simd-construct:
6121 parallel-for-simd-directive iteration-statement
6123 parallel-sections-construct:
6124 parallel-sections-directive section-scope
6126 master-construct:
6127 master-directive structured-block
6129 critical-construct:
6130 critical-directive structured-block
6132 atomic-construct:
6133 atomic-directive expression-statement
6135 ordered-construct:
6136 ordered-directive structured-block
6138 Transactional Memory:
6140 statement:
6141 attribute-specifier-sequence[opt] transaction-statement
6142 attribute-specifier-sequence[opt] transaction-cancel-statement
6144 IF_P is used to track whether there's a (possibly labeled) if statement
6145 which is not enclosed in braces and has an else clause. This is used to
6146 implement -Wparentheses. */
6148 static void
6149 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6151 c_parser_all_labels (parser);
6152 if (loc_after_labels)
6153 *loc_after_labels = c_parser_peek_token (parser)->location;
6154 c_parser_statement_after_labels (parser, if_p, NULL);
6157 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6158 of if-else-if conditions. All labels and standard attributes have
6159 been parsed in the caller.
6161 IF_P is used to track whether there's a (possibly labeled) if statement
6162 which is not enclosed in braces and has an else clause. This is used to
6163 implement -Wparentheses. */
6165 static void
6166 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6167 vec<tree> *chain)
6169 location_t loc = c_parser_peek_token (parser)->location;
6170 tree stmt = NULL_TREE;
6171 bool in_if_block = parser->in_if_block;
6172 parser->in_if_block = false;
6173 if (if_p != NULL)
6174 *if_p = false;
6176 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6177 add_debug_begin_stmt (loc);
6179 switch (c_parser_peek_token (parser)->type)
6181 case CPP_OPEN_BRACE:
6182 add_stmt (c_parser_compound_statement (parser));
6183 break;
6184 case CPP_KEYWORD:
6185 switch (c_parser_peek_token (parser)->keyword)
6187 case RID_IF:
6188 c_parser_if_statement (parser, if_p, chain);
6189 break;
6190 case RID_SWITCH:
6191 c_parser_switch_statement (parser, if_p);
6192 break;
6193 case RID_WHILE:
6194 c_parser_while_statement (parser, false, 0, if_p);
6195 break;
6196 case RID_DO:
6197 c_parser_do_statement (parser, false, 0);
6198 break;
6199 case RID_FOR:
6200 c_parser_for_statement (parser, false, 0, if_p);
6201 break;
6202 case RID_GOTO:
6203 c_parser_consume_token (parser);
6204 if (c_parser_next_token_is (parser, CPP_NAME))
6206 stmt = c_finish_goto_label (loc,
6207 c_parser_peek_token (parser)->value);
6208 c_parser_consume_token (parser);
6210 else if (c_parser_next_token_is (parser, CPP_MULT))
6212 struct c_expr val;
6214 c_parser_consume_token (parser);
6215 val = c_parser_expression (parser);
6216 val = convert_lvalue_to_rvalue (loc, val, false, true);
6217 stmt = c_finish_goto_ptr (loc, val.value);
6219 else
6220 c_parser_error (parser, "expected identifier or %<*%>");
6221 goto expect_semicolon;
6222 case RID_CONTINUE:
6223 c_parser_consume_token (parser);
6224 stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
6225 goto expect_semicolon;
6226 case RID_BREAK:
6227 c_parser_consume_token (parser);
6228 stmt = c_finish_bc_stmt (loc, &c_break_label, true);
6229 goto expect_semicolon;
6230 case RID_RETURN:
6231 c_parser_consume_token (parser);
6232 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6234 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6235 c_parser_consume_token (parser);
6237 else
6239 location_t xloc = c_parser_peek_token (parser)->location;
6240 struct c_expr expr = c_parser_expression_conv (parser);
6241 mark_exp_read (expr.value);
6242 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6243 expr.value, expr.original_type);
6244 goto expect_semicolon;
6246 break;
6247 case RID_ASM:
6248 stmt = c_parser_asm_statement (parser);
6249 break;
6250 case RID_TRANSACTION_ATOMIC:
6251 case RID_TRANSACTION_RELAXED:
6252 stmt = c_parser_transaction (parser,
6253 c_parser_peek_token (parser)->keyword);
6254 break;
6255 case RID_TRANSACTION_CANCEL:
6256 stmt = c_parser_transaction_cancel (parser);
6257 goto expect_semicolon;
6258 case RID_AT_THROW:
6259 gcc_assert (c_dialect_objc ());
6260 c_parser_consume_token (parser);
6261 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6263 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6264 c_parser_consume_token (parser);
6266 else
6268 struct c_expr expr = c_parser_expression (parser);
6269 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6270 expr.value = c_fully_fold (expr.value, false, NULL);
6271 stmt = objc_build_throw_stmt (loc, expr.value);
6272 goto expect_semicolon;
6274 break;
6275 case RID_AT_TRY:
6276 gcc_assert (c_dialect_objc ());
6277 c_parser_objc_try_catch_finally_statement (parser);
6278 break;
6279 case RID_AT_SYNCHRONIZED:
6280 gcc_assert (c_dialect_objc ());
6281 c_parser_objc_synchronized_statement (parser);
6282 break;
6283 case RID_ATTRIBUTE:
6285 /* Allow '__attribute__((fallthrough));'. */
6286 tree attrs = c_parser_gnu_attributes (parser);
6287 if (attribute_fallthrough_p (attrs))
6289 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6291 tree fn = build_call_expr_internal_loc (loc,
6292 IFN_FALLTHROUGH,
6293 void_type_node, 0);
6294 add_stmt (fn);
6295 /* Eat the ';'. */
6296 c_parser_consume_token (parser);
6298 else
6299 warning_at (loc, OPT_Wattributes,
6300 "%<fallthrough%> attribute not followed "
6301 "by %<;%>");
6303 else if (attrs != NULL_TREE)
6304 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6305 " can be applied to a null statement");
6306 break;
6308 default:
6309 goto expr_stmt;
6311 break;
6312 case CPP_SEMICOLON:
6313 c_parser_consume_token (parser);
6314 break;
6315 case CPP_CLOSE_PAREN:
6316 case CPP_CLOSE_SQUARE:
6317 /* Avoid infinite loop in error recovery:
6318 c_parser_skip_until_found stops at a closing nesting
6319 delimiter without consuming it, but here we need to consume
6320 it to proceed further. */
6321 c_parser_error (parser, "expected statement");
6322 c_parser_consume_token (parser);
6323 break;
6324 case CPP_PRAGMA:
6325 c_parser_pragma (parser, pragma_stmt, if_p);
6326 break;
6327 default:
6328 expr_stmt:
6329 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6330 expect_semicolon:
6331 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6332 break;
6334 /* Two cases cannot and do not have line numbers associated: If stmt
6335 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6336 cannot hold line numbers. But that's OK because the statement
6337 will either be changed to a MODIFY_EXPR during gimplification of
6338 the statement expr, or discarded. If stmt was compound, but
6339 without new variables, we will have skipped the creation of a
6340 BIND and will have a bare STATEMENT_LIST. But that's OK because
6341 (recursively) all of the component statements should already have
6342 line numbers assigned. ??? Can we discard no-op statements
6343 earlier? */
6344 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6345 protected_set_expr_location (stmt, loc);
6347 parser->in_if_block = in_if_block;
6350 /* Parse the condition from an if, do, while or for statements. */
6352 static tree
6353 c_parser_condition (c_parser *parser)
6355 location_t loc = c_parser_peek_token (parser)->location;
6356 tree cond;
6357 cond = c_parser_expression_conv (parser).value;
6358 cond = c_objc_common_truthvalue_conversion (loc, cond);
6359 cond = c_fully_fold (cond, false, NULL);
6360 if (warn_sequence_point)
6361 verify_sequence_points (cond);
6362 return cond;
6365 /* Parse a parenthesized condition from an if, do or while statement.
6367 condition:
6368 ( expression )
6370 static tree
6371 c_parser_paren_condition (c_parser *parser)
6373 tree cond;
6374 matching_parens parens;
6375 if (!parens.require_open (parser))
6376 return error_mark_node;
6377 cond = c_parser_condition (parser);
6378 parens.skip_until_found_close (parser);
6379 return cond;
6382 /* Parse a statement which is a block in C99.
6384 IF_P is used to track whether there's a (possibly labeled) if statement
6385 which is not enclosed in braces and has an else clause. This is used to
6386 implement -Wparentheses. */
6388 static tree
6389 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6390 location_t *loc_after_labels)
6392 tree block = c_begin_compound_stmt (flag_isoc99);
6393 location_t loc = c_parser_peek_token (parser)->location;
6394 c_parser_statement (parser, if_p, loc_after_labels);
6395 return c_end_compound_stmt (loc, block, flag_isoc99);
6398 /* Parse the body of an if statement. This is just parsing a
6399 statement but (a) it is a block in C99, (b) we track whether the
6400 body is an if statement for the sake of -Wparentheses warnings, (c)
6401 we handle an empty body specially for the sake of -Wempty-body
6402 warnings, and (d) we call parser_compound_statement directly
6403 because c_parser_statement_after_labels resets
6404 parser->in_if_block.
6406 IF_P is used to track whether there's a (possibly labeled) if statement
6407 which is not enclosed in braces and has an else clause. This is used to
6408 implement -Wparentheses. */
6410 static tree
6411 c_parser_if_body (c_parser *parser, bool *if_p,
6412 const token_indent_info &if_tinfo)
6414 tree block = c_begin_compound_stmt (flag_isoc99);
6415 location_t body_loc = c_parser_peek_token (parser)->location;
6416 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6417 token_indent_info body_tinfo
6418 = get_token_indent_info (c_parser_peek_token (parser));
6420 c_parser_all_labels (parser);
6421 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6423 location_t loc = c_parser_peek_token (parser)->location;
6424 add_stmt (build_empty_stmt (loc));
6425 c_parser_consume_token (parser);
6426 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6427 warning_at (loc, OPT_Wempty_body,
6428 "suggest braces around empty body in an %<if%> statement");
6430 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6431 add_stmt (c_parser_compound_statement (parser));
6432 else
6434 body_loc_after_labels = c_parser_peek_token (parser)->location;
6435 c_parser_statement_after_labels (parser, if_p);
6438 token_indent_info next_tinfo
6439 = get_token_indent_info (c_parser_peek_token (parser));
6440 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6441 if (body_loc_after_labels != UNKNOWN_LOCATION
6442 && next_tinfo.type != CPP_SEMICOLON)
6443 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6444 if_tinfo.location, RID_IF);
6446 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6449 /* Parse the else body of an if statement. This is just parsing a
6450 statement but (a) it is a block in C99, (b) we handle an empty body
6451 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6452 of if-else-if conditions. */
6454 static tree
6455 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6456 vec<tree> *chain)
6458 location_t body_loc = c_parser_peek_token (parser)->location;
6459 tree block = c_begin_compound_stmt (flag_isoc99);
6460 token_indent_info body_tinfo
6461 = get_token_indent_info (c_parser_peek_token (parser));
6462 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6464 c_parser_all_labels (parser);
6465 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6467 location_t loc = c_parser_peek_token (parser)->location;
6468 warning_at (loc,
6469 OPT_Wempty_body,
6470 "suggest braces around empty body in an %<else%> statement");
6471 add_stmt (build_empty_stmt (loc));
6472 c_parser_consume_token (parser);
6474 else
6476 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6477 body_loc_after_labels = c_parser_peek_token (parser)->location;
6478 c_parser_statement_after_labels (parser, NULL, chain);
6481 token_indent_info next_tinfo
6482 = get_token_indent_info (c_parser_peek_token (parser));
6483 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6484 if (body_loc_after_labels != UNKNOWN_LOCATION
6485 && next_tinfo.type != CPP_SEMICOLON)
6486 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6487 else_tinfo.location, RID_ELSE);
6489 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6492 /* We might need to reclassify any previously-lexed identifier, e.g.
6493 when we've left a for loop with an if-statement without else in the
6494 body - we might have used a wrong scope for the token. See PR67784. */
6496 static void
6497 c_parser_maybe_reclassify_token (c_parser *parser)
6499 if (c_parser_next_token_is (parser, CPP_NAME))
6501 c_token *token = c_parser_peek_token (parser);
6503 if (token->id_kind != C_ID_CLASSNAME)
6505 tree decl = lookup_name (token->value);
6507 token->id_kind = C_ID_ID;
6508 if (decl)
6510 if (TREE_CODE (decl) == TYPE_DECL)
6511 token->id_kind = C_ID_TYPENAME;
6513 else if (c_dialect_objc ())
6515 tree objc_interface_decl = objc_is_class_name (token->value);
6516 /* Objective-C class names are in the same namespace as
6517 variables and typedefs, and hence are shadowed by local
6518 declarations. */
6519 if (objc_interface_decl)
6521 token->value = objc_interface_decl;
6522 token->id_kind = C_ID_CLASSNAME;
6529 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6531 if-statement:
6532 if ( expression ) statement
6533 if ( expression ) statement else statement
6535 CHAIN is a vector of if-else-if conditions.
6536 IF_P is used to track whether there's a (possibly labeled) if statement
6537 which is not enclosed in braces and has an else clause. This is used to
6538 implement -Wparentheses. */
6540 static void
6541 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6543 tree block;
6544 location_t loc;
6545 tree cond;
6546 bool nested_if = false;
6547 tree first_body, second_body;
6548 bool in_if_block;
6550 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6551 token_indent_info if_tinfo
6552 = get_token_indent_info (c_parser_peek_token (parser));
6553 c_parser_consume_token (parser);
6554 block = c_begin_compound_stmt (flag_isoc99);
6555 loc = c_parser_peek_token (parser)->location;
6556 cond = c_parser_paren_condition (parser);
6557 in_if_block = parser->in_if_block;
6558 parser->in_if_block = true;
6559 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6560 parser->in_if_block = in_if_block;
6562 if (warn_duplicated_cond)
6563 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6565 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6567 token_indent_info else_tinfo
6568 = get_token_indent_info (c_parser_peek_token (parser));
6569 c_parser_consume_token (parser);
6570 if (warn_duplicated_cond)
6572 if (c_parser_next_token_is_keyword (parser, RID_IF)
6573 && chain == NULL)
6575 /* We've got "if (COND) else if (COND2)". Start the
6576 condition chain and add COND as the first element. */
6577 chain = new vec<tree> ();
6578 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6579 chain->safe_push (cond);
6581 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6583 /* This is if-else without subsequent if. Zap the condition
6584 chain; we would have already warned at this point. */
6585 delete chain;
6586 chain = NULL;
6589 second_body = c_parser_else_body (parser, else_tinfo, chain);
6590 /* Set IF_P to true to indicate that this if statement has an
6591 else clause. This may trigger the Wparentheses warning
6592 below when we get back up to the parent if statement. */
6593 if (if_p != NULL)
6594 *if_p = true;
6596 else
6598 second_body = NULL_TREE;
6600 /* Diagnose an ambiguous else if if-then-else is nested inside
6601 if-then. */
6602 if (nested_if)
6603 warning_at (loc, OPT_Wdangling_else,
6604 "suggest explicit braces to avoid ambiguous %<else%>");
6606 if (warn_duplicated_cond)
6608 /* This if statement does not have an else clause. We don't
6609 need the condition chain anymore. */
6610 delete chain;
6611 chain = NULL;
6614 c_finish_if_stmt (loc, cond, first_body, second_body);
6615 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6617 c_parser_maybe_reclassify_token (parser);
6620 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6622 switch-statement:
6623 switch (expression) statement
6626 static void
6627 c_parser_switch_statement (c_parser *parser, bool *if_p)
6629 struct c_expr ce;
6630 tree block, expr, body, save_break;
6631 location_t switch_loc = c_parser_peek_token (parser)->location;
6632 location_t switch_cond_loc;
6633 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6634 c_parser_consume_token (parser);
6635 block = c_begin_compound_stmt (flag_isoc99);
6636 bool explicit_cast_p = false;
6637 matching_parens parens;
6638 if (parens.require_open (parser))
6640 switch_cond_loc = c_parser_peek_token (parser)->location;
6641 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6642 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6643 explicit_cast_p = true;
6644 ce = c_parser_expression (parser);
6645 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6646 expr = ce.value;
6647 /* ??? expr has no valid location? */
6648 parens.skip_until_found_close (parser);
6650 else
6652 switch_cond_loc = UNKNOWN_LOCATION;
6653 expr = error_mark_node;
6654 ce.original_type = error_mark_node;
6656 c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6657 save_break = c_break_label;
6658 c_break_label = NULL_TREE;
6659 location_t loc_after_labels;
6660 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6661 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6662 location_t next_loc = c_parser_peek_token (parser)->location;
6663 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6664 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6665 RID_SWITCH);
6666 if (c_break_label)
6668 location_t here = c_parser_peek_token (parser)->location;
6669 tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
6670 SET_EXPR_LOCATION (t, here);
6671 SWITCH_BREAK_LABEL_P (c_break_label) = 1;
6672 append_to_statement_list_force (t, &body);
6674 c_finish_case (body, ce.original_type);
6675 c_break_label = save_break;
6676 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6677 c_parser_maybe_reclassify_token (parser);
6680 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6682 while-statement:
6683 while (expression) statement
6685 IF_P is used to track whether there's a (possibly labeled) if statement
6686 which is not enclosed in braces and has an else clause. This is used to
6687 implement -Wparentheses. */
6689 static void
6690 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6691 bool *if_p)
6693 tree block, cond, body, save_break, save_cont;
6694 location_t loc;
6695 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6696 token_indent_info while_tinfo
6697 = get_token_indent_info (c_parser_peek_token (parser));
6698 c_parser_consume_token (parser);
6699 block = c_begin_compound_stmt (flag_isoc99);
6700 loc = c_parser_peek_token (parser)->location;
6701 cond = c_parser_paren_condition (parser);
6702 if (ivdep && cond != error_mark_node)
6703 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6704 build_int_cst (integer_type_node,
6705 annot_expr_ivdep_kind),
6706 integer_zero_node);
6707 if (unroll && cond != error_mark_node)
6708 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6709 build_int_cst (integer_type_node,
6710 annot_expr_unroll_kind),
6711 build_int_cst (integer_type_node, unroll));
6712 save_break = c_break_label;
6713 c_break_label = NULL_TREE;
6714 save_cont = c_cont_label;
6715 c_cont_label = NULL_TREE;
6717 token_indent_info body_tinfo
6718 = get_token_indent_info (c_parser_peek_token (parser));
6720 location_t loc_after_labels;
6721 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6722 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6723 c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body,
6724 c_break_label, c_cont_label, true);
6725 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6726 c_parser_maybe_reclassify_token (parser);
6728 token_indent_info next_tinfo
6729 = get_token_indent_info (c_parser_peek_token (parser));
6730 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6732 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6733 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6734 while_tinfo.location, RID_WHILE);
6736 c_break_label = save_break;
6737 c_cont_label = save_cont;
6740 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6742 do-statement:
6743 do statement while ( expression ) ;
6746 static void
6747 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6749 tree block, cond, body, save_break, save_cont, new_break, new_cont;
6750 location_t loc;
6751 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6752 c_parser_consume_token (parser);
6753 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6754 warning_at (c_parser_peek_token (parser)->location,
6755 OPT_Wempty_body,
6756 "suggest braces around empty body in %<do%> statement");
6757 block = c_begin_compound_stmt (flag_isoc99);
6758 loc = c_parser_peek_token (parser)->location;
6759 save_break = c_break_label;
6760 c_break_label = NULL_TREE;
6761 save_cont = c_cont_label;
6762 c_cont_label = NULL_TREE;
6763 body = c_parser_c99_block_statement (parser, NULL);
6764 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6765 new_break = c_break_label;
6766 c_break_label = save_break;
6767 new_cont = c_cont_label;
6768 c_cont_label = save_cont;
6769 location_t cond_loc = c_parser_peek_token (parser)->location;
6770 cond = c_parser_paren_condition (parser);
6771 if (ivdep && cond != error_mark_node)
6772 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6773 build_int_cst (integer_type_node,
6774 annot_expr_ivdep_kind),
6775 integer_zero_node);
6776 if (unroll && cond != error_mark_node)
6777 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6778 build_int_cst (integer_type_node,
6779 annot_expr_unroll_kind),
6780 build_int_cst (integer_type_node, unroll));
6781 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6782 c_parser_skip_to_end_of_block_or_statement (parser);
6783 c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body,
6784 new_break, new_cont, false);
6785 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6788 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6790 for-statement:
6791 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6792 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6794 The form with a declaration is new in C99.
6796 ??? In accordance with the old parser, the declaration may be a
6797 nested function, which is then rejected in check_for_loop_decls,
6798 but does it make any sense for this to be included in the grammar?
6799 Note in particular that the nested function does not include a
6800 trailing ';', whereas the "declaration" production includes one.
6801 Also, can we reject bad declarations earlier and cheaper than
6802 check_for_loop_decls?
6804 In Objective-C, there are two additional variants:
6806 foreach-statement:
6807 for ( expression in expresssion ) statement
6808 for ( declaration in expression ) statement
6810 This is inconsistent with C, because the second variant is allowed
6811 even if c99 is not enabled.
6813 The rest of the comment documents these Objective-C foreach-statement.
6815 Here is the canonical example of the first variant:
6816 for (object in array) { do something with object }
6817 we call the first expression ("object") the "object_expression" and
6818 the second expression ("array") the "collection_expression".
6819 object_expression must be an lvalue of type "id" (a generic Objective-C
6820 object) because the loop works by assigning to object_expression the
6821 various objects from the collection_expression. collection_expression
6822 must evaluate to something of type "id" which responds to the method
6823 countByEnumeratingWithState:objects:count:.
6825 The canonical example of the second variant is:
6826 for (id object in array) { do something with object }
6827 which is completely equivalent to
6829 id object;
6830 for (object in array) { do something with object }
6832 Note that initizializing 'object' in some way (eg, "for ((object =
6833 xxx) in array) { do something with object }") is possibly
6834 technically valid, but completely pointless as 'object' will be
6835 assigned to something else as soon as the loop starts. We should
6836 most likely reject it (TODO).
6838 The beginning of the Objective-C foreach-statement looks exactly
6839 like the beginning of the for-statement, and we can tell it is a
6840 foreach-statement only because the initial declaration or
6841 expression is terminated by 'in' instead of ';'.
6843 IF_P is used to track whether there's a (possibly labeled) if statement
6844 which is not enclosed in braces and has an else clause. This is used to
6845 implement -Wparentheses. */
6847 static void
6848 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6849 bool *if_p)
6851 tree block, cond, incr, save_break, save_cont, body;
6852 /* The following are only used when parsing an ObjC foreach statement. */
6853 tree object_expression;
6854 /* Silence the bogus uninitialized warning. */
6855 tree collection_expression = NULL;
6856 location_t loc = c_parser_peek_token (parser)->location;
6857 location_t for_loc = loc;
6858 location_t cond_loc = UNKNOWN_LOCATION;
6859 location_t incr_loc = UNKNOWN_LOCATION;
6860 bool is_foreach_statement = false;
6861 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6862 token_indent_info for_tinfo
6863 = get_token_indent_info (c_parser_peek_token (parser));
6864 c_parser_consume_token (parser);
6865 /* Open a compound statement in Objective-C as well, just in case this is
6866 as foreach expression. */
6867 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6868 cond = error_mark_node;
6869 incr = error_mark_node;
6870 matching_parens parens;
6871 if (parens.require_open (parser))
6873 /* Parse the initialization declaration or expression. */
6874 object_expression = error_mark_node;
6875 parser->objc_could_be_foreach_context = c_dialect_objc ();
6876 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6878 parser->objc_could_be_foreach_context = false;
6879 c_parser_consume_token (parser);
6880 c_finish_expr_stmt (loc, NULL_TREE);
6882 else if (c_parser_next_tokens_start_declaration (parser)
6883 || c_parser_nth_token_starts_std_attributes (parser, 1))
6885 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6886 &object_expression, vNULL);
6887 parser->objc_could_be_foreach_context = false;
6889 if (c_parser_next_token_is_keyword (parser, RID_IN))
6891 c_parser_consume_token (parser);
6892 is_foreach_statement = true;
6893 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6894 c_parser_error (parser, "multiple iterating variables in "
6895 "fast enumeration");
6897 else
6898 check_for_loop_decls (for_loc, flag_isoc99);
6900 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6902 /* __extension__ can start a declaration, but is also an
6903 unary operator that can start an expression. Consume all
6904 but the last of a possible series of __extension__ to
6905 determine which. */
6906 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6907 && (c_parser_peek_2nd_token (parser)->keyword
6908 == RID_EXTENSION))
6909 c_parser_consume_token (parser);
6910 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6911 || c_parser_nth_token_starts_std_attributes (parser, 2))
6913 int ext;
6914 ext = disable_extension_diagnostics ();
6915 c_parser_consume_token (parser);
6916 c_parser_declaration_or_fndef (parser, true, true, true, true,
6917 true, &object_expression, vNULL);
6918 parser->objc_could_be_foreach_context = false;
6920 restore_extension_diagnostics (ext);
6921 if (c_parser_next_token_is_keyword (parser, RID_IN))
6923 c_parser_consume_token (parser);
6924 is_foreach_statement = true;
6925 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6926 c_parser_error (parser, "multiple iterating variables in "
6927 "fast enumeration");
6929 else
6930 check_for_loop_decls (for_loc, flag_isoc99);
6932 else
6933 goto init_expr;
6935 else
6937 init_expr:
6939 struct c_expr ce;
6940 tree init_expression;
6941 ce = c_parser_expression (parser);
6942 init_expression = ce.value;
6943 parser->objc_could_be_foreach_context = false;
6944 if (c_parser_next_token_is_keyword (parser, RID_IN))
6946 c_parser_consume_token (parser);
6947 is_foreach_statement = true;
6948 if (! lvalue_p (init_expression))
6949 c_parser_error (parser, "invalid iterating variable in "
6950 "fast enumeration");
6951 object_expression
6952 = c_fully_fold (init_expression, false, NULL);
6954 else
6956 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6957 init_expression = ce.value;
6958 c_finish_expr_stmt (loc, init_expression);
6959 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6960 "expected %<;%>");
6964 /* Parse the loop condition. In the case of a foreach
6965 statement, there is no loop condition. */
6966 gcc_assert (!parser->objc_could_be_foreach_context);
6967 if (!is_foreach_statement)
6969 cond_loc = c_parser_peek_token (parser)->location;
6970 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6972 if (ivdep)
6974 c_parser_error (parser, "missing loop condition in loop "
6975 "with %<GCC ivdep%> pragma");
6976 cond = error_mark_node;
6978 else if (unroll)
6980 c_parser_error (parser, "missing loop condition in loop "
6981 "with %<GCC unroll%> pragma");
6982 cond = error_mark_node;
6984 else
6986 c_parser_consume_token (parser);
6987 cond = NULL_TREE;
6990 else
6992 cond = c_parser_condition (parser);
6993 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6994 "expected %<;%>");
6996 if (ivdep && cond != error_mark_node)
6997 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6998 build_int_cst (integer_type_node,
6999 annot_expr_ivdep_kind),
7000 integer_zero_node);
7001 if (unroll && cond != error_mark_node)
7002 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
7003 build_int_cst (integer_type_node,
7004 annot_expr_unroll_kind),
7005 build_int_cst (integer_type_node, unroll));
7007 /* Parse the increment expression (the third expression in a
7008 for-statement). In the case of a foreach-statement, this is
7009 the expression that follows the 'in'. */
7010 loc = incr_loc = c_parser_peek_token (parser)->location;
7011 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7013 if (is_foreach_statement)
7015 c_parser_error (parser,
7016 "missing collection in fast enumeration");
7017 collection_expression = error_mark_node;
7019 else
7020 incr = c_process_expr_stmt (loc, NULL_TREE);
7022 else
7024 if (is_foreach_statement)
7025 collection_expression
7026 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
7027 else
7029 struct c_expr ce = c_parser_expression (parser);
7030 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
7031 incr = c_process_expr_stmt (loc, ce.value);
7034 parens.skip_until_found_close (parser);
7036 save_break = c_break_label;
7037 c_break_label = NULL_TREE;
7038 save_cont = c_cont_label;
7039 c_cont_label = NULL_TREE;
7041 token_indent_info body_tinfo
7042 = get_token_indent_info (c_parser_peek_token (parser));
7044 location_t loc_after_labels;
7045 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
7046 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
7048 if (is_foreach_statement)
7049 objc_finish_foreach_loop (for_loc, object_expression,
7050 collection_expression, body, c_break_label,
7051 c_cont_label);
7052 else
7053 c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body,
7054 c_break_label, c_cont_label, true);
7055 add_stmt (c_end_compound_stmt (for_loc, block,
7056 flag_isoc99 || c_dialect_objc ()));
7057 c_parser_maybe_reclassify_token (parser);
7059 token_indent_info next_tinfo
7060 = get_token_indent_info (c_parser_peek_token (parser));
7061 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
7063 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
7064 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7065 for_tinfo.location, RID_FOR);
7067 c_break_label = save_break;
7068 c_cont_label = save_cont;
7071 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7072 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7073 tags allowed.
7075 asm-qualifier:
7076 volatile
7077 inline
7078 goto
7080 asm-qualifier-list:
7081 asm-qualifier-list asm-qualifier
7082 asm-qualifier
7084 asm-statement:
7085 asm asm-qualifier-list[opt] ( asm-argument ) ;
7087 asm-argument:
7088 asm-string-literal
7089 asm-string-literal : asm-operands[opt]
7090 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7091 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7092 : asm-clobbers[opt]
7093 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7094 : asm-goto-operands
7096 The form with asm-goto-operands is valid if and only if the
7097 asm-qualifier-list contains goto, and is the only allowed form in that case.
7098 Duplicate asm-qualifiers are not allowed.
7100 The :: token is considered equivalent to two consecutive : tokens. */
7102 static tree
7103 c_parser_asm_statement (c_parser *parser)
7105 tree str, outputs, inputs, clobbers, labels, ret;
7106 bool simple;
7107 location_t asm_loc = c_parser_peek_token (parser)->location;
7108 int section, nsections;
7110 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7111 c_parser_consume_token (parser);
7113 /* Handle the asm-qualifier-list. */
7114 location_t volatile_loc = UNKNOWN_LOCATION;
7115 location_t inline_loc = UNKNOWN_LOCATION;
7116 location_t goto_loc = UNKNOWN_LOCATION;
7117 for (;;)
7119 c_token *token = c_parser_peek_token (parser);
7120 location_t loc = token->location;
7121 switch (token->keyword)
7123 case RID_VOLATILE:
7124 if (volatile_loc)
7126 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7127 inform (volatile_loc, "first seen here");
7129 else
7130 volatile_loc = loc;
7131 c_parser_consume_token (parser);
7132 continue;
7134 case RID_INLINE:
7135 if (inline_loc)
7137 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7138 inform (inline_loc, "first seen here");
7140 else
7141 inline_loc = loc;
7142 c_parser_consume_token (parser);
7143 continue;
7145 case RID_GOTO:
7146 if (goto_loc)
7148 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7149 inform (goto_loc, "first seen here");
7151 else
7152 goto_loc = loc;
7153 c_parser_consume_token (parser);
7154 continue;
7156 case RID_CONST:
7157 case RID_RESTRICT:
7158 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7159 c_parser_consume_token (parser);
7160 continue;
7162 default:
7163 break;
7165 break;
7168 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7169 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7170 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7172 ret = NULL;
7174 matching_parens parens;
7175 if (!parens.require_open (parser))
7176 goto error;
7178 str = c_parser_asm_string_literal (parser);
7179 if (str == NULL_TREE)
7180 goto error_close_paren;
7182 simple = true;
7183 outputs = NULL_TREE;
7184 inputs = NULL_TREE;
7185 clobbers = NULL_TREE;
7186 labels = NULL_TREE;
7188 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7189 goto done_asm;
7191 /* Parse each colon-delimited section of operands. */
7192 nsections = 3 + is_goto;
7193 for (section = 0; section < nsections; ++section)
7195 if (c_parser_next_token_is (parser, CPP_SCOPE))
7197 ++section;
7198 if (section == nsections)
7200 c_parser_error (parser, "expected %<)%>");
7201 goto error_close_paren;
7203 c_parser_consume_token (parser);
7205 else if (!c_parser_require (parser, CPP_COLON,
7206 is_goto
7207 ? G_("expected %<:%>")
7208 : G_("expected %<:%> or %<)%>"),
7209 UNKNOWN_LOCATION, is_goto))
7210 goto error_close_paren;
7212 /* Once past any colon, we're no longer a simple asm. */
7213 simple = false;
7215 if ((!c_parser_next_token_is (parser, CPP_COLON)
7216 && !c_parser_next_token_is (parser, CPP_SCOPE)
7217 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7218 || section == 3)
7219 switch (section)
7221 case 0:
7222 /* For asm goto, we don't allow output operands, but reserve
7223 the slot for a future extension that does allow them. */
7224 if (!is_goto)
7225 outputs = c_parser_asm_operands (parser);
7226 break;
7227 case 1:
7228 inputs = c_parser_asm_operands (parser);
7229 break;
7230 case 2:
7231 clobbers = c_parser_asm_clobbers (parser);
7232 break;
7233 case 3:
7234 labels = c_parser_asm_goto_operands (parser);
7235 break;
7236 default:
7237 gcc_unreachable ();
7240 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7241 goto done_asm;
7244 done_asm:
7245 if (!parens.require_close (parser))
7247 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7248 goto error;
7251 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7252 c_parser_skip_to_end_of_block_or_statement (parser);
7254 ret = build_asm_stmt (is_volatile,
7255 build_asm_expr (asm_loc, str, outputs, inputs,
7256 clobbers, labels, simple, is_inline));
7258 error:
7259 return ret;
7261 error_close_paren:
7262 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7263 goto error;
7266 /* Parse asm operands, a GNU extension.
7268 asm-operands:
7269 asm-operand
7270 asm-operands , asm-operand
7272 asm-operand:
7273 asm-string-literal ( expression )
7274 [ identifier ] asm-string-literal ( expression )
7277 static tree
7278 c_parser_asm_operands (c_parser *parser)
7280 tree list = NULL_TREE;
7281 while (true)
7283 tree name, str;
7284 struct c_expr expr;
7285 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7287 c_parser_consume_token (parser);
7288 if (c_parser_next_token_is (parser, CPP_NAME))
7290 tree id = c_parser_peek_token (parser)->value;
7291 c_parser_consume_token (parser);
7292 name = build_string (IDENTIFIER_LENGTH (id),
7293 IDENTIFIER_POINTER (id));
7295 else
7297 c_parser_error (parser, "expected identifier");
7298 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7299 return NULL_TREE;
7301 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7302 "expected %<]%>");
7304 else
7305 name = NULL_TREE;
7306 str = c_parser_asm_string_literal (parser);
7307 if (str == NULL_TREE)
7308 return NULL_TREE;
7309 matching_parens parens;
7310 if (!parens.require_open (parser))
7311 return NULL_TREE;
7312 expr = c_parser_expression (parser);
7313 mark_exp_read (expr.value);
7314 if (!parens.require_close (parser))
7316 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7317 return NULL_TREE;
7319 list = chainon (list, build_tree_list (build_tree_list (name, str),
7320 expr.value));
7321 if (c_parser_next_token_is (parser, CPP_COMMA))
7322 c_parser_consume_token (parser);
7323 else
7324 break;
7326 return list;
7329 /* Parse asm clobbers, a GNU extension.
7331 asm-clobbers:
7332 asm-string-literal
7333 asm-clobbers , asm-string-literal
7336 static tree
7337 c_parser_asm_clobbers (c_parser *parser)
7339 tree list = NULL_TREE;
7340 while (true)
7342 tree str = c_parser_asm_string_literal (parser);
7343 if (str)
7344 list = tree_cons (NULL_TREE, str, list);
7345 else
7346 return NULL_TREE;
7347 if (c_parser_next_token_is (parser, CPP_COMMA))
7348 c_parser_consume_token (parser);
7349 else
7350 break;
7352 return list;
7355 /* Parse asm goto labels, a GNU extension.
7357 asm-goto-operands:
7358 identifier
7359 asm-goto-operands , identifier
7362 static tree
7363 c_parser_asm_goto_operands (c_parser *parser)
7365 tree list = NULL_TREE;
7366 while (true)
7368 tree name, label;
7370 if (c_parser_next_token_is (parser, CPP_NAME))
7372 c_token *tok = c_parser_peek_token (parser);
7373 name = tok->value;
7374 label = lookup_label_for_goto (tok->location, name);
7375 c_parser_consume_token (parser);
7376 TREE_USED (label) = 1;
7378 else
7380 c_parser_error (parser, "expected identifier");
7381 return NULL_TREE;
7384 name = build_string (IDENTIFIER_LENGTH (name),
7385 IDENTIFIER_POINTER (name));
7386 list = tree_cons (name, label, list);
7387 if (c_parser_next_token_is (parser, CPP_COMMA))
7388 c_parser_consume_token (parser);
7389 else
7390 return nreverse (list);
7394 /* Parse a possibly concatenated sequence of string literals.
7395 TRANSLATE says whether to translate them to the execution character
7396 set; WIDE_OK says whether any kind of prefixed string literal is
7397 permitted in this context. This code is based on that in
7398 lex_string. */
7400 struct c_expr
7401 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7403 struct c_expr ret;
7404 size_t count;
7405 struct obstack str_ob;
7406 struct obstack loc_ob;
7407 cpp_string str, istr, *strs;
7408 c_token *tok;
7409 location_t loc, last_tok_loc;
7410 enum cpp_ttype type;
7411 tree value, string_tree;
7413 tok = c_parser_peek_token (parser);
7414 loc = tok->location;
7415 last_tok_loc = linemap_resolve_location (line_table, loc,
7416 LRK_MACRO_DEFINITION_LOCATION,
7417 NULL);
7418 type = tok->type;
7419 switch (type)
7421 case CPP_STRING:
7422 case CPP_WSTRING:
7423 case CPP_STRING16:
7424 case CPP_STRING32:
7425 case CPP_UTF8STRING:
7426 string_tree = tok->value;
7427 break;
7429 default:
7430 c_parser_error (parser, "expected string literal");
7431 ret.set_error ();
7432 ret.value = NULL_TREE;
7433 ret.original_code = ERROR_MARK;
7434 ret.original_type = NULL_TREE;
7435 return ret;
7438 /* Try to avoid the overhead of creating and destroying an obstack
7439 for the common case of just one string. */
7440 switch (c_parser_peek_2nd_token (parser)->type)
7442 default:
7443 c_parser_consume_token (parser);
7444 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7445 str.len = TREE_STRING_LENGTH (string_tree);
7446 count = 1;
7447 strs = &str;
7448 break;
7450 case CPP_STRING:
7451 case CPP_WSTRING:
7452 case CPP_STRING16:
7453 case CPP_STRING32:
7454 case CPP_UTF8STRING:
7455 gcc_obstack_init (&str_ob);
7456 gcc_obstack_init (&loc_ob);
7457 count = 0;
7460 c_parser_consume_token (parser);
7461 count++;
7462 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7463 str.len = TREE_STRING_LENGTH (string_tree);
7464 if (type != tok->type)
7466 if (type == CPP_STRING)
7467 type = tok->type;
7468 else if (tok->type != CPP_STRING)
7469 error ("unsupported non-standard concatenation "
7470 "of string literals");
7472 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7473 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7474 tok = c_parser_peek_token (parser);
7475 string_tree = tok->value;
7476 last_tok_loc
7477 = linemap_resolve_location (line_table, tok->location,
7478 LRK_MACRO_DEFINITION_LOCATION, NULL);
7480 while (tok->type == CPP_STRING
7481 || tok->type == CPP_WSTRING
7482 || tok->type == CPP_STRING16
7483 || tok->type == CPP_STRING32
7484 || tok->type == CPP_UTF8STRING);
7485 strs = (cpp_string *) obstack_finish (&str_ob);
7488 if (count > 1 && !in_system_header_at (input_location))
7489 warning (OPT_Wtraditional,
7490 "traditional C rejects string constant concatenation");
7492 if ((type == CPP_STRING || wide_ok)
7493 && ((translate
7494 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7495 (parse_in, strs, count, &istr, type)))
7497 value = build_string (istr.len, (const char *) istr.text);
7498 free (CONST_CAST (unsigned char *, istr.text));
7499 if (count > 1)
7501 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7502 gcc_assert (g_string_concat_db);
7503 g_string_concat_db->record_string_concatenation (count, locs);
7506 else
7508 if (type != CPP_STRING && !wide_ok)
7510 error_at (loc, "a wide string is invalid in this context");
7511 type = CPP_STRING;
7513 /* Callers cannot generally handle error_mark_node in this
7514 context, so return the empty string instead. An error has
7515 been issued, either above or from cpp_interpret_string. */
7516 switch (type)
7518 default:
7519 case CPP_STRING:
7520 case CPP_UTF8STRING:
7521 value = build_string (1, "");
7522 break;
7523 case CPP_STRING16:
7524 value = build_string (TYPE_PRECISION (char16_type_node)
7525 / TYPE_PRECISION (char_type_node),
7526 "\0"); /* char16_t is 16 bits */
7527 break;
7528 case CPP_STRING32:
7529 value = build_string (TYPE_PRECISION (char32_type_node)
7530 / TYPE_PRECISION (char_type_node),
7531 "\0\0\0"); /* char32_t is 32 bits */
7532 break;
7533 case CPP_WSTRING:
7534 value = build_string (TYPE_PRECISION (wchar_type_node)
7535 / TYPE_PRECISION (char_type_node),
7536 "\0\0\0"); /* widest supported wchar_t
7537 is 32 bits */
7538 break;
7542 switch (type)
7544 default:
7545 case CPP_STRING:
7546 case CPP_UTF8STRING:
7547 TREE_TYPE (value) = char_array_type_node;
7548 break;
7549 case CPP_STRING16:
7550 TREE_TYPE (value) = char16_array_type_node;
7551 break;
7552 case CPP_STRING32:
7553 TREE_TYPE (value) = char32_array_type_node;
7554 break;
7555 case CPP_WSTRING:
7556 TREE_TYPE (value) = wchar_array_type_node;
7558 value = fix_string_type (value);
7560 if (count > 1)
7562 obstack_free (&str_ob, 0);
7563 obstack_free (&loc_ob, 0);
7566 ret.value = value;
7567 ret.original_code = STRING_CST;
7568 ret.original_type = NULL_TREE;
7569 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7570 parser->seen_string_literal = true;
7571 return ret;
7574 /* Parse an expression other than a compound expression; that is, an
7575 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7576 AFTER is not NULL then it is an Objective-C message expression which
7577 is the primary-expression starting the expression as an initializer.
7579 assignment-expression:
7580 conditional-expression
7581 unary-expression assignment-operator assignment-expression
7583 assignment-operator: one of
7584 = *= /= %= += -= <<= >>= &= ^= |=
7586 In GNU C we accept any conditional expression on the LHS and
7587 diagnose the invalid lvalue rather than producing a syntax
7588 error. */
7590 static struct c_expr
7591 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7592 tree omp_atomic_lhs)
7594 struct c_expr lhs, rhs, ret;
7595 enum tree_code code;
7596 location_t op_location, exp_location;
7597 bool save_in_omp_for = c_in_omp_for;
7598 c_in_omp_for = false;
7599 gcc_assert (!after || c_dialect_objc ());
7600 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7601 op_location = c_parser_peek_token (parser)->location;
7602 switch (c_parser_peek_token (parser)->type)
7604 case CPP_EQ:
7605 code = NOP_EXPR;
7606 break;
7607 case CPP_MULT_EQ:
7608 code = MULT_EXPR;
7609 break;
7610 case CPP_DIV_EQ:
7611 code = TRUNC_DIV_EXPR;
7612 break;
7613 case CPP_MOD_EQ:
7614 code = TRUNC_MOD_EXPR;
7615 break;
7616 case CPP_PLUS_EQ:
7617 code = PLUS_EXPR;
7618 break;
7619 case CPP_MINUS_EQ:
7620 code = MINUS_EXPR;
7621 break;
7622 case CPP_LSHIFT_EQ:
7623 code = LSHIFT_EXPR;
7624 break;
7625 case CPP_RSHIFT_EQ:
7626 code = RSHIFT_EXPR;
7627 break;
7628 case CPP_AND_EQ:
7629 code = BIT_AND_EXPR;
7630 break;
7631 case CPP_XOR_EQ:
7632 code = BIT_XOR_EXPR;
7633 break;
7634 case CPP_OR_EQ:
7635 code = BIT_IOR_EXPR;
7636 break;
7637 default:
7638 c_in_omp_for = save_in_omp_for;
7639 return lhs;
7641 c_parser_consume_token (parser);
7642 exp_location = c_parser_peek_token (parser)->location;
7643 rhs = c_parser_expr_no_commas (parser, NULL);
7644 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7646 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7647 code, exp_location, rhs.value,
7648 rhs.original_type);
7649 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7650 if (code == NOP_EXPR)
7651 ret.original_code = MODIFY_EXPR;
7652 else
7654 TREE_NO_WARNING (ret.value) = 1;
7655 ret.original_code = ERROR_MARK;
7657 ret.original_type = NULL;
7658 c_in_omp_for = save_in_omp_for;
7659 return ret;
7662 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7663 AFTER is not NULL then it is an Objective-C message expression which is
7664 the primary-expression starting the expression as an initializer.
7666 conditional-expression:
7667 logical-OR-expression
7668 logical-OR-expression ? expression : conditional-expression
7670 GNU extensions:
7672 conditional-expression:
7673 logical-OR-expression ? : conditional-expression
7676 static struct c_expr
7677 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7678 tree omp_atomic_lhs)
7680 struct c_expr cond, exp1, exp2, ret;
7681 location_t start, cond_loc, colon_loc;
7683 gcc_assert (!after || c_dialect_objc ());
7685 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7687 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7688 return cond;
7689 if (cond.value != error_mark_node)
7690 start = cond.get_start ();
7691 else
7692 start = UNKNOWN_LOCATION;
7693 cond_loc = c_parser_peek_token (parser)->location;
7694 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7695 c_parser_consume_token (parser);
7696 if (c_parser_next_token_is (parser, CPP_COLON))
7698 tree eptype = NULL_TREE;
7700 location_t middle_loc = c_parser_peek_token (parser)->location;
7701 pedwarn (middle_loc, OPT_Wpedantic,
7702 "ISO C forbids omitting the middle term of a %<?:%> expression");
7703 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7705 eptype = TREE_TYPE (cond.value);
7706 cond.value = TREE_OPERAND (cond.value, 0);
7708 tree e = cond.value;
7709 while (TREE_CODE (e) == COMPOUND_EXPR)
7710 e = TREE_OPERAND (e, 1);
7711 warn_for_omitted_condop (middle_loc, e);
7712 /* Make sure first operand is calculated only once. */
7713 exp1.value = save_expr (default_conversion (cond.value));
7714 if (eptype)
7715 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7716 exp1.original_type = NULL;
7717 exp1.src_range = cond.src_range;
7718 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7719 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7721 else
7723 cond.value
7724 = c_objc_common_truthvalue_conversion
7725 (cond_loc, default_conversion (cond.value));
7726 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7727 exp1 = c_parser_expression_conv (parser);
7728 mark_exp_read (exp1.value);
7729 c_inhibit_evaluation_warnings +=
7730 ((cond.value == truthvalue_true_node)
7731 - (cond.value == truthvalue_false_node));
7734 colon_loc = c_parser_peek_token (parser)->location;
7735 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7737 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7738 ret.set_error ();
7739 ret.original_code = ERROR_MARK;
7740 ret.original_type = NULL;
7741 return ret;
7744 location_t exp2_loc = c_parser_peek_token (parser)->location;
7745 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7746 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7748 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7749 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7750 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7751 ret.value = build_conditional_expr (colon_loc, cond.value,
7752 cond.original_code == C_MAYBE_CONST_EXPR,
7753 exp1.value, exp1.original_type, loc1,
7754 exp2.value, exp2.original_type, loc2);
7755 ret.original_code = ERROR_MARK;
7756 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7757 ret.original_type = NULL;
7758 else
7760 tree t1, t2;
7762 /* If both sides are enum type, the default conversion will have
7763 made the type of the result be an integer type. We want to
7764 remember the enum types we started with. */
7765 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7766 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7767 ret.original_type = ((t1 != error_mark_node
7768 && t2 != error_mark_node
7769 && (TYPE_MAIN_VARIANT (t1)
7770 == TYPE_MAIN_VARIANT (t2)))
7771 ? t1
7772 : NULL);
7774 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7775 return ret;
7778 /* Parse a binary expression; that is, a logical-OR-expression (C90
7779 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7780 NULL then it is an Objective-C message expression which is the
7781 primary-expression starting the expression as an initializer.
7783 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7784 when it should be the unfolded lhs. In a valid OpenMP source,
7785 one of the operands of the toplevel binary expression must be equal
7786 to it. In that case, just return a build2 created binary operation
7787 rather than result of parser_build_binary_op.
7789 multiplicative-expression:
7790 cast-expression
7791 multiplicative-expression * cast-expression
7792 multiplicative-expression / cast-expression
7793 multiplicative-expression % cast-expression
7795 additive-expression:
7796 multiplicative-expression
7797 additive-expression + multiplicative-expression
7798 additive-expression - multiplicative-expression
7800 shift-expression:
7801 additive-expression
7802 shift-expression << additive-expression
7803 shift-expression >> additive-expression
7805 relational-expression:
7806 shift-expression
7807 relational-expression < shift-expression
7808 relational-expression > shift-expression
7809 relational-expression <= shift-expression
7810 relational-expression >= shift-expression
7812 equality-expression:
7813 relational-expression
7814 equality-expression == relational-expression
7815 equality-expression != relational-expression
7817 AND-expression:
7818 equality-expression
7819 AND-expression & equality-expression
7821 exclusive-OR-expression:
7822 AND-expression
7823 exclusive-OR-expression ^ AND-expression
7825 inclusive-OR-expression:
7826 exclusive-OR-expression
7827 inclusive-OR-expression | exclusive-OR-expression
7829 logical-AND-expression:
7830 inclusive-OR-expression
7831 logical-AND-expression && inclusive-OR-expression
7833 logical-OR-expression:
7834 logical-AND-expression
7835 logical-OR-expression || logical-AND-expression
7838 static struct c_expr
7839 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7840 tree omp_atomic_lhs)
7842 /* A binary expression is parsed using operator-precedence parsing,
7843 with the operands being cast expressions. All the binary
7844 operators are left-associative. Thus a binary expression is of
7845 form:
7847 E0 op1 E1 op2 E2 ...
7849 which we represent on a stack. On the stack, the precedence
7850 levels are strictly increasing. When a new operator is
7851 encountered of higher precedence than that at the top of the
7852 stack, it is pushed; its LHS is the top expression, and its RHS
7853 is everything parsed until it is popped. When a new operator is
7854 encountered with precedence less than or equal to that at the top
7855 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7856 by the result of the operation until the operator at the top of
7857 the stack has lower precedence than the new operator or there is
7858 only one element on the stack; then the top expression is the LHS
7859 of the new operator. In the case of logical AND and OR
7860 expressions, we also need to adjust c_inhibit_evaluation_warnings
7861 as appropriate when the operators are pushed and popped. */
7863 struct {
7864 /* The expression at this stack level. */
7865 struct c_expr expr;
7866 /* The precedence of the operator on its left, PREC_NONE at the
7867 bottom of the stack. */
7868 enum c_parser_prec prec;
7869 /* The operation on its left. */
7870 enum tree_code op;
7871 /* The source location of this operation. */
7872 location_t loc;
7873 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
7874 tree sizeof_arg;
7875 } stack[NUM_PRECS];
7876 int sp;
7877 /* Location of the binary operator. */
7878 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7879 #define POP \
7880 do { \
7881 switch (stack[sp].op) \
7883 case TRUTH_ANDIF_EXPR: \
7884 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7885 == truthvalue_false_node); \
7886 break; \
7887 case TRUTH_ORIF_EXPR: \
7888 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7889 == truthvalue_true_node); \
7890 break; \
7891 case TRUNC_DIV_EXPR: \
7892 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7893 && stack[sp].expr.original_code == SIZEOF_EXPR) \
7895 tree type0 = stack[sp - 1].sizeof_arg; \
7896 tree type1 = stack[sp].sizeof_arg; \
7897 tree first_arg = type0; \
7898 if (!TYPE_P (type0)) \
7899 type0 = TREE_TYPE (type0); \
7900 if (!TYPE_P (type1)) \
7901 type1 = TREE_TYPE (type1); \
7902 if (POINTER_TYPE_P (type0) \
7903 && comptypes (TREE_TYPE (type0), type1) \
7904 && !(TREE_CODE (first_arg) == PARM_DECL \
7905 && C_ARRAY_PARAMETER (first_arg) \
7906 && warn_sizeof_array_argument)) \
7908 auto_diagnostic_group d; \
7909 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7910 "division %<sizeof (%T) / sizeof (%T)%> " \
7911 "does not compute the number of array " \
7912 "elements", \
7913 type0, type1)) \
7914 if (DECL_P (first_arg)) \
7915 inform (DECL_SOURCE_LOCATION (first_arg), \
7916 "first %<sizeof%> operand was declared here"); \
7919 break; \
7920 default: \
7921 break; \
7923 stack[sp - 1].expr \
7924 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7925 stack[sp - 1].expr, true, true); \
7926 stack[sp].expr \
7927 = convert_lvalue_to_rvalue (stack[sp].loc, \
7928 stack[sp].expr, true, true); \
7929 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7930 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7931 && ((1 << stack[sp].prec) \
7932 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7933 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7934 && stack[sp].op != TRUNC_MOD_EXPR \
7935 && stack[0].expr.value != error_mark_node \
7936 && stack[1].expr.value != error_mark_node \
7937 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7938 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7939 stack[0].expr.value \
7940 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
7941 stack[0].expr.value, stack[1].expr.value); \
7942 else \
7943 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7944 stack[sp].op, \
7945 stack[sp - 1].expr, \
7946 stack[sp].expr); \
7947 sp--; \
7948 } while (0)
7949 gcc_assert (!after || c_dialect_objc ());
7950 stack[0].loc = c_parser_peek_token (parser)->location;
7951 stack[0].expr = c_parser_cast_expression (parser, after);
7952 stack[0].prec = PREC_NONE;
7953 stack[0].sizeof_arg = c_last_sizeof_arg;
7954 sp = 0;
7955 while (true)
7957 enum c_parser_prec oprec;
7958 enum tree_code ocode;
7959 source_range src_range;
7960 if (parser->error)
7961 goto out;
7962 switch (c_parser_peek_token (parser)->type)
7964 case CPP_MULT:
7965 oprec = PREC_MULT;
7966 ocode = MULT_EXPR;
7967 break;
7968 case CPP_DIV:
7969 oprec = PREC_MULT;
7970 ocode = TRUNC_DIV_EXPR;
7971 break;
7972 case CPP_MOD:
7973 oprec = PREC_MULT;
7974 ocode = TRUNC_MOD_EXPR;
7975 break;
7976 case CPP_PLUS:
7977 oprec = PREC_ADD;
7978 ocode = PLUS_EXPR;
7979 break;
7980 case CPP_MINUS:
7981 oprec = PREC_ADD;
7982 ocode = MINUS_EXPR;
7983 break;
7984 case CPP_LSHIFT:
7985 oprec = PREC_SHIFT;
7986 ocode = LSHIFT_EXPR;
7987 break;
7988 case CPP_RSHIFT:
7989 oprec = PREC_SHIFT;
7990 ocode = RSHIFT_EXPR;
7991 break;
7992 case CPP_LESS:
7993 oprec = PREC_REL;
7994 ocode = LT_EXPR;
7995 break;
7996 case CPP_GREATER:
7997 oprec = PREC_REL;
7998 ocode = GT_EXPR;
7999 break;
8000 case CPP_LESS_EQ:
8001 oprec = PREC_REL;
8002 ocode = LE_EXPR;
8003 break;
8004 case CPP_GREATER_EQ:
8005 oprec = PREC_REL;
8006 ocode = GE_EXPR;
8007 break;
8008 case CPP_EQ_EQ:
8009 oprec = PREC_EQ;
8010 ocode = EQ_EXPR;
8011 break;
8012 case CPP_NOT_EQ:
8013 oprec = PREC_EQ;
8014 ocode = NE_EXPR;
8015 break;
8016 case CPP_AND:
8017 oprec = PREC_BITAND;
8018 ocode = BIT_AND_EXPR;
8019 break;
8020 case CPP_XOR:
8021 oprec = PREC_BITXOR;
8022 ocode = BIT_XOR_EXPR;
8023 break;
8024 case CPP_OR:
8025 oprec = PREC_BITOR;
8026 ocode = BIT_IOR_EXPR;
8027 break;
8028 case CPP_AND_AND:
8029 oprec = PREC_LOGAND;
8030 ocode = TRUTH_ANDIF_EXPR;
8031 break;
8032 case CPP_OR_OR:
8033 oprec = PREC_LOGOR;
8034 ocode = TRUTH_ORIF_EXPR;
8035 break;
8036 default:
8037 /* Not a binary operator, so end of the binary
8038 expression. */
8039 goto out;
8041 binary_loc = c_parser_peek_token (parser)->location;
8042 while (oprec <= stack[sp].prec)
8043 POP;
8044 c_parser_consume_token (parser);
8045 switch (ocode)
8047 case TRUTH_ANDIF_EXPR:
8048 src_range = stack[sp].expr.src_range;
8049 stack[sp].expr
8050 = convert_lvalue_to_rvalue (stack[sp].loc,
8051 stack[sp].expr, true, true);
8052 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8053 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8054 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8055 == truthvalue_false_node);
8056 set_c_expr_source_range (&stack[sp].expr, src_range);
8057 break;
8058 case TRUTH_ORIF_EXPR:
8059 src_range = stack[sp].expr.src_range;
8060 stack[sp].expr
8061 = convert_lvalue_to_rvalue (stack[sp].loc,
8062 stack[sp].expr, true, true);
8063 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8064 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8065 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8066 == truthvalue_true_node);
8067 set_c_expr_source_range (&stack[sp].expr, src_range);
8068 break;
8069 default:
8070 break;
8072 sp++;
8073 stack[sp].loc = binary_loc;
8074 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8075 stack[sp].prec = oprec;
8076 stack[sp].op = ocode;
8077 stack[sp].sizeof_arg = c_last_sizeof_arg;
8079 out:
8080 while (sp > 0)
8081 POP;
8082 return stack[0].expr;
8083 #undef POP
8086 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8087 is not NULL then it is an Objective-C message expression which is the
8088 primary-expression starting the expression as an initializer.
8090 cast-expression:
8091 unary-expression
8092 ( type-name ) unary-expression
8095 static struct c_expr
8096 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8098 location_t cast_loc = c_parser_peek_token (parser)->location;
8099 gcc_assert (!after || c_dialect_objc ());
8100 if (after)
8101 return c_parser_postfix_expression_after_primary (parser,
8102 cast_loc, *after);
8103 /* If the expression begins with a parenthesized type name, it may
8104 be either a cast or a compound literal; we need to see whether
8105 the next character is '{' to tell the difference. If not, it is
8106 an unary expression. Full detection of unknown typenames here
8107 would require a 3-token lookahead. */
8108 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8109 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8111 struct c_type_name *type_name;
8112 struct c_expr ret;
8113 struct c_expr expr;
8114 matching_parens parens;
8115 parens.consume_open (parser);
8116 type_name = c_parser_type_name (parser, true);
8117 parens.skip_until_found_close (parser);
8118 if (type_name == NULL)
8120 ret.set_error ();
8121 ret.original_code = ERROR_MARK;
8122 ret.original_type = NULL;
8123 return ret;
8126 /* Save casted types in the function's used types hash table. */
8127 used_types_insert (type_name->specs->type);
8129 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8130 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8131 cast_loc);
8132 if (type_name->specs->alignas_p)
8133 error_at (type_name->specs->locations[cdw_alignas],
8134 "alignment specified for type name in cast");
8136 location_t expr_loc = c_parser_peek_token (parser)->location;
8137 expr = c_parser_cast_expression (parser, NULL);
8138 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8140 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8141 if (ret.value && expr.value)
8142 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8143 ret.original_code = ERROR_MARK;
8144 ret.original_type = NULL;
8145 return ret;
8147 else
8148 return c_parser_unary_expression (parser);
8151 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8153 unary-expression:
8154 postfix-expression
8155 ++ unary-expression
8156 -- unary-expression
8157 unary-operator cast-expression
8158 sizeof unary-expression
8159 sizeof ( type-name )
8161 unary-operator: one of
8162 & * + - ~ !
8164 GNU extensions:
8166 unary-expression:
8167 __alignof__ unary-expression
8168 __alignof__ ( type-name )
8169 && identifier
8171 (C11 permits _Alignof with type names only.)
8173 unary-operator: one of
8174 __extension__ __real__ __imag__
8176 Transactional Memory:
8178 unary-expression:
8179 transaction-expression
8181 In addition, the GNU syntax treats ++ and -- as unary operators, so
8182 they may be applied to cast expressions with errors for non-lvalues
8183 given later. */
8185 static struct c_expr
8186 c_parser_unary_expression (c_parser *parser)
8188 int ext;
8189 struct c_expr ret, op;
8190 location_t op_loc = c_parser_peek_token (parser)->location;
8191 location_t exp_loc;
8192 location_t finish;
8193 ret.original_code = ERROR_MARK;
8194 ret.original_type = NULL;
8195 switch (c_parser_peek_token (parser)->type)
8197 case CPP_PLUS_PLUS:
8198 c_parser_consume_token (parser);
8199 exp_loc = c_parser_peek_token (parser)->location;
8200 op = c_parser_cast_expression (parser, NULL);
8202 op = default_function_array_read_conversion (exp_loc, op);
8203 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8204 case CPP_MINUS_MINUS:
8205 c_parser_consume_token (parser);
8206 exp_loc = c_parser_peek_token (parser)->location;
8207 op = c_parser_cast_expression (parser, NULL);
8209 op = default_function_array_read_conversion (exp_loc, op);
8210 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8211 case CPP_AND:
8212 c_parser_consume_token (parser);
8213 op = c_parser_cast_expression (parser, NULL);
8214 mark_exp_read (op.value);
8215 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8216 case CPP_MULT:
8218 c_parser_consume_token (parser);
8219 exp_loc = c_parser_peek_token (parser)->location;
8220 op = c_parser_cast_expression (parser, NULL);
8221 finish = op.get_finish ();
8222 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8223 location_t combined_loc = make_location (op_loc, op_loc, finish);
8224 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8225 ret.src_range.m_start = op_loc;
8226 ret.src_range.m_finish = finish;
8227 return ret;
8229 case CPP_PLUS:
8230 if (!c_dialect_objc () && !in_system_header_at (input_location))
8231 warning_at (op_loc,
8232 OPT_Wtraditional,
8233 "traditional C rejects the unary plus operator");
8234 c_parser_consume_token (parser);
8235 exp_loc = c_parser_peek_token (parser)->location;
8236 op = c_parser_cast_expression (parser, NULL);
8237 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8238 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8239 case CPP_MINUS:
8240 c_parser_consume_token (parser);
8241 exp_loc = c_parser_peek_token (parser)->location;
8242 op = c_parser_cast_expression (parser, NULL);
8243 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8244 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8245 case CPP_COMPL:
8246 c_parser_consume_token (parser);
8247 exp_loc = c_parser_peek_token (parser)->location;
8248 op = c_parser_cast_expression (parser, NULL);
8249 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8250 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8251 case CPP_NOT:
8252 c_parser_consume_token (parser);
8253 exp_loc = c_parser_peek_token (parser)->location;
8254 op = c_parser_cast_expression (parser, NULL);
8255 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8256 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8257 case CPP_AND_AND:
8258 /* Refer to the address of a label as a pointer. */
8259 c_parser_consume_token (parser);
8260 if (c_parser_next_token_is (parser, CPP_NAME))
8262 ret.value = finish_label_address_expr
8263 (c_parser_peek_token (parser)->value, op_loc);
8264 set_c_expr_source_range (&ret, op_loc,
8265 c_parser_peek_token (parser)->get_finish ());
8266 c_parser_consume_token (parser);
8268 else
8270 c_parser_error (parser, "expected identifier");
8271 ret.set_error ();
8273 return ret;
8274 case CPP_KEYWORD:
8275 switch (c_parser_peek_token (parser)->keyword)
8277 case RID_SIZEOF:
8278 return c_parser_sizeof_expression (parser);
8279 case RID_ALIGNOF:
8280 return c_parser_alignof_expression (parser);
8281 case RID_BUILTIN_HAS_ATTRIBUTE:
8282 return c_parser_has_attribute_expression (parser);
8283 case RID_EXTENSION:
8284 c_parser_consume_token (parser);
8285 ext = disable_extension_diagnostics ();
8286 ret = c_parser_cast_expression (parser, NULL);
8287 restore_extension_diagnostics (ext);
8288 return ret;
8289 case RID_REALPART:
8290 c_parser_consume_token (parser);
8291 exp_loc = c_parser_peek_token (parser)->location;
8292 op = c_parser_cast_expression (parser, NULL);
8293 op = default_function_array_conversion (exp_loc, op);
8294 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8295 case RID_IMAGPART:
8296 c_parser_consume_token (parser);
8297 exp_loc = c_parser_peek_token (parser)->location;
8298 op = c_parser_cast_expression (parser, NULL);
8299 op = default_function_array_conversion (exp_loc, op);
8300 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8301 case RID_TRANSACTION_ATOMIC:
8302 case RID_TRANSACTION_RELAXED:
8303 return c_parser_transaction_expression (parser,
8304 c_parser_peek_token (parser)->keyword);
8305 default:
8306 return c_parser_postfix_expression (parser);
8308 default:
8309 return c_parser_postfix_expression (parser);
8313 /* Parse a sizeof expression. */
8315 static struct c_expr
8316 c_parser_sizeof_expression (c_parser *parser)
8318 struct c_expr expr;
8319 struct c_expr result;
8320 location_t expr_loc;
8321 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8323 location_t start;
8324 location_t finish = UNKNOWN_LOCATION;
8326 start = c_parser_peek_token (parser)->location;
8328 c_parser_consume_token (parser);
8329 c_inhibit_evaluation_warnings++;
8330 in_sizeof++;
8331 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8332 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8334 /* Either sizeof ( type-name ) or sizeof unary-expression
8335 starting with a compound literal. */
8336 struct c_type_name *type_name;
8337 matching_parens parens;
8338 parens.consume_open (parser);
8339 expr_loc = c_parser_peek_token (parser)->location;
8340 type_name = c_parser_type_name (parser, true);
8341 parens.skip_until_found_close (parser);
8342 finish = parser->tokens_buf[0].location;
8343 if (type_name == NULL)
8345 struct c_expr ret;
8346 c_inhibit_evaluation_warnings--;
8347 in_sizeof--;
8348 ret.set_error ();
8349 ret.original_code = ERROR_MARK;
8350 ret.original_type = NULL;
8351 return ret;
8353 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8355 expr = c_parser_postfix_expression_after_paren_type (parser,
8356 type_name,
8357 expr_loc);
8358 finish = expr.get_finish ();
8359 goto sizeof_expr;
8361 /* sizeof ( type-name ). */
8362 if (type_name->specs->alignas_p)
8363 error_at (type_name->specs->locations[cdw_alignas],
8364 "alignment specified for type name in %<sizeof%>");
8365 c_inhibit_evaluation_warnings--;
8366 in_sizeof--;
8367 result = c_expr_sizeof_type (expr_loc, type_name);
8369 else
8371 expr_loc = c_parser_peek_token (parser)->location;
8372 expr = c_parser_unary_expression (parser);
8373 finish = expr.get_finish ();
8374 sizeof_expr:
8375 c_inhibit_evaluation_warnings--;
8376 in_sizeof--;
8377 mark_exp_read (expr.value);
8378 if (TREE_CODE (expr.value) == COMPONENT_REF
8379 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8380 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8381 result = c_expr_sizeof_expr (expr_loc, expr);
8383 if (finish == UNKNOWN_LOCATION)
8384 finish = start;
8385 set_c_expr_source_range (&result, start, finish);
8386 return result;
8389 /* Parse an alignof expression. */
8391 static struct c_expr
8392 c_parser_alignof_expression (c_parser *parser)
8394 struct c_expr expr;
8395 location_t start_loc = c_parser_peek_token (parser)->location;
8396 location_t end_loc;
8397 tree alignof_spelling = c_parser_peek_token (parser)->value;
8398 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8399 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8400 "_Alignof") == 0;
8401 /* A diagnostic is not required for the use of this identifier in
8402 the implementation namespace; only diagnose it for the C11
8403 spelling because of existing code using the other spellings. */
8404 if (is_c11_alignof)
8406 if (flag_isoc99)
8407 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8408 alignof_spelling);
8409 else
8410 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8411 alignof_spelling);
8413 c_parser_consume_token (parser);
8414 c_inhibit_evaluation_warnings++;
8415 in_alignof++;
8416 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8417 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8419 /* Either __alignof__ ( type-name ) or __alignof__
8420 unary-expression starting with a compound literal. */
8421 location_t loc;
8422 struct c_type_name *type_name;
8423 struct c_expr ret;
8424 matching_parens parens;
8425 parens.consume_open (parser);
8426 loc = c_parser_peek_token (parser)->location;
8427 type_name = c_parser_type_name (parser, true);
8428 end_loc = c_parser_peek_token (parser)->location;
8429 parens.skip_until_found_close (parser);
8430 if (type_name == NULL)
8432 struct c_expr ret;
8433 c_inhibit_evaluation_warnings--;
8434 in_alignof--;
8435 ret.set_error ();
8436 ret.original_code = ERROR_MARK;
8437 ret.original_type = NULL;
8438 return ret;
8440 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8442 expr = c_parser_postfix_expression_after_paren_type (parser,
8443 type_name,
8444 loc);
8445 goto alignof_expr;
8447 /* alignof ( type-name ). */
8448 if (type_name->specs->alignas_p)
8449 error_at (type_name->specs->locations[cdw_alignas],
8450 "alignment specified for type name in %qE",
8451 alignof_spelling);
8452 c_inhibit_evaluation_warnings--;
8453 in_alignof--;
8454 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8455 NULL, NULL),
8456 false, is_c11_alignof, 1);
8457 ret.original_code = ERROR_MARK;
8458 ret.original_type = NULL;
8459 set_c_expr_source_range (&ret, start_loc, end_loc);
8460 return ret;
8462 else
8464 struct c_expr ret;
8465 expr = c_parser_unary_expression (parser);
8466 end_loc = expr.src_range.m_finish;
8467 alignof_expr:
8468 mark_exp_read (expr.value);
8469 c_inhibit_evaluation_warnings--;
8470 in_alignof--;
8471 if (is_c11_alignof)
8472 pedwarn (start_loc,
8473 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8474 alignof_spelling);
8475 ret.value = c_alignof_expr (start_loc, expr.value);
8476 ret.original_code = ERROR_MARK;
8477 ret.original_type = NULL;
8478 set_c_expr_source_range (&ret, start_loc, end_loc);
8479 return ret;
8483 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8484 expression. */
8486 static struct c_expr
8487 c_parser_has_attribute_expression (c_parser *parser)
8489 gcc_assert (c_parser_next_token_is_keyword (parser,
8490 RID_BUILTIN_HAS_ATTRIBUTE));
8491 c_parser_consume_token (parser);
8493 c_inhibit_evaluation_warnings++;
8495 matching_parens parens;
8496 if (!parens.require_open (parser))
8498 c_inhibit_evaluation_warnings--;
8499 in_typeof--;
8501 struct c_expr result;
8502 result.set_error ();
8503 result.original_code = ERROR_MARK;
8504 result.original_type = NULL;
8505 return result;
8508 /* Treat the type argument the same way as in typeof for the purposes
8509 of warnings. FIXME: Generalize this so the warning refers to
8510 __builtin_has_attribute rather than typeof. */
8511 in_typeof++;
8513 /* The first operand: one of DECL, EXPR, or TYPE. */
8514 tree oper = NULL_TREE;
8515 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8517 struct c_type_name *tname = c_parser_type_name (parser);
8518 in_typeof--;
8519 if (tname)
8521 oper = groktypename (tname, NULL, NULL);
8522 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8525 else
8527 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8528 c_inhibit_evaluation_warnings--;
8529 in_typeof--;
8530 if (cexpr.value != error_mark_node)
8532 mark_exp_read (cexpr.value);
8533 oper = cexpr.value;
8534 tree etype = TREE_TYPE (oper);
8535 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8536 /* This is returned with the type so that when the type is
8537 evaluated, this can be evaluated. */
8538 if (was_vm)
8539 oper = c_fully_fold (oper, false, NULL);
8540 pop_maybe_used (was_vm);
8544 struct c_expr result;
8545 result.original_code = ERROR_MARK;
8546 result.original_type = NULL;
8548 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8550 /* Consume the closing parenthesis if that's the next token
8551 in the likely case the built-in was invoked with fewer
8552 than two arguments. */
8553 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8554 c_parser_consume_token (parser);
8555 c_inhibit_evaluation_warnings--;
8556 result.set_error ();
8557 return result;
8560 bool save_translate_strings_p = parser->translate_strings_p;
8562 location_t atloc = c_parser_peek_token (parser)->location;
8563 /* Parse a single attribute. Require no leading comma and do not
8564 allow empty attributes. */
8565 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8567 parser->translate_strings_p = save_translate_strings_p;
8569 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8570 c_parser_consume_token (parser);
8571 else
8573 c_parser_error (parser, "expected identifier");
8574 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8576 result.set_error ();
8577 return result;
8580 if (!attr)
8582 error_at (atloc, "expected identifier");
8583 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8584 "expected %<)%>");
8585 result.set_error ();
8586 return result;
8589 result.original_code = INTEGER_CST;
8590 result.original_type = boolean_type_node;
8592 if (has_attribute (atloc, oper, attr, default_conversion))
8593 result.value = boolean_true_node;
8594 else
8595 result.value = boolean_false_node;
8597 return result;
8600 /* Helper function to read arguments of builtins which are interfaces
8601 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8602 others. The name of the builtin is passed using BNAME parameter.
8603 Function returns true if there were no errors while parsing and
8604 stores the arguments in CEXPR_LIST. If it returns true,
8605 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8606 parenthesis. */
8607 static bool
8608 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8609 vec<c_expr_t, va_gc> **ret_cexpr_list,
8610 bool choose_expr_p,
8611 location_t *out_close_paren_loc)
8613 location_t loc = c_parser_peek_token (parser)->location;
8614 vec<c_expr_t, va_gc> *cexpr_list;
8615 c_expr_t expr;
8616 bool saved_force_folding_builtin_constant_p;
8618 *ret_cexpr_list = NULL;
8619 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8621 error_at (loc, "cannot take address of %qs", bname);
8622 return false;
8625 c_parser_consume_token (parser);
8627 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8629 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8630 c_parser_consume_token (parser);
8631 return true;
8634 saved_force_folding_builtin_constant_p
8635 = force_folding_builtin_constant_p;
8636 force_folding_builtin_constant_p |= choose_expr_p;
8637 expr = c_parser_expr_no_commas (parser, NULL);
8638 force_folding_builtin_constant_p
8639 = saved_force_folding_builtin_constant_p;
8640 vec_alloc (cexpr_list, 1);
8641 vec_safe_push (cexpr_list, expr);
8642 while (c_parser_next_token_is (parser, CPP_COMMA))
8644 c_parser_consume_token (parser);
8645 expr = c_parser_expr_no_commas (parser, NULL);
8646 vec_safe_push (cexpr_list, expr);
8649 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8650 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8651 return false;
8653 *ret_cexpr_list = cexpr_list;
8654 return true;
8657 /* This represents a single generic-association. */
8659 struct c_generic_association
8661 /* The location of the starting token of the type. */
8662 location_t type_location;
8663 /* The association's type, or NULL_TREE for 'default'. */
8664 tree type;
8665 /* The association's expression. */
8666 struct c_expr expression;
8669 /* Parse a generic-selection. (C11 6.5.1.1).
8671 generic-selection:
8672 _Generic ( assignment-expression , generic-assoc-list )
8674 generic-assoc-list:
8675 generic-association
8676 generic-assoc-list , generic-association
8678 generic-association:
8679 type-name : assignment-expression
8680 default : assignment-expression
8683 static struct c_expr
8684 c_parser_generic_selection (c_parser *parser)
8686 struct c_expr selector, error_expr;
8687 tree selector_type;
8688 struct c_generic_association matched_assoc;
8689 int match_found = -1;
8690 location_t generic_loc, selector_loc;
8692 error_expr.original_code = ERROR_MARK;
8693 error_expr.original_type = NULL;
8694 error_expr.set_error ();
8695 matched_assoc.type_location = UNKNOWN_LOCATION;
8696 matched_assoc.type = NULL_TREE;
8697 matched_assoc.expression = error_expr;
8699 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8700 generic_loc = c_parser_peek_token (parser)->location;
8701 c_parser_consume_token (parser);
8702 if (flag_isoc99)
8703 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8704 "ISO C99 does not support %<_Generic%>");
8705 else
8706 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8707 "ISO C90 does not support %<_Generic%>");
8709 matching_parens parens;
8710 if (!parens.require_open (parser))
8711 return error_expr;
8713 c_inhibit_evaluation_warnings++;
8714 selector_loc = c_parser_peek_token (parser)->location;
8715 selector = c_parser_expr_no_commas (parser, NULL);
8716 selector = default_function_array_conversion (selector_loc, selector);
8717 c_inhibit_evaluation_warnings--;
8719 if (selector.value == error_mark_node)
8721 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8722 return selector;
8724 mark_exp_read (selector.value);
8725 selector_type = TREE_TYPE (selector.value);
8726 /* In ISO C terms, rvalues (including the controlling expression of
8727 _Generic) do not have qualified types. */
8728 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8729 selector_type = TYPE_MAIN_VARIANT (selector_type);
8730 /* In ISO C terms, _Noreturn is not part of the type of expressions
8731 such as &abort, but in GCC it is represented internally as a type
8732 qualifier. */
8733 if (FUNCTION_POINTER_TYPE_P (selector_type)
8734 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8735 selector_type
8736 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8738 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8740 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8741 return error_expr;
8744 auto_vec<c_generic_association> associations;
8745 while (1)
8747 struct c_generic_association assoc, *iter;
8748 unsigned int ix;
8749 c_token *token = c_parser_peek_token (parser);
8751 assoc.type_location = token->location;
8752 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8754 c_parser_consume_token (parser);
8755 assoc.type = NULL_TREE;
8757 else
8759 struct c_type_name *type_name;
8761 type_name = c_parser_type_name (parser);
8762 if (type_name == NULL)
8764 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8765 return error_expr;
8767 assoc.type = groktypename (type_name, NULL, NULL);
8768 if (assoc.type == error_mark_node)
8770 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8771 return error_expr;
8774 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8775 error_at (assoc.type_location,
8776 "%<_Generic%> association has function type");
8777 else if (!COMPLETE_TYPE_P (assoc.type))
8778 error_at (assoc.type_location,
8779 "%<_Generic%> association has incomplete type");
8781 if (variably_modified_type_p (assoc.type, NULL_TREE))
8782 error_at (assoc.type_location,
8783 "%<_Generic%> association has "
8784 "variable length type");
8787 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8789 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8790 return error_expr;
8793 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8794 if (assoc.expression.value == error_mark_node)
8796 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8797 return error_expr;
8800 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8802 if (assoc.type == NULL_TREE)
8804 if (iter->type == NULL_TREE)
8806 error_at (assoc.type_location,
8807 "duplicate %<default%> case in %<_Generic%>");
8808 inform (iter->type_location, "original %<default%> is here");
8811 else if (iter->type != NULL_TREE)
8813 if (comptypes (assoc.type, iter->type))
8815 error_at (assoc.type_location,
8816 "%<_Generic%> specifies two compatible types");
8817 inform (iter->type_location, "compatible type is here");
8822 if (assoc.type == NULL_TREE)
8824 if (match_found < 0)
8826 matched_assoc = assoc;
8827 match_found = associations.length ();
8830 else if (comptypes (assoc.type, selector_type))
8832 if (match_found < 0 || matched_assoc.type == NULL_TREE)
8834 matched_assoc = assoc;
8835 match_found = associations.length ();
8837 else
8839 error_at (assoc.type_location,
8840 "%<_Generic%> selector matches multiple associations");
8841 inform (matched_assoc.type_location,
8842 "other match is here");
8846 associations.safe_push (assoc);
8848 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8849 break;
8850 c_parser_consume_token (parser);
8853 unsigned int ix;
8854 struct c_generic_association *iter;
8855 FOR_EACH_VEC_ELT (associations, ix, iter)
8856 if (ix != (unsigned) match_found)
8857 mark_exp_read (iter->expression.value);
8859 if (!parens.require_close (parser))
8861 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8862 return error_expr;
8865 if (match_found < 0)
8867 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8868 "compatible with any association",
8869 selector_type);
8870 return error_expr;
8873 return matched_assoc.expression;
8876 /* Check the validity of a function pointer argument *EXPR (argument
8877 position POS) to __builtin_tgmath. Return the number of function
8878 arguments if possibly valid; return 0 having reported an error if
8879 not valid. */
8881 static unsigned int
8882 check_tgmath_function (c_expr *expr, unsigned int pos)
8884 tree type = TREE_TYPE (expr->value);
8885 if (!FUNCTION_POINTER_TYPE_P (type))
8887 error_at (expr->get_location (),
8888 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8889 pos);
8890 return 0;
8892 type = TREE_TYPE (type);
8893 if (!prototype_p (type))
8895 error_at (expr->get_location (),
8896 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8897 return 0;
8899 if (stdarg_p (type))
8901 error_at (expr->get_location (),
8902 "argument %u of %<__builtin_tgmath%> has variable arguments",
8903 pos);
8904 return 0;
8906 unsigned int nargs = 0;
8907 function_args_iterator iter;
8908 tree t;
8909 FOREACH_FUNCTION_ARGS (type, t, iter)
8911 if (t == void_type_node)
8912 break;
8913 nargs++;
8915 if (nargs == 0)
8917 error_at (expr->get_location (),
8918 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8919 return 0;
8921 return nargs;
8924 /* Ways in which a parameter or return value of a type-generic macro
8925 may vary between the different functions the macro may call. */
8926 enum tgmath_parm_kind
8928 tgmath_fixed, tgmath_real, tgmath_complex
8931 /* Helper function for c_parser_postfix_expression. Parse predefined
8932 identifiers. */
8934 static struct c_expr
8935 c_parser_predefined_identifier (c_parser *parser)
8937 location_t loc = c_parser_peek_token (parser)->location;
8938 switch (c_parser_peek_token (parser)->keyword)
8940 case RID_FUNCTION_NAME:
8941 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8942 "identifier", "__FUNCTION__");
8943 break;
8944 case RID_PRETTY_FUNCTION_NAME:
8945 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8946 "identifier", "__PRETTY_FUNCTION__");
8947 break;
8948 case RID_C99_FUNCTION_NAME:
8949 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8950 "%<__func__%> predefined identifier");
8951 break;
8952 default:
8953 gcc_unreachable ();
8956 struct c_expr expr;
8957 expr.original_code = ERROR_MARK;
8958 expr.original_type = NULL;
8959 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8960 c_parser_peek_token (parser)->value);
8961 set_c_expr_source_range (&expr, loc, loc);
8962 c_parser_consume_token (parser);
8963 return expr;
8966 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8967 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8968 call c_parser_postfix_expression_after_paren_type on encountering them.
8970 postfix-expression:
8971 primary-expression
8972 postfix-expression [ expression ]
8973 postfix-expression ( argument-expression-list[opt] )
8974 postfix-expression . identifier
8975 postfix-expression -> identifier
8976 postfix-expression ++
8977 postfix-expression --
8978 ( type-name ) { initializer-list }
8979 ( type-name ) { initializer-list , }
8981 argument-expression-list:
8982 argument-expression
8983 argument-expression-list , argument-expression
8985 primary-expression:
8986 identifier
8987 constant
8988 string-literal
8989 ( expression )
8990 generic-selection
8992 GNU extensions:
8994 primary-expression:
8995 __func__
8996 (treated as a keyword in GNU C)
8997 __FUNCTION__
8998 __PRETTY_FUNCTION__
8999 ( compound-statement )
9000 __builtin_va_arg ( assignment-expression , type-name )
9001 __builtin_offsetof ( type-name , offsetof-member-designator )
9002 __builtin_choose_expr ( assignment-expression ,
9003 assignment-expression ,
9004 assignment-expression )
9005 __builtin_types_compatible_p ( type-name , type-name )
9006 __builtin_tgmath ( expr-list )
9007 __builtin_complex ( assignment-expression , assignment-expression )
9008 __builtin_shuffle ( assignment-expression , assignment-expression )
9009 __builtin_shuffle ( assignment-expression ,
9010 assignment-expression ,
9011 assignment-expression, )
9012 __builtin_convertvector ( assignment-expression , type-name )
9014 offsetof-member-designator:
9015 identifier
9016 offsetof-member-designator . identifier
9017 offsetof-member-designator [ expression ]
9019 Objective-C:
9021 primary-expression:
9022 [ objc-receiver objc-message-args ]
9023 @selector ( objc-selector-arg )
9024 @protocol ( identifier )
9025 @encode ( type-name )
9026 objc-string-literal
9027 Classname . identifier
9030 static struct c_expr
9031 c_parser_postfix_expression (c_parser *parser)
9033 struct c_expr expr, e1;
9034 struct c_type_name *t1, *t2;
9035 location_t loc = c_parser_peek_token (parser)->location;
9036 source_range tok_range = c_parser_peek_token (parser)->get_range ();
9037 expr.original_code = ERROR_MARK;
9038 expr.original_type = NULL;
9039 switch (c_parser_peek_token (parser)->type)
9041 case CPP_NUMBER:
9042 expr.value = c_parser_peek_token (parser)->value;
9043 set_c_expr_source_range (&expr, tok_range);
9044 loc = c_parser_peek_token (parser)->location;
9045 c_parser_consume_token (parser);
9046 if (TREE_CODE (expr.value) == FIXED_CST
9047 && !targetm.fixed_point_supported_p ())
9049 error_at (loc, "fixed-point types not supported for this target");
9050 expr.set_error ();
9052 break;
9053 case CPP_CHAR:
9054 case CPP_CHAR16:
9055 case CPP_CHAR32:
9056 case CPP_UTF8CHAR:
9057 case CPP_WCHAR:
9058 expr.value = c_parser_peek_token (parser)->value;
9059 /* For the purpose of warning when a pointer is compared with
9060 a zero character constant. */
9061 expr.original_type = char_type_node;
9062 set_c_expr_source_range (&expr, tok_range);
9063 c_parser_consume_token (parser);
9064 break;
9065 case CPP_STRING:
9066 case CPP_STRING16:
9067 case CPP_STRING32:
9068 case CPP_WSTRING:
9069 case CPP_UTF8STRING:
9070 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9071 true);
9072 break;
9073 case CPP_OBJC_STRING:
9074 gcc_assert (c_dialect_objc ());
9075 expr.value
9076 = objc_build_string_object (c_parser_peek_token (parser)->value);
9077 set_c_expr_source_range (&expr, tok_range);
9078 c_parser_consume_token (parser);
9079 break;
9080 case CPP_NAME:
9081 switch (c_parser_peek_token (parser)->id_kind)
9083 case C_ID_ID:
9085 tree id = c_parser_peek_token (parser)->value;
9086 c_parser_consume_token (parser);
9087 expr.value = build_external_ref (loc, id,
9088 (c_parser_peek_token (parser)->type
9089 == CPP_OPEN_PAREN),
9090 &expr.original_type);
9091 set_c_expr_source_range (&expr, tok_range);
9092 break;
9094 case C_ID_CLASSNAME:
9096 /* Here we parse the Objective-C 2.0 Class.name dot
9097 syntax. */
9098 tree class_name = c_parser_peek_token (parser)->value;
9099 tree component;
9100 c_parser_consume_token (parser);
9101 gcc_assert (c_dialect_objc ());
9102 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9104 expr.set_error ();
9105 break;
9107 if (c_parser_next_token_is_not (parser, CPP_NAME))
9109 c_parser_error (parser, "expected identifier");
9110 expr.set_error ();
9111 break;
9113 c_token *component_tok = c_parser_peek_token (parser);
9114 component = component_tok->value;
9115 location_t end_loc = component_tok->get_finish ();
9116 c_parser_consume_token (parser);
9117 expr.value = objc_build_class_component_ref (class_name,
9118 component);
9119 set_c_expr_source_range (&expr, loc, end_loc);
9120 break;
9122 default:
9123 c_parser_error (parser, "expected expression");
9124 expr.set_error ();
9125 break;
9127 break;
9128 case CPP_OPEN_PAREN:
9129 /* A parenthesized expression, statement expression or compound
9130 literal. */
9131 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9133 /* A statement expression. */
9134 tree stmt;
9135 location_t brace_loc;
9136 c_parser_consume_token (parser);
9137 brace_loc = c_parser_peek_token (parser)->location;
9138 c_parser_consume_token (parser);
9139 /* If we've not yet started the current function's statement list,
9140 or we're in the parameter scope of an old-style function
9141 declaration, statement expressions are not allowed. */
9142 if (!building_stmt_list_p () || old_style_parameter_scope ())
9144 error_at (loc, "braced-group within expression allowed "
9145 "only inside a function");
9146 parser->error = true;
9147 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9148 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9149 expr.set_error ();
9150 break;
9152 stmt = c_begin_stmt_expr ();
9153 c_parser_compound_statement_nostart (parser);
9154 location_t close_loc = c_parser_peek_token (parser)->location;
9155 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9156 "expected %<)%>");
9157 pedwarn (loc, OPT_Wpedantic,
9158 "ISO C forbids braced-groups within expressions");
9159 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9160 set_c_expr_source_range (&expr, loc, close_loc);
9161 mark_exp_read (expr.value);
9163 else
9165 /* A parenthesized expression. */
9166 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9167 c_parser_consume_token (parser);
9168 expr = c_parser_expression (parser);
9169 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9170 TREE_NO_WARNING (expr.value) = 1;
9171 if (expr.original_code != C_MAYBE_CONST_EXPR
9172 && expr.original_code != SIZEOF_EXPR)
9173 expr.original_code = ERROR_MARK;
9174 /* Don't change EXPR.ORIGINAL_TYPE. */
9175 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9176 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9177 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9178 "expected %<)%>", loc_open_paren);
9180 break;
9181 case CPP_KEYWORD:
9182 switch (c_parser_peek_token (parser)->keyword)
9184 case RID_FUNCTION_NAME:
9185 case RID_PRETTY_FUNCTION_NAME:
9186 case RID_C99_FUNCTION_NAME:
9187 expr = c_parser_predefined_identifier (parser);
9188 break;
9189 case RID_VA_ARG:
9191 location_t start_loc = loc;
9192 c_parser_consume_token (parser);
9193 matching_parens parens;
9194 if (!parens.require_open (parser))
9196 expr.set_error ();
9197 break;
9199 e1 = c_parser_expr_no_commas (parser, NULL);
9200 mark_exp_read (e1.value);
9201 e1.value = c_fully_fold (e1.value, false, NULL);
9202 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9204 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9205 expr.set_error ();
9206 break;
9208 loc = c_parser_peek_token (parser)->location;
9209 t1 = c_parser_type_name (parser);
9210 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9211 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9212 "expected %<)%>");
9213 if (t1 == NULL)
9215 expr.set_error ();
9217 else
9219 tree type_expr = NULL_TREE;
9220 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9221 groktypename (t1, &type_expr, NULL));
9222 if (type_expr)
9224 expr.value = build2 (C_MAYBE_CONST_EXPR,
9225 TREE_TYPE (expr.value), type_expr,
9226 expr.value);
9227 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9229 set_c_expr_source_range (&expr, start_loc, end_loc);
9232 break;
9233 case RID_OFFSETOF:
9235 c_parser_consume_token (parser);
9236 matching_parens parens;
9237 if (!parens.require_open (parser))
9239 expr.set_error ();
9240 break;
9242 t1 = c_parser_type_name (parser);
9243 if (t1 == NULL)
9244 parser->error = true;
9245 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9246 gcc_assert (parser->error);
9247 if (parser->error)
9249 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9250 expr.set_error ();
9251 break;
9253 tree type = groktypename (t1, NULL, NULL);
9254 tree offsetof_ref;
9255 if (type == error_mark_node)
9256 offsetof_ref = error_mark_node;
9257 else
9259 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9260 SET_EXPR_LOCATION (offsetof_ref, loc);
9262 /* Parse the second argument to __builtin_offsetof. We
9263 must have one identifier, and beyond that we want to
9264 accept sub structure and sub array references. */
9265 if (c_parser_next_token_is (parser, CPP_NAME))
9267 c_token *comp_tok = c_parser_peek_token (parser);
9268 offsetof_ref = build_component_ref
9269 (loc, offsetof_ref, comp_tok->value, comp_tok->location);
9270 c_parser_consume_token (parser);
9271 while (c_parser_next_token_is (parser, CPP_DOT)
9272 || c_parser_next_token_is (parser,
9273 CPP_OPEN_SQUARE)
9274 || c_parser_next_token_is (parser,
9275 CPP_DEREF))
9277 if (c_parser_next_token_is (parser, CPP_DEREF))
9279 loc = c_parser_peek_token (parser)->location;
9280 offsetof_ref = build_array_ref (loc,
9281 offsetof_ref,
9282 integer_zero_node);
9283 goto do_dot;
9285 else if (c_parser_next_token_is (parser, CPP_DOT))
9287 do_dot:
9288 c_parser_consume_token (parser);
9289 if (c_parser_next_token_is_not (parser,
9290 CPP_NAME))
9292 c_parser_error (parser, "expected identifier");
9293 break;
9295 c_token *comp_tok = c_parser_peek_token (parser);
9296 offsetof_ref = build_component_ref
9297 (loc, offsetof_ref, comp_tok->value,
9298 comp_tok->location);
9299 c_parser_consume_token (parser);
9301 else
9303 struct c_expr ce;
9304 tree idx;
9305 loc = c_parser_peek_token (parser)->location;
9306 c_parser_consume_token (parser);
9307 ce = c_parser_expression (parser);
9308 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9309 idx = ce.value;
9310 idx = c_fully_fold (idx, false, NULL);
9311 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9312 "expected %<]%>");
9313 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9317 else
9318 c_parser_error (parser, "expected identifier");
9319 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9320 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9321 "expected %<)%>");
9322 expr.value = fold_offsetof (offsetof_ref);
9323 set_c_expr_source_range (&expr, loc, end_loc);
9325 break;
9326 case RID_CHOOSE_EXPR:
9328 vec<c_expr_t, va_gc> *cexpr_list;
9329 c_expr_t *e1_p, *e2_p, *e3_p;
9330 tree c;
9331 location_t close_paren_loc;
9333 c_parser_consume_token (parser);
9334 if (!c_parser_get_builtin_args (parser,
9335 "__builtin_choose_expr",
9336 &cexpr_list, true,
9337 &close_paren_loc))
9339 expr.set_error ();
9340 break;
9343 if (vec_safe_length (cexpr_list) != 3)
9345 error_at (loc, "wrong number of arguments to "
9346 "%<__builtin_choose_expr%>");
9347 expr.set_error ();
9348 break;
9351 e1_p = &(*cexpr_list)[0];
9352 e2_p = &(*cexpr_list)[1];
9353 e3_p = &(*cexpr_list)[2];
9355 c = e1_p->value;
9356 mark_exp_read (e2_p->value);
9357 mark_exp_read (e3_p->value);
9358 if (TREE_CODE (c) != INTEGER_CST
9359 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9360 error_at (loc,
9361 "first argument to %<__builtin_choose_expr%> not"
9362 " a constant");
9363 constant_expression_warning (c);
9364 expr = integer_zerop (c) ? *e3_p : *e2_p;
9365 set_c_expr_source_range (&expr, loc, close_paren_loc);
9366 break;
9368 case RID_TYPES_COMPATIBLE_P:
9370 c_parser_consume_token (parser);
9371 matching_parens parens;
9372 if (!parens.require_open (parser))
9374 expr.set_error ();
9375 break;
9377 t1 = c_parser_type_name (parser);
9378 if (t1 == NULL)
9380 expr.set_error ();
9381 break;
9383 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9385 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9386 expr.set_error ();
9387 break;
9389 t2 = c_parser_type_name (parser);
9390 if (t2 == NULL)
9392 expr.set_error ();
9393 break;
9395 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9396 parens.skip_until_found_close (parser);
9397 tree e1, e2;
9398 e1 = groktypename (t1, NULL, NULL);
9399 e2 = groktypename (t2, NULL, NULL);
9400 if (e1 == error_mark_node || e2 == error_mark_node)
9402 expr.set_error ();
9403 break;
9406 e1 = TYPE_MAIN_VARIANT (e1);
9407 e2 = TYPE_MAIN_VARIANT (e2);
9409 expr.value
9410 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9411 set_c_expr_source_range (&expr, loc, close_paren_loc);
9413 break;
9414 case RID_BUILTIN_TGMATH:
9416 vec<c_expr_t, va_gc> *cexpr_list;
9417 location_t close_paren_loc;
9419 c_parser_consume_token (parser);
9420 if (!c_parser_get_builtin_args (parser,
9421 "__builtin_tgmath",
9422 &cexpr_list, false,
9423 &close_paren_loc))
9425 expr.set_error ();
9426 break;
9429 if (vec_safe_length (cexpr_list) < 3)
9431 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9432 expr.set_error ();
9433 break;
9436 unsigned int i;
9437 c_expr_t *p;
9438 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9439 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9440 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9441 if (nargs == 0)
9443 expr.set_error ();
9444 break;
9446 if (vec_safe_length (cexpr_list) < nargs)
9448 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9449 expr.set_error ();
9450 break;
9452 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9453 if (num_functions < 2)
9455 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9456 expr.set_error ();
9457 break;
9460 /* The first NUM_FUNCTIONS expressions are the function
9461 pointers. The remaining NARGS expressions are the
9462 arguments that are to be passed to one of those
9463 functions, chosen following <tgmath.h> rules. */
9464 for (unsigned int j = 1; j < num_functions; j++)
9466 unsigned int this_nargs
9467 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9468 if (this_nargs == 0)
9470 expr.set_error ();
9471 goto out;
9473 if (this_nargs != nargs)
9475 error_at ((*cexpr_list)[j].get_location (),
9476 "argument %u of %<__builtin_tgmath%> has "
9477 "wrong number of arguments", j + 1);
9478 expr.set_error ();
9479 goto out;
9483 /* The functions all have the same number of arguments.
9484 Determine whether arguments and return types vary in
9485 ways permitted for <tgmath.h> functions. */
9486 /* The first entry in each of these vectors is for the
9487 return type, subsequent entries for parameter
9488 types. */
9489 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9490 auto_vec<tree> parm_first (nargs + 1);
9491 auto_vec<bool> parm_complex (nargs + 1);
9492 auto_vec<bool> parm_varies (nargs + 1);
9493 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9494 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9495 parm_first.quick_push (first_ret);
9496 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9497 parm_varies.quick_push (false);
9498 function_args_iterator iter;
9499 tree t;
9500 unsigned int argpos;
9501 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9503 if (t == void_type_node)
9504 break;
9505 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9506 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9507 parm_varies.quick_push (false);
9509 for (unsigned int j = 1; j < num_functions; j++)
9511 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9512 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9513 if (ret != parm_first[0])
9515 parm_varies[0] = true;
9516 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9517 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9519 error_at ((*cexpr_list)[0].get_location (),
9520 "invalid type-generic return type for "
9521 "argument %u of %<__builtin_tgmath%>",
9523 expr.set_error ();
9524 goto out;
9526 if (!SCALAR_FLOAT_TYPE_P (ret)
9527 && !COMPLEX_FLOAT_TYPE_P (ret))
9529 error_at ((*cexpr_list)[j].get_location (),
9530 "invalid type-generic return type for "
9531 "argument %u of %<__builtin_tgmath%>",
9532 j + 1);
9533 expr.set_error ();
9534 goto out;
9537 if (TREE_CODE (ret) == COMPLEX_TYPE)
9538 parm_complex[0] = true;
9539 argpos = 1;
9540 FOREACH_FUNCTION_ARGS (type, t, iter)
9542 if (t == void_type_node)
9543 break;
9544 t = TYPE_MAIN_VARIANT (t);
9545 if (t != parm_first[argpos])
9547 parm_varies[argpos] = true;
9548 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9549 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9551 error_at ((*cexpr_list)[0].get_location (),
9552 "invalid type-generic type for "
9553 "argument %u of argument %u of "
9554 "%<__builtin_tgmath%>", argpos, 1);
9555 expr.set_error ();
9556 goto out;
9558 if (!SCALAR_FLOAT_TYPE_P (t)
9559 && !COMPLEX_FLOAT_TYPE_P (t))
9561 error_at ((*cexpr_list)[j].get_location (),
9562 "invalid type-generic type for "
9563 "argument %u of argument %u of "
9564 "%<__builtin_tgmath%>", argpos, j + 1);
9565 expr.set_error ();
9566 goto out;
9569 if (TREE_CODE (t) == COMPLEX_TYPE)
9570 parm_complex[argpos] = true;
9571 argpos++;
9574 enum tgmath_parm_kind max_variation = tgmath_fixed;
9575 for (unsigned int j = 0; j <= nargs; j++)
9577 enum tgmath_parm_kind this_kind;
9578 if (parm_varies[j])
9580 if (parm_complex[j])
9581 max_variation = this_kind = tgmath_complex;
9582 else
9584 this_kind = tgmath_real;
9585 if (max_variation != tgmath_complex)
9586 max_variation = tgmath_real;
9589 else
9590 this_kind = tgmath_fixed;
9591 parm_kind.quick_push (this_kind);
9593 if (max_variation == tgmath_fixed)
9595 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9596 "all have the same type");
9597 expr.set_error ();
9598 break;
9601 /* Identify a parameter (not the return type) that varies,
9602 including with complex types if any variation includes
9603 complex types; there must be at least one such
9604 parameter. */
9605 unsigned int tgarg = 0;
9606 for (unsigned int j = 1; j <= nargs; j++)
9607 if (parm_kind[j] == max_variation)
9609 tgarg = j;
9610 break;
9612 if (tgarg == 0)
9614 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9615 "lack type-generic parameter");
9616 expr.set_error ();
9617 break;
9620 /* Determine the type of the relevant parameter for each
9621 function. */
9622 auto_vec<tree> tg_type (num_functions);
9623 for (unsigned int j = 0; j < num_functions; j++)
9625 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9626 argpos = 1;
9627 FOREACH_FUNCTION_ARGS (type, t, iter)
9629 if (argpos == tgarg)
9631 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9632 break;
9634 argpos++;
9638 /* Verify that the corresponding types are different for
9639 all the listed functions. Also determine whether all
9640 the types are complex, whether all the types are
9641 standard or binary, and whether all the types are
9642 decimal. */
9643 bool all_complex = true;
9644 bool all_binary = true;
9645 bool all_decimal = true;
9646 hash_set<tree> tg_types;
9647 FOR_EACH_VEC_ELT (tg_type, i, t)
9649 if (TREE_CODE (t) == COMPLEX_TYPE)
9650 all_decimal = false;
9651 else
9653 all_complex = false;
9654 if (DECIMAL_FLOAT_TYPE_P (t))
9655 all_binary = false;
9656 else
9657 all_decimal = false;
9659 if (tg_types.add (t))
9661 error_at ((*cexpr_list)[i].get_location (),
9662 "duplicate type-generic parameter type for "
9663 "function argument %u of %<__builtin_tgmath%>",
9664 i + 1);
9665 expr.set_error ();
9666 goto out;
9670 /* Verify that other parameters and the return type whose
9671 types vary have their types varying in the correct
9672 way. */
9673 for (unsigned int j = 0; j < num_functions; j++)
9675 tree exp_type = tg_type[j];
9676 tree exp_real_type = exp_type;
9677 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9678 exp_real_type = TREE_TYPE (exp_type);
9679 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9680 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9681 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9682 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9684 error_at ((*cexpr_list)[j].get_location (),
9685 "bad return type for function argument %u "
9686 "of %<__builtin_tgmath%>", j + 1);
9687 expr.set_error ();
9688 goto out;
9690 argpos = 1;
9691 FOREACH_FUNCTION_ARGS (type, t, iter)
9693 if (t == void_type_node)
9694 break;
9695 t = TYPE_MAIN_VARIANT (t);
9696 if ((parm_kind[argpos] == tgmath_complex
9697 && t != exp_type)
9698 || (parm_kind[argpos] == tgmath_real
9699 && t != exp_real_type))
9701 error_at ((*cexpr_list)[j].get_location (),
9702 "bad type for argument %u of "
9703 "function argument %u of "
9704 "%<__builtin_tgmath%>", argpos, j + 1);
9705 expr.set_error ();
9706 goto out;
9708 argpos++;
9712 /* The functions listed are a valid set of functions for a
9713 <tgmath.h> macro to select between. Identify the
9714 matching function, if any. First, the argument types
9715 must be combined following <tgmath.h> rules. Integer
9716 types are treated as _Decimal64 if any type-generic
9717 argument is decimal, or if the only alternatives for
9718 type-generic arguments are of decimal types, and are
9719 otherwise treated as double (or _Complex double for
9720 complex integer types, or _Float64 or _Complex _Float64
9721 if all the return types are the same _FloatN or
9722 _FloatNx type). After that adjustment, types are
9723 combined following the usual arithmetic conversions.
9724 If the function only accepts complex arguments, a
9725 complex type is produced. */
9726 bool arg_complex = all_complex;
9727 bool arg_binary = all_binary;
9728 bool arg_int_decimal = all_decimal;
9729 for (unsigned int j = 1; j <= nargs; j++)
9731 if (parm_kind[j] == tgmath_fixed)
9732 continue;
9733 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9734 tree type = TREE_TYPE (ce->value);
9735 if (!INTEGRAL_TYPE_P (type)
9736 && !SCALAR_FLOAT_TYPE_P (type)
9737 && TREE_CODE (type) != COMPLEX_TYPE)
9739 error_at (ce->get_location (),
9740 "invalid type of argument %u of type-generic "
9741 "function", j);
9742 expr.set_error ();
9743 goto out;
9745 if (DECIMAL_FLOAT_TYPE_P (type))
9747 arg_int_decimal = true;
9748 if (all_complex)
9750 error_at (ce->get_location (),
9751 "decimal floating-point argument %u to "
9752 "complex-only type-generic function", j);
9753 expr.set_error ();
9754 goto out;
9756 else if (all_binary)
9758 error_at (ce->get_location (),
9759 "decimal floating-point argument %u to "
9760 "binary-only type-generic function", j);
9761 expr.set_error ();
9762 goto out;
9764 else if (arg_complex)
9766 error_at (ce->get_location (),
9767 "both complex and decimal floating-point "
9768 "arguments to type-generic function");
9769 expr.set_error ();
9770 goto out;
9772 else if (arg_binary)
9774 error_at (ce->get_location (),
9775 "both binary and decimal floating-point "
9776 "arguments to type-generic function");
9777 expr.set_error ();
9778 goto out;
9781 else if (TREE_CODE (type) == COMPLEX_TYPE)
9783 arg_complex = true;
9784 if (COMPLEX_FLOAT_TYPE_P (type))
9785 arg_binary = true;
9786 if (all_decimal)
9788 error_at (ce->get_location (),
9789 "complex argument %u to "
9790 "decimal-only type-generic function", j);
9791 expr.set_error ();
9792 goto out;
9794 else if (arg_int_decimal)
9796 error_at (ce->get_location (),
9797 "both complex and decimal floating-point "
9798 "arguments to type-generic function");
9799 expr.set_error ();
9800 goto out;
9803 else if (SCALAR_FLOAT_TYPE_P (type))
9805 arg_binary = true;
9806 if (all_decimal)
9808 error_at (ce->get_location (),
9809 "binary argument %u to "
9810 "decimal-only type-generic function", j);
9811 expr.set_error ();
9812 goto out;
9814 else if (arg_int_decimal)
9816 error_at (ce->get_location (),
9817 "both binary and decimal floating-point "
9818 "arguments to type-generic function");
9819 expr.set_error ();
9820 goto out;
9824 /* For a macro rounding its result to a narrower type, map
9825 integer types to _Float64 not double if the return type
9826 is a _FloatN or _FloatNx type. */
9827 bool arg_int_float64 = false;
9828 if (parm_kind[0] == tgmath_fixed
9829 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9830 && float64_type_node != NULL_TREE)
9831 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9832 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9834 arg_int_float64 = true;
9835 break;
9837 tree arg_real = NULL_TREE;
9838 for (unsigned int j = 1; j <= nargs; j++)
9840 if (parm_kind[j] == tgmath_fixed)
9841 continue;
9842 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9843 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9844 if (TREE_CODE (type) == COMPLEX_TYPE)
9845 type = TREE_TYPE (type);
9846 if (INTEGRAL_TYPE_P (type))
9847 type = (arg_int_decimal
9848 ? dfloat64_type_node
9849 : arg_int_float64
9850 ? float64_type_node
9851 : double_type_node);
9852 if (arg_real == NULL_TREE)
9853 arg_real = type;
9854 else
9855 arg_real = common_type (arg_real, type);
9856 if (arg_real == error_mark_node)
9858 expr.set_error ();
9859 goto out;
9862 tree arg_type = (arg_complex
9863 ? build_complex_type (arg_real)
9864 : arg_real);
9866 /* Look for a function to call with type-generic parameter
9867 type ARG_TYPE. */
9868 c_expr_t *fn = NULL;
9869 for (unsigned int j = 0; j < num_functions; j++)
9871 if (tg_type[j] == arg_type)
9873 fn = &(*cexpr_list)[j];
9874 break;
9877 if (fn == NULL
9878 && parm_kind[0] == tgmath_fixed
9879 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9881 /* Presume this is a macro that rounds its result to a
9882 narrower type, and look for the first function with
9883 at least the range and precision of the argument
9884 type. */
9885 for (unsigned int j = 0; j < num_functions; j++)
9887 if (arg_complex
9888 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9889 continue;
9890 tree real_tg_type = (arg_complex
9891 ? TREE_TYPE (tg_type[j])
9892 : tg_type[j]);
9893 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9894 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9895 continue;
9896 scalar_float_mode arg_mode
9897 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9898 scalar_float_mode tg_mode
9899 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9900 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9901 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9902 if (arg_fmt->b == tg_fmt->b
9903 && arg_fmt->p <= tg_fmt->p
9904 && arg_fmt->emax <= tg_fmt->emax
9905 && (arg_fmt->emin - arg_fmt->p
9906 >= tg_fmt->emin - tg_fmt->p))
9908 fn = &(*cexpr_list)[j];
9909 break;
9913 if (fn == NULL)
9915 error_at (loc, "no matching function for type-generic call");
9916 expr.set_error ();
9917 break;
9920 /* Construct a call to FN. */
9921 vec<tree, va_gc> *args;
9922 vec_alloc (args, nargs);
9923 vec<tree, va_gc> *origtypes;
9924 vec_alloc (origtypes, nargs);
9925 auto_vec<location_t> arg_loc (nargs);
9926 for (unsigned int j = 0; j < nargs; j++)
9928 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9929 args->quick_push (ce->value);
9930 arg_loc.quick_push (ce->get_location ());
9931 origtypes->quick_push (ce->original_type);
9933 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9934 args, origtypes);
9935 set_c_expr_source_range (&expr, loc, close_paren_loc);
9936 break;
9938 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9940 vec<c_expr_t, va_gc> *cexpr_list;
9941 c_expr_t *e2_p;
9942 tree chain_value;
9943 location_t close_paren_loc;
9945 c_parser_consume_token (parser);
9946 if (!c_parser_get_builtin_args (parser,
9947 "__builtin_call_with_static_chain",
9948 &cexpr_list, false,
9949 &close_paren_loc))
9951 expr.set_error ();
9952 break;
9954 if (vec_safe_length (cexpr_list) != 2)
9956 error_at (loc, "wrong number of arguments to "
9957 "%<__builtin_call_with_static_chain%>");
9958 expr.set_error ();
9959 break;
9962 expr = (*cexpr_list)[0];
9963 e2_p = &(*cexpr_list)[1];
9964 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9965 chain_value = e2_p->value;
9966 mark_exp_read (chain_value);
9968 if (TREE_CODE (expr.value) != CALL_EXPR)
9969 error_at (loc, "first argument to "
9970 "%<__builtin_call_with_static_chain%> "
9971 "must be a call expression");
9972 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9973 error_at (loc, "second argument to "
9974 "%<__builtin_call_with_static_chain%> "
9975 "must be a pointer type");
9976 else
9977 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9978 set_c_expr_source_range (&expr, loc, close_paren_loc);
9979 break;
9981 case RID_BUILTIN_COMPLEX:
9983 vec<c_expr_t, va_gc> *cexpr_list;
9984 c_expr_t *e1_p, *e2_p;
9985 location_t close_paren_loc;
9987 c_parser_consume_token (parser);
9988 if (!c_parser_get_builtin_args (parser,
9989 "__builtin_complex",
9990 &cexpr_list, false,
9991 &close_paren_loc))
9993 expr.set_error ();
9994 break;
9997 if (vec_safe_length (cexpr_list) != 2)
9999 error_at (loc, "wrong number of arguments to "
10000 "%<__builtin_complex%>");
10001 expr.set_error ();
10002 break;
10005 e1_p = &(*cexpr_list)[0];
10006 e2_p = &(*cexpr_list)[1];
10008 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
10009 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
10010 e1_p->value = convert (TREE_TYPE (e1_p->value),
10011 TREE_OPERAND (e1_p->value, 0));
10012 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
10013 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
10014 e2_p->value = convert (TREE_TYPE (e2_p->value),
10015 TREE_OPERAND (e2_p->value, 0));
10016 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10017 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10018 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
10019 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
10021 error_at (loc, "%<__builtin_complex%> operand "
10022 "not of real binary floating-point type");
10023 expr.set_error ();
10024 break;
10026 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10027 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10029 error_at (loc,
10030 "%<__builtin_complex%> operands of different types");
10031 expr.set_error ();
10032 break;
10034 pedwarn_c90 (loc, OPT_Wpedantic,
10035 "ISO C90 does not support complex types");
10036 expr.value = build2_loc (loc, COMPLEX_EXPR,
10037 build_complex_type
10038 (TYPE_MAIN_VARIANT
10039 (TREE_TYPE (e1_p->value))),
10040 e1_p->value, e2_p->value);
10041 set_c_expr_source_range (&expr, loc, close_paren_loc);
10042 break;
10044 case RID_BUILTIN_SHUFFLE:
10046 vec<c_expr_t, va_gc> *cexpr_list;
10047 unsigned int i;
10048 c_expr_t *p;
10049 location_t close_paren_loc;
10051 c_parser_consume_token (parser);
10052 if (!c_parser_get_builtin_args (parser,
10053 "__builtin_shuffle",
10054 &cexpr_list, false,
10055 &close_paren_loc))
10057 expr.set_error ();
10058 break;
10061 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10062 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10064 if (vec_safe_length (cexpr_list) == 2)
10065 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10066 NULL_TREE,
10067 (*cexpr_list)[1].value);
10069 else if (vec_safe_length (cexpr_list) == 3)
10070 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10071 (*cexpr_list)[1].value,
10072 (*cexpr_list)[2].value);
10073 else
10075 error_at (loc, "wrong number of arguments to "
10076 "%<__builtin_shuffle%>");
10077 expr.set_error ();
10079 set_c_expr_source_range (&expr, loc, close_paren_loc);
10080 break;
10082 case RID_BUILTIN_CONVERTVECTOR:
10084 location_t start_loc = loc;
10085 c_parser_consume_token (parser);
10086 matching_parens parens;
10087 if (!parens.require_open (parser))
10089 expr.set_error ();
10090 break;
10092 e1 = c_parser_expr_no_commas (parser, NULL);
10093 mark_exp_read (e1.value);
10094 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10096 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10097 expr.set_error ();
10098 break;
10100 loc = c_parser_peek_token (parser)->location;
10101 t1 = c_parser_type_name (parser);
10102 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10103 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10104 "expected %<)%>");
10105 if (t1 == NULL)
10106 expr.set_error ();
10107 else
10109 tree type_expr = NULL_TREE;
10110 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10111 groktypename (t1, &type_expr,
10112 NULL));
10113 set_c_expr_source_range (&expr, start_loc, end_loc);
10116 break;
10117 case RID_AT_SELECTOR:
10119 gcc_assert (c_dialect_objc ());
10120 c_parser_consume_token (parser);
10121 matching_parens parens;
10122 if (!parens.require_open (parser))
10124 expr.set_error ();
10125 break;
10127 tree sel = c_parser_objc_selector_arg (parser);
10128 location_t close_loc = c_parser_peek_token (parser)->location;
10129 parens.skip_until_found_close (parser);
10130 expr.value = objc_build_selector_expr (loc, sel);
10131 set_c_expr_source_range (&expr, loc, close_loc);
10133 break;
10134 case RID_AT_PROTOCOL:
10136 gcc_assert (c_dialect_objc ());
10137 c_parser_consume_token (parser);
10138 matching_parens parens;
10139 if (!parens.require_open (parser))
10141 expr.set_error ();
10142 break;
10144 if (c_parser_next_token_is_not (parser, CPP_NAME))
10146 c_parser_error (parser, "expected identifier");
10147 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10148 expr.set_error ();
10149 break;
10151 tree id = c_parser_peek_token (parser)->value;
10152 c_parser_consume_token (parser);
10153 location_t close_loc = c_parser_peek_token (parser)->location;
10154 parens.skip_until_found_close (parser);
10155 expr.value = objc_build_protocol_expr (id);
10156 set_c_expr_source_range (&expr, loc, close_loc);
10158 break;
10159 case RID_AT_ENCODE:
10161 /* Extension to support C-structures in the archiver. */
10162 gcc_assert (c_dialect_objc ());
10163 c_parser_consume_token (parser);
10164 matching_parens parens;
10165 if (!parens.require_open (parser))
10167 expr.set_error ();
10168 break;
10170 t1 = c_parser_type_name (parser);
10171 if (t1 == NULL)
10173 expr.set_error ();
10174 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10175 break;
10177 location_t close_loc = c_parser_peek_token (parser)->location;
10178 parens.skip_until_found_close (parser);
10179 tree type = groktypename (t1, NULL, NULL);
10180 expr.value = objc_build_encode_expr (type);
10181 set_c_expr_source_range (&expr, loc, close_loc);
10183 break;
10184 case RID_GENERIC:
10185 expr = c_parser_generic_selection (parser);
10186 break;
10187 default:
10188 c_parser_error (parser, "expected expression");
10189 expr.set_error ();
10190 break;
10192 break;
10193 case CPP_OPEN_SQUARE:
10194 if (c_dialect_objc ())
10196 tree receiver, args;
10197 c_parser_consume_token (parser);
10198 receiver = c_parser_objc_receiver (parser);
10199 args = c_parser_objc_message_args (parser);
10200 location_t close_loc = c_parser_peek_token (parser)->location;
10201 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10202 "expected %<]%>");
10203 expr.value = objc_build_message_expr (receiver, args);
10204 set_c_expr_source_range (&expr, loc, close_loc);
10205 break;
10207 /* Else fall through to report error. */
10208 /* FALLTHRU */
10209 default:
10210 c_parser_error (parser, "expected expression");
10211 expr.set_error ();
10212 break;
10214 out:
10215 return c_parser_postfix_expression_after_primary
10216 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10219 /* Parse a postfix expression after a parenthesized type name: the
10220 brace-enclosed initializer of a compound literal, possibly followed
10221 by some postfix operators. This is separate because it is not
10222 possible to tell until after the type name whether a cast
10223 expression has a cast or a compound literal, or whether the operand
10224 of sizeof is a parenthesized type name or starts with a compound
10225 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10226 location of the first token after the parentheses around the type
10227 name. */
10229 static struct c_expr
10230 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10231 struct c_type_name *type_name,
10232 location_t type_loc)
10234 tree type;
10235 struct c_expr init;
10236 bool non_const;
10237 struct c_expr expr;
10238 location_t start_loc;
10239 tree type_expr = NULL_TREE;
10240 bool type_expr_const = true;
10241 check_compound_literal_type (type_loc, type_name);
10242 rich_location richloc (line_table, type_loc);
10243 start_init (NULL_TREE, NULL, 0, &richloc);
10244 type = groktypename (type_name, &type_expr, &type_expr_const);
10245 start_loc = c_parser_peek_token (parser)->location;
10246 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10248 error_at (type_loc, "compound literal has variable size");
10249 type = error_mark_node;
10251 init = c_parser_braced_init (parser, type, false, NULL);
10252 finish_init ();
10253 maybe_warn_string_init (type_loc, type, init);
10255 if (type != error_mark_node
10256 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10257 && current_function_decl)
10259 error ("compound literal qualified by address-space qualifier");
10260 type = error_mark_node;
10263 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10264 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10265 ? CONSTRUCTOR_NON_CONST (init.value)
10266 : init.original_code == C_MAYBE_CONST_EXPR);
10267 non_const |= !type_expr_const;
10268 unsigned int alignas_align = 0;
10269 if (type != error_mark_node
10270 && type_name->specs->align_log != -1)
10272 alignas_align = 1U << type_name->specs->align_log;
10273 if (alignas_align < min_align_of_type (type))
10275 error_at (type_name->specs->locations[cdw_alignas],
10276 "%<_Alignas%> specifiers cannot reduce "
10277 "alignment of compound literal");
10278 alignas_align = 0;
10281 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10282 alignas_align);
10283 set_c_expr_source_range (&expr, init.src_range);
10284 expr.original_code = ERROR_MARK;
10285 expr.original_type = NULL;
10286 if (type != error_mark_node
10287 && expr.value != error_mark_node
10288 && type_expr)
10290 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10292 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10293 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10295 else
10297 gcc_assert (!non_const);
10298 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10299 type_expr, expr.value);
10302 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10305 /* Callback function for sizeof_pointer_memaccess_warning to compare
10306 types. */
10308 static bool
10309 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10311 return comptypes (type1, type2) == 1;
10314 /* Warn for patterns where abs-like function appears to be used incorrectly,
10315 gracefully ignore any non-abs-like function. The warning location should
10316 be LOC. FNDECL is the declaration of called function, it must be a
10317 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10318 call. */
10320 static void
10321 warn_for_abs (location_t loc, tree fndecl, tree arg)
10323 /* Avoid warning in unreachable subexpressions. */
10324 if (c_inhibit_evaluation_warnings)
10325 return;
10327 tree atype = TREE_TYPE (arg);
10329 /* Casts from pointers (and thus arrays and fndecls) will generate
10330 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10331 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10332 types and possibly other exotic types. */
10333 if (!INTEGRAL_TYPE_P (atype)
10334 && !SCALAR_FLOAT_TYPE_P (atype)
10335 && TREE_CODE (atype) != COMPLEX_TYPE)
10336 return;
10338 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10340 switch (fcode)
10342 case BUILT_IN_ABS:
10343 case BUILT_IN_LABS:
10344 case BUILT_IN_LLABS:
10345 case BUILT_IN_IMAXABS:
10346 if (!INTEGRAL_TYPE_P (atype))
10348 if (SCALAR_FLOAT_TYPE_P (atype))
10349 warning_at (loc, OPT_Wabsolute_value,
10350 "using integer absolute value function %qD when "
10351 "argument is of floating-point type %qT",
10352 fndecl, atype);
10353 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10354 warning_at (loc, OPT_Wabsolute_value,
10355 "using integer absolute value function %qD when "
10356 "argument is of complex type %qT", fndecl, atype);
10357 else
10358 gcc_unreachable ();
10359 return;
10361 if (TYPE_UNSIGNED (atype))
10362 warning_at (loc, OPT_Wabsolute_value,
10363 "taking the absolute value of unsigned type %qT "
10364 "has no effect", atype);
10365 break;
10367 CASE_FLT_FN (BUILT_IN_FABS):
10368 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10369 if (!SCALAR_FLOAT_TYPE_P (atype)
10370 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10372 if (INTEGRAL_TYPE_P (atype))
10373 warning_at (loc, OPT_Wabsolute_value,
10374 "using floating-point absolute value function %qD "
10375 "when argument is of integer type %qT", fndecl, atype);
10376 else if (DECIMAL_FLOAT_TYPE_P (atype))
10377 warning_at (loc, OPT_Wabsolute_value,
10378 "using floating-point absolute value function %qD "
10379 "when argument is of decimal floating-point type %qT",
10380 fndecl, atype);
10381 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10382 warning_at (loc, OPT_Wabsolute_value,
10383 "using floating-point absolute value function %qD when "
10384 "argument is of complex type %qT", fndecl, atype);
10385 else
10386 gcc_unreachable ();
10387 return;
10389 break;
10391 CASE_FLT_FN (BUILT_IN_CABS):
10392 if (TREE_CODE (atype) != COMPLEX_TYPE)
10394 if (INTEGRAL_TYPE_P (atype))
10395 warning_at (loc, OPT_Wabsolute_value,
10396 "using complex absolute value function %qD when "
10397 "argument is of integer type %qT", fndecl, atype);
10398 else if (SCALAR_FLOAT_TYPE_P (atype))
10399 warning_at (loc, OPT_Wabsolute_value,
10400 "using complex absolute value function %qD when "
10401 "argument is of floating-point type %qT",
10402 fndecl, atype);
10403 else
10404 gcc_unreachable ();
10406 return;
10408 break;
10410 case BUILT_IN_FABSD32:
10411 case BUILT_IN_FABSD64:
10412 case BUILT_IN_FABSD128:
10413 if (!DECIMAL_FLOAT_TYPE_P (atype))
10415 if (INTEGRAL_TYPE_P (atype))
10416 warning_at (loc, OPT_Wabsolute_value,
10417 "using decimal floating-point absolute value "
10418 "function %qD when argument is of integer type %qT",
10419 fndecl, atype);
10420 else if (SCALAR_FLOAT_TYPE_P (atype))
10421 warning_at (loc, OPT_Wabsolute_value,
10422 "using decimal floating-point absolute value "
10423 "function %qD when argument is of floating-point "
10424 "type %qT", fndecl, atype);
10425 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10426 warning_at (loc, OPT_Wabsolute_value,
10427 "using decimal floating-point absolute value "
10428 "function %qD when argument is of complex type %qT",
10429 fndecl, atype);
10430 else
10431 gcc_unreachable ();
10432 return;
10434 break;
10436 default:
10437 return;
10440 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10441 return;
10443 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10444 if (TREE_CODE (atype) == COMPLEX_TYPE)
10446 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10447 atype = TREE_TYPE (atype);
10448 ftype = TREE_TYPE (ftype);
10451 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10452 warning_at (loc, OPT_Wabsolute_value,
10453 "absolute value function %qD given an argument of type %qT "
10454 "but has parameter of type %qT which may cause truncation "
10455 "of value", fndecl, atype, ftype);
10459 /* Parse a postfix expression after the initial primary or compound
10460 literal; that is, parse a series of postfix operators.
10462 EXPR_LOC is the location of the primary expression. */
10464 static struct c_expr
10465 c_parser_postfix_expression_after_primary (c_parser *parser,
10466 location_t expr_loc,
10467 struct c_expr expr)
10469 struct c_expr orig_expr;
10470 tree ident, idx;
10471 location_t sizeof_arg_loc[3], comp_loc;
10472 tree sizeof_arg[3];
10473 unsigned int literal_zero_mask;
10474 unsigned int i;
10475 vec<tree, va_gc> *exprlist;
10476 vec<tree, va_gc> *origtypes = NULL;
10477 vec<location_t> arg_loc = vNULL;
10478 location_t start;
10479 location_t finish;
10481 while (true)
10483 location_t op_loc = c_parser_peek_token (parser)->location;
10484 switch (c_parser_peek_token (parser)->type)
10486 case CPP_OPEN_SQUARE:
10487 /* Array reference. */
10488 c_parser_consume_token (parser);
10489 idx = c_parser_expression (parser).value;
10490 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10491 "expected %<]%>");
10492 start = expr.get_start ();
10493 finish = parser->tokens_buf[0].location;
10494 expr.value = build_array_ref (op_loc, expr.value, idx);
10495 set_c_expr_source_range (&expr, start, finish);
10496 expr.original_code = ERROR_MARK;
10497 expr.original_type = NULL;
10498 break;
10499 case CPP_OPEN_PAREN:
10500 /* Function call. */
10502 matching_parens parens;
10503 parens.consume_open (parser);
10504 for (i = 0; i < 3; i++)
10506 sizeof_arg[i] = NULL_TREE;
10507 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10509 literal_zero_mask = 0;
10510 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10511 exprlist = NULL;
10512 else
10513 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10514 sizeof_arg_loc, sizeof_arg,
10515 &arg_loc, &literal_zero_mask);
10516 parens.skip_until_found_close (parser);
10518 orig_expr = expr;
10519 mark_exp_read (expr.value);
10520 if (warn_sizeof_pointer_memaccess)
10521 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10522 expr.value, exprlist,
10523 sizeof_arg,
10524 sizeof_ptr_memacc_comptypes);
10525 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10527 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10528 && vec_safe_length (exprlist) == 3)
10530 tree arg0 = (*exprlist)[0];
10531 tree arg2 = (*exprlist)[2];
10532 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10534 if (warn_absolute_value
10535 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10536 && vec_safe_length (exprlist) == 1)
10537 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10540 start = expr.get_start ();
10541 finish = parser->tokens_buf[0].get_finish ();
10542 expr.value
10543 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10544 exprlist, origtypes);
10545 set_c_expr_source_range (&expr, start, finish);
10547 expr.original_code = ERROR_MARK;
10548 if (TREE_CODE (expr.value) == INTEGER_CST
10549 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10550 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10551 expr.original_code = C_MAYBE_CONST_EXPR;
10552 expr.original_type = NULL;
10553 if (exprlist)
10555 release_tree_vector (exprlist);
10556 release_tree_vector (origtypes);
10558 arg_loc.release ();
10559 break;
10560 case CPP_DOT:
10561 /* Structure element reference. */
10562 c_parser_consume_token (parser);
10563 expr = default_function_array_conversion (expr_loc, expr);
10564 if (c_parser_next_token_is (parser, CPP_NAME))
10566 c_token *comp_tok = c_parser_peek_token (parser);
10567 ident = comp_tok->value;
10568 comp_loc = comp_tok->location;
10570 else
10572 c_parser_error (parser, "expected identifier");
10573 expr.set_error ();
10574 expr.original_code = ERROR_MARK;
10575 expr.original_type = NULL;
10576 return expr;
10578 start = expr.get_start ();
10579 finish = c_parser_peek_token (parser)->get_finish ();
10580 c_parser_consume_token (parser);
10581 expr.value = build_component_ref (op_loc, expr.value, ident,
10582 comp_loc);
10583 set_c_expr_source_range (&expr, start, finish);
10584 expr.original_code = ERROR_MARK;
10585 if (TREE_CODE (expr.value) != COMPONENT_REF)
10586 expr.original_type = NULL;
10587 else
10589 /* Remember the original type of a bitfield. */
10590 tree field = TREE_OPERAND (expr.value, 1);
10591 if (TREE_CODE (field) != FIELD_DECL)
10592 expr.original_type = NULL;
10593 else
10594 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10596 break;
10597 case CPP_DEREF:
10598 /* Structure element reference. */
10599 c_parser_consume_token (parser);
10600 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10601 if (c_parser_next_token_is (parser, CPP_NAME))
10603 c_token *comp_tok = c_parser_peek_token (parser);
10604 ident = comp_tok->value;
10605 comp_loc = comp_tok->location;
10607 else
10609 c_parser_error (parser, "expected identifier");
10610 expr.set_error ();
10611 expr.original_code = ERROR_MARK;
10612 expr.original_type = NULL;
10613 return expr;
10615 start = expr.get_start ();
10616 finish = c_parser_peek_token (parser)->get_finish ();
10617 c_parser_consume_token (parser);
10618 expr.value = build_component_ref (op_loc,
10619 build_indirect_ref (op_loc,
10620 expr.value,
10621 RO_ARROW),
10622 ident, comp_loc);
10623 set_c_expr_source_range (&expr, start, finish);
10624 expr.original_code = ERROR_MARK;
10625 if (TREE_CODE (expr.value) != COMPONENT_REF)
10626 expr.original_type = NULL;
10627 else
10629 /* Remember the original type of a bitfield. */
10630 tree field = TREE_OPERAND (expr.value, 1);
10631 if (TREE_CODE (field) != FIELD_DECL)
10632 expr.original_type = NULL;
10633 else
10634 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10636 break;
10637 case CPP_PLUS_PLUS:
10638 /* Postincrement. */
10639 start = expr.get_start ();
10640 finish = c_parser_peek_token (parser)->get_finish ();
10641 c_parser_consume_token (parser);
10642 expr = default_function_array_read_conversion (expr_loc, expr);
10643 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10644 expr.value, false);
10645 set_c_expr_source_range (&expr, start, finish);
10646 expr.original_code = ERROR_MARK;
10647 expr.original_type = NULL;
10648 break;
10649 case CPP_MINUS_MINUS:
10650 /* Postdecrement. */
10651 start = expr.get_start ();
10652 finish = c_parser_peek_token (parser)->get_finish ();
10653 c_parser_consume_token (parser);
10654 expr = default_function_array_read_conversion (expr_loc, expr);
10655 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10656 expr.value, false);
10657 set_c_expr_source_range (&expr, start, finish);
10658 expr.original_code = ERROR_MARK;
10659 expr.original_type = NULL;
10660 break;
10661 default:
10662 return expr;
10667 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10669 expression:
10670 assignment-expression
10671 expression , assignment-expression
10674 static struct c_expr
10675 c_parser_expression (c_parser *parser)
10677 location_t tloc = c_parser_peek_token (parser)->location;
10678 struct c_expr expr;
10679 expr = c_parser_expr_no_commas (parser, NULL);
10680 if (c_parser_next_token_is (parser, CPP_COMMA))
10681 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10682 while (c_parser_next_token_is (parser, CPP_COMMA))
10684 struct c_expr next;
10685 tree lhsval;
10686 location_t loc = c_parser_peek_token (parser)->location;
10687 location_t expr_loc;
10688 c_parser_consume_token (parser);
10689 expr_loc = c_parser_peek_token (parser)->location;
10690 lhsval = expr.value;
10691 while (TREE_CODE (lhsval) == COMPOUND_EXPR)
10692 lhsval = TREE_OPERAND (lhsval, 1);
10693 if (DECL_P (lhsval) || handled_component_p (lhsval))
10694 mark_exp_read (lhsval);
10695 next = c_parser_expr_no_commas (parser, NULL);
10696 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10697 expr.value = build_compound_expr (loc, expr.value, next.value);
10698 expr.original_code = COMPOUND_EXPR;
10699 expr.original_type = next.original_type;
10701 return expr;
10704 /* Parse an expression and convert functions or arrays to pointers and
10705 lvalues to rvalues. */
10707 static struct c_expr
10708 c_parser_expression_conv (c_parser *parser)
10710 struct c_expr expr;
10711 location_t loc = c_parser_peek_token (parser)->location;
10712 expr = c_parser_expression (parser);
10713 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10714 return expr;
10717 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10718 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10720 static inline void
10721 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10722 unsigned int idx)
10724 if (idx >= HOST_BITS_PER_INT)
10725 return;
10727 c_token *tok = c_parser_peek_token (parser);
10728 switch (tok->type)
10730 case CPP_NUMBER:
10731 case CPP_CHAR:
10732 case CPP_WCHAR:
10733 case CPP_CHAR16:
10734 case CPP_CHAR32:
10735 case CPP_UTF8CHAR:
10736 /* If a parameter is literal zero alone, remember it
10737 for -Wmemset-transposed-args warning. */
10738 if (integer_zerop (tok->value)
10739 && !TREE_OVERFLOW (tok->value)
10740 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10741 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10742 *literal_zero_mask |= 1U << idx;
10743 default:
10744 break;
10748 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10749 functions and arrays to pointers and lvalues to rvalues. If
10750 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10751 locations of function arguments into this vector.
10753 nonempty-expr-list:
10754 assignment-expression
10755 nonempty-expr-list , assignment-expression
10758 static vec<tree, va_gc> *
10759 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10760 vec<tree, va_gc> **p_orig_types,
10761 location_t *sizeof_arg_loc, tree *sizeof_arg,
10762 vec<location_t> *locations,
10763 unsigned int *literal_zero_mask)
10765 vec<tree, va_gc> *ret;
10766 vec<tree, va_gc> *orig_types;
10767 struct c_expr expr;
10768 unsigned int idx = 0;
10770 ret = make_tree_vector ();
10771 if (p_orig_types == NULL)
10772 orig_types = NULL;
10773 else
10774 orig_types = make_tree_vector ();
10776 if (literal_zero_mask)
10777 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10778 expr = c_parser_expr_no_commas (parser, NULL);
10779 if (convert_p)
10780 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10781 if (fold_p)
10782 expr.value = c_fully_fold (expr.value, false, NULL);
10783 ret->quick_push (expr.value);
10784 if (orig_types)
10785 orig_types->quick_push (expr.original_type);
10786 if (locations)
10787 locations->safe_push (expr.get_location ());
10788 if (sizeof_arg != NULL
10789 && expr.original_code == SIZEOF_EXPR)
10791 sizeof_arg[0] = c_last_sizeof_arg;
10792 sizeof_arg_loc[0] = c_last_sizeof_loc;
10794 while (c_parser_next_token_is (parser, CPP_COMMA))
10796 c_parser_consume_token (parser);
10797 if (literal_zero_mask)
10798 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10799 expr = c_parser_expr_no_commas (parser, NULL);
10800 if (convert_p)
10801 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10802 true);
10803 if (fold_p)
10804 expr.value = c_fully_fold (expr.value, false, NULL);
10805 vec_safe_push (ret, expr.value);
10806 if (orig_types)
10807 vec_safe_push (orig_types, expr.original_type);
10808 if (locations)
10809 locations->safe_push (expr.get_location ());
10810 if (++idx < 3
10811 && sizeof_arg != NULL
10812 && expr.original_code == SIZEOF_EXPR)
10814 sizeof_arg[idx] = c_last_sizeof_arg;
10815 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10818 if (orig_types)
10819 *p_orig_types = orig_types;
10820 return ret;
10823 /* Parse Objective-C-specific constructs. */
10825 /* Parse an objc-class-definition.
10827 objc-class-definition:
10828 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10829 objc-class-instance-variables[opt] objc-methodprotolist @end
10830 @implementation identifier objc-superclass[opt]
10831 objc-class-instance-variables[opt]
10832 @interface identifier ( identifier ) objc-protocol-refs[opt]
10833 objc-methodprotolist @end
10834 @interface identifier ( ) objc-protocol-refs[opt]
10835 objc-methodprotolist @end
10836 @implementation identifier ( identifier )
10838 objc-superclass:
10839 : identifier
10841 "@interface identifier (" must start "@interface identifier (
10842 identifier ) ...": objc-methodprotolist in the first production may
10843 not start with a parenthesized identifier as a declarator of a data
10844 definition with no declaration specifiers if the objc-superclass,
10845 objc-protocol-refs and objc-class-instance-variables are omitted. */
10847 static void
10848 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10850 bool iface_p;
10851 tree id1;
10852 tree superclass;
10853 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10854 iface_p = true;
10855 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10856 iface_p = false;
10857 else
10858 gcc_unreachable ();
10860 c_parser_consume_token (parser);
10861 if (c_parser_next_token_is_not (parser, CPP_NAME))
10863 c_parser_error (parser, "expected identifier");
10864 return;
10866 id1 = c_parser_peek_token (parser)->value;
10867 c_parser_consume_token (parser);
10868 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10870 /* We have a category or class extension. */
10871 tree id2;
10872 tree proto = NULL_TREE;
10873 matching_parens parens;
10874 parens.consume_open (parser);
10875 if (c_parser_next_token_is_not (parser, CPP_NAME))
10877 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10879 /* We have a class extension. */
10880 id2 = NULL_TREE;
10882 else
10884 c_parser_error (parser, "expected identifier or %<)%>");
10885 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10886 return;
10889 else
10891 id2 = c_parser_peek_token (parser)->value;
10892 c_parser_consume_token (parser);
10894 parens.skip_until_found_close (parser);
10895 if (!iface_p)
10897 objc_start_category_implementation (id1, id2);
10898 return;
10900 if (c_parser_next_token_is (parser, CPP_LESS))
10901 proto = c_parser_objc_protocol_refs (parser);
10902 objc_start_category_interface (id1, id2, proto, attributes);
10903 c_parser_objc_methodprotolist (parser);
10904 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10905 objc_finish_interface ();
10906 return;
10908 if (c_parser_next_token_is (parser, CPP_COLON))
10910 c_parser_consume_token (parser);
10911 if (c_parser_next_token_is_not (parser, CPP_NAME))
10913 c_parser_error (parser, "expected identifier");
10914 return;
10916 superclass = c_parser_peek_token (parser)->value;
10917 c_parser_consume_token (parser);
10919 else
10920 superclass = NULL_TREE;
10921 if (iface_p)
10923 tree proto = NULL_TREE;
10924 if (c_parser_next_token_is (parser, CPP_LESS))
10925 proto = c_parser_objc_protocol_refs (parser);
10926 objc_start_class_interface (id1, superclass, proto, attributes);
10928 else
10929 objc_start_class_implementation (id1, superclass);
10930 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10931 c_parser_objc_class_instance_variables (parser);
10932 if (iface_p)
10934 objc_continue_interface ();
10935 c_parser_objc_methodprotolist (parser);
10936 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10937 objc_finish_interface ();
10939 else
10941 objc_continue_implementation ();
10942 return;
10946 /* Parse objc-class-instance-variables.
10948 objc-class-instance-variables:
10949 { objc-instance-variable-decl-list[opt] }
10951 objc-instance-variable-decl-list:
10952 objc-visibility-spec
10953 objc-instance-variable-decl ;
10955 objc-instance-variable-decl-list objc-visibility-spec
10956 objc-instance-variable-decl-list objc-instance-variable-decl ;
10957 objc-instance-variable-decl-list ;
10959 objc-visibility-spec:
10960 @private
10961 @protected
10962 @public
10964 objc-instance-variable-decl:
10965 struct-declaration
10968 static void
10969 c_parser_objc_class_instance_variables (c_parser *parser)
10971 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
10972 c_parser_consume_token (parser);
10973 while (c_parser_next_token_is_not (parser, CPP_EOF))
10975 tree decls;
10976 /* Parse any stray semicolon. */
10977 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10979 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
10980 "extra semicolon");
10981 c_parser_consume_token (parser);
10982 continue;
10984 /* Stop if at the end of the instance variables. */
10985 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10987 c_parser_consume_token (parser);
10988 break;
10990 /* Parse any objc-visibility-spec. */
10991 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
10993 c_parser_consume_token (parser);
10994 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
10995 continue;
10997 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
10999 c_parser_consume_token (parser);
11000 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11001 continue;
11003 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11005 c_parser_consume_token (parser);
11006 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11007 continue;
11009 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11011 c_parser_consume_token (parser);
11012 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11013 continue;
11015 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11017 c_parser_pragma (parser, pragma_external, NULL);
11018 continue;
11021 /* Parse some comma-separated declarations. */
11022 decls = c_parser_struct_declaration (parser);
11023 if (decls == NULL)
11025 /* There is a syntax error. We want to skip the offending
11026 tokens up to the next ';' (included) or '}'
11027 (excluded). */
11029 /* First, skip manually a ')' or ']'. This is because they
11030 reduce the nesting level, so c_parser_skip_until_found()
11031 wouldn't be able to skip past them. */
11032 c_token *token = c_parser_peek_token (parser);
11033 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11034 c_parser_consume_token (parser);
11036 /* Then, do the standard skipping. */
11037 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11039 /* We hopefully recovered. Start normal parsing again. */
11040 parser->error = false;
11041 continue;
11043 else
11045 /* Comma-separated instance variables are chained together
11046 in reverse order; add them one by one. */
11047 tree ivar = nreverse (decls);
11048 for (; ivar; ivar = DECL_CHAIN (ivar))
11049 objc_add_instance_variable (copy_node (ivar));
11051 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11055 /* Parse an objc-class-declaration.
11057 objc-class-declaration:
11058 @class identifier-list ;
11061 static void
11062 c_parser_objc_class_declaration (c_parser *parser)
11064 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11065 c_parser_consume_token (parser);
11066 /* Any identifiers, including those declared as type names, are OK
11067 here. */
11068 while (true)
11070 tree id;
11071 if (c_parser_next_token_is_not (parser, CPP_NAME))
11073 c_parser_error (parser, "expected identifier");
11074 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11075 parser->error = false;
11076 return;
11078 id = c_parser_peek_token (parser)->value;
11079 objc_declare_class (id);
11080 c_parser_consume_token (parser);
11081 if (c_parser_next_token_is (parser, CPP_COMMA))
11082 c_parser_consume_token (parser);
11083 else
11084 break;
11086 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11089 /* Parse an objc-alias-declaration.
11091 objc-alias-declaration:
11092 @compatibility_alias identifier identifier ;
11095 static void
11096 c_parser_objc_alias_declaration (c_parser *parser)
11098 tree id1, id2;
11099 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11100 c_parser_consume_token (parser);
11101 if (c_parser_next_token_is_not (parser, CPP_NAME))
11103 c_parser_error (parser, "expected identifier");
11104 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11105 return;
11107 id1 = c_parser_peek_token (parser)->value;
11108 c_parser_consume_token (parser);
11109 if (c_parser_next_token_is_not (parser, CPP_NAME))
11111 c_parser_error (parser, "expected identifier");
11112 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11113 return;
11115 id2 = c_parser_peek_token (parser)->value;
11116 c_parser_consume_token (parser);
11117 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11118 objc_declare_alias (id1, id2);
11121 /* Parse an objc-protocol-definition.
11123 objc-protocol-definition:
11124 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11125 @protocol identifier-list ;
11127 "@protocol identifier ;" should be resolved as "@protocol
11128 identifier-list ;": objc-methodprotolist may not start with a
11129 semicolon in the first alternative if objc-protocol-refs are
11130 omitted. */
11132 static void
11133 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11135 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11137 c_parser_consume_token (parser);
11138 if (c_parser_next_token_is_not (parser, CPP_NAME))
11140 c_parser_error (parser, "expected identifier");
11141 return;
11143 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11144 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11146 /* Any identifiers, including those declared as type names, are
11147 OK here. */
11148 while (true)
11150 tree id;
11151 if (c_parser_next_token_is_not (parser, CPP_NAME))
11153 c_parser_error (parser, "expected identifier");
11154 break;
11156 id = c_parser_peek_token (parser)->value;
11157 objc_declare_protocol (id, attributes);
11158 c_parser_consume_token (parser);
11159 if (c_parser_next_token_is (parser, CPP_COMMA))
11160 c_parser_consume_token (parser);
11161 else
11162 break;
11164 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11166 else
11168 tree id = c_parser_peek_token (parser)->value;
11169 tree proto = NULL_TREE;
11170 c_parser_consume_token (parser);
11171 if (c_parser_next_token_is (parser, CPP_LESS))
11172 proto = c_parser_objc_protocol_refs (parser);
11173 parser->objc_pq_context = true;
11174 objc_start_protocol (id, proto, attributes);
11175 c_parser_objc_methodprotolist (parser);
11176 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11177 parser->objc_pq_context = false;
11178 objc_finish_interface ();
11182 /* Parse an objc-method-type.
11184 objc-method-type:
11188 Return true if it is a class method (+) and false if it is
11189 an instance method (-).
11191 static inline bool
11192 c_parser_objc_method_type (c_parser *parser)
11194 switch (c_parser_peek_token (parser)->type)
11196 case CPP_PLUS:
11197 c_parser_consume_token (parser);
11198 return true;
11199 case CPP_MINUS:
11200 c_parser_consume_token (parser);
11201 return false;
11202 default:
11203 gcc_unreachable ();
11207 /* Parse an objc-method-definition.
11209 objc-method-definition:
11210 objc-method-type objc-method-decl ;[opt] compound-statement
11213 static void
11214 c_parser_objc_method_definition (c_parser *parser)
11216 bool is_class_method = c_parser_objc_method_type (parser);
11217 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11218 parser->objc_pq_context = true;
11219 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11220 &expr);
11221 if (decl == error_mark_node)
11222 return; /* Bail here. */
11224 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11226 c_parser_consume_token (parser);
11227 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11228 "extra semicolon in method definition specified");
11231 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11233 c_parser_error (parser, "expected %<{%>");
11234 return;
11237 parser->objc_pq_context = false;
11238 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11240 add_stmt (c_parser_compound_statement (parser));
11241 objc_finish_method_definition (current_function_decl);
11243 else
11245 /* This code is executed when we find a method definition
11246 outside of an @implementation context (or invalid for other
11247 reasons). Parse the method (to keep going) but do not emit
11248 any code.
11250 c_parser_compound_statement (parser);
11254 /* Parse an objc-methodprotolist.
11256 objc-methodprotolist:
11257 empty
11258 objc-methodprotolist objc-methodproto
11259 objc-methodprotolist declaration
11260 objc-methodprotolist ;
11261 @optional
11262 @required
11264 The declaration is a data definition, which may be missing
11265 declaration specifiers under the same rules and diagnostics as
11266 other data definitions outside functions, and the stray semicolon
11267 is diagnosed the same way as a stray semicolon outside a
11268 function. */
11270 static void
11271 c_parser_objc_methodprotolist (c_parser *parser)
11273 while (true)
11275 /* The list is terminated by @end. */
11276 switch (c_parser_peek_token (parser)->type)
11278 case CPP_SEMICOLON:
11279 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11280 "ISO C does not allow extra %<;%> outside of a function");
11281 c_parser_consume_token (parser);
11282 break;
11283 case CPP_PLUS:
11284 case CPP_MINUS:
11285 c_parser_objc_methodproto (parser);
11286 break;
11287 case CPP_PRAGMA:
11288 c_parser_pragma (parser, pragma_external, NULL);
11289 break;
11290 case CPP_EOF:
11291 return;
11292 default:
11293 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11294 return;
11295 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11296 c_parser_objc_at_property_declaration (parser);
11297 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11299 objc_set_method_opt (true);
11300 c_parser_consume_token (parser);
11302 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11304 objc_set_method_opt (false);
11305 c_parser_consume_token (parser);
11307 else
11308 c_parser_declaration_or_fndef (parser, false, false, true,
11309 false, true, NULL, vNULL);
11310 break;
11315 /* Parse an objc-methodproto.
11317 objc-methodproto:
11318 objc-method-type objc-method-decl ;
11321 static void
11322 c_parser_objc_methodproto (c_parser *parser)
11324 bool is_class_method = c_parser_objc_method_type (parser);
11325 tree decl, attributes = NULL_TREE;
11327 /* Remember protocol qualifiers in prototypes. */
11328 parser->objc_pq_context = true;
11329 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11330 NULL);
11331 /* Forget protocol qualifiers now. */
11332 parser->objc_pq_context = false;
11334 /* Do not allow the presence of attributes to hide an erroneous
11335 method implementation in the interface section. */
11336 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11338 c_parser_error (parser, "expected %<;%>");
11339 return;
11342 if (decl != error_mark_node)
11343 objc_add_method_declaration (is_class_method, decl, attributes);
11345 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11348 /* If we are at a position that method attributes may be present, check that
11349 there are not any parsed already (a syntax error) and then collect any
11350 specified at the current location. Finally, if new attributes were present,
11351 check that the next token is legal ( ';' for decls and '{' for defs). */
11353 static bool
11354 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11356 bool bad = false;
11357 if (*attributes)
11359 c_parser_error (parser,
11360 "method attributes must be specified at the end only");
11361 *attributes = NULL_TREE;
11362 bad = true;
11365 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11366 *attributes = c_parser_gnu_attributes (parser);
11368 /* If there were no attributes here, just report any earlier error. */
11369 if (*attributes == NULL_TREE || bad)
11370 return bad;
11372 /* If the attributes are followed by a ; or {, then just report any earlier
11373 error. */
11374 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11375 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11376 return bad;
11378 /* We've got attributes, but not at the end. */
11379 c_parser_error (parser,
11380 "expected %<;%> or %<{%> after method attribute definition");
11381 return true;
11384 /* Parse an objc-method-decl.
11386 objc-method-decl:
11387 ( objc-type-name ) objc-selector
11388 objc-selector
11389 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11390 objc-keyword-selector objc-optparmlist
11391 gnu-attributes
11393 objc-keyword-selector:
11394 objc-keyword-decl
11395 objc-keyword-selector objc-keyword-decl
11397 objc-keyword-decl:
11398 objc-selector : ( objc-type-name ) identifier
11399 objc-selector : identifier
11400 : ( objc-type-name ) identifier
11401 : identifier
11403 objc-optparmlist:
11404 objc-optparms objc-optellipsis
11406 objc-optparms:
11407 empty
11408 objc-opt-parms , parameter-declaration
11410 objc-optellipsis:
11411 empty
11412 , ...
11415 static tree
11416 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11417 tree *attributes, tree *expr)
11419 tree type = NULL_TREE;
11420 tree sel;
11421 tree parms = NULL_TREE;
11422 bool ellipsis = false;
11423 bool attr_err = false;
11425 *attributes = NULL_TREE;
11426 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11428 matching_parens parens;
11429 parens.consume_open (parser);
11430 type = c_parser_objc_type_name (parser);
11431 parens.skip_until_found_close (parser);
11433 sel = c_parser_objc_selector (parser);
11434 /* If there is no selector, or a colon follows, we have an
11435 objc-keyword-selector. If there is a selector, and a colon does
11436 not follow, that selector ends the objc-method-decl. */
11437 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11439 tree tsel = sel;
11440 tree list = NULL_TREE;
11441 while (true)
11443 tree atype = NULL_TREE, id, keyworddecl;
11444 tree param_attr = NULL_TREE;
11445 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11446 break;
11447 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11449 c_parser_consume_token (parser);
11450 atype = c_parser_objc_type_name (parser);
11451 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11452 "expected %<)%>");
11454 /* New ObjC allows attributes on method parameters. */
11455 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11456 param_attr = c_parser_gnu_attributes (parser);
11457 if (c_parser_next_token_is_not (parser, CPP_NAME))
11459 c_parser_error (parser, "expected identifier");
11460 return error_mark_node;
11462 id = c_parser_peek_token (parser)->value;
11463 c_parser_consume_token (parser);
11464 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11465 list = chainon (list, keyworddecl);
11466 tsel = c_parser_objc_selector (parser);
11467 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11468 break;
11471 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11473 /* Parse the optional parameter list. Optional Objective-C
11474 method parameters follow the C syntax, and may include '...'
11475 to denote a variable number of arguments. */
11476 parms = make_node (TREE_LIST);
11477 while (c_parser_next_token_is (parser, CPP_COMMA))
11479 struct c_parm *parm;
11480 c_parser_consume_token (parser);
11481 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11483 ellipsis = true;
11484 c_parser_consume_token (parser);
11485 attr_err |= c_parser_objc_maybe_method_attributes
11486 (parser, attributes) ;
11487 break;
11489 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11490 if (parm == NULL)
11491 break;
11492 parms = chainon (parms,
11493 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11495 sel = list;
11497 else
11498 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11500 if (sel == NULL)
11502 c_parser_error (parser, "objective-c method declaration is expected");
11503 return error_mark_node;
11506 if (attr_err)
11507 return error_mark_node;
11509 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11512 /* Parse an objc-type-name.
11514 objc-type-name:
11515 objc-type-qualifiers[opt] type-name
11516 objc-type-qualifiers[opt]
11518 objc-type-qualifiers:
11519 objc-type-qualifier
11520 objc-type-qualifiers objc-type-qualifier
11522 objc-type-qualifier: one of
11523 in out inout bycopy byref oneway
11526 static tree
11527 c_parser_objc_type_name (c_parser *parser)
11529 tree quals = NULL_TREE;
11530 struct c_type_name *type_name = NULL;
11531 tree type = NULL_TREE;
11532 while (true)
11534 c_token *token = c_parser_peek_token (parser);
11535 if (token->type == CPP_KEYWORD
11536 && (token->keyword == RID_IN
11537 || token->keyword == RID_OUT
11538 || token->keyword == RID_INOUT
11539 || token->keyword == RID_BYCOPY
11540 || token->keyword == RID_BYREF
11541 || token->keyword == RID_ONEWAY))
11543 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11544 c_parser_consume_token (parser);
11546 else
11547 break;
11549 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11550 type_name = c_parser_type_name (parser);
11551 if (type_name)
11552 type = groktypename (type_name, NULL, NULL);
11554 /* If the type is unknown, and error has already been produced and
11555 we need to recover from the error. In that case, use NULL_TREE
11556 for the type, as if no type had been specified; this will use the
11557 default type ('id') which is good for error recovery. */
11558 if (type == error_mark_node)
11559 type = NULL_TREE;
11561 return build_tree_list (quals, type);
11564 /* Parse objc-protocol-refs.
11566 objc-protocol-refs:
11567 < identifier-list >
11570 static tree
11571 c_parser_objc_protocol_refs (c_parser *parser)
11573 tree list = NULL_TREE;
11574 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11575 c_parser_consume_token (parser);
11576 /* Any identifiers, including those declared as type names, are OK
11577 here. */
11578 while (true)
11580 tree id;
11581 if (c_parser_next_token_is_not (parser, CPP_NAME))
11583 c_parser_error (parser, "expected identifier");
11584 break;
11586 id = c_parser_peek_token (parser)->value;
11587 list = chainon (list, build_tree_list (NULL_TREE, id));
11588 c_parser_consume_token (parser);
11589 if (c_parser_next_token_is (parser, CPP_COMMA))
11590 c_parser_consume_token (parser);
11591 else
11592 break;
11594 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11595 return list;
11598 /* Parse an objc-try-catch-finally-statement.
11600 objc-try-catch-finally-statement:
11601 @try compound-statement objc-catch-list[opt]
11602 @try compound-statement objc-catch-list[opt] @finally compound-statement
11604 objc-catch-list:
11605 @catch ( objc-catch-parameter-declaration ) compound-statement
11606 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11608 objc-catch-parameter-declaration:
11609 parameter-declaration
11610 '...'
11612 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11614 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11615 for C++. Keep them in sync. */
11617 static void
11618 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11620 location_t location;
11621 tree stmt;
11623 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11624 c_parser_consume_token (parser);
11625 location = c_parser_peek_token (parser)->location;
11626 objc_maybe_warn_exceptions (location);
11627 stmt = c_parser_compound_statement (parser);
11628 objc_begin_try_stmt (location, stmt);
11630 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11632 struct c_parm *parm;
11633 tree parameter_declaration = error_mark_node;
11634 bool seen_open_paren = false;
11636 c_parser_consume_token (parser);
11637 matching_parens parens;
11638 if (!parens.require_open (parser))
11639 seen_open_paren = true;
11640 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11642 /* We have "@catch (...)" (where the '...' are literally
11643 what is in the code). Skip the '...'.
11644 parameter_declaration is set to NULL_TREE, and
11645 objc_being_catch_clauses() knows that that means
11646 '...'. */
11647 c_parser_consume_token (parser);
11648 parameter_declaration = NULL_TREE;
11650 else
11652 /* We have "@catch (NSException *exception)" or something
11653 like that. Parse the parameter declaration. */
11654 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11655 if (parm == NULL)
11656 parameter_declaration = error_mark_node;
11657 else
11658 parameter_declaration = grokparm (parm, NULL);
11660 if (seen_open_paren)
11661 parens.require_close (parser);
11662 else
11664 /* If there was no open parenthesis, we are recovering from
11665 an error, and we are trying to figure out what mistake
11666 the user has made. */
11668 /* If there is an immediate closing parenthesis, the user
11669 probably forgot the opening one (ie, they typed "@catch
11670 NSException *e)". Parse the closing parenthesis and keep
11671 going. */
11672 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11673 c_parser_consume_token (parser);
11675 /* If these is no immediate closing parenthesis, the user
11676 probably doesn't know that parenthesis are required at
11677 all (ie, they typed "@catch NSException *e"). So, just
11678 forget about the closing parenthesis and keep going. */
11680 objc_begin_catch_clause (parameter_declaration);
11681 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11682 c_parser_compound_statement_nostart (parser);
11683 objc_finish_catch_clause ();
11685 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11687 c_parser_consume_token (parser);
11688 location = c_parser_peek_token (parser)->location;
11689 stmt = c_parser_compound_statement (parser);
11690 objc_build_finally_clause (location, stmt);
11692 objc_finish_try_stmt ();
11695 /* Parse an objc-synchronized-statement.
11697 objc-synchronized-statement:
11698 @synchronized ( expression ) compound-statement
11701 static void
11702 c_parser_objc_synchronized_statement (c_parser *parser)
11704 location_t loc;
11705 tree expr, stmt;
11706 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11707 c_parser_consume_token (parser);
11708 loc = c_parser_peek_token (parser)->location;
11709 objc_maybe_warn_exceptions (loc);
11710 matching_parens parens;
11711 if (parens.require_open (parser))
11713 struct c_expr ce = c_parser_expression (parser);
11714 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11715 expr = ce.value;
11716 expr = c_fully_fold (expr, false, NULL);
11717 parens.skip_until_found_close (parser);
11719 else
11720 expr = error_mark_node;
11721 stmt = c_parser_compound_statement (parser);
11722 objc_build_synchronized (loc, expr, stmt);
11725 /* Parse an objc-selector; return NULL_TREE without an error if the
11726 next token is not an objc-selector.
11728 objc-selector:
11729 identifier
11730 one of
11731 enum struct union if else while do for switch case default
11732 break continue return goto asm sizeof typeof __alignof
11733 unsigned long const short volatile signed restrict _Complex
11734 in out inout bycopy byref oneway int char float double void _Bool
11735 _Atomic
11737 ??? Why this selection of keywords but not, for example, storage
11738 class specifiers? */
11740 static tree
11741 c_parser_objc_selector (c_parser *parser)
11743 c_token *token = c_parser_peek_token (parser);
11744 tree value = token->value;
11745 if (token->type == CPP_NAME)
11747 c_parser_consume_token (parser);
11748 return value;
11750 if (token->type != CPP_KEYWORD)
11751 return NULL_TREE;
11752 switch (token->keyword)
11754 case RID_ENUM:
11755 case RID_STRUCT:
11756 case RID_UNION:
11757 case RID_IF:
11758 case RID_ELSE:
11759 case RID_WHILE:
11760 case RID_DO:
11761 case RID_FOR:
11762 case RID_SWITCH:
11763 case RID_CASE:
11764 case RID_DEFAULT:
11765 case RID_BREAK:
11766 case RID_CONTINUE:
11767 case RID_RETURN:
11768 case RID_GOTO:
11769 case RID_ASM:
11770 case RID_SIZEOF:
11771 case RID_TYPEOF:
11772 case RID_ALIGNOF:
11773 case RID_UNSIGNED:
11774 case RID_LONG:
11775 case RID_CONST:
11776 case RID_SHORT:
11777 case RID_VOLATILE:
11778 case RID_SIGNED:
11779 case RID_RESTRICT:
11780 case RID_COMPLEX:
11781 case RID_IN:
11782 case RID_OUT:
11783 case RID_INOUT:
11784 case RID_BYCOPY:
11785 case RID_BYREF:
11786 case RID_ONEWAY:
11787 case RID_INT:
11788 case RID_CHAR:
11789 case RID_FLOAT:
11790 case RID_DOUBLE:
11791 CASE_RID_FLOATN_NX:
11792 case RID_VOID:
11793 case RID_BOOL:
11794 case RID_ATOMIC:
11795 case RID_AUTO_TYPE:
11796 case RID_INT_N_0:
11797 case RID_INT_N_1:
11798 case RID_INT_N_2:
11799 case RID_INT_N_3:
11800 c_parser_consume_token (parser);
11801 return value;
11802 default:
11803 return NULL_TREE;
11807 /* Parse an objc-selector-arg.
11809 objc-selector-arg:
11810 objc-selector
11811 objc-keywordname-list
11813 objc-keywordname-list:
11814 objc-keywordname
11815 objc-keywordname-list objc-keywordname
11817 objc-keywordname:
11818 objc-selector :
11822 static tree
11823 c_parser_objc_selector_arg (c_parser *parser)
11825 tree sel = c_parser_objc_selector (parser);
11826 tree list = NULL_TREE;
11827 if (sel
11828 && c_parser_next_token_is_not (parser, CPP_COLON)
11829 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11830 return sel;
11831 while (true)
11833 if (c_parser_next_token_is (parser, CPP_SCOPE))
11835 c_parser_consume_token (parser);
11836 list = chainon (list, build_tree_list (sel, NULL_TREE));
11837 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11839 else
11841 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11842 return list;
11843 list = chainon (list, build_tree_list (sel, NULL_TREE));
11845 sel = c_parser_objc_selector (parser);
11846 if (!sel
11847 && c_parser_next_token_is_not (parser, CPP_COLON)
11848 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11849 break;
11851 return list;
11854 /* Parse an objc-receiver.
11856 objc-receiver:
11857 expression
11858 class-name
11859 type-name
11862 static tree
11863 c_parser_objc_receiver (c_parser *parser)
11865 location_t loc = c_parser_peek_token (parser)->location;
11867 if (c_parser_peek_token (parser)->type == CPP_NAME
11868 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11869 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11871 tree id = c_parser_peek_token (parser)->value;
11872 c_parser_consume_token (parser);
11873 return objc_get_class_reference (id);
11875 struct c_expr ce = c_parser_expression (parser);
11876 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11877 return c_fully_fold (ce.value, false, NULL);
11880 /* Parse objc-message-args.
11882 objc-message-args:
11883 objc-selector
11884 objc-keywordarg-list
11886 objc-keywordarg-list:
11887 objc-keywordarg
11888 objc-keywordarg-list objc-keywordarg
11890 objc-keywordarg:
11891 objc-selector : objc-keywordexpr
11892 : objc-keywordexpr
11895 static tree
11896 c_parser_objc_message_args (c_parser *parser)
11898 tree sel = c_parser_objc_selector (parser);
11899 tree list = NULL_TREE;
11900 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11901 return sel;
11902 while (true)
11904 tree keywordexpr;
11905 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11906 return error_mark_node;
11907 keywordexpr = c_parser_objc_keywordexpr (parser);
11908 list = chainon (list, build_tree_list (sel, keywordexpr));
11909 sel = c_parser_objc_selector (parser);
11910 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11911 break;
11913 return list;
11916 /* Parse an objc-keywordexpr.
11918 objc-keywordexpr:
11919 nonempty-expr-list
11922 static tree
11923 c_parser_objc_keywordexpr (c_parser *parser)
11925 tree ret;
11926 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11927 NULL, NULL, NULL, NULL);
11928 if (vec_safe_length (expr_list) == 1)
11930 /* Just return the expression, remove a level of
11931 indirection. */
11932 ret = (*expr_list)[0];
11934 else
11936 /* We have a comma expression, we will collapse later. */
11937 ret = build_tree_list_vec (expr_list);
11939 release_tree_vector (expr_list);
11940 return ret;
11943 /* A check, needed in several places, that ObjC interface, implementation or
11944 method definitions are not prefixed by incorrect items. */
11945 static bool
11946 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11947 struct c_declspecs *specs)
11949 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11950 || specs->typespec_kind != ctsk_none)
11952 c_parser_error (parser,
11953 "no type or storage class may be specified here,");
11954 c_parser_skip_to_end_of_block_or_statement (parser);
11955 return true;
11957 return false;
11960 /* Parse an Objective-C @property declaration. The syntax is:
11962 objc-property-declaration:
11963 '@property' objc-property-attributes[opt] struct-declaration ;
11965 objc-property-attributes:
11966 '(' objc-property-attribute-list ')'
11968 objc-property-attribute-list:
11969 objc-property-attribute
11970 objc-property-attribute-list, objc-property-attribute
11972 objc-property-attribute
11973 'getter' = identifier
11974 'setter' = identifier
11975 'readonly'
11976 'readwrite'
11977 'assign'
11978 'retain'
11979 'copy'
11980 'nonatomic'
11982 For example:
11983 @property NSString *name;
11984 @property (readonly) id object;
11985 @property (retain, nonatomic, getter=getTheName) id name;
11986 @property int a, b, c;
11988 PS: This function is identical to cp_parser_objc_at_propery_declaration
11989 for C++. Keep them in sync. */
11990 static void
11991 c_parser_objc_at_property_declaration (c_parser *parser)
11993 /* The following variables hold the attributes of the properties as
11994 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
11995 seen. When we see an attribute, we set them to 'true' (if they
11996 are boolean properties) or to the identifier (if they have an
11997 argument, ie, for getter and setter). Note that here we only
11998 parse the list of attributes, check the syntax and accumulate the
11999 attributes that we find. objc_add_property_declaration() will
12000 then process the information. */
12001 bool property_assign = false;
12002 bool property_copy = false;
12003 tree property_getter_ident = NULL_TREE;
12004 bool property_nonatomic = false;
12005 bool property_readonly = false;
12006 bool property_readwrite = false;
12007 bool property_retain = false;
12008 tree property_setter_ident = NULL_TREE;
12010 /* 'properties' is the list of properties that we read. Usually a
12011 single one, but maybe more (eg, in "@property int a, b, c;" there
12012 are three). */
12013 tree properties;
12014 location_t loc;
12016 loc = c_parser_peek_token (parser)->location;
12017 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12019 c_parser_consume_token (parser); /* Eat '@property'. */
12021 /* Parse the optional attribute list... */
12022 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12024 matching_parens parens;
12026 /* Eat the '(' */
12027 parens.consume_open (parser);
12029 /* Property attribute keywords are valid now. */
12030 parser->objc_property_attr_context = true;
12032 while (true)
12034 bool syntax_error = false;
12035 c_token *token = c_parser_peek_token (parser);
12036 enum rid keyword;
12038 if (token->type != CPP_KEYWORD)
12040 if (token->type == CPP_CLOSE_PAREN)
12041 c_parser_error (parser, "expected identifier");
12042 else
12044 c_parser_consume_token (parser);
12045 c_parser_error (parser, "unknown property attribute");
12047 break;
12049 keyword = token->keyword;
12050 c_parser_consume_token (parser);
12051 switch (keyword)
12053 case RID_ASSIGN: property_assign = true; break;
12054 case RID_COPY: property_copy = true; break;
12055 case RID_NONATOMIC: property_nonatomic = true; break;
12056 case RID_READONLY: property_readonly = true; break;
12057 case RID_READWRITE: property_readwrite = true; break;
12058 case RID_RETAIN: property_retain = true; break;
12060 case RID_GETTER:
12061 case RID_SETTER:
12062 if (c_parser_next_token_is_not (parser, CPP_EQ))
12064 if (keyword == RID_GETTER)
12065 c_parser_error (parser,
12066 "missing %<=%> (after %<getter%> attribute)");
12067 else
12068 c_parser_error (parser,
12069 "missing %<=%> (after %<setter%> attribute)");
12070 syntax_error = true;
12071 break;
12073 c_parser_consume_token (parser); /* eat the = */
12074 if (c_parser_next_token_is_not (parser, CPP_NAME))
12076 c_parser_error (parser, "expected identifier");
12077 syntax_error = true;
12078 break;
12080 if (keyword == RID_SETTER)
12082 if (property_setter_ident != NULL_TREE)
12083 c_parser_error (parser, "the %<setter%> attribute may only be specified once");
12084 else
12085 property_setter_ident = c_parser_peek_token (parser)->value;
12086 c_parser_consume_token (parser);
12087 if (c_parser_next_token_is_not (parser, CPP_COLON))
12088 c_parser_error (parser, "setter name must terminate with %<:%>");
12089 else
12090 c_parser_consume_token (parser);
12092 else
12094 if (property_getter_ident != NULL_TREE)
12095 c_parser_error (parser, "the %<getter%> attribute may only be specified once");
12096 else
12097 property_getter_ident = c_parser_peek_token (parser)->value;
12098 c_parser_consume_token (parser);
12100 break;
12101 default:
12102 c_parser_error (parser, "unknown property attribute");
12103 syntax_error = true;
12104 break;
12107 if (syntax_error)
12108 break;
12110 if (c_parser_next_token_is (parser, CPP_COMMA))
12111 c_parser_consume_token (parser);
12112 else
12113 break;
12115 parser->objc_property_attr_context = false;
12116 parens.skip_until_found_close (parser);
12118 /* ... and the property declaration(s). */
12119 properties = c_parser_struct_declaration (parser);
12121 if (properties == error_mark_node)
12123 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12124 parser->error = false;
12125 return;
12128 if (properties == NULL_TREE)
12129 c_parser_error (parser, "expected identifier");
12130 else
12132 /* Comma-separated properties are chained together in
12133 reverse order; add them one by one. */
12134 properties = nreverse (properties);
12136 for (; properties; properties = TREE_CHAIN (properties))
12137 objc_add_property_declaration (loc, copy_node (properties),
12138 property_readonly, property_readwrite,
12139 property_assign, property_retain,
12140 property_copy, property_nonatomic,
12141 property_getter_ident, property_setter_ident);
12144 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12145 parser->error = false;
12148 /* Parse an Objective-C @synthesize declaration. The syntax is:
12150 objc-synthesize-declaration:
12151 @synthesize objc-synthesize-identifier-list ;
12153 objc-synthesize-identifier-list:
12154 objc-synthesize-identifier
12155 objc-synthesize-identifier-list, objc-synthesize-identifier
12157 objc-synthesize-identifier
12158 identifier
12159 identifier = identifier
12161 For example:
12162 @synthesize MyProperty;
12163 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12165 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12166 for C++. Keep them in sync.
12168 static void
12169 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12171 tree list = NULL_TREE;
12172 location_t loc;
12173 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12174 loc = c_parser_peek_token (parser)->location;
12176 c_parser_consume_token (parser);
12177 while (true)
12179 tree property, ivar;
12180 if (c_parser_next_token_is_not (parser, CPP_NAME))
12182 c_parser_error (parser, "expected identifier");
12183 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12184 /* Once we find the semicolon, we can resume normal parsing.
12185 We have to reset parser->error manually because
12186 c_parser_skip_until_found() won't reset it for us if the
12187 next token is precisely a semicolon. */
12188 parser->error = false;
12189 return;
12191 property = c_parser_peek_token (parser)->value;
12192 c_parser_consume_token (parser);
12193 if (c_parser_next_token_is (parser, CPP_EQ))
12195 c_parser_consume_token (parser);
12196 if (c_parser_next_token_is_not (parser, CPP_NAME))
12198 c_parser_error (parser, "expected identifier");
12199 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12200 parser->error = false;
12201 return;
12203 ivar = c_parser_peek_token (parser)->value;
12204 c_parser_consume_token (parser);
12206 else
12207 ivar = NULL_TREE;
12208 list = chainon (list, build_tree_list (ivar, property));
12209 if (c_parser_next_token_is (parser, CPP_COMMA))
12210 c_parser_consume_token (parser);
12211 else
12212 break;
12214 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12215 objc_add_synthesize_declaration (loc, list);
12218 /* Parse an Objective-C @dynamic declaration. The syntax is:
12220 objc-dynamic-declaration:
12221 @dynamic identifier-list ;
12223 For example:
12224 @dynamic MyProperty;
12225 @dynamic MyProperty, AnotherProperty;
12227 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12228 for C++. Keep them in sync.
12230 static void
12231 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12233 tree list = NULL_TREE;
12234 location_t loc;
12235 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12236 loc = c_parser_peek_token (parser)->location;
12238 c_parser_consume_token (parser);
12239 while (true)
12241 tree property;
12242 if (c_parser_next_token_is_not (parser, CPP_NAME))
12244 c_parser_error (parser, "expected identifier");
12245 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12246 parser->error = false;
12247 return;
12249 property = c_parser_peek_token (parser)->value;
12250 list = chainon (list, build_tree_list (NULL_TREE, property));
12251 c_parser_consume_token (parser);
12252 if (c_parser_next_token_is (parser, CPP_COMMA))
12253 c_parser_consume_token (parser);
12254 else
12255 break;
12257 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12258 objc_add_dynamic_declaration (loc, list);
12262 /* Parse a pragma GCC ivdep. */
12264 static bool
12265 c_parse_pragma_ivdep (c_parser *parser)
12267 c_parser_consume_pragma (parser);
12268 c_parser_skip_to_pragma_eol (parser);
12269 return true;
12272 /* Parse a pragma GCC unroll. */
12274 static unsigned short
12275 c_parser_pragma_unroll (c_parser *parser)
12277 unsigned short unroll;
12278 c_parser_consume_pragma (parser);
12279 location_t location = c_parser_peek_token (parser)->location;
12280 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12281 mark_exp_read (expr);
12282 expr = c_fully_fold (expr, false, NULL);
12283 HOST_WIDE_INT lunroll = 0;
12284 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12285 || TREE_CODE (expr) != INTEGER_CST
12286 || (lunroll = tree_to_shwi (expr)) < 0
12287 || lunroll >= USHRT_MAX)
12289 error_at (location, "%<#pragma GCC unroll%> requires an"
12290 " assignment-expression that evaluates to a non-negative"
12291 " integral constant less than %u", USHRT_MAX);
12292 unroll = 0;
12294 else
12296 unroll = (unsigned short)lunroll;
12297 if (unroll == 0)
12298 unroll = 1;
12301 c_parser_skip_to_pragma_eol (parser);
12302 return unroll;
12305 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12306 should be considered, statements. ALLOW_STMT is true if we're within
12307 the context of a function and such pragmas are to be allowed. Returns
12308 true if we actually parsed such a pragma. */
12310 static bool
12311 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12313 unsigned int id;
12314 const char *construct = NULL;
12316 id = c_parser_peek_token (parser)->pragma_kind;
12317 gcc_assert (id != PRAGMA_NONE);
12319 switch (id)
12321 case PRAGMA_OACC_DECLARE:
12322 c_parser_oacc_declare (parser);
12323 return false;
12325 case PRAGMA_OACC_ENTER_DATA:
12326 if (context != pragma_compound)
12328 construct = "acc enter data";
12329 in_compound:
12330 if (context == pragma_stmt)
12332 error_at (c_parser_peek_token (parser)->location,
12333 "%<#pragma %s%> may only be used in compound "
12334 "statements", construct);
12335 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12336 return false;
12338 goto bad_stmt;
12340 c_parser_oacc_enter_exit_data (parser, true);
12341 return false;
12343 case PRAGMA_OACC_EXIT_DATA:
12344 if (context != pragma_compound)
12346 construct = "acc exit data";
12347 goto in_compound;
12349 c_parser_oacc_enter_exit_data (parser, false);
12350 return false;
12352 case PRAGMA_OACC_ROUTINE:
12353 if (context != pragma_external)
12355 error_at (c_parser_peek_token (parser)->location,
12356 "%<#pragma acc routine%> must be at file scope");
12357 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12358 return false;
12360 c_parser_oacc_routine (parser, context);
12361 return false;
12363 case PRAGMA_OACC_UPDATE:
12364 if (context != pragma_compound)
12366 construct = "acc update";
12367 goto in_compound;
12369 c_parser_oacc_update (parser);
12370 return false;
12372 case PRAGMA_OMP_BARRIER:
12373 if (context != pragma_compound)
12375 construct = "omp barrier";
12376 goto in_compound;
12378 c_parser_omp_barrier (parser);
12379 return false;
12381 case PRAGMA_OMP_DEPOBJ:
12382 if (context != pragma_compound)
12384 construct = "omp depobj";
12385 goto in_compound;
12387 c_parser_omp_depobj (parser);
12388 return false;
12390 case PRAGMA_OMP_FLUSH:
12391 if (context != pragma_compound)
12393 construct = "omp flush";
12394 goto in_compound;
12396 c_parser_omp_flush (parser);
12397 return false;
12399 case PRAGMA_OMP_TASKWAIT:
12400 if (context != pragma_compound)
12402 construct = "omp taskwait";
12403 goto in_compound;
12405 c_parser_omp_taskwait (parser);
12406 return false;
12408 case PRAGMA_OMP_TASKYIELD:
12409 if (context != pragma_compound)
12411 construct = "omp taskyield";
12412 goto in_compound;
12414 c_parser_omp_taskyield (parser);
12415 return false;
12417 case PRAGMA_OMP_CANCEL:
12418 if (context != pragma_compound)
12420 construct = "omp cancel";
12421 goto in_compound;
12423 c_parser_omp_cancel (parser);
12424 return false;
12426 case PRAGMA_OMP_CANCELLATION_POINT:
12427 c_parser_omp_cancellation_point (parser, context);
12428 return false;
12430 case PRAGMA_OMP_THREADPRIVATE:
12431 c_parser_omp_threadprivate (parser);
12432 return false;
12434 case PRAGMA_OMP_TARGET:
12435 return c_parser_omp_target (parser, context, if_p);
12437 case PRAGMA_OMP_END_DECLARE_TARGET:
12438 c_parser_omp_end_declare_target (parser);
12439 return false;
12441 case PRAGMA_OMP_SCAN:
12442 error_at (c_parser_peek_token (parser)->location,
12443 "%<#pragma omp scan%> may only be used in "
12444 "a loop construct with %<inscan%> %<reduction%> clause");
12445 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12446 return false;
12448 case PRAGMA_OMP_SECTION:
12449 error_at (c_parser_peek_token (parser)->location,
12450 "%<#pragma omp section%> may only be used in "
12451 "%<#pragma omp sections%> construct");
12452 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12453 return false;
12455 case PRAGMA_OMP_DECLARE:
12456 c_parser_omp_declare (parser, context);
12457 return false;
12459 case PRAGMA_OMP_REQUIRES:
12460 if (context != pragma_external)
12462 error_at (c_parser_peek_token (parser)->location,
12463 "%<#pragma omp requires%> may only be used at file scope");
12464 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12465 return false;
12467 c_parser_omp_requires (parser);
12468 return false;
12470 case PRAGMA_OMP_ORDERED:
12471 return c_parser_omp_ordered (parser, context, if_p);
12473 case PRAGMA_IVDEP:
12475 const bool ivdep = c_parse_pragma_ivdep (parser);
12476 unsigned short unroll;
12477 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12478 unroll = c_parser_pragma_unroll (parser);
12479 else
12480 unroll = 0;
12481 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12482 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12483 && !c_parser_next_token_is_keyword (parser, RID_DO))
12485 c_parser_error (parser, "for, while or do statement expected");
12486 return false;
12488 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12489 c_parser_for_statement (parser, ivdep, unroll, if_p);
12490 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12491 c_parser_while_statement (parser, ivdep, unroll, if_p);
12492 else
12493 c_parser_do_statement (parser, ivdep, unroll);
12495 return false;
12497 case PRAGMA_UNROLL:
12499 unsigned short unroll = c_parser_pragma_unroll (parser);
12500 bool ivdep;
12501 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12502 ivdep = c_parse_pragma_ivdep (parser);
12503 else
12504 ivdep = false;
12505 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12506 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12507 && !c_parser_next_token_is_keyword (parser, RID_DO))
12509 c_parser_error (parser, "for, while or do statement expected");
12510 return false;
12512 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12513 c_parser_for_statement (parser, ivdep, unroll, if_p);
12514 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12515 c_parser_while_statement (parser, ivdep, unroll, if_p);
12516 else
12517 c_parser_do_statement (parser, ivdep, unroll);
12519 return false;
12521 case PRAGMA_GCC_PCH_PREPROCESS:
12522 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12523 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12524 return false;
12526 case PRAGMA_OACC_WAIT:
12527 if (context != pragma_compound)
12529 construct = "acc wait";
12530 goto in_compound;
12532 /* FALL THROUGH. */
12534 default:
12535 if (id < PRAGMA_FIRST_EXTERNAL)
12537 if (context != pragma_stmt && context != pragma_compound)
12539 bad_stmt:
12540 c_parser_error (parser, "expected declaration specifiers");
12541 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12542 return false;
12544 c_parser_omp_construct (parser, if_p);
12545 return true;
12547 break;
12550 c_parser_consume_pragma (parser);
12551 c_invoke_pragma_handler (id);
12553 /* Skip to EOL, but suppress any error message. Those will have been
12554 generated by the handler routine through calling error, as opposed
12555 to calling c_parser_error. */
12556 parser->error = true;
12557 c_parser_skip_to_pragma_eol (parser);
12559 return false;
12562 /* The interface the pragma parsers have to the lexer. */
12564 enum cpp_ttype
12565 pragma_lex (tree *value, location_t *loc)
12567 c_token *tok = c_parser_peek_token (the_parser);
12568 enum cpp_ttype ret = tok->type;
12570 *value = tok->value;
12571 if (loc)
12572 *loc = tok->location;
12574 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12575 ret = CPP_EOF;
12576 else if (ret == CPP_STRING)
12577 *value = c_parser_string_literal (the_parser, false, false).value;
12578 else
12580 if (ret == CPP_KEYWORD)
12581 ret = CPP_NAME;
12582 c_parser_consume_token (the_parser);
12585 return ret;
12588 static void
12589 c_parser_pragma_pch_preprocess (c_parser *parser)
12591 tree name = NULL;
12593 parser->lex_joined_string = true;
12594 c_parser_consume_pragma (parser);
12595 if (c_parser_next_token_is (parser, CPP_STRING))
12597 name = c_parser_peek_token (parser)->value;
12598 c_parser_consume_token (parser);
12600 else
12601 c_parser_error (parser, "expected string literal");
12602 c_parser_skip_to_pragma_eol (parser);
12603 parser->lex_joined_string = false;
12605 if (name)
12606 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12609 /* OpenACC and OpenMP parsing routines. */
12611 /* Returns name of the next clause.
12612 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12613 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12614 returned and the token is consumed. */
12616 static pragma_omp_clause
12617 c_parser_omp_clause_name (c_parser *parser)
12619 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12621 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12622 result = PRAGMA_OACC_CLAUSE_AUTO;
12623 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12624 result = PRAGMA_OMP_CLAUSE_IF;
12625 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12626 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12627 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12628 result = PRAGMA_OMP_CLAUSE_FOR;
12629 else if (c_parser_next_token_is (parser, CPP_NAME))
12631 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12633 switch (p[0])
12635 case 'a':
12636 if (!strcmp ("aligned", p))
12637 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12638 else if (!strcmp ("async", p))
12639 result = PRAGMA_OACC_CLAUSE_ASYNC;
12640 else if (!strcmp ("attach", p))
12641 result = PRAGMA_OACC_CLAUSE_ATTACH;
12642 break;
12643 case 'b':
12644 if (!strcmp ("bind", p))
12645 result = PRAGMA_OMP_CLAUSE_BIND;
12646 break;
12647 case 'c':
12648 if (!strcmp ("collapse", p))
12649 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12650 else if (!strcmp ("copy", p))
12651 result = PRAGMA_OACC_CLAUSE_COPY;
12652 else if (!strcmp ("copyin", p))
12653 result = PRAGMA_OMP_CLAUSE_COPYIN;
12654 else if (!strcmp ("copyout", p))
12655 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12656 else if (!strcmp ("copyprivate", p))
12657 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12658 else if (!strcmp ("create", p))
12659 result = PRAGMA_OACC_CLAUSE_CREATE;
12660 break;
12661 case 'd':
12662 if (!strcmp ("defaultmap", p))
12663 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12664 else if (!strcmp ("delete", p))
12665 result = PRAGMA_OACC_CLAUSE_DELETE;
12666 else if (!strcmp ("depend", p))
12667 result = PRAGMA_OMP_CLAUSE_DEPEND;
12668 else if (!strcmp ("detach", p))
12669 result = PRAGMA_OACC_CLAUSE_DETACH;
12670 else if (!strcmp ("device", p))
12671 result = PRAGMA_OMP_CLAUSE_DEVICE;
12672 else if (!strcmp ("deviceptr", p))
12673 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12674 else if (!strcmp ("device_resident", p))
12675 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12676 else if (!strcmp ("device_type", p))
12677 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12678 else if (!strcmp ("dist_schedule", p))
12679 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12680 break;
12681 case 'f':
12682 if (!strcmp ("final", p))
12683 result = PRAGMA_OMP_CLAUSE_FINAL;
12684 else if (!strcmp ("finalize", p))
12685 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12686 else if (!strcmp ("firstprivate", p))
12687 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12688 else if (!strcmp ("from", p))
12689 result = PRAGMA_OMP_CLAUSE_FROM;
12690 break;
12691 case 'g':
12692 if (!strcmp ("gang", p))
12693 result = PRAGMA_OACC_CLAUSE_GANG;
12694 else if (!strcmp ("grainsize", p))
12695 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12696 break;
12697 case 'h':
12698 if (!strcmp ("hint", p))
12699 result = PRAGMA_OMP_CLAUSE_HINT;
12700 else if (!strcmp ("host", p))
12701 result = PRAGMA_OACC_CLAUSE_HOST;
12702 break;
12703 case 'i':
12704 if (!strcmp ("if_present", p))
12705 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12706 else if (!strcmp ("in_reduction", p))
12707 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12708 else if (!strcmp ("inbranch", p))
12709 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12710 else if (!strcmp ("independent", p))
12711 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12712 else if (!strcmp ("is_device_ptr", p))
12713 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12714 break;
12715 case 'l':
12716 if (!strcmp ("lastprivate", p))
12717 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12718 else if (!strcmp ("linear", p))
12719 result = PRAGMA_OMP_CLAUSE_LINEAR;
12720 else if (!strcmp ("link", p))
12721 result = PRAGMA_OMP_CLAUSE_LINK;
12722 break;
12723 case 'm':
12724 if (!strcmp ("map", p))
12725 result = PRAGMA_OMP_CLAUSE_MAP;
12726 else if (!strcmp ("mergeable", p))
12727 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12728 break;
12729 case 'n':
12730 if (!strcmp ("no_create", p))
12731 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12732 else if (!strcmp ("nogroup", p))
12733 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12734 else if (!strcmp ("nontemporal", p))
12735 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12736 else if (!strcmp ("notinbranch", p))
12737 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12738 else if (!strcmp ("nowait", p))
12739 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12740 else if (!strcmp ("num_gangs", p))
12741 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12742 else if (!strcmp ("num_tasks", p))
12743 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12744 else if (!strcmp ("num_teams", p))
12745 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12746 else if (!strcmp ("num_threads", p))
12747 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12748 else if (!strcmp ("num_workers", p))
12749 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12750 break;
12751 case 'o':
12752 if (!strcmp ("ordered", p))
12753 result = PRAGMA_OMP_CLAUSE_ORDERED;
12754 else if (!strcmp ("order", p))
12755 result = PRAGMA_OMP_CLAUSE_ORDER;
12756 break;
12757 case 'p':
12758 if (!strcmp ("parallel", p))
12759 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12760 else if (!strcmp ("present", p))
12761 result = PRAGMA_OACC_CLAUSE_PRESENT;
12762 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12763 clauses. */
12764 else if (!strcmp ("present_or_copy", p)
12765 || !strcmp ("pcopy", p))
12766 result = PRAGMA_OACC_CLAUSE_COPY;
12767 else if (!strcmp ("present_or_copyin", p)
12768 || !strcmp ("pcopyin", p))
12769 result = PRAGMA_OACC_CLAUSE_COPYIN;
12770 else if (!strcmp ("present_or_copyout", p)
12771 || !strcmp ("pcopyout", p))
12772 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12773 else if (!strcmp ("present_or_create", p)
12774 || !strcmp ("pcreate", p))
12775 result = PRAGMA_OACC_CLAUSE_CREATE;
12776 else if (!strcmp ("priority", p))
12777 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12778 else if (!strcmp ("private", p))
12779 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12780 else if (!strcmp ("proc_bind", p))
12781 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12782 break;
12783 case 'r':
12784 if (!strcmp ("reduction", p))
12785 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12786 break;
12787 case 's':
12788 if (!strcmp ("safelen", p))
12789 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12790 else if (!strcmp ("schedule", p))
12791 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12792 else if (!strcmp ("sections", p))
12793 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12794 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12795 result = PRAGMA_OACC_CLAUSE_HOST;
12796 else if (!strcmp ("seq", p))
12797 result = PRAGMA_OACC_CLAUSE_SEQ;
12798 else if (!strcmp ("shared", p))
12799 result = PRAGMA_OMP_CLAUSE_SHARED;
12800 else if (!strcmp ("simd", p))
12801 result = PRAGMA_OMP_CLAUSE_SIMD;
12802 else if (!strcmp ("simdlen", p))
12803 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12804 break;
12805 case 't':
12806 if (!strcmp ("task_reduction", p))
12807 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12808 else if (!strcmp ("taskgroup", p))
12809 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12810 else if (!strcmp ("thread_limit", p))
12811 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12812 else if (!strcmp ("threads", p))
12813 result = PRAGMA_OMP_CLAUSE_THREADS;
12814 else if (!strcmp ("tile", p))
12815 result = PRAGMA_OACC_CLAUSE_TILE;
12816 else if (!strcmp ("to", p))
12817 result = PRAGMA_OMP_CLAUSE_TO;
12818 break;
12819 case 'u':
12820 if (!strcmp ("uniform", p))
12821 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12822 else if (!strcmp ("untied", p))
12823 result = PRAGMA_OMP_CLAUSE_UNTIED;
12824 else if (!strcmp ("use_device", p))
12825 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12826 else if (!strcmp ("use_device_addr", p))
12827 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12828 else if (!strcmp ("use_device_ptr", p))
12829 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12830 break;
12831 case 'v':
12832 if (!strcmp ("vector", p))
12833 result = PRAGMA_OACC_CLAUSE_VECTOR;
12834 else if (!strcmp ("vector_length", p))
12835 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12836 break;
12837 case 'w':
12838 if (!strcmp ("wait", p))
12839 result = PRAGMA_OACC_CLAUSE_WAIT;
12840 else if (!strcmp ("worker", p))
12841 result = PRAGMA_OACC_CLAUSE_WORKER;
12842 break;
12846 if (result != PRAGMA_OMP_CLAUSE_NONE)
12847 c_parser_consume_token (parser);
12849 return result;
12852 /* Validate that a clause of the given type does not already exist. */
12854 static void
12855 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12856 const char *name)
12858 if (tree c = omp_find_clause (clauses, code))
12859 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12862 /* OpenACC 2.0
12863 Parse wait clause or wait directive parameters. */
12865 static tree
12866 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12868 vec<tree, va_gc> *args;
12869 tree t, args_tree;
12871 matching_parens parens;
12872 if (!parens.require_open (parser))
12873 return list;
12875 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12876 args_tree = build_tree_list_vec (args);
12878 for (t = args_tree; t; t = TREE_CHAIN (t))
12880 tree targ = TREE_VALUE (t);
12882 if (targ != error_mark_node)
12884 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12886 c_parser_error (parser, "expression must be integral");
12887 targ = error_mark_node;
12889 else
12891 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12893 OMP_CLAUSE_DECL (c) = targ;
12894 OMP_CLAUSE_CHAIN (c) = list;
12895 list = c;
12900 release_tree_vector (args);
12901 parens.require_close (parser);
12902 return list;
12905 /* OpenACC 2.0, OpenMP 2.5:
12906 variable-list:
12907 identifier
12908 variable-list , identifier
12910 If KIND is nonzero, create the appropriate node and install the
12911 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12912 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12914 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12915 return the list created.
12917 The optional ALLOW_DEREF argument is true if list items can use the deref
12918 (->) operator. */
12920 static tree
12921 c_parser_omp_variable_list (c_parser *parser,
12922 location_t clause_loc,
12923 enum omp_clause_code kind, tree list,
12924 bool allow_deref = false)
12926 auto_vec<c_token> tokens;
12927 unsigned int tokens_avail = 0;
12928 bool first = true;
12930 while (1)
12932 bool array_section_p = false;
12933 if (kind == OMP_CLAUSE_DEPEND)
12935 if (c_parser_next_token_is_not (parser, CPP_NAME)
12936 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
12938 struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
12939 if (expr.value != error_mark_node)
12941 tree u = build_omp_clause (clause_loc, kind);
12942 OMP_CLAUSE_DECL (u) = expr.value;
12943 OMP_CLAUSE_CHAIN (u) = list;
12944 list = u;
12947 if (c_parser_next_token_is_not (parser, CPP_COMMA))
12948 break;
12950 c_parser_consume_token (parser);
12951 first = false;
12952 continue;
12955 tokens.truncate (0);
12956 unsigned int nesting_depth = 0;
12957 while (1)
12959 c_token *token = c_parser_peek_token (parser);
12960 switch (token->type)
12962 case CPP_EOF:
12963 case CPP_PRAGMA_EOL:
12964 break;
12965 case CPP_OPEN_BRACE:
12966 case CPP_OPEN_PAREN:
12967 case CPP_OPEN_SQUARE:
12968 ++nesting_depth;
12969 goto add;
12970 case CPP_CLOSE_BRACE:
12971 case CPP_CLOSE_PAREN:
12972 case CPP_CLOSE_SQUARE:
12973 if (nesting_depth-- == 0)
12974 break;
12975 goto add;
12976 case CPP_COMMA:
12977 if (nesting_depth == 0)
12978 break;
12979 goto add;
12980 default:
12981 add:
12982 tokens.safe_push (*token);
12983 c_parser_consume_token (parser);
12984 continue;
12986 break;
12989 /* Make sure nothing tries to read past the end of the tokens. */
12990 c_token eof_token;
12991 memset (&eof_token, 0, sizeof (eof_token));
12992 eof_token.type = CPP_EOF;
12993 tokens.safe_push (eof_token);
12994 tokens.safe_push (eof_token);
12996 tokens_avail = parser->tokens_avail;
12997 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
12998 parser->tokens = tokens.address ();
12999 parser->tokens_avail = tokens.length ();
13002 tree t = NULL_TREE;
13004 if (c_parser_next_token_is (parser, CPP_NAME)
13005 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13007 t = lookup_name (c_parser_peek_token (parser)->value);
13009 if (t == NULL_TREE)
13011 undeclared_variable (c_parser_peek_token (parser)->location,
13012 c_parser_peek_token (parser)->value);
13013 t = error_mark_node;
13016 c_parser_consume_token (parser);
13018 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13019 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13020 || (c_parser_peek_token (parser)->keyword
13021 == RID_PRETTY_FUNCTION_NAME)
13022 || (c_parser_peek_token (parser)->keyword
13023 == RID_C99_FUNCTION_NAME)))
13024 t = c_parser_predefined_identifier (parser).value;
13025 else
13027 if (first)
13028 c_parser_error (parser, "expected identifier");
13029 break;
13032 if (t == error_mark_node)
13034 else if (kind != 0)
13036 switch (kind)
13038 case OMP_CLAUSE__CACHE_:
13039 /* The OpenACC cache directive explicitly only allows "array
13040 elements or subarrays". */
13041 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13043 c_parser_error (parser, "expected %<[%>");
13044 t = error_mark_node;
13045 break;
13047 /* FALLTHROUGH */
13048 case OMP_CLAUSE_MAP:
13049 case OMP_CLAUSE_FROM:
13050 case OMP_CLAUSE_TO:
13051 while (c_parser_next_token_is (parser, CPP_DOT)
13052 || (allow_deref
13053 && c_parser_next_token_is (parser, CPP_DEREF)))
13055 location_t op_loc = c_parser_peek_token (parser)->location;
13056 if (c_parser_next_token_is (parser, CPP_DEREF))
13057 t = build_simple_mem_ref (t);
13058 c_parser_consume_token (parser);
13059 if (!c_parser_next_token_is (parser, CPP_NAME))
13061 c_parser_error (parser, "expected identifier");
13062 t = error_mark_node;
13063 break;
13066 c_token *comp_tok = c_parser_peek_token (parser);
13067 tree ident = comp_tok->value;
13068 location_t comp_loc = comp_tok->location;
13069 c_parser_consume_token (parser);
13070 t = build_component_ref (op_loc, t, ident, comp_loc);
13072 /* FALLTHROUGH */
13073 case OMP_CLAUSE_DEPEND:
13074 case OMP_CLAUSE_REDUCTION:
13075 case OMP_CLAUSE_IN_REDUCTION:
13076 case OMP_CLAUSE_TASK_REDUCTION:
13077 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13079 tree low_bound = NULL_TREE, length = NULL_TREE;
13081 c_parser_consume_token (parser);
13082 if (!c_parser_next_token_is (parser, CPP_COLON))
13084 location_t expr_loc
13085 = c_parser_peek_token (parser)->location;
13086 c_expr expr = c_parser_expression (parser);
13087 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13088 false, true);
13089 low_bound = expr.value;
13091 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13092 length = integer_one_node;
13093 else
13095 /* Look for `:'. */
13096 if (!c_parser_require (parser, CPP_COLON,
13097 "expected %<:%>"))
13099 t = error_mark_node;
13100 break;
13102 array_section_p = true;
13103 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13105 location_t expr_loc
13106 = c_parser_peek_token (parser)->location;
13107 c_expr expr = c_parser_expression (parser);
13108 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13109 false, true);
13110 length = expr.value;
13113 /* Look for the closing `]'. */
13114 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13115 "expected %<]%>"))
13117 t = error_mark_node;
13118 break;
13121 t = tree_cons (low_bound, length, t);
13123 if (kind == OMP_CLAUSE_DEPEND
13124 && t != error_mark_node
13125 && parser->tokens_avail != 2)
13127 if (array_section_p)
13129 error_at (c_parser_peek_token (parser)->location,
13130 "expected %<)%> or %<,%>");
13131 t = error_mark_node;
13133 else
13135 parser->tokens = tokens.address ();
13136 parser->tokens_avail = tokens.length ();
13138 t = c_parser_expr_no_commas (parser, NULL).value;
13139 if (t != error_mark_node && parser->tokens_avail != 2)
13141 error_at (c_parser_peek_token (parser)->location,
13142 "expected %<)%> or %<,%>");
13143 t = error_mark_node;
13147 break;
13148 default:
13149 break;
13152 if (t != error_mark_node)
13154 tree u = build_omp_clause (clause_loc, kind);
13155 OMP_CLAUSE_DECL (u) = t;
13156 OMP_CLAUSE_CHAIN (u) = list;
13157 list = u;
13160 else
13161 list = tree_cons (t, NULL_TREE, list);
13163 if (kind == OMP_CLAUSE_DEPEND)
13165 parser->tokens = &parser->tokens_buf[0];
13166 parser->tokens_avail = tokens_avail;
13168 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13169 break;
13171 c_parser_consume_token (parser);
13172 first = false;
13175 return list;
13178 /* Similarly, but expect leading and trailing parenthesis. This is a very
13179 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13180 argument is true if list items can use the deref (->) operator. */
13182 static tree
13183 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13184 tree list, bool allow_deref = false)
13186 /* The clauses location. */
13187 location_t loc = c_parser_peek_token (parser)->location;
13189 matching_parens parens;
13190 if (parens.require_open (parser))
13192 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13193 parens.skip_until_found_close (parser);
13195 return list;
13198 /* OpenACC 2.0:
13199 copy ( variable-list )
13200 copyin ( variable-list )
13201 copyout ( variable-list )
13202 create ( variable-list )
13203 delete ( variable-list )
13204 present ( variable-list )
13206 OpenACC 2.6:
13207 no_create ( variable-list )
13208 attach ( variable-list )
13209 detach ( variable-list ) */
13211 static tree
13212 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13213 tree list)
13215 enum gomp_map_kind kind;
13216 switch (c_kind)
13218 case PRAGMA_OACC_CLAUSE_ATTACH:
13219 kind = GOMP_MAP_ATTACH;
13220 break;
13221 case PRAGMA_OACC_CLAUSE_COPY:
13222 kind = GOMP_MAP_TOFROM;
13223 break;
13224 case PRAGMA_OACC_CLAUSE_COPYIN:
13225 kind = GOMP_MAP_TO;
13226 break;
13227 case PRAGMA_OACC_CLAUSE_COPYOUT:
13228 kind = GOMP_MAP_FROM;
13229 break;
13230 case PRAGMA_OACC_CLAUSE_CREATE:
13231 kind = GOMP_MAP_ALLOC;
13232 break;
13233 case PRAGMA_OACC_CLAUSE_DELETE:
13234 kind = GOMP_MAP_RELEASE;
13235 break;
13236 case PRAGMA_OACC_CLAUSE_DETACH:
13237 kind = GOMP_MAP_DETACH;
13238 break;
13239 case PRAGMA_OACC_CLAUSE_DEVICE:
13240 kind = GOMP_MAP_FORCE_TO;
13241 break;
13242 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13243 kind = GOMP_MAP_DEVICE_RESIDENT;
13244 break;
13245 case PRAGMA_OACC_CLAUSE_HOST:
13246 kind = GOMP_MAP_FORCE_FROM;
13247 break;
13248 case PRAGMA_OACC_CLAUSE_LINK:
13249 kind = GOMP_MAP_LINK;
13250 break;
13251 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13252 kind = GOMP_MAP_IF_PRESENT;
13253 break;
13254 case PRAGMA_OACC_CLAUSE_PRESENT:
13255 kind = GOMP_MAP_FORCE_PRESENT;
13256 break;
13257 default:
13258 gcc_unreachable ();
13260 tree nl, c;
13261 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13263 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13264 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13266 return nl;
13269 /* OpenACC 2.0:
13270 deviceptr ( variable-list ) */
13272 static tree
13273 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13275 location_t loc = c_parser_peek_token (parser)->location;
13276 tree vars, t;
13278 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13279 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13280 variable-list must only allow for pointer variables. */
13281 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13282 for (t = vars; t && t; t = TREE_CHAIN (t))
13284 tree v = TREE_PURPOSE (t);
13286 /* FIXME diagnostics: Ideally we should keep individual
13287 locations for all the variables in the var list to make the
13288 following errors more precise. Perhaps
13289 c_parser_omp_var_list_parens() should construct a list of
13290 locations to go along with the var list. */
13292 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13293 error_at (loc, "%qD is not a variable", v);
13294 else if (TREE_TYPE (v) == error_mark_node)
13296 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13297 error_at (loc, "%qD is not a pointer variable", v);
13299 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13300 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13301 OMP_CLAUSE_DECL (u) = v;
13302 OMP_CLAUSE_CHAIN (u) = list;
13303 list = u;
13306 return list;
13309 /* OpenACC 2.0, OpenMP 3.0:
13310 collapse ( constant-expression ) */
13312 static tree
13313 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13315 tree c, num = error_mark_node;
13316 HOST_WIDE_INT n;
13317 location_t loc;
13319 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13320 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13322 loc = c_parser_peek_token (parser)->location;
13323 matching_parens parens;
13324 if (parens.require_open (parser))
13326 num = c_parser_expr_no_commas (parser, NULL).value;
13327 parens.skip_until_found_close (parser);
13329 if (num == error_mark_node)
13330 return list;
13331 mark_exp_read (num);
13332 num = c_fully_fold (num, false, NULL);
13333 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13334 || !tree_fits_shwi_p (num)
13335 || (n = tree_to_shwi (num)) <= 0
13336 || (int) n != n)
13338 error_at (loc,
13339 "collapse argument needs positive constant integer expression");
13340 return list;
13342 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13343 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13344 OMP_CLAUSE_CHAIN (c) = list;
13345 return c;
13348 /* OpenMP 2.5:
13349 copyin ( variable-list ) */
13351 static tree
13352 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13354 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13357 /* OpenMP 2.5:
13358 copyprivate ( variable-list ) */
13360 static tree
13361 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13363 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13366 /* OpenMP 2.5:
13367 default ( none | shared )
13369 OpenACC:
13370 default ( none | present ) */
13372 static tree
13373 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13375 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13376 location_t loc = c_parser_peek_token (parser)->location;
13377 tree c;
13379 matching_parens parens;
13380 if (!parens.require_open (parser))
13381 return list;
13382 if (c_parser_next_token_is (parser, CPP_NAME))
13384 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13386 switch (p[0])
13388 case 'n':
13389 if (strcmp ("none", p) != 0)
13390 goto invalid_kind;
13391 kind = OMP_CLAUSE_DEFAULT_NONE;
13392 break;
13394 case 'p':
13395 if (strcmp ("present", p) != 0 || !is_oacc)
13396 goto invalid_kind;
13397 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13398 break;
13400 case 's':
13401 if (strcmp ("shared", p) != 0 || is_oacc)
13402 goto invalid_kind;
13403 kind = OMP_CLAUSE_DEFAULT_SHARED;
13404 break;
13406 default:
13407 goto invalid_kind;
13410 c_parser_consume_token (parser);
13412 else
13414 invalid_kind:
13415 if (is_oacc)
13416 c_parser_error (parser, "expected %<none%> or %<present%>");
13417 else
13418 c_parser_error (parser, "expected %<none%> or %<shared%>");
13420 parens.skip_until_found_close (parser);
13422 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13423 return list;
13425 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13426 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13427 OMP_CLAUSE_CHAIN (c) = list;
13428 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13430 return c;
13433 /* OpenMP 2.5:
13434 firstprivate ( variable-list ) */
13436 static tree
13437 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13439 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13442 /* OpenMP 3.1:
13443 final ( expression ) */
13445 static tree
13446 c_parser_omp_clause_final (c_parser *parser, tree list)
13448 location_t loc = c_parser_peek_token (parser)->location;
13449 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13451 matching_parens parens;
13452 tree t, c;
13453 if (!parens.require_open (parser))
13454 t = error_mark_node;
13455 else
13457 location_t eloc = c_parser_peek_token (parser)->location;
13458 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13459 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13460 t = c_objc_common_truthvalue_conversion (eloc, t);
13461 t = c_fully_fold (t, false, NULL);
13462 parens.skip_until_found_close (parser);
13465 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13467 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13468 OMP_CLAUSE_FINAL_EXPR (c) = t;
13469 OMP_CLAUSE_CHAIN (c) = list;
13470 list = c;
13472 else
13473 c_parser_error (parser, "expected %<(%>");
13475 return list;
13478 /* OpenACC, OpenMP 2.5:
13479 if ( expression )
13481 OpenMP 4.5:
13482 if ( directive-name-modifier : expression )
13484 directive-name-modifier:
13485 parallel | task | taskloop | target data | target | target update
13486 | target enter data | target exit data
13488 OpenMP 5.0:
13489 directive-name-modifier:
13490 ... | simd | cancel */
13492 static tree
13493 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13495 location_t location = c_parser_peek_token (parser)->location;
13496 enum tree_code if_modifier = ERROR_MARK;
13498 matching_parens parens;
13499 if (!parens.require_open (parser))
13500 return list;
13502 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13504 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13505 int n = 2;
13506 if (strcmp (p, "cancel") == 0)
13507 if_modifier = VOID_CST;
13508 else if (strcmp (p, "parallel") == 0)
13509 if_modifier = OMP_PARALLEL;
13510 else if (strcmp (p, "simd") == 0)
13511 if_modifier = OMP_SIMD;
13512 else if (strcmp (p, "task") == 0)
13513 if_modifier = OMP_TASK;
13514 else if (strcmp (p, "taskloop") == 0)
13515 if_modifier = OMP_TASKLOOP;
13516 else if (strcmp (p, "target") == 0)
13518 if_modifier = OMP_TARGET;
13519 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13521 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13522 if (strcmp ("data", p) == 0)
13523 if_modifier = OMP_TARGET_DATA;
13524 else if (strcmp ("update", p) == 0)
13525 if_modifier = OMP_TARGET_UPDATE;
13526 else if (strcmp ("enter", p) == 0)
13527 if_modifier = OMP_TARGET_ENTER_DATA;
13528 else if (strcmp ("exit", p) == 0)
13529 if_modifier = OMP_TARGET_EXIT_DATA;
13530 if (if_modifier != OMP_TARGET)
13532 n = 3;
13533 c_parser_consume_token (parser);
13535 else
13537 location_t loc = c_parser_peek_2nd_token (parser)->location;
13538 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13539 "or %<exit%>");
13540 if_modifier = ERROR_MARK;
13542 if (if_modifier == OMP_TARGET_ENTER_DATA
13543 || if_modifier == OMP_TARGET_EXIT_DATA)
13545 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13547 p = IDENTIFIER_POINTER
13548 (c_parser_peek_2nd_token (parser)->value);
13549 if (strcmp ("data", p) == 0)
13550 n = 4;
13552 if (n == 4)
13553 c_parser_consume_token (parser);
13554 else
13556 location_t loc
13557 = c_parser_peek_2nd_token (parser)->location;
13558 error_at (loc, "expected %<data%>");
13559 if_modifier = ERROR_MARK;
13564 if (if_modifier != ERROR_MARK)
13566 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13568 c_parser_consume_token (parser);
13569 c_parser_consume_token (parser);
13571 else
13573 if (n > 2)
13575 location_t loc = c_parser_peek_2nd_token (parser)->location;
13576 error_at (loc, "expected %<:%>");
13578 if_modifier = ERROR_MARK;
13583 location_t loc = c_parser_peek_token (parser)->location;
13584 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13585 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13586 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13587 t = c_fully_fold (t, false, NULL);
13588 parens.skip_until_found_close (parser);
13590 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13591 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13593 if (if_modifier != ERROR_MARK
13594 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13596 const char *p = NULL;
13597 switch (if_modifier)
13599 case VOID_CST: p = "cancel"; break;
13600 case OMP_PARALLEL: p = "parallel"; break;
13601 case OMP_SIMD: p = "simd"; break;
13602 case OMP_TASK: p = "task"; break;
13603 case OMP_TASKLOOP: p = "taskloop"; break;
13604 case OMP_TARGET_DATA: p = "target data"; break;
13605 case OMP_TARGET: p = "target"; break;
13606 case OMP_TARGET_UPDATE: p = "target update"; break;
13607 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13608 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13609 default: gcc_unreachable ();
13611 error_at (location, "too many %<if%> clauses with %qs modifier",
13613 return list;
13615 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13617 if (!is_omp)
13618 error_at (location, "too many %<if%> clauses");
13619 else
13620 error_at (location, "too many %<if%> clauses without modifier");
13621 return list;
13623 else if (if_modifier == ERROR_MARK
13624 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13626 error_at (location, "if any %<if%> clause has modifier, then all "
13627 "%<if%> clauses have to use modifier");
13628 return list;
13632 c = build_omp_clause (location, OMP_CLAUSE_IF);
13633 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13634 OMP_CLAUSE_IF_EXPR (c) = t;
13635 OMP_CLAUSE_CHAIN (c) = list;
13636 return c;
13639 /* OpenMP 2.5:
13640 lastprivate ( variable-list )
13642 OpenMP 5.0:
13643 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13645 static tree
13646 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13648 /* The clauses location. */
13649 location_t loc = c_parser_peek_token (parser)->location;
13651 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13653 bool conditional = false;
13654 if (c_parser_next_token_is (parser, CPP_NAME)
13655 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13657 const char *p
13658 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13659 if (strcmp (p, "conditional") == 0)
13661 conditional = true;
13662 c_parser_consume_token (parser);
13663 c_parser_consume_token (parser);
13666 tree nlist = c_parser_omp_variable_list (parser, loc,
13667 OMP_CLAUSE_LASTPRIVATE, list);
13668 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13669 if (conditional)
13670 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13671 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13672 return nlist;
13674 return list;
13677 /* OpenMP 3.1:
13678 mergeable */
13680 static tree
13681 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13683 tree c;
13685 /* FIXME: Should we allow duplicates? */
13686 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13688 c = build_omp_clause (c_parser_peek_token (parser)->location,
13689 OMP_CLAUSE_MERGEABLE);
13690 OMP_CLAUSE_CHAIN (c) = list;
13692 return c;
13695 /* OpenMP 2.5:
13696 nowait */
13698 static tree
13699 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13701 tree c;
13702 location_t loc = c_parser_peek_token (parser)->location;
13704 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13706 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13707 OMP_CLAUSE_CHAIN (c) = list;
13708 return c;
13711 /* OpenMP 2.5:
13712 num_threads ( expression ) */
13714 static tree
13715 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13717 location_t num_threads_loc = c_parser_peek_token (parser)->location;
13718 matching_parens parens;
13719 if (parens.require_open (parser))
13721 location_t expr_loc = c_parser_peek_token (parser)->location;
13722 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13723 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13724 tree c, t = expr.value;
13725 t = c_fully_fold (t, false, NULL);
13727 parens.skip_until_found_close (parser);
13729 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13731 c_parser_error (parser, "expected integer expression");
13732 return list;
13735 /* Attempt to statically determine when the number isn't positive. */
13736 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13737 build_int_cst (TREE_TYPE (t), 0));
13738 protected_set_expr_location (c, expr_loc);
13739 if (c == boolean_true_node)
13741 warning_at (expr_loc, 0,
13742 "%<num_threads%> value must be positive");
13743 t = integer_one_node;
13746 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13748 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13749 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13750 OMP_CLAUSE_CHAIN (c) = list;
13751 list = c;
13754 return list;
13757 /* OpenMP 4.5:
13758 num_tasks ( expression ) */
13760 static tree
13761 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13763 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13764 matching_parens parens;
13765 if (parens.require_open (parser))
13767 location_t expr_loc = c_parser_peek_token (parser)->location;
13768 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13769 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13770 tree c, t = expr.value;
13771 t = c_fully_fold (t, false, NULL);
13773 parens.skip_until_found_close (parser);
13775 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13777 c_parser_error (parser, "expected integer expression");
13778 return list;
13781 /* Attempt to statically determine when the number isn't positive. */
13782 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13783 build_int_cst (TREE_TYPE (t), 0));
13784 if (CAN_HAVE_LOCATION_P (c))
13785 SET_EXPR_LOCATION (c, expr_loc);
13786 if (c == boolean_true_node)
13788 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13789 t = integer_one_node;
13792 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13794 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13795 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13796 OMP_CLAUSE_CHAIN (c) = list;
13797 list = c;
13800 return list;
13803 /* OpenMP 4.5:
13804 grainsize ( expression ) */
13806 static tree
13807 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13809 location_t grainsize_loc = c_parser_peek_token (parser)->location;
13810 matching_parens parens;
13811 if (parens.require_open (parser))
13813 location_t expr_loc = c_parser_peek_token (parser)->location;
13814 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13815 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13816 tree c, t = expr.value;
13817 t = c_fully_fold (t, false, NULL);
13819 parens.skip_until_found_close (parser);
13821 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13823 c_parser_error (parser, "expected integer expression");
13824 return list;
13827 /* Attempt to statically determine when the number isn't positive. */
13828 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13829 build_int_cst (TREE_TYPE (t), 0));
13830 if (CAN_HAVE_LOCATION_P (c))
13831 SET_EXPR_LOCATION (c, expr_loc);
13832 if (c == boolean_true_node)
13834 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
13835 t = integer_one_node;
13838 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
13840 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
13841 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
13842 OMP_CLAUSE_CHAIN (c) = list;
13843 list = c;
13846 return list;
13849 /* OpenMP 4.5:
13850 priority ( expression ) */
13852 static tree
13853 c_parser_omp_clause_priority (c_parser *parser, tree list)
13855 location_t priority_loc = c_parser_peek_token (parser)->location;
13856 matching_parens parens;
13857 if (parens.require_open (parser))
13859 location_t expr_loc = c_parser_peek_token (parser)->location;
13860 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13861 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13862 tree c, t = expr.value;
13863 t = c_fully_fold (t, false, NULL);
13865 parens.skip_until_found_close (parser);
13867 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13869 c_parser_error (parser, "expected integer expression");
13870 return list;
13873 /* Attempt to statically determine when the number isn't
13874 non-negative. */
13875 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
13876 build_int_cst (TREE_TYPE (t), 0));
13877 if (CAN_HAVE_LOCATION_P (c))
13878 SET_EXPR_LOCATION (c, expr_loc);
13879 if (c == boolean_true_node)
13881 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
13882 t = integer_one_node;
13885 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
13887 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
13888 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
13889 OMP_CLAUSE_CHAIN (c) = list;
13890 list = c;
13893 return list;
13896 /* OpenMP 4.5:
13897 hint ( expression ) */
13899 static tree
13900 c_parser_omp_clause_hint (c_parser *parser, tree list)
13902 location_t hint_loc = c_parser_peek_token (parser)->location;
13903 matching_parens parens;
13904 if (parens.require_open (parser))
13906 location_t expr_loc = c_parser_peek_token (parser)->location;
13907 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13908 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13909 tree c, t = expr.value;
13910 t = c_fully_fold (t, false, NULL);
13911 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
13912 || TREE_CODE (t) != INTEGER_CST
13913 || tree_int_cst_sgn (t) == -1)
13915 c_parser_error (parser, "expected constant integer expression "
13916 "with valid sync-hint value");
13917 return list;
13919 parens.skip_until_found_close (parser);
13920 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
13922 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
13923 OMP_CLAUSE_HINT_EXPR (c) = t;
13924 OMP_CLAUSE_CHAIN (c) = list;
13925 list = c;
13928 return list;
13931 /* OpenMP 4.5:
13932 defaultmap ( tofrom : scalar )
13934 OpenMP 5.0:
13935 defaultmap ( implicit-behavior [ : variable-category ] ) */
13937 static tree
13938 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
13940 location_t loc = c_parser_peek_token (parser)->location;
13941 tree c;
13942 const char *p;
13943 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13944 enum omp_clause_defaultmap_kind category
13945 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
13947 matching_parens parens;
13948 if (!parens.require_open (parser))
13949 return list;
13950 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
13951 p = "default";
13952 else if (!c_parser_next_token_is (parser, CPP_NAME))
13954 invalid_behavior:
13955 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
13956 "%<tofrom%>, %<firstprivate%>, %<none%> "
13957 "or %<default%>");
13958 goto out_err;
13960 else
13961 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13963 switch (p[0])
13965 case 'a':
13966 if (strcmp ("alloc", p) == 0)
13967 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
13968 else
13969 goto invalid_behavior;
13970 break;
13972 case 'd':
13973 if (strcmp ("default", p) == 0)
13974 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13975 else
13976 goto invalid_behavior;
13977 break;
13979 case 'f':
13980 if (strcmp ("firstprivate", p) == 0)
13981 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
13982 else if (strcmp ("from", p) == 0)
13983 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
13984 else
13985 goto invalid_behavior;
13986 break;
13988 case 'n':
13989 if (strcmp ("none", p) == 0)
13990 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
13991 else
13992 goto invalid_behavior;
13993 break;
13995 case 't':
13996 if (strcmp ("tofrom", p) == 0)
13997 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
13998 else if (strcmp ("to", p) == 0)
13999 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14000 else
14001 goto invalid_behavior;
14002 break;
14004 default:
14005 goto invalid_behavior;
14007 c_parser_consume_token (parser);
14009 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14011 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14012 goto out_err;
14013 if (!c_parser_next_token_is (parser, CPP_NAME))
14015 invalid_category:
14016 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14017 "%<pointer%>");
14018 goto out_err;
14020 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14021 switch (p[0])
14023 case 'a':
14024 if (strcmp ("aggregate", p) == 0)
14025 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14026 else
14027 goto invalid_category;
14028 break;
14030 case 'p':
14031 if (strcmp ("pointer", p) == 0)
14032 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14033 else
14034 goto invalid_category;
14035 break;
14037 case 's':
14038 if (strcmp ("scalar", p) == 0)
14039 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14040 else
14041 goto invalid_category;
14042 break;
14044 default:
14045 goto invalid_category;
14048 c_parser_consume_token (parser);
14050 parens.skip_until_found_close (parser);
14052 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14053 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14054 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14055 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14056 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14057 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14059 enum omp_clause_defaultmap_kind cat = category;
14060 location_t loc = OMP_CLAUSE_LOCATION (c);
14061 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14062 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14063 p = NULL;
14064 switch (cat)
14066 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14067 p = NULL;
14068 break;
14069 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14070 p = "aggregate";
14071 break;
14072 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14073 p = "pointer";
14074 break;
14075 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14076 p = "scalar";
14077 break;
14078 default:
14079 gcc_unreachable ();
14081 if (p)
14082 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14084 else
14085 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14086 "category");
14087 break;
14090 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14091 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14092 OMP_CLAUSE_CHAIN (c) = list;
14093 return c;
14095 out_err:
14096 parens.skip_until_found_close (parser);
14097 return list;
14100 /* OpenACC 2.0:
14101 use_device ( variable-list )
14103 OpenMP 4.5:
14104 use_device_ptr ( variable-list ) */
14106 static tree
14107 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14109 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14110 list);
14113 /* OpenMP 5.0:
14114 use_device_addr ( variable-list ) */
14116 static tree
14117 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14119 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14120 list);
14123 /* OpenMP 4.5:
14124 is_device_ptr ( variable-list ) */
14126 static tree
14127 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14129 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14132 /* OpenACC:
14133 num_gangs ( expression )
14134 num_workers ( expression )
14135 vector_length ( expression ) */
14137 static tree
14138 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14139 tree list)
14141 location_t loc = c_parser_peek_token (parser)->location;
14143 matching_parens parens;
14144 if (!parens.require_open (parser))
14145 return list;
14147 location_t expr_loc = c_parser_peek_token (parser)->location;
14148 c_expr expr = c_parser_expression (parser);
14149 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14150 tree c, t = expr.value;
14151 t = c_fully_fold (t, false, NULL);
14153 parens.skip_until_found_close (parser);
14155 if (t == error_mark_node)
14156 return list;
14157 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14159 error_at (expr_loc, "%qs expression must be integral",
14160 omp_clause_code_name[code]);
14161 return list;
14164 /* Attempt to statically determine when the number isn't positive. */
14165 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14166 build_int_cst (TREE_TYPE (t), 0));
14167 protected_set_expr_location (c, expr_loc);
14168 if (c == boolean_true_node)
14170 warning_at (expr_loc, 0,
14171 "%qs value must be positive",
14172 omp_clause_code_name[code]);
14173 t = integer_one_node;
14176 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14178 c = build_omp_clause (loc, code);
14179 OMP_CLAUSE_OPERAND (c, 0) = t;
14180 OMP_CLAUSE_CHAIN (c) = list;
14181 return c;
14184 /* OpenACC:
14186 gang [( gang-arg-list )]
14187 worker [( [num:] int-expr )]
14188 vector [( [length:] int-expr )]
14190 where gang-arg is one of:
14192 [num:] int-expr
14193 static: size-expr
14195 and size-expr may be:
14198 int-expr
14201 static tree
14202 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14203 omp_clause_code kind,
14204 const char *str, tree list)
14206 const char *id = "num";
14207 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14209 if (kind == OMP_CLAUSE_VECTOR)
14210 id = "length";
14212 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14214 c_parser_consume_token (parser);
14218 c_token *next = c_parser_peek_token (parser);
14219 int idx = 0;
14221 /* Gang static argument. */
14222 if (kind == OMP_CLAUSE_GANG
14223 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14225 c_parser_consume_token (parser);
14227 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14228 goto cleanup_error;
14230 idx = 1;
14231 if (ops[idx] != NULL_TREE)
14233 c_parser_error (parser, "too many %<static%> arguments");
14234 goto cleanup_error;
14237 /* Check for the '*' argument. */
14238 if (c_parser_next_token_is (parser, CPP_MULT)
14239 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14240 || c_parser_peek_2nd_token (parser)->type
14241 == CPP_CLOSE_PAREN))
14243 c_parser_consume_token (parser);
14244 ops[idx] = integer_minus_one_node;
14246 if (c_parser_next_token_is (parser, CPP_COMMA))
14248 c_parser_consume_token (parser);
14249 continue;
14251 else
14252 break;
14255 /* Worker num: argument and vector length: arguments. */
14256 else if (c_parser_next_token_is (parser, CPP_NAME)
14257 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14258 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14260 c_parser_consume_token (parser); /* id */
14261 c_parser_consume_token (parser); /* ':' */
14264 /* Now collect the actual argument. */
14265 if (ops[idx] != NULL_TREE)
14267 c_parser_error (parser, "unexpected argument");
14268 goto cleanup_error;
14271 location_t expr_loc = c_parser_peek_token (parser)->location;
14272 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14273 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14274 tree expr = cexpr.value;
14275 if (expr == error_mark_node)
14276 goto cleanup_error;
14278 expr = c_fully_fold (expr, false, NULL);
14280 /* Attempt to statically determine when the number isn't a
14281 positive integer. */
14283 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14285 c_parser_error (parser, "expected integer expression");
14286 return list;
14289 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14290 build_int_cst (TREE_TYPE (expr), 0));
14291 if (c == boolean_true_node)
14293 warning_at (loc, 0,
14294 "%qs value must be positive", str);
14295 expr = integer_one_node;
14298 ops[idx] = expr;
14300 if (kind == OMP_CLAUSE_GANG
14301 && c_parser_next_token_is (parser, CPP_COMMA))
14303 c_parser_consume_token (parser);
14304 continue;
14306 break;
14308 while (1);
14310 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14311 goto cleanup_error;
14314 check_no_duplicate_clause (list, kind, str);
14316 c = build_omp_clause (loc, kind);
14318 if (ops[1])
14319 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14321 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14322 OMP_CLAUSE_CHAIN (c) = list;
14324 return c;
14326 cleanup_error:
14327 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14328 return list;
14331 /* OpenACC 2.5:
14332 auto
14333 finalize
14334 independent
14335 nohost
14336 seq */
14338 static tree
14339 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14340 tree list)
14342 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14344 tree c = build_omp_clause (loc, code);
14345 OMP_CLAUSE_CHAIN (c) = list;
14347 return c;
14350 /* OpenACC:
14351 async [( int-expr )] */
14353 static tree
14354 c_parser_oacc_clause_async (c_parser *parser, tree list)
14356 tree c, t;
14357 location_t loc = c_parser_peek_token (parser)->location;
14359 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14361 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14363 c_parser_consume_token (parser);
14365 t = c_parser_expression (parser).value;
14366 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14367 c_parser_error (parser, "expected integer expression");
14368 else if (t == error_mark_node
14369 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14370 return list;
14372 else
14373 t = c_fully_fold (t, false, NULL);
14375 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14377 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14378 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14379 OMP_CLAUSE_CHAIN (c) = list;
14380 list = c;
14382 return list;
14385 /* OpenACC 2.0:
14386 tile ( size-expr-list ) */
14388 static tree
14389 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14391 tree c, expr = error_mark_node;
14392 location_t loc;
14393 tree tile = NULL_TREE;
14395 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14396 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14398 loc = c_parser_peek_token (parser)->location;
14399 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14400 return list;
14404 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14405 return list;
14407 if (c_parser_next_token_is (parser, CPP_MULT)
14408 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14409 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14411 c_parser_consume_token (parser);
14412 expr = integer_zero_node;
14414 else
14416 location_t expr_loc = c_parser_peek_token (parser)->location;
14417 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14418 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14419 expr = cexpr.value;
14421 if (expr == error_mark_node)
14423 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14424 "expected %<)%>");
14425 return list;
14428 expr = c_fully_fold (expr, false, NULL);
14430 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14431 || !tree_fits_shwi_p (expr)
14432 || tree_to_shwi (expr) <= 0)
14434 error_at (expr_loc, "%<tile%> argument needs positive"
14435 " integral constant");
14436 expr = integer_zero_node;
14440 tile = tree_cons (NULL_TREE, expr, tile);
14442 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14444 /* Consume the trailing ')'. */
14445 c_parser_consume_token (parser);
14447 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14448 tile = nreverse (tile);
14449 OMP_CLAUSE_TILE_LIST (c) = tile;
14450 OMP_CLAUSE_CHAIN (c) = list;
14451 return c;
14454 /* OpenACC:
14455 wait [( int-expr-list )] */
14457 static tree
14458 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14460 location_t clause_loc = c_parser_peek_token (parser)->location;
14462 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14463 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14464 else
14466 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14468 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14469 OMP_CLAUSE_CHAIN (c) = list;
14470 list = c;
14473 return list;
14477 /* OpenMP 5.0:
14478 order ( concurrent ) */
14480 static tree
14481 c_parser_omp_clause_order (c_parser *parser, tree list)
14483 location_t loc = c_parser_peek_token (parser)->location;
14484 tree c;
14485 const char *p;
14487 matching_parens parens;
14488 if (!parens.require_open (parser))
14489 return list;
14490 if (!c_parser_next_token_is (parser, CPP_NAME))
14492 c_parser_error (parser, "expected %<concurrent%>");
14493 goto out_err;
14495 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14496 if (strcmp (p, "concurrent") != 0)
14498 c_parser_error (parser, "expected %<concurrent%>");
14499 goto out_err;
14501 c_parser_consume_token (parser);
14502 parens.skip_until_found_close (parser);
14503 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14504 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14505 OMP_CLAUSE_CHAIN (c) = list;
14506 return c;
14508 out_err:
14509 parens.skip_until_found_close (parser);
14510 return list;
14514 /* OpenMP 5.0:
14515 bind ( teams | parallel | thread ) */
14517 static tree
14518 c_parser_omp_clause_bind (c_parser *parser, tree list)
14520 location_t loc = c_parser_peek_token (parser)->location;
14521 tree c;
14522 const char *p;
14523 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14525 matching_parens parens;
14526 if (!parens.require_open (parser))
14527 return list;
14528 if (!c_parser_next_token_is (parser, CPP_NAME))
14530 invalid:
14531 c_parser_error (parser,
14532 "expected %<teams%>, %<parallel%> or %<thread%>");
14533 parens.skip_until_found_close (parser);
14534 return list;
14536 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14537 if (strcmp (p, "teams") == 0)
14538 kind = OMP_CLAUSE_BIND_TEAMS;
14539 else if (strcmp (p, "parallel") == 0)
14540 kind = OMP_CLAUSE_BIND_PARALLEL;
14541 else if (strcmp (p, "thread") != 0)
14542 goto invalid;
14543 c_parser_consume_token (parser);
14544 parens.skip_until_found_close (parser);
14545 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14546 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14547 OMP_CLAUSE_BIND_KIND (c) = kind;
14548 OMP_CLAUSE_CHAIN (c) = list;
14549 return c;
14553 /* OpenMP 2.5:
14554 ordered
14556 OpenMP 4.5:
14557 ordered ( constant-expression ) */
14559 static tree
14560 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14562 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14564 tree c, num = NULL_TREE;
14565 HOST_WIDE_INT n;
14566 location_t loc = c_parser_peek_token (parser)->location;
14567 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14569 matching_parens parens;
14570 parens.consume_open (parser);
14571 num = c_parser_expr_no_commas (parser, NULL).value;
14572 parens.skip_until_found_close (parser);
14574 if (num == error_mark_node)
14575 return list;
14576 if (num)
14578 mark_exp_read (num);
14579 num = c_fully_fold (num, false, NULL);
14580 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14581 || !tree_fits_shwi_p (num)
14582 || (n = tree_to_shwi (num)) <= 0
14583 || (int) n != n)
14585 error_at (loc, "ordered argument needs positive "
14586 "constant integer expression");
14587 return list;
14590 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14591 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14592 OMP_CLAUSE_CHAIN (c) = list;
14593 return c;
14596 /* OpenMP 2.5:
14597 private ( variable-list ) */
14599 static tree
14600 c_parser_omp_clause_private (c_parser *parser, tree list)
14602 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14605 /* OpenMP 2.5:
14606 reduction ( reduction-operator : variable-list )
14608 reduction-operator:
14609 One of: + * - & ^ | && ||
14611 OpenMP 3.1:
14613 reduction-operator:
14614 One of: + * - & ^ | && || max min
14616 OpenMP 4.0:
14618 reduction-operator:
14619 One of: + * - & ^ | && ||
14620 identifier
14622 OpenMP 5.0:
14623 reduction ( reduction-modifier, reduction-operator : variable-list )
14624 in_reduction ( reduction-operator : variable-list )
14625 task_reduction ( reduction-operator : variable-list ) */
14627 static tree
14628 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14629 bool is_omp, tree list)
14631 location_t clause_loc = c_parser_peek_token (parser)->location;
14632 matching_parens parens;
14633 if (parens.require_open (parser))
14635 bool task = false;
14636 bool inscan = false;
14637 enum tree_code code = ERROR_MARK;
14638 tree reduc_id = NULL_TREE;
14640 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14642 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14643 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14645 c_parser_consume_token (parser);
14646 c_parser_consume_token (parser);
14648 else if (c_parser_next_token_is (parser, CPP_NAME)
14649 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14651 const char *p
14652 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14653 if (strcmp (p, "task") == 0)
14654 task = true;
14655 else if (strcmp (p, "inscan") == 0)
14656 inscan = true;
14657 if (task || inscan)
14659 c_parser_consume_token (parser);
14660 c_parser_consume_token (parser);
14665 switch (c_parser_peek_token (parser)->type)
14667 case CPP_PLUS:
14668 code = PLUS_EXPR;
14669 break;
14670 case CPP_MULT:
14671 code = MULT_EXPR;
14672 break;
14673 case CPP_MINUS:
14674 code = MINUS_EXPR;
14675 break;
14676 case CPP_AND:
14677 code = BIT_AND_EXPR;
14678 break;
14679 case CPP_XOR:
14680 code = BIT_XOR_EXPR;
14681 break;
14682 case CPP_OR:
14683 code = BIT_IOR_EXPR;
14684 break;
14685 case CPP_AND_AND:
14686 code = TRUTH_ANDIF_EXPR;
14687 break;
14688 case CPP_OR_OR:
14689 code = TRUTH_ORIF_EXPR;
14690 break;
14691 case CPP_NAME:
14693 const char *p
14694 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14695 if (strcmp (p, "min") == 0)
14697 code = MIN_EXPR;
14698 break;
14700 if (strcmp (p, "max") == 0)
14702 code = MAX_EXPR;
14703 break;
14705 reduc_id = c_parser_peek_token (parser)->value;
14706 break;
14708 default:
14709 c_parser_error (parser,
14710 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14711 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14712 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14713 return list;
14715 c_parser_consume_token (parser);
14716 reduc_id = c_omp_reduction_id (code, reduc_id);
14717 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14719 tree nl, c;
14721 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
14722 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14724 tree d = OMP_CLAUSE_DECL (c), type;
14725 if (TREE_CODE (d) != TREE_LIST)
14726 type = TREE_TYPE (d);
14727 else
14729 int cnt = 0;
14730 tree t;
14731 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
14732 cnt++;
14733 type = TREE_TYPE (t);
14734 while (cnt > 0)
14736 if (TREE_CODE (type) != POINTER_TYPE
14737 && TREE_CODE (type) != ARRAY_TYPE)
14738 break;
14739 type = TREE_TYPE (type);
14740 cnt--;
14743 while (TREE_CODE (type) == ARRAY_TYPE)
14744 type = TREE_TYPE (type);
14745 OMP_CLAUSE_REDUCTION_CODE (c) = code;
14746 if (task)
14747 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
14748 else if (inscan)
14749 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
14750 if (code == ERROR_MARK
14751 || !(INTEGRAL_TYPE_P (type)
14752 || TREE_CODE (type) == REAL_TYPE
14753 || TREE_CODE (type) == COMPLEX_TYPE))
14754 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
14755 = c_omp_reduction_lookup (reduc_id,
14756 TYPE_MAIN_VARIANT (type));
14759 list = nl;
14761 parens.skip_until_found_close (parser);
14763 return list;
14766 /* OpenMP 2.5:
14767 schedule ( schedule-kind )
14768 schedule ( schedule-kind , expression )
14770 schedule-kind:
14771 static | dynamic | guided | runtime | auto
14773 OpenMP 4.5:
14774 schedule ( schedule-modifier : schedule-kind )
14775 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14777 schedule-modifier:
14778 simd
14779 monotonic
14780 nonmonotonic */
14782 static tree
14783 c_parser_omp_clause_schedule (c_parser *parser, tree list)
14785 tree c, t;
14786 location_t loc = c_parser_peek_token (parser)->location;
14787 int modifiers = 0, nmodifiers = 0;
14789 matching_parens parens;
14790 if (!parens.require_open (parser))
14791 return list;
14793 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
14795 location_t comma = UNKNOWN_LOCATION;
14796 while (c_parser_next_token_is (parser, CPP_NAME))
14798 tree kind = c_parser_peek_token (parser)->value;
14799 const char *p = IDENTIFIER_POINTER (kind);
14800 if (strcmp ("simd", p) == 0)
14801 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
14802 else if (strcmp ("monotonic", p) == 0)
14803 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
14804 else if (strcmp ("nonmonotonic", p) == 0)
14805 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
14806 else
14807 break;
14808 comma = UNKNOWN_LOCATION;
14809 c_parser_consume_token (parser);
14810 if (nmodifiers++ == 0
14811 && c_parser_next_token_is (parser, CPP_COMMA))
14813 comma = c_parser_peek_token (parser)->location;
14814 c_parser_consume_token (parser);
14816 else
14818 c_parser_require (parser, CPP_COLON, "expected %<:%>");
14819 break;
14822 if (comma != UNKNOWN_LOCATION)
14823 error_at (comma, "expected %<:%>");
14825 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
14826 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14827 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14828 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14830 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14831 "specified");
14832 modifiers = 0;
14835 if (c_parser_next_token_is (parser, CPP_NAME))
14837 tree kind = c_parser_peek_token (parser)->value;
14838 const char *p = IDENTIFIER_POINTER (kind);
14840 switch (p[0])
14842 case 'd':
14843 if (strcmp ("dynamic", p) != 0)
14844 goto invalid_kind;
14845 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
14846 break;
14848 case 'g':
14849 if (strcmp ("guided", p) != 0)
14850 goto invalid_kind;
14851 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
14852 break;
14854 case 'r':
14855 if (strcmp ("runtime", p) != 0)
14856 goto invalid_kind;
14857 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
14858 break;
14860 default:
14861 goto invalid_kind;
14864 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
14865 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
14866 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14867 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
14868 else
14869 goto invalid_kind;
14871 c_parser_consume_token (parser);
14872 if (c_parser_next_token_is (parser, CPP_COMMA))
14874 location_t here;
14875 c_parser_consume_token (parser);
14877 here = c_parser_peek_token (parser)->location;
14878 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14879 expr = convert_lvalue_to_rvalue (here, expr, false, true);
14880 t = expr.value;
14881 t = c_fully_fold (t, false, NULL);
14883 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
14884 error_at (here, "schedule %<runtime%> does not take "
14885 "a %<chunk_size%> parameter");
14886 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
14887 error_at (here,
14888 "schedule %<auto%> does not take "
14889 "a %<chunk_size%> parameter");
14890 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
14892 /* Attempt to statically determine when the number isn't
14893 positive. */
14894 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
14895 build_int_cst (TREE_TYPE (t), 0));
14896 protected_set_expr_location (s, loc);
14897 if (s == boolean_true_node)
14899 warning_at (loc, 0,
14900 "chunk size value must be positive");
14901 t = integer_one_node;
14903 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
14905 else
14906 c_parser_error (parser, "expected integer expression");
14908 parens.skip_until_found_close (parser);
14910 else
14911 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14912 "expected %<,%> or %<)%>");
14914 OMP_CLAUSE_SCHEDULE_KIND (c)
14915 = (enum omp_clause_schedule_kind)
14916 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
14918 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
14919 OMP_CLAUSE_CHAIN (c) = list;
14920 return c;
14922 invalid_kind:
14923 c_parser_error (parser, "invalid schedule kind");
14924 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14925 return list;
14928 /* OpenMP 2.5:
14929 shared ( variable-list ) */
14931 static tree
14932 c_parser_omp_clause_shared (c_parser *parser, tree list)
14934 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
14937 /* OpenMP 3.0:
14938 untied */
14940 static tree
14941 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14943 tree c;
14945 /* FIXME: Should we allow duplicates? */
14946 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
14948 c = build_omp_clause (c_parser_peek_token (parser)->location,
14949 OMP_CLAUSE_UNTIED);
14950 OMP_CLAUSE_CHAIN (c) = list;
14952 return c;
14955 /* OpenMP 4.0:
14956 inbranch
14957 notinbranch */
14959 static tree
14960 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
14961 enum omp_clause_code code, tree list)
14963 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14965 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14966 OMP_CLAUSE_CHAIN (c) = list;
14968 return c;
14971 /* OpenMP 4.0:
14972 parallel
14974 sections
14975 taskgroup */
14977 static tree
14978 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
14979 enum omp_clause_code code, tree list)
14981 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14982 OMP_CLAUSE_CHAIN (c) = list;
14984 return c;
14987 /* OpenMP 4.5:
14988 nogroup */
14990 static tree
14991 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14993 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
14994 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
14995 OMP_CLAUSE_NOGROUP);
14996 OMP_CLAUSE_CHAIN (c) = list;
14997 return c;
15000 /* OpenMP 4.5:
15001 simd
15002 threads */
15004 static tree
15005 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15006 enum omp_clause_code code, tree list)
15008 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15009 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15010 OMP_CLAUSE_CHAIN (c) = list;
15011 return c;
15014 /* OpenMP 4.0:
15015 num_teams ( expression ) */
15017 static tree
15018 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15020 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15021 matching_parens parens;
15022 if (parens.require_open (parser))
15024 location_t expr_loc = c_parser_peek_token (parser)->location;
15025 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15026 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15027 tree c, t = expr.value;
15028 t = c_fully_fold (t, false, NULL);
15030 parens.skip_until_found_close (parser);
15032 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15034 c_parser_error (parser, "expected integer expression");
15035 return list;
15038 /* Attempt to statically determine when the number isn't positive. */
15039 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15040 build_int_cst (TREE_TYPE (t), 0));
15041 protected_set_expr_location (c, expr_loc);
15042 if (c == boolean_true_node)
15044 warning_at (expr_loc, 0, "%<num_teams%> value must be positive");
15045 t = integer_one_node;
15048 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15050 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15051 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
15052 OMP_CLAUSE_CHAIN (c) = list;
15053 list = c;
15056 return list;
15059 /* OpenMP 4.0:
15060 thread_limit ( expression ) */
15062 static tree
15063 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15065 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15066 matching_parens parens;
15067 if (parens.require_open (parser))
15069 location_t expr_loc = c_parser_peek_token (parser)->location;
15070 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15071 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15072 tree c, t = expr.value;
15073 t = c_fully_fold (t, false, NULL);
15075 parens.skip_until_found_close (parser);
15077 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15079 c_parser_error (parser, "expected integer expression");
15080 return list;
15083 /* Attempt to statically determine when the number isn't positive. */
15084 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15085 build_int_cst (TREE_TYPE (t), 0));
15086 protected_set_expr_location (c, expr_loc);
15087 if (c == boolean_true_node)
15089 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15090 t = integer_one_node;
15093 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15094 "thread_limit");
15096 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15097 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15098 OMP_CLAUSE_CHAIN (c) = list;
15099 list = c;
15102 return list;
15105 /* OpenMP 4.0:
15106 aligned ( variable-list )
15107 aligned ( variable-list : constant-expression ) */
15109 static tree
15110 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15112 location_t clause_loc = c_parser_peek_token (parser)->location;
15113 tree nl, c;
15115 matching_parens parens;
15116 if (!parens.require_open (parser))
15117 return list;
15119 nl = c_parser_omp_variable_list (parser, clause_loc,
15120 OMP_CLAUSE_ALIGNED, list);
15122 if (c_parser_next_token_is (parser, CPP_COLON))
15124 c_parser_consume_token (parser);
15125 location_t expr_loc = c_parser_peek_token (parser)->location;
15126 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15127 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15128 tree alignment = expr.value;
15129 alignment = c_fully_fold (alignment, false, NULL);
15130 if (TREE_CODE (alignment) != INTEGER_CST
15131 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15132 || tree_int_cst_sgn (alignment) != 1)
15134 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15135 "be positive constant integer expression");
15136 alignment = NULL_TREE;
15139 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15140 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15143 parens.skip_until_found_close (parser);
15144 return nl;
15147 /* OpenMP 4.0:
15148 linear ( variable-list )
15149 linear ( variable-list : expression )
15151 OpenMP 4.5:
15152 linear ( modifier ( variable-list ) )
15153 linear ( modifier ( variable-list ) : expression ) */
15155 static tree
15156 c_parser_omp_clause_linear (c_parser *parser, tree list)
15158 location_t clause_loc = c_parser_peek_token (parser)->location;
15159 tree nl, c, step;
15160 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15162 matching_parens parens;
15163 if (!parens.require_open (parser))
15164 return list;
15166 if (c_parser_next_token_is (parser, CPP_NAME))
15168 c_token *tok = c_parser_peek_token (parser);
15169 const char *p = IDENTIFIER_POINTER (tok->value);
15170 if (strcmp ("val", p) == 0)
15171 kind = OMP_CLAUSE_LINEAR_VAL;
15172 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15173 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15174 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15176 c_parser_consume_token (parser);
15177 c_parser_consume_token (parser);
15181 nl = c_parser_omp_variable_list (parser, clause_loc,
15182 OMP_CLAUSE_LINEAR, list);
15184 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15185 parens.skip_until_found_close (parser);
15187 if (c_parser_next_token_is (parser, CPP_COLON))
15189 c_parser_consume_token (parser);
15190 location_t expr_loc = c_parser_peek_token (parser)->location;
15191 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15192 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15193 step = expr.value;
15194 step = c_fully_fold (step, false, NULL);
15195 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15197 error_at (clause_loc, "%<linear%> clause step expression must "
15198 "be integral");
15199 step = integer_one_node;
15203 else
15204 step = integer_one_node;
15206 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15208 OMP_CLAUSE_LINEAR_STEP (c) = step;
15209 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15212 parens.skip_until_found_close (parser);
15213 return nl;
15216 /* OpenMP 5.0:
15217 nontemporal ( variable-list ) */
15219 static tree
15220 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15222 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15225 /* OpenMP 4.0:
15226 safelen ( constant-expression ) */
15228 static tree
15229 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15231 location_t clause_loc = c_parser_peek_token (parser)->location;
15232 tree c, t;
15234 matching_parens parens;
15235 if (!parens.require_open (parser))
15236 return list;
15238 location_t expr_loc = c_parser_peek_token (parser)->location;
15239 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15240 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15241 t = expr.value;
15242 t = c_fully_fold (t, false, NULL);
15243 if (TREE_CODE (t) != INTEGER_CST
15244 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15245 || tree_int_cst_sgn (t) != 1)
15247 error_at (clause_loc, "%<safelen%> clause expression must "
15248 "be positive constant integer expression");
15249 t = NULL_TREE;
15252 parens.skip_until_found_close (parser);
15253 if (t == NULL_TREE || t == error_mark_node)
15254 return list;
15256 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15258 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15259 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15260 OMP_CLAUSE_CHAIN (c) = list;
15261 return c;
15264 /* OpenMP 4.0:
15265 simdlen ( constant-expression ) */
15267 static tree
15268 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15270 location_t clause_loc = c_parser_peek_token (parser)->location;
15271 tree c, t;
15273 matching_parens parens;
15274 if (!parens.require_open (parser))
15275 return list;
15277 location_t expr_loc = c_parser_peek_token (parser)->location;
15278 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15279 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15280 t = expr.value;
15281 t = c_fully_fold (t, false, NULL);
15282 if (TREE_CODE (t) != INTEGER_CST
15283 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15284 || tree_int_cst_sgn (t) != 1)
15286 error_at (clause_loc, "%<simdlen%> clause expression must "
15287 "be positive constant integer expression");
15288 t = NULL_TREE;
15291 parens.skip_until_found_close (parser);
15292 if (t == NULL_TREE || t == error_mark_node)
15293 return list;
15295 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15297 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15298 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15299 OMP_CLAUSE_CHAIN (c) = list;
15300 return c;
15303 /* OpenMP 4.5:
15304 vec:
15305 identifier [+/- integer]
15306 vec , identifier [+/- integer]
15309 static tree
15310 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15311 tree list)
15313 tree vec = NULL;
15314 if (c_parser_next_token_is_not (parser, CPP_NAME)
15315 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15317 c_parser_error (parser, "expected identifier");
15318 return list;
15321 while (c_parser_next_token_is (parser, CPP_NAME)
15322 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15324 tree t = lookup_name (c_parser_peek_token (parser)->value);
15325 tree addend = NULL;
15327 if (t == NULL_TREE)
15329 undeclared_variable (c_parser_peek_token (parser)->location,
15330 c_parser_peek_token (parser)->value);
15331 t = error_mark_node;
15334 c_parser_consume_token (parser);
15336 bool neg = false;
15337 if (c_parser_next_token_is (parser, CPP_MINUS))
15338 neg = true;
15339 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15341 addend = integer_zero_node;
15342 neg = false;
15343 goto add_to_vector;
15345 c_parser_consume_token (parser);
15347 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15349 c_parser_error (parser, "expected integer");
15350 return list;
15353 addend = c_parser_peek_token (parser)->value;
15354 if (TREE_CODE (addend) != INTEGER_CST)
15356 c_parser_error (parser, "expected integer");
15357 return list;
15359 c_parser_consume_token (parser);
15361 add_to_vector:
15362 if (t != error_mark_node)
15364 vec = tree_cons (addend, t, vec);
15365 if (neg)
15366 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15369 if (c_parser_next_token_is_not (parser, CPP_COMMA))
15370 break;
15372 c_parser_consume_token (parser);
15375 if (vec == NULL_TREE)
15376 return list;
15378 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15379 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15380 OMP_CLAUSE_DECL (u) = nreverse (vec);
15381 OMP_CLAUSE_CHAIN (u) = list;
15382 return u;
15385 /* OpenMP 5.0:
15386 iterators ( iterators-definition )
15388 iterators-definition:
15389 iterator-specifier
15390 iterator-specifier , iterators-definition
15392 iterator-specifier:
15393 identifier = range-specification
15394 iterator-type identifier = range-specification
15396 range-specification:
15397 begin : end
15398 begin : end : step */
15400 static tree
15401 c_parser_omp_iterators (c_parser *parser)
15403 tree ret = NULL_TREE, *last = &ret;
15404 c_parser_consume_token (parser);
15406 push_scope ();
15408 matching_parens parens;
15409 if (!parens.require_open (parser))
15410 return error_mark_node;
15414 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
15415 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
15417 struct c_type_name *type = c_parser_type_name (parser);
15418 if (type != NULL)
15419 iter_type = groktypename (type, &type_expr, NULL);
15421 if (iter_type == NULL_TREE)
15422 iter_type = integer_type_node;
15424 location_t loc = c_parser_peek_token (parser)->location;
15425 if (!c_parser_next_token_is (parser, CPP_NAME))
15427 c_parser_error (parser, "expected identifier");
15428 break;
15431 tree id = c_parser_peek_token (parser)->value;
15432 c_parser_consume_token (parser);
15434 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15435 break;
15437 location_t eloc = c_parser_peek_token (parser)->location;
15438 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15439 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15440 tree begin = expr.value;
15442 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15443 break;
15445 eloc = c_parser_peek_token (parser)->location;
15446 expr = c_parser_expr_no_commas (parser, NULL);
15447 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15448 tree end = expr.value;
15450 tree step = integer_one_node;
15451 if (c_parser_next_token_is (parser, CPP_COLON))
15453 c_parser_consume_token (parser);
15454 eloc = c_parser_peek_token (parser)->location;
15455 expr = c_parser_expr_no_commas (parser, NULL);
15456 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15457 step = expr.value;
15460 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
15461 DECL_ARTIFICIAL (iter_var) = 1;
15462 DECL_CONTEXT (iter_var) = current_function_decl;
15463 pushdecl (iter_var);
15465 *last = make_tree_vec (6);
15466 TREE_VEC_ELT (*last, 0) = iter_var;
15467 TREE_VEC_ELT (*last, 1) = begin;
15468 TREE_VEC_ELT (*last, 2) = end;
15469 TREE_VEC_ELT (*last, 3) = step;
15470 last = &TREE_CHAIN (*last);
15472 if (c_parser_next_token_is (parser, CPP_COMMA))
15474 c_parser_consume_token (parser);
15475 continue;
15477 break;
15479 while (1);
15481 parens.skip_until_found_close (parser);
15482 return ret ? ret : error_mark_node;
15485 /* OpenMP 4.0:
15486 depend ( depend-kind: variable-list )
15488 depend-kind:
15489 in | out | inout
15491 OpenMP 4.5:
15492 depend ( source )
15494 depend ( sink : vec )
15496 OpenMP 5.0:
15497 depend ( depend-modifier , depend-kind: variable-list )
15499 depend-kind:
15500 in | out | inout | mutexinoutset | depobj
15502 depend-modifier:
15503 iterator ( iterators-definition ) */
15505 static tree
15506 c_parser_omp_clause_depend (c_parser *parser, tree list)
15508 location_t clause_loc = c_parser_peek_token (parser)->location;
15509 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
15510 tree nl, c, iterators = NULL_TREE;
15512 matching_parens parens;
15513 if (!parens.require_open (parser))
15514 return list;
15518 if (c_parser_next_token_is_not (parser, CPP_NAME))
15519 goto invalid_kind;
15521 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15522 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
15524 iterators = c_parser_omp_iterators (parser);
15525 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
15526 continue;
15528 if (strcmp ("in", p) == 0)
15529 kind = OMP_CLAUSE_DEPEND_IN;
15530 else if (strcmp ("inout", p) == 0)
15531 kind = OMP_CLAUSE_DEPEND_INOUT;
15532 else if (strcmp ("mutexinoutset", p) == 0)
15533 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
15534 else if (strcmp ("out", p) == 0)
15535 kind = OMP_CLAUSE_DEPEND_OUT;
15536 else if (strcmp ("depobj", p) == 0)
15537 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
15538 else if (strcmp ("sink", p) == 0)
15539 kind = OMP_CLAUSE_DEPEND_SINK;
15540 else if (strcmp ("source", p) == 0)
15541 kind = OMP_CLAUSE_DEPEND_SOURCE;
15542 else
15543 goto invalid_kind;
15544 break;
15546 while (1);
15548 c_parser_consume_token (parser);
15550 if (iterators
15551 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
15553 pop_scope ();
15554 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
15555 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
15556 iterators = NULL_TREE;
15559 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
15561 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15562 OMP_CLAUSE_DEPEND_KIND (c) = kind;
15563 OMP_CLAUSE_DECL (c) = NULL_TREE;
15564 OMP_CLAUSE_CHAIN (c) = list;
15565 parens.skip_until_found_close (parser);
15566 return c;
15569 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15570 goto resync_fail;
15572 if (kind == OMP_CLAUSE_DEPEND_SINK)
15573 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
15574 else
15576 nl = c_parser_omp_variable_list (parser, clause_loc,
15577 OMP_CLAUSE_DEPEND, list);
15579 if (iterators)
15581 tree block = pop_scope ();
15582 if (iterators == error_mark_node)
15583 iterators = NULL_TREE;
15584 else
15585 TREE_VEC_ELT (iterators, 5) = block;
15588 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15590 OMP_CLAUSE_DEPEND_KIND (c) = kind;
15591 if (iterators)
15592 OMP_CLAUSE_DECL (c)
15593 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
15597 parens.skip_until_found_close (parser);
15598 return nl;
15600 invalid_kind:
15601 c_parser_error (parser, "invalid depend kind");
15602 resync_fail:
15603 parens.skip_until_found_close (parser);
15604 if (iterators)
15605 pop_scope ();
15606 return list;
15609 /* OpenMP 4.0:
15610 map ( map-kind: variable-list )
15611 map ( variable-list )
15613 map-kind:
15614 alloc | to | from | tofrom
15616 OpenMP 4.5:
15617 map-kind:
15618 alloc | to | from | tofrom | release | delete
15620 map ( always [,] map-kind: variable-list ) */
15622 static tree
15623 c_parser_omp_clause_map (c_parser *parser, tree list)
15625 location_t clause_loc = c_parser_peek_token (parser)->location;
15626 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
15627 int always = 0;
15628 enum c_id_kind always_id_kind = C_ID_NONE;
15629 location_t always_loc = UNKNOWN_LOCATION;
15630 tree always_id = NULL_TREE;
15631 tree nl, c;
15633 matching_parens parens;
15634 if (!parens.require_open (parser))
15635 return list;
15637 if (c_parser_next_token_is (parser, CPP_NAME))
15639 c_token *tok = c_parser_peek_token (parser);
15640 const char *p = IDENTIFIER_POINTER (tok->value);
15641 always_id_kind = tok->id_kind;
15642 always_loc = tok->location;
15643 always_id = tok->value;
15644 if (strcmp ("always", p) == 0)
15646 c_token *sectok = c_parser_peek_2nd_token (parser);
15647 if (sectok->type == CPP_COMMA)
15649 c_parser_consume_token (parser);
15650 c_parser_consume_token (parser);
15651 always = 2;
15653 else if (sectok->type == CPP_NAME)
15655 p = IDENTIFIER_POINTER (sectok->value);
15656 if (strcmp ("alloc", p) == 0
15657 || strcmp ("to", p) == 0
15658 || strcmp ("from", p) == 0
15659 || strcmp ("tofrom", p) == 0
15660 || strcmp ("release", p) == 0
15661 || strcmp ("delete", p) == 0)
15663 c_parser_consume_token (parser);
15664 always = 1;
15670 if (c_parser_next_token_is (parser, CPP_NAME)
15671 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15673 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15674 if (strcmp ("alloc", p) == 0)
15675 kind = GOMP_MAP_ALLOC;
15676 else if (strcmp ("to", p) == 0)
15677 kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
15678 else if (strcmp ("from", p) == 0)
15679 kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
15680 else if (strcmp ("tofrom", p) == 0)
15681 kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
15682 else if (strcmp ("release", p) == 0)
15683 kind = GOMP_MAP_RELEASE;
15684 else if (strcmp ("delete", p) == 0)
15685 kind = GOMP_MAP_DELETE;
15686 else
15688 c_parser_error (parser, "invalid map kind");
15689 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15690 "expected %<)%>");
15691 return list;
15693 c_parser_consume_token (parser);
15694 c_parser_consume_token (parser);
15696 else if (always)
15698 if (always_id_kind != C_ID_ID)
15700 c_parser_error (parser, "expected identifier");
15701 parens.skip_until_found_close (parser);
15702 return list;
15705 tree t = lookup_name (always_id);
15706 if (t == NULL_TREE)
15708 undeclared_variable (always_loc, always_id);
15709 t = error_mark_node;
15711 if (t != error_mark_node)
15713 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP);
15714 OMP_CLAUSE_DECL (u) = t;
15715 OMP_CLAUSE_CHAIN (u) = list;
15716 OMP_CLAUSE_SET_MAP_KIND (u, kind);
15717 list = u;
15719 if (always == 1)
15721 parens.skip_until_found_close (parser);
15722 return list;
15726 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
15728 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15729 OMP_CLAUSE_SET_MAP_KIND (c, kind);
15731 parens.skip_until_found_close (parser);
15732 return nl;
15735 /* OpenMP 4.0:
15736 device ( expression ) */
15738 static tree
15739 c_parser_omp_clause_device (c_parser *parser, tree list)
15741 location_t clause_loc = c_parser_peek_token (parser)->location;
15742 matching_parens parens;
15743 if (parens.require_open (parser))
15745 location_t expr_loc = c_parser_peek_token (parser)->location;
15746 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15747 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15748 tree c, t = expr.value;
15749 t = c_fully_fold (t, false, NULL);
15751 parens.skip_until_found_close (parser);
15753 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15755 c_parser_error (parser, "expected integer expression");
15756 return list;
15759 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
15761 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
15762 OMP_CLAUSE_DEVICE_ID (c) = t;
15763 OMP_CLAUSE_CHAIN (c) = list;
15764 list = c;
15767 return list;
15770 /* OpenMP 4.0:
15771 dist_schedule ( static )
15772 dist_schedule ( static , expression ) */
15774 static tree
15775 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
15777 tree c, t = NULL_TREE;
15778 location_t loc = c_parser_peek_token (parser)->location;
15780 matching_parens parens;
15781 if (!parens.require_open (parser))
15782 return list;
15784 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
15786 c_parser_error (parser, "invalid dist_schedule kind");
15787 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15788 "expected %<)%>");
15789 return list;
15792 c_parser_consume_token (parser);
15793 if (c_parser_next_token_is (parser, CPP_COMMA))
15795 c_parser_consume_token (parser);
15797 location_t expr_loc = c_parser_peek_token (parser)->location;
15798 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15799 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15800 t = expr.value;
15801 t = c_fully_fold (t, false, NULL);
15802 parens.skip_until_found_close (parser);
15804 else
15805 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15806 "expected %<,%> or %<)%>");
15808 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15809 "dist_schedule"); */
15810 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
15811 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
15812 if (t == error_mark_node)
15813 return list;
15815 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
15816 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
15817 OMP_CLAUSE_CHAIN (c) = list;
15818 return c;
15821 /* OpenMP 4.0:
15822 proc_bind ( proc-bind-kind )
15824 proc-bind-kind:
15825 master | close | spread */
15827 static tree
15828 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
15830 location_t clause_loc = c_parser_peek_token (parser)->location;
15831 enum omp_clause_proc_bind_kind kind;
15832 tree c;
15834 matching_parens parens;
15835 if (!parens.require_open (parser))
15836 return list;
15838 if (c_parser_next_token_is (parser, CPP_NAME))
15840 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15841 if (strcmp ("master", p) == 0)
15842 kind = OMP_CLAUSE_PROC_BIND_MASTER;
15843 else if (strcmp ("close", p) == 0)
15844 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
15845 else if (strcmp ("spread", p) == 0)
15846 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
15847 else
15848 goto invalid_kind;
15850 else
15851 goto invalid_kind;
15853 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
15854 c_parser_consume_token (parser);
15855 parens.skip_until_found_close (parser);
15856 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
15857 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
15858 OMP_CLAUSE_CHAIN (c) = list;
15859 return c;
15861 invalid_kind:
15862 c_parser_error (parser, "invalid proc_bind kind");
15863 parens.skip_until_found_close (parser);
15864 return list;
15867 /* OpenMP 5.0:
15868 device_type ( host | nohost | any ) */
15870 static tree
15871 c_parser_omp_clause_device_type (c_parser *parser, tree list)
15873 location_t clause_loc = c_parser_peek_token (parser)->location;
15874 enum omp_clause_device_type_kind kind;
15875 tree c;
15877 matching_parens parens;
15878 if (!parens.require_open (parser))
15879 return list;
15881 if (c_parser_next_token_is (parser, CPP_NAME))
15883 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15884 if (strcmp ("host", p) == 0)
15885 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
15886 else if (strcmp ("nohost", p) == 0)
15887 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
15888 else if (strcmp ("any", p) == 0)
15889 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
15890 else
15891 goto invalid_kind;
15893 else
15894 goto invalid_kind;
15896 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15897 "device_type"); */
15898 c_parser_consume_token (parser);
15899 parens.skip_until_found_close (parser);
15900 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
15901 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
15902 OMP_CLAUSE_CHAIN (c) = list;
15903 return c;
15905 invalid_kind:
15906 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
15907 parens.skip_until_found_close (parser);
15908 return list;
15911 /* OpenMP 4.0:
15912 to ( variable-list ) */
15914 static tree
15915 c_parser_omp_clause_to (c_parser *parser, tree list)
15917 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list);
15920 /* OpenMP 4.0:
15921 from ( variable-list ) */
15923 static tree
15924 c_parser_omp_clause_from (c_parser *parser, tree list)
15926 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list);
15929 /* OpenMP 4.0:
15930 uniform ( variable-list ) */
15932 static tree
15933 c_parser_omp_clause_uniform (c_parser *parser, tree list)
15935 /* The clauses location. */
15936 location_t loc = c_parser_peek_token (parser)->location;
15938 matching_parens parens;
15939 if (parens.require_open (parser))
15941 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
15942 list);
15943 parens.skip_until_found_close (parser);
15945 return list;
15948 /* Parse all OpenACC clauses. The set clauses allowed by the directive
15949 is a bitmask in MASK. Return the list of clauses found. */
15951 static tree
15952 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
15953 const char *where, bool finish_p = true)
15955 tree clauses = NULL;
15956 bool first = true;
15958 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
15960 location_t here;
15961 pragma_omp_clause c_kind;
15962 const char *c_name;
15963 tree prev = clauses;
15965 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
15966 c_parser_consume_token (parser);
15968 here = c_parser_peek_token (parser)->location;
15969 c_kind = c_parser_omp_clause_name (parser);
15971 switch (c_kind)
15973 case PRAGMA_OACC_CLAUSE_ASYNC:
15974 clauses = c_parser_oacc_clause_async (parser, clauses);
15975 c_name = "async";
15976 break;
15977 case PRAGMA_OACC_CLAUSE_AUTO:
15978 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
15979 clauses);
15980 c_name = "auto";
15981 break;
15982 case PRAGMA_OACC_CLAUSE_ATTACH:
15983 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15984 c_name = "attach";
15985 break;
15986 case PRAGMA_OACC_CLAUSE_COLLAPSE:
15987 clauses = c_parser_omp_clause_collapse (parser, clauses);
15988 c_name = "collapse";
15989 break;
15990 case PRAGMA_OACC_CLAUSE_COPY:
15991 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15992 c_name = "copy";
15993 break;
15994 case PRAGMA_OACC_CLAUSE_COPYIN:
15995 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15996 c_name = "copyin";
15997 break;
15998 case PRAGMA_OACC_CLAUSE_COPYOUT:
15999 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16000 c_name = "copyout";
16001 break;
16002 case PRAGMA_OACC_CLAUSE_CREATE:
16003 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16004 c_name = "create";
16005 break;
16006 case PRAGMA_OACC_CLAUSE_DELETE:
16007 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16008 c_name = "delete";
16009 break;
16010 case PRAGMA_OMP_CLAUSE_DEFAULT:
16011 clauses = c_parser_omp_clause_default (parser, clauses, true);
16012 c_name = "default";
16013 break;
16014 case PRAGMA_OACC_CLAUSE_DETACH:
16015 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16016 c_name = "detach";
16017 break;
16018 case PRAGMA_OACC_CLAUSE_DEVICE:
16019 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16020 c_name = "device";
16021 break;
16022 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16023 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16024 c_name = "deviceptr";
16025 break;
16026 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16027 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16028 c_name = "device_resident";
16029 break;
16030 case PRAGMA_OACC_CLAUSE_FINALIZE:
16031 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16032 clauses);
16033 c_name = "finalize";
16034 break;
16035 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16036 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16037 c_name = "firstprivate";
16038 break;
16039 case PRAGMA_OACC_CLAUSE_GANG:
16040 c_name = "gang";
16041 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16042 c_name, clauses);
16043 break;
16044 case PRAGMA_OACC_CLAUSE_HOST:
16045 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16046 c_name = "host";
16047 break;
16048 case PRAGMA_OACC_CLAUSE_IF:
16049 clauses = c_parser_omp_clause_if (parser, clauses, false);
16050 c_name = "if";
16051 break;
16052 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16053 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16054 clauses);
16055 c_name = "if_present";
16056 break;
16057 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16058 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16059 clauses);
16060 c_name = "independent";
16061 break;
16062 case PRAGMA_OACC_CLAUSE_LINK:
16063 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16064 c_name = "link";
16065 break;
16066 case PRAGMA_OACC_CLAUSE_NO_CREATE:
16067 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16068 c_name = "no_create";
16069 break;
16070 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16071 clauses = c_parser_oacc_single_int_clause (parser,
16072 OMP_CLAUSE_NUM_GANGS,
16073 clauses);
16074 c_name = "num_gangs";
16075 break;
16076 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16077 clauses = c_parser_oacc_single_int_clause (parser,
16078 OMP_CLAUSE_NUM_WORKERS,
16079 clauses);
16080 c_name = "num_workers";
16081 break;
16082 case PRAGMA_OACC_CLAUSE_PRESENT:
16083 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16084 c_name = "present";
16085 break;
16086 case PRAGMA_OACC_CLAUSE_PRIVATE:
16087 clauses = c_parser_omp_clause_private (parser, clauses);
16088 c_name = "private";
16089 break;
16090 case PRAGMA_OACC_CLAUSE_REDUCTION:
16091 clauses
16092 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16093 false, clauses);
16094 c_name = "reduction";
16095 break;
16096 case PRAGMA_OACC_CLAUSE_SEQ:
16097 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16098 clauses);
16099 c_name = "seq";
16100 break;
16101 case PRAGMA_OACC_CLAUSE_TILE:
16102 clauses = c_parser_oacc_clause_tile (parser, clauses);
16103 c_name = "tile";
16104 break;
16105 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16106 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16107 c_name = "use_device";
16108 break;
16109 case PRAGMA_OACC_CLAUSE_VECTOR:
16110 c_name = "vector";
16111 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16112 c_name, clauses);
16113 break;
16114 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16115 clauses = c_parser_oacc_single_int_clause (parser,
16116 OMP_CLAUSE_VECTOR_LENGTH,
16117 clauses);
16118 c_name = "vector_length";
16119 break;
16120 case PRAGMA_OACC_CLAUSE_WAIT:
16121 clauses = c_parser_oacc_clause_wait (parser, clauses);
16122 c_name = "wait";
16123 break;
16124 case PRAGMA_OACC_CLAUSE_WORKER:
16125 c_name = "worker";
16126 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16127 c_name, clauses);
16128 break;
16129 default:
16130 c_parser_error (parser, "expected %<#pragma acc%> clause");
16131 goto saw_error;
16134 first = false;
16136 if (((mask >> c_kind) & 1) == 0)
16138 /* Remove the invalid clause(s) from the list to avoid
16139 confusing the rest of the compiler. */
16140 clauses = prev;
16141 error_at (here, "%qs is not valid for %qs", c_name, where);
16145 saw_error:
16146 c_parser_skip_to_pragma_eol (parser);
16148 if (finish_p)
16149 return c_finish_omp_clauses (clauses, C_ORT_ACC);
16151 return clauses;
16154 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16155 is a bitmask in MASK. Return the list of clauses found.
16156 FINISH_P set if c_finish_omp_clauses should be called.
16157 NESTED non-zero if clauses should be terminated by closing paren instead
16158 of end of pragma. If it is 2, additionally commas are required in between
16159 the clauses. */
16161 static tree
16162 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16163 const char *where, bool finish_p = true,
16164 int nested = 0)
16166 tree clauses = NULL;
16167 bool first = true;
16169 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16171 location_t here;
16172 pragma_omp_clause c_kind;
16173 const char *c_name;
16174 tree prev = clauses;
16176 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16177 break;
16179 if (!first)
16181 if (c_parser_next_token_is (parser, CPP_COMMA))
16182 c_parser_consume_token (parser);
16183 else if (nested == 2)
16184 error_at (c_parser_peek_token (parser)->location,
16185 "clauses in %<simd%> trait should be separated "
16186 "by %<,%>");
16189 here = c_parser_peek_token (parser)->location;
16190 c_kind = c_parser_omp_clause_name (parser);
16192 switch (c_kind)
16194 case PRAGMA_OMP_CLAUSE_BIND:
16195 clauses = c_parser_omp_clause_bind (parser, clauses);
16196 c_name = "bind";
16197 break;
16198 case PRAGMA_OMP_CLAUSE_COLLAPSE:
16199 clauses = c_parser_omp_clause_collapse (parser, clauses);
16200 c_name = "collapse";
16201 break;
16202 case PRAGMA_OMP_CLAUSE_COPYIN:
16203 clauses = c_parser_omp_clause_copyin (parser, clauses);
16204 c_name = "copyin";
16205 break;
16206 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16207 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16208 c_name = "copyprivate";
16209 break;
16210 case PRAGMA_OMP_CLAUSE_DEFAULT:
16211 clauses = c_parser_omp_clause_default (parser, clauses, false);
16212 c_name = "default";
16213 break;
16214 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
16215 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16216 c_name = "firstprivate";
16217 break;
16218 case PRAGMA_OMP_CLAUSE_FINAL:
16219 clauses = c_parser_omp_clause_final (parser, clauses);
16220 c_name = "final";
16221 break;
16222 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
16223 clauses = c_parser_omp_clause_grainsize (parser, clauses);
16224 c_name = "grainsize";
16225 break;
16226 case PRAGMA_OMP_CLAUSE_HINT:
16227 clauses = c_parser_omp_clause_hint (parser, clauses);
16228 c_name = "hint";
16229 break;
16230 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
16231 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
16232 c_name = "defaultmap";
16233 break;
16234 case PRAGMA_OMP_CLAUSE_IF:
16235 clauses = c_parser_omp_clause_if (parser, clauses, true);
16236 c_name = "if";
16237 break;
16238 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
16239 clauses
16240 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
16241 true, clauses);
16242 c_name = "in_reduction";
16243 break;
16244 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
16245 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
16246 c_name = "lastprivate";
16247 break;
16248 case PRAGMA_OMP_CLAUSE_MERGEABLE:
16249 clauses = c_parser_omp_clause_mergeable (parser, clauses);
16250 c_name = "mergeable";
16251 break;
16252 case PRAGMA_OMP_CLAUSE_NOWAIT:
16253 clauses = c_parser_omp_clause_nowait (parser, clauses);
16254 c_name = "nowait";
16255 break;
16256 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
16257 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
16258 c_name = "num_tasks";
16259 break;
16260 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
16261 clauses = c_parser_omp_clause_num_threads (parser, clauses);
16262 c_name = "num_threads";
16263 break;
16264 case PRAGMA_OMP_CLAUSE_ORDER:
16265 clauses = c_parser_omp_clause_order (parser, clauses);
16266 c_name = "order";
16267 break;
16268 case PRAGMA_OMP_CLAUSE_ORDERED:
16269 clauses = c_parser_omp_clause_ordered (parser, clauses);
16270 c_name = "ordered";
16271 break;
16272 case PRAGMA_OMP_CLAUSE_PRIORITY:
16273 clauses = c_parser_omp_clause_priority (parser, clauses);
16274 c_name = "priority";
16275 break;
16276 case PRAGMA_OMP_CLAUSE_PRIVATE:
16277 clauses = c_parser_omp_clause_private (parser, clauses);
16278 c_name = "private";
16279 break;
16280 case PRAGMA_OMP_CLAUSE_REDUCTION:
16281 clauses
16282 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16283 true, clauses);
16284 c_name = "reduction";
16285 break;
16286 case PRAGMA_OMP_CLAUSE_SCHEDULE:
16287 clauses = c_parser_omp_clause_schedule (parser, clauses);
16288 c_name = "schedule";
16289 break;
16290 case PRAGMA_OMP_CLAUSE_SHARED:
16291 clauses = c_parser_omp_clause_shared (parser, clauses);
16292 c_name = "shared";
16293 break;
16294 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
16295 clauses
16296 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
16297 true, clauses);
16298 c_name = "task_reduction";
16299 break;
16300 case PRAGMA_OMP_CLAUSE_UNTIED:
16301 clauses = c_parser_omp_clause_untied (parser, clauses);
16302 c_name = "untied";
16303 break;
16304 case PRAGMA_OMP_CLAUSE_INBRANCH:
16305 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
16306 clauses);
16307 c_name = "inbranch";
16308 break;
16309 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
16310 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
16311 c_name = "nontemporal";
16312 break;
16313 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
16314 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
16315 clauses);
16316 c_name = "notinbranch";
16317 break;
16318 case PRAGMA_OMP_CLAUSE_PARALLEL:
16319 clauses
16320 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
16321 clauses);
16322 c_name = "parallel";
16323 if (!first)
16325 clause_not_first:
16326 error_at (here, "%qs must be the first clause of %qs",
16327 c_name, where);
16328 clauses = prev;
16330 break;
16331 case PRAGMA_OMP_CLAUSE_FOR:
16332 clauses
16333 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
16334 clauses);
16335 c_name = "for";
16336 if (!first)
16337 goto clause_not_first;
16338 break;
16339 case PRAGMA_OMP_CLAUSE_SECTIONS:
16340 clauses
16341 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
16342 clauses);
16343 c_name = "sections";
16344 if (!first)
16345 goto clause_not_first;
16346 break;
16347 case PRAGMA_OMP_CLAUSE_TASKGROUP:
16348 clauses
16349 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
16350 clauses);
16351 c_name = "taskgroup";
16352 if (!first)
16353 goto clause_not_first;
16354 break;
16355 case PRAGMA_OMP_CLAUSE_LINK:
16356 clauses
16357 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
16358 c_name = "link";
16359 break;
16360 case PRAGMA_OMP_CLAUSE_TO:
16361 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
16362 clauses
16363 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
16364 clauses);
16365 else
16366 clauses = c_parser_omp_clause_to (parser, clauses);
16367 c_name = "to";
16368 break;
16369 case PRAGMA_OMP_CLAUSE_FROM:
16370 clauses = c_parser_omp_clause_from (parser, clauses);
16371 c_name = "from";
16372 break;
16373 case PRAGMA_OMP_CLAUSE_UNIFORM:
16374 clauses = c_parser_omp_clause_uniform (parser, clauses);
16375 c_name = "uniform";
16376 break;
16377 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
16378 clauses = c_parser_omp_clause_num_teams (parser, clauses);
16379 c_name = "num_teams";
16380 break;
16381 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
16382 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
16383 c_name = "thread_limit";
16384 break;
16385 case PRAGMA_OMP_CLAUSE_ALIGNED:
16386 clauses = c_parser_omp_clause_aligned (parser, clauses);
16387 c_name = "aligned";
16388 break;
16389 case PRAGMA_OMP_CLAUSE_LINEAR:
16390 clauses = c_parser_omp_clause_linear (parser, clauses);
16391 c_name = "linear";
16392 break;
16393 case PRAGMA_OMP_CLAUSE_DEPEND:
16394 clauses = c_parser_omp_clause_depend (parser, clauses);
16395 c_name = "depend";
16396 break;
16397 case PRAGMA_OMP_CLAUSE_MAP:
16398 clauses = c_parser_omp_clause_map (parser, clauses);
16399 c_name = "map";
16400 break;
16401 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
16402 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16403 c_name = "use_device_ptr";
16404 break;
16405 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
16406 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
16407 c_name = "use_device_addr";
16408 break;
16409 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
16410 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
16411 c_name = "is_device_ptr";
16412 break;
16413 case PRAGMA_OMP_CLAUSE_DEVICE:
16414 clauses = c_parser_omp_clause_device (parser, clauses);
16415 c_name = "device";
16416 break;
16417 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
16418 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
16419 c_name = "dist_schedule";
16420 break;
16421 case PRAGMA_OMP_CLAUSE_PROC_BIND:
16422 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
16423 c_name = "proc_bind";
16424 break;
16425 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
16426 clauses = c_parser_omp_clause_device_type (parser, clauses);
16427 c_name = "device_type";
16428 break;
16429 case PRAGMA_OMP_CLAUSE_SAFELEN:
16430 clauses = c_parser_omp_clause_safelen (parser, clauses);
16431 c_name = "safelen";
16432 break;
16433 case PRAGMA_OMP_CLAUSE_SIMDLEN:
16434 clauses = c_parser_omp_clause_simdlen (parser, clauses);
16435 c_name = "simdlen";
16436 break;
16437 case PRAGMA_OMP_CLAUSE_NOGROUP:
16438 clauses = c_parser_omp_clause_nogroup (parser, clauses);
16439 c_name = "nogroup";
16440 break;
16441 case PRAGMA_OMP_CLAUSE_THREADS:
16442 clauses
16443 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
16444 clauses);
16445 c_name = "threads";
16446 break;
16447 case PRAGMA_OMP_CLAUSE_SIMD:
16448 clauses
16449 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
16450 clauses);
16451 c_name = "simd";
16452 break;
16453 default:
16454 c_parser_error (parser, "expected %<#pragma omp%> clause");
16455 goto saw_error;
16458 first = false;
16460 if (((mask >> c_kind) & 1) == 0)
16462 /* Remove the invalid clause(s) from the list to avoid
16463 confusing the rest of the compiler. */
16464 clauses = prev;
16465 error_at (here, "%qs is not valid for %qs", c_name, where);
16469 saw_error:
16470 if (!nested)
16471 c_parser_skip_to_pragma_eol (parser);
16473 if (finish_p)
16475 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
16476 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
16477 return c_finish_omp_clauses (clauses, C_ORT_OMP);
16480 return clauses;
16483 /* OpenACC 2.0, OpenMP 2.5:
16484 structured-block:
16485 statement
16487 In practice, we're also interested in adding the statement to an
16488 outer node. So it is convenient if we work around the fact that
16489 c_parser_statement calls add_stmt. */
16491 static tree
16492 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
16494 tree stmt = push_stmt_list ();
16495 c_parser_statement (parser, if_p);
16496 return pop_stmt_list (stmt);
16499 /* OpenACC 2.0:
16500 # pragma acc cache (variable-list) new-line
16502 LOC is the location of the #pragma token.
16505 static tree
16506 c_parser_oacc_cache (location_t loc, c_parser *parser)
16508 tree stmt, clauses;
16510 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
16511 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16513 c_parser_skip_to_pragma_eol (parser);
16515 stmt = make_node (OACC_CACHE);
16516 TREE_TYPE (stmt) = void_type_node;
16517 OACC_CACHE_CLAUSES (stmt) = clauses;
16518 SET_EXPR_LOCATION (stmt, loc);
16519 add_stmt (stmt);
16521 return stmt;
16524 /* OpenACC 2.0:
16525 # pragma acc data oacc-data-clause[optseq] new-line
16526 structured-block
16528 LOC is the location of the #pragma token.
16531 #define OACC_DATA_CLAUSE_MASK \
16532 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16533 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16534 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16535 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16536 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16542 static tree
16543 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
16545 tree stmt, clauses, block;
16547 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
16548 "#pragma acc data");
16550 block = c_begin_omp_parallel ();
16551 add_stmt (c_parser_omp_structured_block (parser, if_p));
16553 stmt = c_finish_oacc_data (loc, clauses, block);
16555 return stmt;
16558 /* OpenACC 2.0:
16559 # pragma acc declare oacc-data-clause[optseq] new-line
16562 #define OACC_DECLARE_CLAUSE_MASK \
16563 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16567 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
16569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
16570 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16572 static void
16573 c_parser_oacc_declare (c_parser *parser)
16575 location_t pragma_loc = c_parser_peek_token (parser)->location;
16576 tree clauses, stmt, t, decl;
16578 bool error = false;
16580 c_parser_consume_pragma (parser);
16582 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
16583 "#pragma acc declare");
16584 if (!clauses)
16586 error_at (pragma_loc,
16587 "no valid clauses specified in %<#pragma acc declare%>");
16588 return;
16591 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
16593 location_t loc = OMP_CLAUSE_LOCATION (t);
16594 decl = OMP_CLAUSE_DECL (t);
16595 if (!DECL_P (decl))
16597 error_at (loc, "array section in %<#pragma acc declare%>");
16598 error = true;
16599 continue;
16602 switch (OMP_CLAUSE_MAP_KIND (t))
16604 case GOMP_MAP_FIRSTPRIVATE_POINTER:
16605 case GOMP_MAP_ALLOC:
16606 case GOMP_MAP_TO:
16607 case GOMP_MAP_FORCE_DEVICEPTR:
16608 case GOMP_MAP_DEVICE_RESIDENT:
16609 break;
16611 case GOMP_MAP_LINK:
16612 if (!global_bindings_p ()
16613 && (TREE_STATIC (decl)
16614 || !DECL_EXTERNAL (decl)))
16616 error_at (loc,
16617 "%qD must be a global variable in "
16618 "%<#pragma acc declare link%>",
16619 decl);
16620 error = true;
16621 continue;
16623 break;
16625 default:
16626 if (global_bindings_p ())
16628 error_at (loc, "invalid OpenACC clause at file scope");
16629 error = true;
16630 continue;
16632 if (DECL_EXTERNAL (decl))
16634 error_at (loc,
16635 "invalid use of %<extern%> variable %qD "
16636 "in %<#pragma acc declare%>", decl);
16637 error = true;
16638 continue;
16640 else if (TREE_PUBLIC (decl))
16642 error_at (loc,
16643 "invalid use of %<global%> variable %qD "
16644 "in %<#pragma acc declare%>", decl);
16645 error = true;
16646 continue;
16648 break;
16651 if (!c_check_in_current_scope (decl))
16653 error_at (loc,
16654 "%qD must be a variable declared in the same scope as "
16655 "%<#pragma acc declare%>", decl);
16656 error = true;
16657 continue;
16660 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
16661 || lookup_attribute ("omp declare target link",
16662 DECL_ATTRIBUTES (decl)))
16664 error_at (loc, "variable %qD used more than once with "
16665 "%<#pragma acc declare%>", decl);
16666 error = true;
16667 continue;
16670 if (!error)
16672 tree id;
16674 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
16675 id = get_identifier ("omp declare target link");
16676 else
16677 id = get_identifier ("omp declare target");
16679 DECL_ATTRIBUTES (decl)
16680 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
16682 if (global_bindings_p ())
16684 symtab_node *node = symtab_node::get (decl);
16685 if (node != NULL)
16687 node->offloadable = 1;
16688 if (ENABLE_OFFLOADING)
16690 g->have_offload = true;
16691 if (is_a <varpool_node *> (node))
16692 vec_safe_push (offload_vars, decl);
16699 if (error || global_bindings_p ())
16700 return;
16702 stmt = make_node (OACC_DECLARE);
16703 TREE_TYPE (stmt) = void_type_node;
16704 OACC_DECLARE_CLAUSES (stmt) = clauses;
16705 SET_EXPR_LOCATION (stmt, pragma_loc);
16707 add_stmt (stmt);
16709 return;
16712 /* OpenACC 2.0:
16713 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16717 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16720 LOC is the location of the #pragma token.
16723 #define OACC_ENTER_DATA_CLAUSE_MASK \
16724 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16728 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16729 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16731 #define OACC_EXIT_DATA_CLAUSE_MASK \
16732 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
16736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
16737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
16738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16740 static void
16741 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
16743 location_t loc = c_parser_peek_token (parser)->location;
16744 tree clauses, stmt;
16745 const char *p = "";
16747 c_parser_consume_pragma (parser);
16749 if (c_parser_next_token_is (parser, CPP_NAME))
16751 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16752 c_parser_consume_token (parser);
16755 if (strcmp (p, "data") != 0)
16757 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
16758 enter ? "enter" : "exit");
16759 parser->error = true;
16760 c_parser_skip_to_pragma_eol (parser);
16761 return;
16764 if (enter)
16765 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
16766 "#pragma acc enter data");
16767 else
16768 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
16769 "#pragma acc exit data");
16771 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
16773 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
16774 enter ? "enter" : "exit");
16775 return;
16778 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
16779 TREE_TYPE (stmt) = void_type_node;
16780 OMP_STANDALONE_CLAUSES (stmt) = clauses;
16781 SET_EXPR_LOCATION (stmt, loc);
16782 add_stmt (stmt);
16786 /* OpenACC 2.0:
16787 # pragma acc host_data oacc-data-clause[optseq] new-line
16788 structured-block
16791 #define OACC_HOST_DATA_CLAUSE_MASK \
16792 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
16793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
16796 static tree
16797 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
16799 tree stmt, clauses, block;
16801 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
16802 "#pragma acc host_data");
16804 block = c_begin_omp_parallel ();
16805 add_stmt (c_parser_omp_structured_block (parser, if_p));
16806 stmt = c_finish_oacc_host_data (loc, clauses, block);
16807 return stmt;
16811 /* OpenACC 2.0:
16813 # pragma acc loop oacc-loop-clause[optseq] new-line
16814 structured-block
16816 LOC is the location of the #pragma token.
16819 #define OACC_LOOP_CLAUSE_MASK \
16820 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
16821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
16827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
16828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
16829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
16830 static tree
16831 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
16832 omp_clause_mask mask, tree *cclauses, bool *if_p)
16834 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
16836 strcat (p_name, " loop");
16837 mask |= OACC_LOOP_CLAUSE_MASK;
16839 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
16840 cclauses == NULL);
16841 if (cclauses)
16843 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
16844 if (*cclauses)
16845 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
16846 if (clauses)
16847 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16850 tree block = c_begin_compound_stmt (true);
16851 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
16852 if_p);
16853 block = c_end_compound_stmt (loc, block, true);
16854 add_stmt (block);
16856 return stmt;
16859 /* OpenACC 2.0:
16860 # pragma acc kernels oacc-kernels-clause[optseq] new-line
16861 structured-block
16865 # pragma acc parallel oacc-parallel-clause[optseq] new-line
16866 structured-block
16868 OpenACC 2.6:
16870 # pragma acc serial oacc-serial-clause[optseq] new-line
16871 structured-block
16873 LOC is the location of the #pragma token.
16876 #define OACC_KERNELS_CLAUSE_MASK \
16877 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16883 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16893 #define OACC_PARALLEL_CLAUSE_MASK \
16894 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16906 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16907 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16908 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16913 #define OACC_SERIAL_CLAUSE_MASK \
16914 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16919 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16920 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16921 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16922 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16923 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16925 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16926 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16928 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16930 static tree
16931 c_parser_oacc_compute (location_t loc, c_parser *parser,
16932 enum pragma_kind p_kind, char *p_name, bool *if_p)
16934 omp_clause_mask mask;
16935 enum tree_code code;
16936 switch (p_kind)
16938 case PRAGMA_OACC_KERNELS:
16939 strcat (p_name, " kernels");
16940 mask = OACC_KERNELS_CLAUSE_MASK;
16941 code = OACC_KERNELS;
16942 break;
16943 case PRAGMA_OACC_PARALLEL:
16944 strcat (p_name, " parallel");
16945 mask = OACC_PARALLEL_CLAUSE_MASK;
16946 code = OACC_PARALLEL;
16947 break;
16948 case PRAGMA_OACC_SERIAL:
16949 strcat (p_name, " serial");
16950 mask = OACC_SERIAL_CLAUSE_MASK;
16951 code = OACC_SERIAL;
16952 break;
16953 default:
16954 gcc_unreachable ();
16957 if (c_parser_next_token_is (parser, CPP_NAME))
16959 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16960 if (strcmp (p, "loop") == 0)
16962 c_parser_consume_token (parser);
16963 tree block = c_begin_omp_parallel ();
16964 tree clauses;
16965 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
16966 return c_finish_omp_construct (loc, code, block, clauses);
16970 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
16972 tree block = c_begin_omp_parallel ();
16973 add_stmt (c_parser_omp_structured_block (parser, if_p));
16975 return c_finish_omp_construct (loc, code, block, clauses);
16978 /* OpenACC 2.0:
16979 # pragma acc routine oacc-routine-clause[optseq] new-line
16980 function-definition
16982 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
16985 #define OACC_ROUTINE_CLAUSE_MASK \
16986 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16987 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
16991 /* Parse an OpenACC routine directive. For named directives, we apply
16992 immediately to the named function. For unnamed ones we then parse
16993 a declaration or definition, which must be for a function. */
16995 static void
16996 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
16998 gcc_checking_assert (context == pragma_external);
17000 oacc_routine_data data;
17001 data.error_seen = false;
17002 data.fndecl_seen = false;
17003 data.loc = c_parser_peek_token (parser)->location;
17005 c_parser_consume_pragma (parser);
17007 /* Look for optional '( name )'. */
17008 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17010 c_parser_consume_token (parser); /* '(' */
17012 tree decl = NULL_TREE;
17013 c_token *name_token = c_parser_peek_token (parser);
17014 location_t name_loc = name_token->location;
17015 if (name_token->type == CPP_NAME
17016 && (name_token->id_kind == C_ID_ID
17017 || name_token->id_kind == C_ID_TYPENAME))
17019 decl = lookup_name (name_token->value);
17020 if (!decl)
17021 error_at (name_loc,
17022 "%qE has not been declared", name_token->value);
17023 c_parser_consume_token (parser);
17025 else
17026 c_parser_error (parser, "expected function name");
17028 if (!decl
17029 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17031 c_parser_skip_to_pragma_eol (parser, false);
17032 return;
17035 data.clauses
17036 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17037 "#pragma acc routine");
17038 /* The clauses are in reverse order; fix that to make later diagnostic
17039 emission easier. */
17040 data.clauses = nreverse (data.clauses);
17042 if (TREE_CODE (decl) != FUNCTION_DECL)
17044 error_at (name_loc, "%qD does not refer to a function", decl);
17045 return;
17048 c_finish_oacc_routine (&data, decl, false);
17050 else /* No optional '( name )'. */
17052 data.clauses
17053 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17054 "#pragma acc routine");
17055 /* The clauses are in reverse order; fix that to make later diagnostic
17056 emission easier. */
17057 data.clauses = nreverse (data.clauses);
17059 /* Emit a helpful diagnostic if there's another pragma following this
17060 one. Also don't allow a static assertion declaration, as in the
17061 following we'll just parse a *single* "declaration or function
17062 definition", and the static assertion counts an one. */
17063 if (c_parser_next_token_is (parser, CPP_PRAGMA)
17064 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17066 error_at (data.loc,
17067 "%<#pragma acc routine%> not immediately followed by"
17068 " function declaration or definition");
17069 /* ..., and then just keep going. */
17070 return;
17073 /* We only have to consider the pragma_external case here. */
17074 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17075 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17077 int ext = disable_extension_diagnostics ();
17079 c_parser_consume_token (parser);
17080 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17081 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17082 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17083 NULL, vNULL, false, NULL, &data);
17084 restore_extension_diagnostics (ext);
17086 else
17087 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17088 NULL, vNULL, false, NULL, &data);
17092 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17093 IS_DEFN is true if we're applying it to the definition. */
17095 static void
17096 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17097 bool is_defn)
17099 /* Keep going if we're in error reporting mode. */
17100 if (data->error_seen
17101 || fndecl == error_mark_node)
17102 return;
17104 if (data->fndecl_seen)
17106 error_at (data->loc,
17107 "%<#pragma acc routine%> not immediately followed by"
17108 " a single function declaration or definition");
17109 data->error_seen = true;
17110 return;
17112 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17114 error_at (data->loc,
17115 "%<#pragma acc routine%> not immediately followed by"
17116 " function declaration or definition");
17117 data->error_seen = true;
17118 return;
17121 int compatible
17122 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17123 "#pragma acc routine");
17124 if (compatible < 0)
17126 data->error_seen = true;
17127 return;
17129 if (compatible > 0)
17132 else
17134 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17136 error_at (data->loc,
17137 TREE_USED (fndecl)
17138 ? G_("%<#pragma acc routine%> must be applied before use")
17139 : G_("%<#pragma acc routine%> must be applied before"
17140 " definition"));
17141 data->error_seen = true;
17142 return;
17145 /* Set the routine's level of parallelism. */
17146 tree dims = oacc_build_routine_dims (data->clauses);
17147 oacc_replace_fn_attrib (fndecl, dims);
17149 /* Add an "omp declare target" attribute. */
17150 DECL_ATTRIBUTES (fndecl)
17151 = tree_cons (get_identifier ("omp declare target"),
17152 data->clauses, DECL_ATTRIBUTES (fndecl));
17155 /* Remember that we've used this "#pragma acc routine". */
17156 data->fndecl_seen = true;
17159 /* OpenACC 2.0:
17160 # pragma acc update oacc-update-clause[optseq] new-line
17163 #define OACC_UPDATE_CLAUSE_MASK \
17164 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17165 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17166 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17167 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17168 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17169 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17171 static void
17172 c_parser_oacc_update (c_parser *parser)
17174 location_t loc = c_parser_peek_token (parser)->location;
17176 c_parser_consume_pragma (parser);
17178 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17179 "#pragma acc update");
17180 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17182 error_at (loc,
17183 "%<#pragma acc update%> must contain at least one "
17184 "%<device%> or %<host%> or %<self%> clause");
17185 return;
17188 if (parser->error)
17189 return;
17191 tree stmt = make_node (OACC_UPDATE);
17192 TREE_TYPE (stmt) = void_type_node;
17193 OACC_UPDATE_CLAUSES (stmt) = clauses;
17194 SET_EXPR_LOCATION (stmt, loc);
17195 add_stmt (stmt);
17198 /* OpenACC 2.0:
17199 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17201 LOC is the location of the #pragma token.
17204 #define OACC_WAIT_CLAUSE_MASK \
17205 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17207 static tree
17208 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
17210 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
17212 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17213 list = c_parser_oacc_wait_list (parser, loc, list);
17215 strcpy (p_name, " wait");
17216 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
17217 stmt = c_finish_oacc_wait (loc, list, clauses);
17218 add_stmt (stmt);
17220 return stmt;
17223 /* OpenMP 2.5:
17224 # pragma omp atomic new-line
17225 expression-stmt
17227 expression-stmt:
17228 x binop= expr | x++ | ++x | x-- | --x
17229 binop:
17230 +, *, -, /, &, ^, |, <<, >>
17232 where x is an lvalue expression with scalar type.
17234 OpenMP 3.1:
17235 # pragma omp atomic new-line
17236 update-stmt
17238 # pragma omp atomic read new-line
17239 read-stmt
17241 # pragma omp atomic write new-line
17242 write-stmt
17244 # pragma omp atomic update new-line
17245 update-stmt
17247 # pragma omp atomic capture new-line
17248 capture-stmt
17250 # pragma omp atomic capture new-line
17251 capture-block
17253 read-stmt:
17254 v = x
17255 write-stmt:
17256 x = expr
17257 update-stmt:
17258 expression-stmt | x = x binop expr
17259 capture-stmt:
17260 v = expression-stmt
17261 capture-block:
17262 { v = x; update-stmt; } | { update-stmt; v = x; }
17264 OpenMP 4.0:
17265 update-stmt:
17266 expression-stmt | x = x binop expr | x = expr binop x
17267 capture-stmt:
17268 v = update-stmt
17269 capture-block:
17270 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17272 where x and v are lvalue expressions with scalar type.
17274 LOC is the location of the #pragma token. */
17276 static void
17277 c_parser_omp_atomic (location_t loc, c_parser *parser)
17279 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
17280 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
17281 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
17282 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
17283 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
17284 struct c_expr expr;
17285 location_t eloc;
17286 bool structured_block = false;
17287 bool swapped = false;
17288 bool non_lvalue_p;
17289 bool first = true;
17290 tree clauses = NULL_TREE;
17292 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17294 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
17295 c_parser_consume_token (parser);
17297 first = false;
17299 if (c_parser_next_token_is (parser, CPP_NAME))
17301 const char *p
17302 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17303 location_t cloc = c_parser_peek_token (parser)->location;
17304 enum tree_code new_code = ERROR_MARK;
17305 enum omp_memory_order new_memory_order
17306 = OMP_MEMORY_ORDER_UNSPECIFIED;
17308 if (!strcmp (p, "read"))
17309 new_code = OMP_ATOMIC_READ;
17310 else if (!strcmp (p, "write"))
17311 new_code = NOP_EXPR;
17312 else if (!strcmp (p, "update"))
17313 new_code = OMP_ATOMIC;
17314 else if (!strcmp (p, "capture"))
17315 new_code = OMP_ATOMIC_CAPTURE_NEW;
17316 else if (!strcmp (p, "seq_cst"))
17317 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17318 else if (!strcmp (p, "acq_rel"))
17319 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17320 else if (!strcmp (p, "release"))
17321 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
17322 else if (!strcmp (p, "acquire"))
17323 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17324 else if (!strcmp (p, "relaxed"))
17325 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
17326 else if (!strcmp (p, "hint"))
17328 c_parser_consume_token (parser);
17329 clauses = c_parser_omp_clause_hint (parser, clauses);
17330 continue;
17332 else
17334 p = NULL;
17335 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
17336 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17337 "%<release%>, %<relaxed%> or %<hint%> clause");
17339 if (p)
17341 if (new_code != ERROR_MARK)
17343 if (code != ERROR_MARK)
17344 error_at (cloc, "too many atomic clauses");
17345 else
17346 code = new_code;
17348 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17350 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17351 error_at (cloc, "too many memory order clauses");
17352 else
17353 memory_order = new_memory_order;
17355 c_parser_consume_token (parser);
17356 continue;
17359 break;
17361 c_parser_skip_to_pragma_eol (parser);
17363 if (code == ERROR_MARK)
17364 code = OMP_ATOMIC;
17365 if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
17367 omp_requires_mask
17368 = (enum omp_requires) (omp_requires_mask
17369 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
17370 switch ((enum omp_memory_order)
17371 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
17373 case OMP_MEMORY_ORDER_UNSPECIFIED:
17374 case OMP_MEMORY_ORDER_RELAXED:
17375 memory_order = OMP_MEMORY_ORDER_RELAXED;
17376 break;
17377 case OMP_MEMORY_ORDER_SEQ_CST:
17378 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17379 break;
17380 case OMP_MEMORY_ORDER_ACQ_REL:
17381 switch (code)
17383 case OMP_ATOMIC_READ:
17384 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17385 break;
17386 case NOP_EXPR: /* atomic write */
17387 case OMP_ATOMIC:
17388 memory_order = OMP_MEMORY_ORDER_RELEASE;
17389 break;
17390 default:
17391 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17392 break;
17394 break;
17395 default:
17396 gcc_unreachable ();
17399 else
17400 switch (code)
17402 case OMP_ATOMIC_READ:
17403 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17404 || memory_order == OMP_MEMORY_ORDER_RELEASE)
17406 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
17407 "%<acq_rel%> or %<release%> clauses");
17408 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17410 break;
17411 case NOP_EXPR: /* atomic write */
17412 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17413 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17415 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
17416 "%<acq_rel%> or %<acquire%> clauses");
17417 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17419 break;
17420 case OMP_ATOMIC:
17421 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17422 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17424 error_at (loc, "%<#pragma omp atomic update%> incompatible with "
17425 "%<acq_rel%> or %<acquire%> clauses");
17426 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17428 break;
17429 default:
17430 break;
17433 switch (code)
17435 case OMP_ATOMIC_READ:
17436 case NOP_EXPR: /* atomic write */
17437 v = c_parser_cast_expression (parser, NULL).value;
17438 non_lvalue_p = !lvalue_p (v);
17439 v = c_fully_fold (v, false, NULL, true);
17440 if (v == error_mark_node)
17441 goto saw_error;
17442 if (non_lvalue_p)
17443 v = non_lvalue (v);
17444 loc = c_parser_peek_token (parser)->location;
17445 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17446 goto saw_error;
17447 if (code == NOP_EXPR)
17449 lhs = c_parser_expression (parser).value;
17450 lhs = c_fully_fold (lhs, false, NULL);
17451 if (lhs == error_mark_node)
17452 goto saw_error;
17454 else
17456 lhs = c_parser_cast_expression (parser, NULL).value;
17457 non_lvalue_p = !lvalue_p (lhs);
17458 lhs = c_fully_fold (lhs, false, NULL, true);
17459 if (lhs == error_mark_node)
17460 goto saw_error;
17461 if (non_lvalue_p)
17462 lhs = non_lvalue (lhs);
17464 if (code == NOP_EXPR)
17466 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17467 opcode. */
17468 code = OMP_ATOMIC;
17469 rhs = lhs;
17470 lhs = v;
17471 v = NULL_TREE;
17473 goto done;
17474 case OMP_ATOMIC_CAPTURE_NEW:
17475 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
17477 c_parser_consume_token (parser);
17478 structured_block = true;
17480 else
17482 v = c_parser_cast_expression (parser, NULL).value;
17483 non_lvalue_p = !lvalue_p (v);
17484 v = c_fully_fold (v, false, NULL, true);
17485 if (v == error_mark_node)
17486 goto saw_error;
17487 if (non_lvalue_p)
17488 v = non_lvalue (v);
17489 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17490 goto saw_error;
17492 break;
17493 default:
17494 break;
17497 /* For structured_block case we don't know yet whether
17498 old or new x should be captured. */
17499 restart:
17500 eloc = c_parser_peek_token (parser)->location;
17501 expr = c_parser_cast_expression (parser, NULL);
17502 lhs = expr.value;
17503 expr = default_function_array_conversion (eloc, expr);
17504 unfolded_lhs = expr.value;
17505 lhs = c_fully_fold (lhs, false, NULL, true);
17506 orig_lhs = lhs;
17507 switch (TREE_CODE (lhs))
17509 case ERROR_MARK:
17510 saw_error:
17511 c_parser_skip_to_end_of_block_or_statement (parser);
17512 if (structured_block)
17514 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17515 c_parser_consume_token (parser);
17516 else if (code == OMP_ATOMIC_CAPTURE_NEW)
17518 c_parser_skip_to_end_of_block_or_statement (parser);
17519 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17520 c_parser_consume_token (parser);
17523 return;
17525 case POSTINCREMENT_EXPR:
17526 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17527 code = OMP_ATOMIC_CAPTURE_OLD;
17528 /* FALLTHROUGH */
17529 case PREINCREMENT_EXPR:
17530 lhs = TREE_OPERAND (lhs, 0);
17531 unfolded_lhs = NULL_TREE;
17532 opcode = PLUS_EXPR;
17533 rhs = integer_one_node;
17534 break;
17536 case POSTDECREMENT_EXPR:
17537 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17538 code = OMP_ATOMIC_CAPTURE_OLD;
17539 /* FALLTHROUGH */
17540 case PREDECREMENT_EXPR:
17541 lhs = TREE_OPERAND (lhs, 0);
17542 unfolded_lhs = NULL_TREE;
17543 opcode = MINUS_EXPR;
17544 rhs = integer_one_node;
17545 break;
17547 case COMPOUND_EXPR:
17548 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
17549 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
17550 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
17551 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
17552 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17553 (TREE_OPERAND (lhs, 1), 0), 0)))
17554 == BOOLEAN_TYPE)
17555 /* Undo effects of boolean_increment for post {in,de}crement. */
17556 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
17557 /* FALLTHRU */
17558 case MODIFY_EXPR:
17559 if (TREE_CODE (lhs) == MODIFY_EXPR
17560 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
17562 /* Undo effects of boolean_increment. */
17563 if (integer_onep (TREE_OPERAND (lhs, 1)))
17565 /* This is pre or post increment. */
17566 rhs = TREE_OPERAND (lhs, 1);
17567 lhs = TREE_OPERAND (lhs, 0);
17568 unfolded_lhs = NULL_TREE;
17569 opcode = NOP_EXPR;
17570 if (code == OMP_ATOMIC_CAPTURE_NEW
17571 && !structured_block
17572 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17573 code = OMP_ATOMIC_CAPTURE_OLD;
17574 break;
17576 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
17577 && TREE_OPERAND (lhs, 0)
17578 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
17580 /* This is pre or post decrement. */
17581 rhs = TREE_OPERAND (lhs, 1);
17582 lhs = TREE_OPERAND (lhs, 0);
17583 unfolded_lhs = NULL_TREE;
17584 opcode = NOP_EXPR;
17585 if (code == OMP_ATOMIC_CAPTURE_NEW
17586 && !structured_block
17587 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17588 code = OMP_ATOMIC_CAPTURE_OLD;
17589 break;
17592 /* FALLTHRU */
17593 default:
17594 if (!lvalue_p (unfolded_lhs))
17595 lhs = non_lvalue (lhs);
17596 switch (c_parser_peek_token (parser)->type)
17598 case CPP_MULT_EQ:
17599 opcode = MULT_EXPR;
17600 break;
17601 case CPP_DIV_EQ:
17602 opcode = TRUNC_DIV_EXPR;
17603 break;
17604 case CPP_PLUS_EQ:
17605 opcode = PLUS_EXPR;
17606 break;
17607 case CPP_MINUS_EQ:
17608 opcode = MINUS_EXPR;
17609 break;
17610 case CPP_LSHIFT_EQ:
17611 opcode = LSHIFT_EXPR;
17612 break;
17613 case CPP_RSHIFT_EQ:
17614 opcode = RSHIFT_EXPR;
17615 break;
17616 case CPP_AND_EQ:
17617 opcode = BIT_AND_EXPR;
17618 break;
17619 case CPP_OR_EQ:
17620 opcode = BIT_IOR_EXPR;
17621 break;
17622 case CPP_XOR_EQ:
17623 opcode = BIT_XOR_EXPR;
17624 break;
17625 case CPP_EQ:
17626 c_parser_consume_token (parser);
17627 eloc = c_parser_peek_token (parser)->location;
17628 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
17629 rhs1 = expr.value;
17630 switch (TREE_CODE (rhs1))
17632 case MULT_EXPR:
17633 case TRUNC_DIV_EXPR:
17634 case RDIV_EXPR:
17635 case PLUS_EXPR:
17636 case MINUS_EXPR:
17637 case LSHIFT_EXPR:
17638 case RSHIFT_EXPR:
17639 case BIT_AND_EXPR:
17640 case BIT_IOR_EXPR:
17641 case BIT_XOR_EXPR:
17642 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
17644 opcode = TREE_CODE (rhs1);
17645 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17646 true);
17647 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17648 true);
17649 goto stmt_done;
17651 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
17653 opcode = TREE_CODE (rhs1);
17654 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17655 true);
17656 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17657 true);
17658 swapped = !commutative_tree_code (opcode);
17659 goto stmt_done;
17661 break;
17662 case ERROR_MARK:
17663 goto saw_error;
17664 default:
17665 break;
17667 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
17669 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17671 code = OMP_ATOMIC_CAPTURE_OLD;
17672 v = lhs;
17673 lhs = NULL_TREE;
17674 expr = default_function_array_read_conversion (eloc, expr);
17675 unfolded_lhs1 = expr.value;
17676 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
17677 rhs1 = NULL_TREE;
17678 c_parser_consume_token (parser);
17679 goto restart;
17681 if (structured_block)
17683 opcode = NOP_EXPR;
17684 expr = default_function_array_read_conversion (eloc, expr);
17685 rhs = c_fully_fold (expr.value, false, NULL, true);
17686 rhs1 = NULL_TREE;
17687 goto stmt_done;
17690 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
17691 goto saw_error;
17692 default:
17693 c_parser_error (parser,
17694 "invalid operator for %<#pragma omp atomic%>");
17695 goto saw_error;
17698 /* Arrange to pass the location of the assignment operator to
17699 c_finish_omp_atomic. */
17700 loc = c_parser_peek_token (parser)->location;
17701 c_parser_consume_token (parser);
17702 eloc = c_parser_peek_token (parser)->location;
17703 expr = c_parser_expression (parser);
17704 expr = default_function_array_read_conversion (eloc, expr);
17705 rhs = expr.value;
17706 rhs = c_fully_fold (rhs, false, NULL, true);
17707 break;
17709 stmt_done:
17710 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17712 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
17713 goto saw_error;
17714 v = c_parser_cast_expression (parser, NULL).value;
17715 non_lvalue_p = !lvalue_p (v);
17716 v = c_fully_fold (v, false, NULL, true);
17717 if (v == error_mark_node)
17718 goto saw_error;
17719 if (non_lvalue_p)
17720 v = non_lvalue (v);
17721 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17722 goto saw_error;
17723 eloc = c_parser_peek_token (parser)->location;
17724 expr = c_parser_cast_expression (parser, NULL);
17725 lhs1 = expr.value;
17726 expr = default_function_array_read_conversion (eloc, expr);
17727 unfolded_lhs1 = expr.value;
17728 lhs1 = c_fully_fold (lhs1, false, NULL, true);
17729 if (lhs1 == error_mark_node)
17730 goto saw_error;
17731 if (!lvalue_p (unfolded_lhs1))
17732 lhs1 = non_lvalue (lhs1);
17734 if (structured_block)
17736 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17737 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
17739 done:
17740 if (unfolded_lhs && unfolded_lhs1
17741 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
17743 error ("%<#pragma omp atomic capture%> uses two different "
17744 "expressions for memory");
17745 stmt = error_mark_node;
17747 else
17748 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1,
17749 swapped, memory_order);
17750 if (stmt != error_mark_node)
17751 add_stmt (stmt);
17753 if (!structured_block)
17754 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17758 /* OpenMP 2.5:
17759 # pragma omp barrier new-line
17762 static void
17763 c_parser_omp_barrier (c_parser *parser)
17765 location_t loc = c_parser_peek_token (parser)->location;
17766 c_parser_consume_pragma (parser);
17767 c_parser_skip_to_pragma_eol (parser);
17769 c_finish_omp_barrier (loc);
17772 /* OpenMP 2.5:
17773 # pragma omp critical [(name)] new-line
17774 structured-block
17776 OpenMP 4.5:
17777 # pragma omp critical [(name) [hint(expression)]] new-line
17779 LOC is the location of the #pragma itself. */
17781 #define OMP_CRITICAL_CLAUSE_MASK \
17782 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
17784 static tree
17785 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
17787 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
17789 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17791 c_parser_consume_token (parser);
17792 if (c_parser_next_token_is (parser, CPP_NAME))
17794 name = c_parser_peek_token (parser)->value;
17795 c_parser_consume_token (parser);
17796 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
17798 else
17799 c_parser_error (parser, "expected identifier");
17801 if (c_parser_next_token_is (parser, CPP_COMMA)
17802 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
17803 c_parser_consume_token (parser);
17805 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
17806 "#pragma omp critical");
17807 stmt = c_parser_omp_structured_block (parser, if_p);
17808 return c_finish_omp_critical (loc, stmt, name, clauses);
17811 /* OpenMP 5.0:
17812 # pragma omp depobj ( depobj ) depobj-clause new-line
17814 depobj-clause:
17815 depend (dependence-type : locator)
17816 destroy
17817 update (dependence-type)
17819 dependence-type:
17822 inout
17823 mutexinout */
17825 static void
17826 c_parser_omp_depobj (c_parser *parser)
17828 location_t loc = c_parser_peek_token (parser)->location;
17829 c_parser_consume_pragma (parser);
17830 matching_parens parens;
17831 if (!parens.require_open (parser))
17833 c_parser_skip_to_pragma_eol (parser);
17834 return;
17837 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
17838 if (depobj != error_mark_node)
17840 if (!lvalue_p (depobj))
17842 error_at (EXPR_LOC_OR_LOC (depobj, loc),
17843 "%<depobj%> expression is not lvalue expression");
17844 depobj = error_mark_node;
17846 else
17848 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
17849 depobj, false);
17850 if (addr == error_mark_node)
17851 depobj = error_mark_node;
17852 else
17853 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
17854 addr, RO_UNARY_STAR);
17858 parens.skip_until_found_close (parser);
17859 tree clause = NULL_TREE;
17860 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
17861 location_t c_loc = c_parser_peek_token (parser)->location;
17862 if (c_parser_next_token_is (parser, CPP_NAME))
17864 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17866 c_parser_consume_token (parser);
17867 if (!strcmp ("depend", p))
17869 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
17870 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
17871 if (!clause)
17872 clause = error_mark_node;
17874 else if (!strcmp ("destroy", p))
17875 kind = OMP_CLAUSE_DEPEND_LAST;
17876 else if (!strcmp ("update", p))
17878 matching_parens c_parens;
17879 if (c_parens.require_open (parser))
17881 location_t c2_loc = c_parser_peek_token (parser)->location;
17882 if (c_parser_next_token_is (parser, CPP_NAME))
17884 const char *p2
17885 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17887 c_parser_consume_token (parser);
17888 if (!strcmp ("in", p2))
17889 kind = OMP_CLAUSE_DEPEND_IN;
17890 else if (!strcmp ("out", p2))
17891 kind = OMP_CLAUSE_DEPEND_OUT;
17892 else if (!strcmp ("inout", p2))
17893 kind = OMP_CLAUSE_DEPEND_INOUT;
17894 else if (!strcmp ("mutexinoutset", p2))
17895 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
17897 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
17899 clause = error_mark_node;
17900 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
17901 "%<mutexinoutset%>");
17903 c_parens.skip_until_found_close (parser);
17905 else
17906 clause = error_mark_node;
17909 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
17911 clause = error_mark_node;
17912 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
17914 c_parser_skip_to_pragma_eol (parser);
17916 c_finish_omp_depobj (loc, depobj, kind, clause);
17920 /* OpenMP 2.5:
17921 # pragma omp flush flush-vars[opt] new-line
17923 flush-vars:
17924 ( variable-list )
17926 OpenMP 5.0:
17927 # pragma omp flush memory-order-clause new-line */
17929 static void
17930 c_parser_omp_flush (c_parser *parser)
17932 location_t loc = c_parser_peek_token (parser)->location;
17933 c_parser_consume_pragma (parser);
17934 enum memmodel mo = MEMMODEL_LAST;
17935 if (c_parser_next_token_is (parser, CPP_NAME))
17937 const char *p
17938 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17940 if (!strcmp (p, "acq_rel"))
17941 mo = MEMMODEL_ACQ_REL;
17942 else if (!strcmp (p, "release"))
17943 mo = MEMMODEL_RELEASE;
17944 else if (!strcmp (p, "acquire"))
17945 mo = MEMMODEL_ACQUIRE;
17946 else
17947 error_at (c_parser_peek_token (parser)->location,
17948 "expected %<acq_rel%>, %<release%> or %<acquire%>");
17949 c_parser_consume_token (parser);
17951 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17953 if (mo != MEMMODEL_LAST)
17954 error_at (c_parser_peek_token (parser)->location,
17955 "%<flush%> list specified together with memory order "
17956 "clause");
17957 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
17959 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17960 c_parser_error (parser, "expected %<(%> or end of line");
17961 c_parser_skip_to_pragma_eol (parser);
17963 c_finish_omp_flush (loc, mo);
17966 /* OpenMP 5.0:
17968 scan-loop-body:
17969 { structured-block scan-directive structured-block } */
17971 static void
17972 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
17974 tree substmt;
17975 location_t loc;
17976 tree clauses = NULL_TREE;
17978 loc = c_parser_peek_token (parser)->location;
17979 if (!open_brace_parsed
17980 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
17982 /* Avoid skipping until the end of the block. */
17983 parser->error = false;
17984 return;
17987 substmt = c_parser_omp_structured_block (parser, NULL);
17988 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
17989 SET_EXPR_LOCATION (substmt, loc);
17990 add_stmt (substmt);
17992 loc = c_parser_peek_token (parser)->location;
17993 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
17995 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
17997 c_parser_consume_pragma (parser);
17999 if (c_parser_next_token_is (parser, CPP_NAME))
18001 const char *p
18002 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18003 if (strcmp (p, "inclusive") == 0)
18004 clause = OMP_CLAUSE_INCLUSIVE;
18005 else if (strcmp (p, "exclusive") == 0)
18006 clause = OMP_CLAUSE_EXCLUSIVE;
18008 if (clause != OMP_CLAUSE_ERROR)
18010 c_parser_consume_token (parser);
18011 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
18013 else
18014 c_parser_error (parser, "expected %<inclusive%> or "
18015 "%<exclusive%> clause");
18016 c_parser_skip_to_pragma_eol (parser);
18018 else
18019 error ("expected %<#pragma omp scan%>");
18021 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
18022 substmt = c_parser_omp_structured_block (parser, NULL);
18023 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
18024 SET_EXPR_LOCATION (substmt, loc);
18025 add_stmt (substmt);
18027 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
18028 "expected %<}%>");
18031 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
18032 The real trick here is to determine the loop control variable early
18033 so that we can push a new decl if necessary to make it private.
18034 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
18035 respectively. */
18037 static tree
18038 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
18039 tree clauses, tree *cclauses, bool *if_p)
18041 tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
18042 tree declv, condv, incrv, initv, ret = NULL_TREE;
18043 tree pre_body = NULL_TREE, this_pre_body;
18044 tree ordered_cl = NULL_TREE;
18045 bool fail = false, open_brace_parsed = false;
18046 int i, collapse = 1, ordered = 0, count, nbraces = 0;
18047 location_t for_loc;
18048 bool tiling = false;
18049 bool inscan = false;
18050 vec<tree, va_gc> *for_block = make_tree_vector ();
18052 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
18053 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
18054 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
18055 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
18057 tiling = true;
18058 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
18060 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
18061 && OMP_CLAUSE_ORDERED_EXPR (cl))
18063 ordered_cl = cl;
18064 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
18066 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
18067 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
18068 && (code == OMP_SIMD || code == OMP_FOR))
18069 inscan = true;
18071 if (ordered && ordered < collapse)
18073 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
18074 "%<ordered%> clause parameter is less than %<collapse%>");
18075 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
18076 = build_int_cst (NULL_TREE, collapse);
18077 ordered = collapse;
18079 if (ordered)
18081 for (tree *pc = &clauses; *pc; )
18082 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
18084 error_at (OMP_CLAUSE_LOCATION (*pc),
18085 "%<linear%> clause may not be specified together "
18086 "with %<ordered%> clause with a parameter");
18087 *pc = OMP_CLAUSE_CHAIN (*pc);
18089 else
18090 pc = &OMP_CLAUSE_CHAIN (*pc);
18093 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
18094 count = ordered ? ordered : collapse;
18096 declv = make_tree_vec (count);
18097 initv = make_tree_vec (count);
18098 condv = make_tree_vec (count);
18099 incrv = make_tree_vec (count);
18101 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
18103 c_parser_error (parser, "for statement expected");
18104 return NULL;
18106 for_loc = c_parser_peek_token (parser)->location;
18107 c_parser_consume_token (parser);
18109 for (i = 0; i < count; i++)
18111 int bracecount = 0;
18113 matching_parens parens;
18114 if (!parens.require_open (parser))
18115 goto pop_scopes;
18117 /* Parse the initialization declaration or expression. */
18118 if (c_parser_next_tokens_start_declaration (parser))
18120 if (i > 0)
18121 vec_safe_push (for_block, c_begin_compound_stmt (true));
18122 this_pre_body = push_stmt_list ();
18123 c_in_omp_for = true;
18124 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
18125 NULL, vNULL);
18126 c_in_omp_for = false;
18127 if (this_pre_body)
18129 this_pre_body = pop_stmt_list (this_pre_body);
18130 if (pre_body)
18132 tree t = pre_body;
18133 pre_body = push_stmt_list ();
18134 add_stmt (t);
18135 add_stmt (this_pre_body);
18136 pre_body = pop_stmt_list (pre_body);
18138 else
18139 pre_body = this_pre_body;
18141 decl = check_for_loop_decls (for_loc, flag_isoc99);
18142 if (decl == NULL)
18143 goto error_init;
18144 if (DECL_INITIAL (decl) == error_mark_node)
18145 decl = error_mark_node;
18146 init = decl;
18148 else if (c_parser_next_token_is (parser, CPP_NAME)
18149 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
18151 struct c_expr decl_exp;
18152 struct c_expr init_exp;
18153 location_t init_loc;
18155 decl_exp = c_parser_postfix_expression (parser);
18156 decl = decl_exp.value;
18158 c_parser_require (parser, CPP_EQ, "expected %<=%>");
18160 init_loc = c_parser_peek_token (parser)->location;
18161 init_exp = c_parser_expr_no_commas (parser, NULL);
18162 init_exp = default_function_array_read_conversion (init_loc,
18163 init_exp);
18164 c_in_omp_for = true;
18165 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
18166 NOP_EXPR, init_loc, init_exp.value,
18167 init_exp.original_type);
18168 c_in_omp_for = false;
18169 init = c_process_expr_stmt (init_loc, init);
18171 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18173 else
18175 error_init:
18176 c_parser_error (parser,
18177 "expected iteration declaration or initialization");
18178 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18179 "expected %<)%>");
18180 fail = true;
18181 goto parse_next;
18184 /* Parse the loop condition. */
18185 cond = NULL_TREE;
18186 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
18188 location_t cond_loc = c_parser_peek_token (parser)->location;
18189 c_in_omp_for = true;
18190 struct c_expr cond_expr
18191 = c_parser_binary_expression (parser, NULL, NULL_TREE);
18192 c_in_omp_for = false;
18194 cond = cond_expr.value;
18195 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
18196 switch (cond_expr.original_code)
18198 case GT_EXPR:
18199 case GE_EXPR:
18200 case LT_EXPR:
18201 case LE_EXPR:
18202 break;
18203 case NE_EXPR:
18204 if (code != OACC_LOOP)
18205 break;
18206 /* FALLTHRU. */
18207 default:
18208 /* Can't be cond = error_mark_node, because we want to preserve
18209 the location until c_finish_omp_for. */
18210 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
18211 break;
18213 protected_set_expr_location (cond, cond_loc);
18215 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18217 /* Parse the increment expression. */
18218 incr = NULL_TREE;
18219 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
18221 location_t incr_loc = c_parser_peek_token (parser)->location;
18223 incr = c_process_expr_stmt (incr_loc,
18224 c_parser_expression (parser).value);
18226 parens.skip_until_found_close (parser);
18228 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
18229 fail = true;
18230 else
18232 TREE_VEC_ELT (declv, i) = decl;
18233 TREE_VEC_ELT (initv, i) = init;
18234 TREE_VEC_ELT (condv, i) = cond;
18235 TREE_VEC_ELT (incrv, i) = incr;
18238 parse_next:
18239 if (i == count - 1)
18240 break;
18242 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18243 in between the collapsed for loops to be still considered perfectly
18244 nested. Hopefully the final version clarifies this.
18245 For now handle (multiple) {'s and empty statements. */
18248 if (c_parser_next_token_is_keyword (parser, RID_FOR))
18250 c_parser_consume_token (parser);
18251 break;
18253 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18255 c_parser_consume_token (parser);
18256 bracecount++;
18258 else if (bracecount
18259 && c_parser_next_token_is (parser, CPP_SEMICOLON))
18260 c_parser_consume_token (parser);
18261 else
18263 c_parser_error (parser, "not enough perfectly nested loops");
18264 if (bracecount)
18266 open_brace_parsed = true;
18267 bracecount--;
18269 fail = true;
18270 count = 0;
18271 break;
18274 while (1);
18276 nbraces += bracecount;
18279 if (nbraces)
18280 if_p = NULL;
18282 save_break = c_break_label;
18283 c_break_label = size_one_node;
18284 save_cont = c_cont_label;
18285 c_cont_label = NULL_TREE;
18286 body = push_stmt_list ();
18288 if (inscan)
18289 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
18290 else if (open_brace_parsed)
18292 location_t here = c_parser_peek_token (parser)->location;
18293 stmt = c_begin_compound_stmt (true);
18294 c_parser_compound_statement_nostart (parser);
18295 add_stmt (c_end_compound_stmt (here, stmt, true));
18297 else
18298 add_stmt (c_parser_c99_block_statement (parser, if_p));
18299 if (c_cont_label)
18301 tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
18302 SET_EXPR_LOCATION (t, loc);
18303 add_stmt (t);
18306 body = pop_stmt_list (body);
18307 c_break_label = save_break;
18308 c_cont_label = save_cont;
18310 while (nbraces)
18312 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18314 c_parser_consume_token (parser);
18315 nbraces--;
18317 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
18318 c_parser_consume_token (parser);
18319 else
18321 c_parser_error (parser, "collapsed loops not perfectly nested");
18322 while (nbraces)
18324 location_t here = c_parser_peek_token (parser)->location;
18325 stmt = c_begin_compound_stmt (true);
18326 add_stmt (body);
18327 c_parser_compound_statement_nostart (parser);
18328 body = c_end_compound_stmt (here, stmt, true);
18329 nbraces--;
18331 goto pop_scopes;
18335 /* Only bother calling c_finish_omp_for if we haven't already generated
18336 an error from the initialization parsing. */
18337 if (!fail)
18339 c_in_omp_for = true;
18340 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
18341 incrv, body, pre_body, true);
18342 c_in_omp_for = false;
18344 /* Check for iterators appearing in lb, b or incr expressions. */
18345 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
18346 stmt = NULL_TREE;
18348 if (stmt)
18350 add_stmt (stmt);
18352 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
18354 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
18355 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
18356 tree decl = TREE_OPERAND (init, 0);
18357 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
18358 gcc_assert (COMPARISON_CLASS_P (cond));
18359 gcc_assert (TREE_OPERAND (cond, 0) == decl);
18361 tree op0 = TREE_OPERAND (init, 1);
18362 if (!OMP_FOR_NON_RECTANGULAR (stmt)
18363 || TREE_CODE (op0) != TREE_VEC)
18364 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
18365 else
18367 TREE_VEC_ELT (op0, 1)
18368 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
18369 TREE_VEC_ELT (op0, 2)
18370 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
18373 tree op1 = TREE_OPERAND (cond, 1);
18374 if (!OMP_FOR_NON_RECTANGULAR (stmt)
18375 || TREE_CODE (op1) != TREE_VEC)
18376 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
18377 else
18379 TREE_VEC_ELT (op1, 1)
18380 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
18381 TREE_VEC_ELT (op1, 2)
18382 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
18386 if (cclauses != NULL
18387 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
18389 tree *c;
18390 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
18391 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
18392 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
18393 c = &OMP_CLAUSE_CHAIN (*c);
18394 else
18396 for (i = 0; i < count; i++)
18397 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
18398 break;
18399 if (i == count)
18400 c = &OMP_CLAUSE_CHAIN (*c);
18401 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
18403 error_at (loc,
18404 "iteration variable %qD should not be firstprivate",
18405 OMP_CLAUSE_DECL (*c));
18406 *c = OMP_CLAUSE_CHAIN (*c);
18408 else
18410 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
18411 tree l = *c;
18412 *c = OMP_CLAUSE_CHAIN (*c);
18413 if (code == OMP_SIMD)
18415 OMP_CLAUSE_CHAIN (l)
18416 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18417 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
18419 else
18421 OMP_CLAUSE_CHAIN (l) = clauses;
18422 clauses = l;
18427 OMP_FOR_CLAUSES (stmt) = clauses;
18429 ret = stmt;
18431 pop_scopes:
18432 while (!for_block->is_empty ())
18434 /* FIXME diagnostics: LOC below should be the actual location of
18435 this particular for block. We need to build a list of
18436 locations to go along with FOR_BLOCK. */
18437 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
18438 add_stmt (stmt);
18440 release_tree_vector (for_block);
18441 return ret;
18444 /* Helper function for OpenMP parsing, split clauses and call
18445 finish_omp_clauses on each of the set of clauses afterwards. */
18447 static void
18448 omp_split_clauses (location_t loc, enum tree_code code,
18449 omp_clause_mask mask, tree clauses, tree *cclauses)
18451 int i;
18452 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
18453 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
18454 if (cclauses[i])
18455 cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP);
18458 /* OpenMP 5.0:
18459 #pragma omp loop loop-clause[optseq] new-line
18460 for-loop
18462 LOC is the location of the #pragma token.
18465 #define OMP_LOOP_CLAUSE_MASK \
18466 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
18471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18473 static tree
18474 c_parser_omp_loop (location_t loc, c_parser *parser,
18475 char *p_name, omp_clause_mask mask, tree *cclauses,
18476 bool *if_p)
18478 tree block, clauses, ret;
18480 strcat (p_name, " loop");
18481 mask |= OMP_LOOP_CLAUSE_MASK;
18483 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18484 if (cclauses)
18486 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
18487 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
18490 block = c_begin_compound_stmt (true);
18491 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
18492 block = c_end_compound_stmt (loc, block, true);
18493 add_stmt (block);
18495 return ret;
18498 /* OpenMP 4.0:
18499 #pragma omp simd simd-clause[optseq] new-line
18500 for-loop
18502 LOC is the location of the #pragma token.
18505 #define OMP_SIMD_CLAUSE_MASK \
18506 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
18507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
18508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
18510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18514 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18515 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
18516 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18518 static tree
18519 c_parser_omp_simd (location_t loc, c_parser *parser,
18520 char *p_name, omp_clause_mask mask, tree *cclauses,
18521 bool *if_p)
18523 tree block, clauses, ret;
18525 strcat (p_name, " simd");
18526 mask |= OMP_SIMD_CLAUSE_MASK;
18528 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18529 if (cclauses)
18531 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
18532 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
18533 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
18534 OMP_CLAUSE_ORDERED);
18535 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
18537 error_at (OMP_CLAUSE_LOCATION (c),
18538 "%<ordered%> clause with parameter may not be specified "
18539 "on %qs construct", p_name);
18540 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
18544 block = c_begin_compound_stmt (true);
18545 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
18546 block = c_end_compound_stmt (loc, block, true);
18547 add_stmt (block);
18549 return ret;
18552 /* OpenMP 2.5:
18553 #pragma omp for for-clause[optseq] new-line
18554 for-loop
18556 OpenMP 4.0:
18557 #pragma omp for simd for-simd-clause[optseq] new-line
18558 for-loop
18560 LOC is the location of the #pragma token.
18563 #define OMP_FOR_CLAUSE_MASK \
18564 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18567 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
18570 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
18571 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18575 static tree
18576 c_parser_omp_for (location_t loc, c_parser *parser,
18577 char *p_name, omp_clause_mask mask, tree *cclauses,
18578 bool *if_p)
18580 tree block, clauses, ret;
18582 strcat (p_name, " for");
18583 mask |= OMP_FOR_CLAUSE_MASK;
18584 /* parallel for{, simd} disallows nowait clause, but for
18585 target {teams distribute ,}parallel for{, simd} it should be accepted. */
18586 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
18587 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18588 /* Composite distribute parallel for{, simd} disallows ordered clause. */
18589 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18590 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
18592 if (c_parser_next_token_is (parser, CPP_NAME))
18594 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18596 if (strcmp (p, "simd") == 0)
18598 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18599 if (cclauses == NULL)
18600 cclauses = cclauses_buf;
18602 c_parser_consume_token (parser);
18603 if (!flag_openmp) /* flag_openmp_simd */
18604 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
18605 if_p);
18606 block = c_begin_compound_stmt (true);
18607 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
18608 block = c_end_compound_stmt (loc, block, true);
18609 if (ret == NULL_TREE)
18610 return ret;
18611 ret = make_node (OMP_FOR);
18612 TREE_TYPE (ret) = void_type_node;
18613 OMP_FOR_BODY (ret) = block;
18614 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18615 SET_EXPR_LOCATION (ret, loc);
18616 add_stmt (ret);
18617 return ret;
18620 if (!flag_openmp) /* flag_openmp_simd */
18622 c_parser_skip_to_pragma_eol (parser, false);
18623 return NULL_TREE;
18626 /* Composite distribute parallel for disallows linear clause. */
18627 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18628 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
18630 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18631 if (cclauses)
18633 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
18634 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18637 block = c_begin_compound_stmt (true);
18638 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
18639 block = c_end_compound_stmt (loc, block, true);
18640 add_stmt (block);
18642 return ret;
18645 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
18646 omp_clause_mask, tree *, bool *);
18648 /* OpenMP 2.5:
18649 # pragma omp master new-line
18650 structured-block
18652 LOC is the location of the #pragma token.
18655 static tree
18656 c_parser_omp_master (location_t loc, c_parser *parser,
18657 char *p_name, omp_clause_mask mask, tree *cclauses,
18658 bool *if_p)
18660 tree block, clauses, ret;
18662 strcat (p_name, " master");
18664 if (c_parser_next_token_is (parser, CPP_NAME))
18666 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18668 if (strcmp (p, "taskloop") == 0)
18670 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18671 if (cclauses == NULL)
18672 cclauses = cclauses_buf;
18674 c_parser_consume_token (parser);
18675 if (!flag_openmp) /* flag_openmp_simd */
18676 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18677 if_p);
18678 block = c_begin_compound_stmt (true);
18679 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18680 if_p);
18681 block = c_end_compound_stmt (loc, block, true);
18682 if (ret == NULL_TREE)
18683 return ret;
18684 ret = c_finish_omp_master (loc, block);
18685 return ret;
18688 if (!flag_openmp) /* flag_openmp_simd */
18690 c_parser_skip_to_pragma_eol (parser, false);
18691 return NULL_TREE;
18694 if (cclauses)
18696 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
18697 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
18699 else
18700 c_parser_skip_to_pragma_eol (parser);
18702 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
18703 if_p));
18706 /* OpenMP 2.5:
18707 # pragma omp ordered new-line
18708 structured-block
18710 OpenMP 4.5:
18711 # pragma omp ordered ordered-clauses new-line
18712 structured-block
18714 # pragma omp ordered depend-clauses new-line */
18716 #define OMP_ORDERED_CLAUSE_MASK \
18717 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
18718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
18720 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
18721 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18723 static bool
18724 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
18725 bool *if_p)
18727 location_t loc = c_parser_peek_token (parser)->location;
18728 c_parser_consume_pragma (parser);
18730 if (context != pragma_stmt && context != pragma_compound)
18732 c_parser_error (parser, "expected declaration specifiers");
18733 c_parser_skip_to_pragma_eol (parser, false);
18734 return false;
18737 if (c_parser_next_token_is (parser, CPP_NAME))
18739 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18741 if (!strcmp ("depend", p))
18743 if (!flag_openmp) /* flag_openmp_simd */
18745 c_parser_skip_to_pragma_eol (parser, false);
18746 return false;
18748 if (context == pragma_stmt)
18750 error_at (loc,
18751 "%<#pragma omp ordered%> with %<depend%> clause may "
18752 "only be used in compound statements");
18753 c_parser_skip_to_pragma_eol (parser, false);
18754 return false;
18757 tree clauses
18758 = c_parser_omp_all_clauses (parser,
18759 OMP_ORDERED_DEPEND_CLAUSE_MASK,
18760 "#pragma omp ordered");
18761 c_finish_omp_ordered (loc, clauses, NULL_TREE);
18762 return false;
18766 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
18767 "#pragma omp ordered");
18769 if (!flag_openmp /* flag_openmp_simd */
18770 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
18771 return false;
18773 c_finish_omp_ordered (loc, clauses,
18774 c_parser_omp_structured_block (parser, if_p));
18775 return true;
18778 /* OpenMP 2.5:
18780 section-scope:
18781 { section-sequence }
18783 section-sequence:
18784 section-directive[opt] structured-block
18785 section-sequence section-directive structured-block
18787 SECTIONS_LOC is the location of the #pragma omp sections. */
18789 static tree
18790 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
18792 tree stmt, substmt;
18793 bool error_suppress = false;
18794 location_t loc;
18796 loc = c_parser_peek_token (parser)->location;
18797 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18799 /* Avoid skipping until the end of the block. */
18800 parser->error = false;
18801 return NULL_TREE;
18804 stmt = push_stmt_list ();
18806 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
18808 substmt = c_parser_omp_structured_block (parser, NULL);
18809 substmt = build1 (OMP_SECTION, void_type_node, substmt);
18810 SET_EXPR_LOCATION (substmt, loc);
18811 add_stmt (substmt);
18814 while (1)
18816 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18817 break;
18818 if (c_parser_next_token_is (parser, CPP_EOF))
18819 break;
18821 loc = c_parser_peek_token (parser)->location;
18822 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
18824 c_parser_consume_pragma (parser);
18825 c_parser_skip_to_pragma_eol (parser);
18826 error_suppress = false;
18828 else if (!error_suppress)
18830 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
18831 error_suppress = true;
18834 substmt = c_parser_omp_structured_block (parser, NULL);
18835 substmt = build1 (OMP_SECTION, void_type_node, substmt);
18836 SET_EXPR_LOCATION (substmt, loc);
18837 add_stmt (substmt);
18839 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
18840 "expected %<#pragma omp section%> or %<}%>");
18842 substmt = pop_stmt_list (stmt);
18844 stmt = make_node (OMP_SECTIONS);
18845 SET_EXPR_LOCATION (stmt, sections_loc);
18846 TREE_TYPE (stmt) = void_type_node;
18847 OMP_SECTIONS_BODY (stmt) = substmt;
18849 return add_stmt (stmt);
18852 /* OpenMP 2.5:
18853 # pragma omp sections sections-clause[optseq] newline
18854 sections-scope
18856 LOC is the location of the #pragma token.
18859 #define OMP_SECTIONS_CLAUSE_MASK \
18860 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18864 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18866 static tree
18867 c_parser_omp_sections (location_t loc, c_parser *parser,
18868 char *p_name, omp_clause_mask mask, tree *cclauses)
18870 tree block, clauses, ret;
18872 strcat (p_name, " sections");
18873 mask |= OMP_SECTIONS_CLAUSE_MASK;
18874 if (cclauses)
18875 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18877 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18878 if (cclauses)
18880 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
18881 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
18884 block = c_begin_compound_stmt (true);
18885 ret = c_parser_omp_sections_scope (loc, parser);
18886 if (ret)
18887 OMP_SECTIONS_CLAUSES (ret) = clauses;
18888 block = c_end_compound_stmt (loc, block, true);
18889 add_stmt (block);
18891 return ret;
18894 /* OpenMP 2.5:
18895 # pragma omp parallel parallel-clause[optseq] new-line
18896 structured-block
18897 # pragma omp parallel for parallel-for-clause[optseq] new-line
18898 structured-block
18899 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
18900 structured-block
18902 OpenMP 4.0:
18903 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
18904 structured-block
18906 LOC is the location of the #pragma token.
18909 #define OMP_PARALLEL_CLAUSE_MASK \
18910 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
18916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
18918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
18920 static tree
18921 c_parser_omp_parallel (location_t loc, c_parser *parser,
18922 char *p_name, omp_clause_mask mask, tree *cclauses,
18923 bool *if_p)
18925 tree stmt, clauses, block;
18927 strcat (p_name, " parallel");
18928 mask |= OMP_PARALLEL_CLAUSE_MASK;
18929 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
18930 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
18931 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
18932 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
18934 if (c_parser_next_token_is_keyword (parser, RID_FOR))
18936 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18937 if (cclauses == NULL)
18938 cclauses = cclauses_buf;
18940 c_parser_consume_token (parser);
18941 if (!flag_openmp) /* flag_openmp_simd */
18942 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
18943 block = c_begin_omp_parallel ();
18944 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
18945 stmt
18946 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18947 block);
18948 if (ret == NULL_TREE)
18949 return ret;
18950 OMP_PARALLEL_COMBINED (stmt) = 1;
18951 return stmt;
18953 /* When combined with distribute, parallel has to be followed by for.
18954 #pragma omp target parallel is allowed though. */
18955 else if (cclauses
18956 && (mask & (OMP_CLAUSE_MASK_1
18957 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18959 error_at (loc, "expected %<for%> after %qs", p_name);
18960 c_parser_skip_to_pragma_eol (parser);
18961 return NULL_TREE;
18963 else if (c_parser_next_token_is (parser, CPP_NAME))
18965 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18966 if (cclauses == NULL && strcmp (p, "master") == 0)
18968 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18969 cclauses = cclauses_buf;
18971 c_parser_consume_token (parser);
18972 if (!flag_openmp) /* flag_openmp_simd */
18973 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18974 if_p);
18975 block = c_begin_omp_parallel ();
18976 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18977 if_p);
18978 stmt = c_finish_omp_parallel (loc,
18979 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18980 block);
18981 if (ret == NULL)
18982 return ret;
18983 OMP_PARALLEL_COMBINED (stmt) = 1;
18984 return stmt;
18986 else if (strcmp (p, "loop") == 0)
18988 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18989 if (cclauses == NULL)
18990 cclauses = cclauses_buf;
18992 c_parser_consume_token (parser);
18993 if (!flag_openmp) /* flag_openmp_simd */
18994 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18995 if_p);
18996 block = c_begin_omp_parallel ();
18997 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18998 if_p);
18999 stmt
19000 = c_finish_omp_parallel (loc,
19001 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19002 block);
19003 if (ret == NULL_TREE)
19004 return ret;
19005 OMP_PARALLEL_COMBINED (stmt) = 1;
19006 return stmt;
19008 else if (!flag_openmp) /* flag_openmp_simd */
19010 c_parser_skip_to_pragma_eol (parser, false);
19011 return NULL_TREE;
19013 else if (cclauses == NULL && strcmp (p, "sections") == 0)
19015 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19016 cclauses = cclauses_buf;
19018 c_parser_consume_token (parser);
19019 block = c_begin_omp_parallel ();
19020 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
19021 stmt = c_finish_omp_parallel (loc,
19022 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19023 block);
19024 OMP_PARALLEL_COMBINED (stmt) = 1;
19025 return stmt;
19028 else if (!flag_openmp) /* flag_openmp_simd */
19030 c_parser_skip_to_pragma_eol (parser, false);
19031 return NULL_TREE;
19034 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19035 if (cclauses)
19037 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
19038 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
19041 block = c_begin_omp_parallel ();
19042 c_parser_statement (parser, if_p);
19043 stmt = c_finish_omp_parallel (loc, clauses, block);
19045 return stmt;
19048 /* OpenMP 2.5:
19049 # pragma omp single single-clause[optseq] new-line
19050 structured-block
19052 LOC is the location of the #pragma.
19055 #define OMP_SINGLE_CLAUSE_MASK \
19056 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
19059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19061 static tree
19062 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
19064 tree stmt = make_node (OMP_SINGLE);
19065 SET_EXPR_LOCATION (stmt, loc);
19066 TREE_TYPE (stmt) = void_type_node;
19068 OMP_SINGLE_CLAUSES (stmt)
19069 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
19070 "#pragma omp single");
19071 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
19073 return add_stmt (stmt);
19076 /* OpenMP 3.0:
19077 # pragma omp task task-clause[optseq] new-line
19079 LOC is the location of the #pragma.
19082 #define OMP_TASK_CLAUSE_MASK \
19083 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
19085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
19086 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19087 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19088 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19089 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
19090 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
19091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
19093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
19095 static tree
19096 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
19098 tree clauses, block;
19100 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
19101 "#pragma omp task");
19103 block = c_begin_omp_task ();
19104 c_parser_statement (parser, if_p);
19105 return c_finish_omp_task (loc, clauses, block);
19108 /* OpenMP 3.0:
19109 # pragma omp taskwait new-line
19111 OpenMP 5.0:
19112 # pragma omp taskwait taskwait-clause[optseq] new-line
19115 #define OMP_TASKWAIT_CLAUSE_MASK \
19116 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19118 static void
19119 c_parser_omp_taskwait (c_parser *parser)
19121 location_t loc = c_parser_peek_token (parser)->location;
19122 c_parser_consume_pragma (parser);
19124 tree clauses
19125 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
19126 "#pragma omp taskwait");
19128 if (clauses)
19130 tree stmt = make_node (OMP_TASK);
19131 TREE_TYPE (stmt) = void_node;
19132 OMP_TASK_CLAUSES (stmt) = clauses;
19133 OMP_TASK_BODY (stmt) = NULL_TREE;
19134 SET_EXPR_LOCATION (stmt, loc);
19135 add_stmt (stmt);
19137 else
19138 c_finish_omp_taskwait (loc);
19141 /* OpenMP 3.1:
19142 # pragma omp taskyield new-line
19145 static void
19146 c_parser_omp_taskyield (c_parser *parser)
19148 location_t loc = c_parser_peek_token (parser)->location;
19149 c_parser_consume_pragma (parser);
19150 c_parser_skip_to_pragma_eol (parser);
19152 c_finish_omp_taskyield (loc);
19155 /* OpenMP 4.0:
19156 # pragma omp taskgroup new-line
19158 OpenMP 5.0:
19159 # pragma omp taskgroup taskgroup-clause[optseq] new-line
19162 #define OMP_TASKGROUP_CLAUSE_MASK \
19163 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19165 static tree
19166 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
19168 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
19169 "#pragma omp taskgroup");
19171 tree body = c_parser_omp_structured_block (parser, if_p);
19172 return c_finish_omp_taskgroup (loc, body, clauses);
19175 /* OpenMP 4.0:
19176 # pragma omp cancel cancel-clause[optseq] new-line
19178 LOC is the location of the #pragma.
19181 #define OMP_CANCEL_CLAUSE_MASK \
19182 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19183 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19184 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19185 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
19186 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
19188 static void
19189 c_parser_omp_cancel (c_parser *parser)
19191 location_t loc = c_parser_peek_token (parser)->location;
19193 c_parser_consume_pragma (parser);
19194 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
19195 "#pragma omp cancel");
19197 c_finish_omp_cancel (loc, clauses);
19200 /* OpenMP 4.0:
19201 # pragma omp cancellation point cancelpt-clause[optseq] new-line
19203 LOC is the location of the #pragma.
19206 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
19207 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19209 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19210 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
19212 static void
19213 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
19215 location_t loc = c_parser_peek_token (parser)->location;
19216 tree clauses;
19217 bool point_seen = false;
19219 c_parser_consume_pragma (parser);
19220 if (c_parser_next_token_is (parser, CPP_NAME))
19222 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19223 if (strcmp (p, "point") == 0)
19225 c_parser_consume_token (parser);
19226 point_seen = true;
19229 if (!point_seen)
19231 c_parser_error (parser, "expected %<point%>");
19232 c_parser_skip_to_pragma_eol (parser);
19233 return;
19236 if (context != pragma_compound)
19238 if (context == pragma_stmt)
19239 error_at (loc,
19240 "%<#pragma %s%> may only be used in compound statements",
19241 "omp cancellation point");
19242 else
19243 c_parser_error (parser, "expected declaration specifiers");
19244 c_parser_skip_to_pragma_eol (parser, false);
19245 return;
19248 clauses
19249 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
19250 "#pragma omp cancellation point");
19252 c_finish_omp_cancellation_point (loc, clauses);
19255 /* OpenMP 4.0:
19256 #pragma omp distribute distribute-clause[optseq] new-line
19257 for-loop */
19259 #define OMP_DISTRIBUTE_CLAUSE_MASK \
19260 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19261 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19262 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19263 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19264 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
19266 static tree
19267 c_parser_omp_distribute (location_t loc, c_parser *parser,
19268 char *p_name, omp_clause_mask mask, tree *cclauses,
19269 bool *if_p)
19271 tree clauses, block, ret;
19273 strcat (p_name, " distribute");
19274 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
19276 if (c_parser_next_token_is (parser, CPP_NAME))
19278 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19279 bool simd = false;
19280 bool parallel = false;
19282 if (strcmp (p, "simd") == 0)
19283 simd = true;
19284 else
19285 parallel = strcmp (p, "parallel") == 0;
19286 if (parallel || simd)
19288 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19289 if (cclauses == NULL)
19290 cclauses = cclauses_buf;
19291 c_parser_consume_token (parser);
19292 if (!flag_openmp) /* flag_openmp_simd */
19294 if (simd)
19295 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19296 if_p);
19297 else
19298 return c_parser_omp_parallel (loc, parser, p_name, mask,
19299 cclauses, if_p);
19301 block = c_begin_compound_stmt (true);
19302 if (simd)
19303 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19304 if_p);
19305 else
19306 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
19307 if_p);
19308 block = c_end_compound_stmt (loc, block, true);
19309 if (ret == NULL)
19310 return ret;
19311 ret = make_node (OMP_DISTRIBUTE);
19312 TREE_TYPE (ret) = void_type_node;
19313 OMP_FOR_BODY (ret) = block;
19314 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19315 SET_EXPR_LOCATION (ret, loc);
19316 add_stmt (ret);
19317 return ret;
19320 if (!flag_openmp) /* flag_openmp_simd */
19322 c_parser_skip_to_pragma_eol (parser, false);
19323 return NULL_TREE;
19326 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19327 if (cclauses)
19329 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
19330 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19333 block = c_begin_compound_stmt (true);
19334 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
19335 if_p);
19336 block = c_end_compound_stmt (loc, block, true);
19337 add_stmt (block);
19339 return ret;
19342 /* OpenMP 4.0:
19343 # pragma omp teams teams-clause[optseq] new-line
19344 structured-block */
19346 #define OMP_TEAMS_CLAUSE_MASK \
19347 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19348 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
19352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
19353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
19355 static tree
19356 c_parser_omp_teams (location_t loc, c_parser *parser,
19357 char *p_name, omp_clause_mask mask, tree *cclauses,
19358 bool *if_p)
19360 tree clauses, block, ret;
19362 strcat (p_name, " teams");
19363 mask |= OMP_TEAMS_CLAUSE_MASK;
19365 if (c_parser_next_token_is (parser, CPP_NAME))
19367 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19368 if (strcmp (p, "distribute") == 0)
19370 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19371 if (cclauses == NULL)
19372 cclauses = cclauses_buf;
19374 c_parser_consume_token (parser);
19375 if (!flag_openmp) /* flag_openmp_simd */
19376 return c_parser_omp_distribute (loc, parser, p_name, mask,
19377 cclauses, if_p);
19378 block = c_begin_omp_parallel ();
19379 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
19380 if_p);
19381 block = c_end_compound_stmt (loc, block, true);
19382 if (ret == NULL)
19383 return ret;
19384 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19385 ret = make_node (OMP_TEAMS);
19386 TREE_TYPE (ret) = void_type_node;
19387 OMP_TEAMS_CLAUSES (ret) = clauses;
19388 OMP_TEAMS_BODY (ret) = block;
19389 OMP_TEAMS_COMBINED (ret) = 1;
19390 SET_EXPR_LOCATION (ret, loc);
19391 return add_stmt (ret);
19393 else if (strcmp (p, "loop") == 0)
19395 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19396 if (cclauses == NULL)
19397 cclauses = cclauses_buf;
19399 c_parser_consume_token (parser);
19400 if (!flag_openmp) /* flag_openmp_simd */
19401 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19402 if_p);
19403 block = c_begin_omp_parallel ();
19404 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
19405 block = c_end_compound_stmt (loc, block, true);
19406 if (ret == NULL)
19407 return ret;
19408 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19409 ret = make_node (OMP_TEAMS);
19410 TREE_TYPE (ret) = void_type_node;
19411 OMP_TEAMS_CLAUSES (ret) = clauses;
19412 OMP_TEAMS_BODY (ret) = block;
19413 OMP_TEAMS_COMBINED (ret) = 1;
19414 SET_EXPR_LOCATION (ret, loc);
19415 return add_stmt (ret);
19418 if (!flag_openmp) /* flag_openmp_simd */
19420 c_parser_skip_to_pragma_eol (parser, false);
19421 return NULL_TREE;
19424 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19425 if (cclauses)
19427 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
19428 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19431 tree stmt = make_node (OMP_TEAMS);
19432 TREE_TYPE (stmt) = void_type_node;
19433 OMP_TEAMS_CLAUSES (stmt) = clauses;
19434 block = c_begin_omp_parallel ();
19435 add_stmt (c_parser_omp_structured_block (parser, if_p));
19436 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19437 SET_EXPR_LOCATION (stmt, loc);
19439 return add_stmt (stmt);
19442 /* OpenMP 4.0:
19443 # pragma omp target data target-data-clause[optseq] new-line
19444 structured-block */
19446 #define OMP_TARGET_DATA_CLAUSE_MASK \
19447 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19448 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19449 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19450 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19451 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
19453 static tree
19454 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
19456 tree clauses
19457 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
19458 "#pragma omp target data");
19459 int map_seen = 0;
19460 for (tree *pc = &clauses; *pc;)
19462 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19463 switch (OMP_CLAUSE_MAP_KIND (*pc))
19465 case GOMP_MAP_TO:
19466 case GOMP_MAP_ALWAYS_TO:
19467 case GOMP_MAP_FROM:
19468 case GOMP_MAP_ALWAYS_FROM:
19469 case GOMP_MAP_TOFROM:
19470 case GOMP_MAP_ALWAYS_TOFROM:
19471 case GOMP_MAP_ALLOC:
19472 map_seen = 3;
19473 break;
19474 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19475 case GOMP_MAP_ALWAYS_POINTER:
19476 break;
19477 default:
19478 map_seen |= 1;
19479 error_at (OMP_CLAUSE_LOCATION (*pc),
19480 "%<#pragma omp target data%> with map-type other "
19481 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19482 "on %<map%> clause");
19483 *pc = OMP_CLAUSE_CHAIN (*pc);
19484 continue;
19486 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
19487 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
19488 map_seen = 3;
19489 pc = &OMP_CLAUSE_CHAIN (*pc);
19492 if (map_seen != 3)
19494 if (map_seen == 0)
19495 error_at (loc,
19496 "%<#pragma omp target data%> must contain at least "
19497 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19498 "clause");
19499 return NULL_TREE;
19502 tree stmt = make_node (OMP_TARGET_DATA);
19503 TREE_TYPE (stmt) = void_type_node;
19504 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
19505 keep_next_level ();
19506 tree block = c_begin_compound_stmt (true);
19507 add_stmt (c_parser_omp_structured_block (parser, if_p));
19508 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19510 SET_EXPR_LOCATION (stmt, loc);
19511 return add_stmt (stmt);
19514 /* OpenMP 4.0:
19515 # pragma omp target update target-update-clause[optseq] new-line */
19517 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
19518 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
19519 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19520 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19521 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19522 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19523 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19525 static bool
19526 c_parser_omp_target_update (location_t loc, c_parser *parser,
19527 enum pragma_context context)
19529 if (context == pragma_stmt)
19531 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19532 "omp target update");
19533 c_parser_skip_to_pragma_eol (parser, false);
19534 return false;
19537 tree clauses
19538 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
19539 "#pragma omp target update");
19540 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
19541 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
19543 error_at (loc,
19544 "%<#pragma omp target update%> must contain at least one "
19545 "%<from%> or %<to%> clauses");
19546 return false;
19549 tree stmt = make_node (OMP_TARGET_UPDATE);
19550 TREE_TYPE (stmt) = void_type_node;
19551 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
19552 SET_EXPR_LOCATION (stmt, loc);
19553 add_stmt (stmt);
19554 return false;
19557 /* OpenMP 4.5:
19558 # pragma omp target enter data target-data-clause[optseq] new-line */
19560 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
19561 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19562 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19563 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19567 static tree
19568 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
19569 enum pragma_context context)
19571 bool data_seen = false;
19572 if (c_parser_next_token_is (parser, CPP_NAME))
19574 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19575 if (strcmp (p, "data") == 0)
19577 c_parser_consume_token (parser);
19578 data_seen = true;
19581 if (!data_seen)
19583 c_parser_error (parser, "expected %<data%>");
19584 c_parser_skip_to_pragma_eol (parser);
19585 return NULL_TREE;
19588 if (context == pragma_stmt)
19590 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19591 "omp target enter data");
19592 c_parser_skip_to_pragma_eol (parser, false);
19593 return NULL_TREE;
19596 tree clauses
19597 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
19598 "#pragma omp target enter data");
19599 int map_seen = 0;
19600 for (tree *pc = &clauses; *pc;)
19602 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19603 switch (OMP_CLAUSE_MAP_KIND (*pc))
19605 case GOMP_MAP_TO:
19606 case GOMP_MAP_ALWAYS_TO:
19607 case GOMP_MAP_ALLOC:
19608 map_seen = 3;
19609 break;
19610 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19611 case GOMP_MAP_ALWAYS_POINTER:
19612 break;
19613 default:
19614 map_seen |= 1;
19615 error_at (OMP_CLAUSE_LOCATION (*pc),
19616 "%<#pragma omp target enter data%> with map-type other "
19617 "than %<to%> or %<alloc%> on %<map%> clause");
19618 *pc = OMP_CLAUSE_CHAIN (*pc);
19619 continue;
19621 pc = &OMP_CLAUSE_CHAIN (*pc);
19624 if (map_seen != 3)
19626 if (map_seen == 0)
19627 error_at (loc,
19628 "%<#pragma omp target enter data%> must contain at least "
19629 "one %<map%> clause");
19630 return NULL_TREE;
19633 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
19634 TREE_TYPE (stmt) = void_type_node;
19635 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
19636 SET_EXPR_LOCATION (stmt, loc);
19637 add_stmt (stmt);
19638 return stmt;
19641 /* OpenMP 4.5:
19642 # pragma omp target exit data target-data-clause[optseq] new-line */
19644 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
19645 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19646 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19647 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19651 static tree
19652 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
19653 enum pragma_context context)
19655 bool data_seen = false;
19656 if (c_parser_next_token_is (parser, CPP_NAME))
19658 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19659 if (strcmp (p, "data") == 0)
19661 c_parser_consume_token (parser);
19662 data_seen = true;
19665 if (!data_seen)
19667 c_parser_error (parser, "expected %<data%>");
19668 c_parser_skip_to_pragma_eol (parser);
19669 return NULL_TREE;
19672 if (context == pragma_stmt)
19674 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19675 "omp target exit data");
19676 c_parser_skip_to_pragma_eol (parser, false);
19677 return NULL_TREE;
19680 tree clauses
19681 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
19682 "#pragma omp target exit data");
19684 int map_seen = 0;
19685 for (tree *pc = &clauses; *pc;)
19687 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19688 switch (OMP_CLAUSE_MAP_KIND (*pc))
19690 case GOMP_MAP_FROM:
19691 case GOMP_MAP_ALWAYS_FROM:
19692 case GOMP_MAP_RELEASE:
19693 case GOMP_MAP_DELETE:
19694 map_seen = 3;
19695 break;
19696 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19697 case GOMP_MAP_ALWAYS_POINTER:
19698 break;
19699 default:
19700 map_seen |= 1;
19701 error_at (OMP_CLAUSE_LOCATION (*pc),
19702 "%<#pragma omp target exit data%> with map-type other "
19703 "than %<from%>, %<release%> or %<delete%> on %<map%>"
19704 " clause");
19705 *pc = OMP_CLAUSE_CHAIN (*pc);
19706 continue;
19708 pc = &OMP_CLAUSE_CHAIN (*pc);
19711 if (map_seen != 3)
19713 if (map_seen == 0)
19714 error_at (loc,
19715 "%<#pragma omp target exit data%> must contain at least one "
19716 "%<map%> clause");
19717 return NULL_TREE;
19720 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
19721 TREE_TYPE (stmt) = void_type_node;
19722 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
19723 SET_EXPR_LOCATION (stmt, loc);
19724 add_stmt (stmt);
19725 return stmt;
19728 /* OpenMP 4.0:
19729 # pragma omp target target-clause[optseq] new-line
19730 structured-block */
19732 #define OMP_TARGET_CLAUSE_MASK \
19733 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
19741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
19743 static bool
19744 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
19746 location_t loc = c_parser_peek_token (parser)->location;
19747 c_parser_consume_pragma (parser);
19748 tree *pc = NULL, stmt, block;
19750 if (context != pragma_stmt && context != pragma_compound)
19752 c_parser_error (parser, "expected declaration specifiers");
19753 c_parser_skip_to_pragma_eol (parser);
19754 return false;
19757 if (flag_openmp)
19758 omp_requires_mask
19759 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
19761 if (c_parser_next_token_is (parser, CPP_NAME))
19763 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19764 enum tree_code ccode = ERROR_MARK;
19766 if (strcmp (p, "teams") == 0)
19767 ccode = OMP_TEAMS;
19768 else if (strcmp (p, "parallel") == 0)
19769 ccode = OMP_PARALLEL;
19770 else if (strcmp (p, "simd") == 0)
19771 ccode = OMP_SIMD;
19772 if (ccode != ERROR_MARK)
19774 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
19775 char p_name[sizeof ("#pragma omp target teams distribute "
19776 "parallel for simd")];
19778 c_parser_consume_token (parser);
19779 strcpy (p_name, "#pragma omp target");
19780 if (!flag_openmp) /* flag_openmp_simd */
19782 tree stmt;
19783 switch (ccode)
19785 case OMP_TEAMS:
19786 stmt = c_parser_omp_teams (loc, parser, p_name,
19787 OMP_TARGET_CLAUSE_MASK,
19788 cclauses, if_p);
19789 break;
19790 case OMP_PARALLEL:
19791 stmt = c_parser_omp_parallel (loc, parser, p_name,
19792 OMP_TARGET_CLAUSE_MASK,
19793 cclauses, if_p);
19794 break;
19795 case OMP_SIMD:
19796 stmt = c_parser_omp_simd (loc, parser, p_name,
19797 OMP_TARGET_CLAUSE_MASK,
19798 cclauses, if_p);
19799 break;
19800 default:
19801 gcc_unreachable ();
19803 return stmt != NULL_TREE;
19805 keep_next_level ();
19806 tree block = c_begin_compound_stmt (true), ret;
19807 switch (ccode)
19809 case OMP_TEAMS:
19810 ret = c_parser_omp_teams (loc, parser, p_name,
19811 OMP_TARGET_CLAUSE_MASK, cclauses,
19812 if_p);
19813 break;
19814 case OMP_PARALLEL:
19815 ret = c_parser_omp_parallel (loc, parser, p_name,
19816 OMP_TARGET_CLAUSE_MASK, cclauses,
19817 if_p);
19818 break;
19819 case OMP_SIMD:
19820 ret = c_parser_omp_simd (loc, parser, p_name,
19821 OMP_TARGET_CLAUSE_MASK, cclauses,
19822 if_p);
19823 break;
19824 default:
19825 gcc_unreachable ();
19827 block = c_end_compound_stmt (loc, block, true);
19828 if (ret == NULL_TREE)
19829 return false;
19830 if (ccode == OMP_TEAMS)
19832 /* For combined target teams, ensure the num_teams and
19833 thread_limit clause expressions are evaluated on the host,
19834 before entering the target construct. */
19835 tree c;
19836 for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19837 c; c = OMP_CLAUSE_CHAIN (c))
19838 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
19839 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
19840 && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
19842 tree expr = OMP_CLAUSE_OPERAND (c, 0);
19843 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
19844 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
19845 expr, NULL_TREE, NULL_TREE);
19846 add_stmt (expr);
19847 OMP_CLAUSE_OPERAND (c, 0) = expr;
19848 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
19849 OMP_CLAUSE_FIRSTPRIVATE);
19850 OMP_CLAUSE_DECL (tc) = tmp;
19851 OMP_CLAUSE_CHAIN (tc)
19852 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
19853 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
19856 tree stmt = make_node (OMP_TARGET);
19857 TREE_TYPE (stmt) = void_type_node;
19858 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
19859 OMP_TARGET_BODY (stmt) = block;
19860 OMP_TARGET_COMBINED (stmt) = 1;
19861 SET_EXPR_LOCATION (stmt, loc);
19862 add_stmt (stmt);
19863 pc = &OMP_TARGET_CLAUSES (stmt);
19864 goto check_clauses;
19866 else if (!flag_openmp) /* flag_openmp_simd */
19868 c_parser_skip_to_pragma_eol (parser, false);
19869 return false;
19871 else if (strcmp (p, "data") == 0)
19873 c_parser_consume_token (parser);
19874 c_parser_omp_target_data (loc, parser, if_p);
19875 return true;
19877 else if (strcmp (p, "enter") == 0)
19879 c_parser_consume_token (parser);
19880 c_parser_omp_target_enter_data (loc, parser, context);
19881 return false;
19883 else if (strcmp (p, "exit") == 0)
19885 c_parser_consume_token (parser);
19886 c_parser_omp_target_exit_data (loc, parser, context);
19887 return false;
19889 else if (strcmp (p, "update") == 0)
19891 c_parser_consume_token (parser);
19892 return c_parser_omp_target_update (loc, parser, context);
19895 if (!flag_openmp) /* flag_openmp_simd */
19897 c_parser_skip_to_pragma_eol (parser, false);
19898 return false;
19901 stmt = make_node (OMP_TARGET);
19902 TREE_TYPE (stmt) = void_type_node;
19904 OMP_TARGET_CLAUSES (stmt)
19905 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
19906 "#pragma omp target");
19907 pc = &OMP_TARGET_CLAUSES (stmt);
19908 keep_next_level ();
19909 block = c_begin_compound_stmt (true);
19910 add_stmt (c_parser_omp_structured_block (parser, if_p));
19911 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19913 SET_EXPR_LOCATION (stmt, loc);
19914 add_stmt (stmt);
19916 check_clauses:
19917 while (*pc)
19919 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19920 switch (OMP_CLAUSE_MAP_KIND (*pc))
19922 case GOMP_MAP_TO:
19923 case GOMP_MAP_ALWAYS_TO:
19924 case GOMP_MAP_FROM:
19925 case GOMP_MAP_ALWAYS_FROM:
19926 case GOMP_MAP_TOFROM:
19927 case GOMP_MAP_ALWAYS_TOFROM:
19928 case GOMP_MAP_ALLOC:
19929 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19930 case GOMP_MAP_ALWAYS_POINTER:
19931 break;
19932 default:
19933 error_at (OMP_CLAUSE_LOCATION (*pc),
19934 "%<#pragma omp target%> with map-type other "
19935 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19936 "on %<map%> clause");
19937 *pc = OMP_CLAUSE_CHAIN (*pc);
19938 continue;
19940 pc = &OMP_CLAUSE_CHAIN (*pc);
19942 cfun->has_omp_target = true;
19943 return true;
19946 /* OpenMP 4.0:
19947 # pragma omp declare simd declare-simd-clauses[optseq] new-line
19949 OpenMP 5.0:
19950 # pragma omp declare variant (identifier) match(context-selector) new-line
19953 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
19954 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19955 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19956 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19957 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
19958 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
19959 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
19961 static void
19962 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
19964 c_token *token = c_parser_peek_token (parser);
19965 gcc_assert (token->type == CPP_NAME);
19966 tree kind = token->value;
19967 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
19968 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
19970 auto_vec<c_token> clauses;
19971 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19973 c_token *token = c_parser_peek_token (parser);
19974 if (token->type == CPP_EOF)
19976 c_parser_skip_to_pragma_eol (parser);
19977 return;
19979 clauses.safe_push (*token);
19980 c_parser_consume_token (parser);
19982 clauses.safe_push (*c_parser_peek_token (parser));
19983 c_parser_skip_to_pragma_eol (parser);
19985 while (c_parser_next_token_is (parser, CPP_PRAGMA))
19987 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
19988 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
19989 || c_parser_peek_2nd_token (parser)->value != kind)
19991 error ("%<#pragma omp declare %s%> must be followed by "
19992 "function declaration or definition or another "
19993 "%<#pragma omp declare %s%>",
19994 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
19995 return;
19997 c_parser_consume_pragma (parser);
19998 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20000 c_token *token = c_parser_peek_token (parser);
20001 if (token->type == CPP_EOF)
20003 c_parser_skip_to_pragma_eol (parser);
20004 return;
20006 clauses.safe_push (*token);
20007 c_parser_consume_token (parser);
20009 clauses.safe_push (*c_parser_peek_token (parser));
20010 c_parser_skip_to_pragma_eol (parser);
20013 /* Make sure nothing tries to read past the end of the tokens. */
20014 c_token eof_token;
20015 memset (&eof_token, 0, sizeof (eof_token));
20016 eof_token.type = CPP_EOF;
20017 clauses.safe_push (eof_token);
20018 clauses.safe_push (eof_token);
20020 switch (context)
20022 case pragma_external:
20023 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20024 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20026 int ext = disable_extension_diagnostics ();
20028 c_parser_consume_token (parser);
20029 while (c_parser_next_token_is (parser, CPP_KEYWORD)
20030 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20031 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20032 NULL, clauses);
20033 restore_extension_diagnostics (ext);
20035 else
20036 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20037 NULL, clauses);
20038 break;
20039 case pragma_struct:
20040 case pragma_param:
20041 case pragma_stmt:
20042 error ("%<#pragma omp declare %s%> must be followed by "
20043 "function declaration or definition",
20044 IDENTIFIER_POINTER (kind));
20045 break;
20046 case pragma_compound:
20047 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20048 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20050 int ext = disable_extension_diagnostics ();
20052 c_parser_consume_token (parser);
20053 while (c_parser_next_token_is (parser, CPP_KEYWORD)
20054 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20055 if (c_parser_next_tokens_start_declaration (parser))
20057 c_parser_declaration_or_fndef (parser, true, true, true, true,
20058 true, NULL, clauses);
20059 restore_extension_diagnostics (ext);
20060 break;
20062 restore_extension_diagnostics (ext);
20064 else if (c_parser_next_tokens_start_declaration (parser))
20066 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
20067 NULL, clauses);
20068 break;
20070 error ("%<#pragma omp declare %s%> must be followed by "
20071 "function declaration or definition",
20072 IDENTIFIER_POINTER (kind));
20073 break;
20074 default:
20075 gcc_unreachable ();
20079 static const char *const omp_construct_selectors[] = {
20080 "simd", "target", "teams", "parallel", "for", NULL };
20081 static const char *const omp_device_selectors[] = {
20082 "kind", "isa", "arch", NULL };
20083 static const char *const omp_implementation_selectors[] = {
20084 "vendor", "extension", "atomic_default_mem_order", "unified_address",
20085 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
20086 static const char *const omp_user_selectors[] = {
20087 "condition", NULL };
20089 /* OpenMP 5.0:
20091 trait-selector:
20092 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
20094 trait-score:
20095 score(score-expression) */
20097 static tree
20098 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
20100 tree ret = NULL_TREE;
20103 tree selector;
20104 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20105 || c_parser_next_token_is (parser, CPP_NAME))
20106 selector = c_parser_peek_token (parser)->value;
20107 else
20109 c_parser_error (parser, "expected trait selector name");
20110 return error_mark_node;
20113 tree properties = NULL_TREE;
20114 const char *const *selectors = NULL;
20115 bool allow_score = true;
20116 bool allow_user = false;
20117 int property_limit = 0;
20118 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
20119 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
20120 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
20121 switch (IDENTIFIER_POINTER (set)[0])
20123 case 'c': /* construct */
20124 selectors = omp_construct_selectors;
20125 allow_score = false;
20126 property_limit = 1;
20127 property_kind = CTX_PROPERTY_SIMD;
20128 break;
20129 case 'd': /* device */
20130 selectors = omp_device_selectors;
20131 allow_score = false;
20132 allow_user = true;
20133 property_limit = 3;
20134 property_kind = CTX_PROPERTY_NAME_LIST;
20135 break;
20136 case 'i': /* implementation */
20137 selectors = omp_implementation_selectors;
20138 allow_user = true;
20139 property_limit = 3;
20140 property_kind = CTX_PROPERTY_NAME_LIST;
20141 break;
20142 case 'u': /* user */
20143 selectors = omp_user_selectors;
20144 property_limit = 1;
20145 property_kind = CTX_PROPERTY_EXPR;
20146 break;
20147 default:
20148 gcc_unreachable ();
20150 for (int i = 0; ; i++)
20152 if (selectors[i] == NULL)
20154 if (allow_user)
20156 property_kind = CTX_PROPERTY_USER;
20157 break;
20159 else
20161 error_at (c_parser_peek_token (parser)->location,
20162 "selector %qs not allowed for context selector "
20163 "set %qs", IDENTIFIER_POINTER (selector),
20164 IDENTIFIER_POINTER (set));
20165 c_parser_consume_token (parser);
20166 return error_mark_node;
20169 if (i == property_limit)
20170 property_kind = CTX_PROPERTY_NONE;
20171 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
20172 break;
20174 if (property_kind == CTX_PROPERTY_NAME_LIST
20175 && IDENTIFIER_POINTER (set)[0] == 'i'
20176 && strcmp (IDENTIFIER_POINTER (selector),
20177 "atomic_default_mem_order") == 0)
20178 property_kind = CTX_PROPERTY_ID;
20180 c_parser_consume_token (parser);
20182 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20184 if (property_kind == CTX_PROPERTY_NONE)
20186 error_at (c_parser_peek_token (parser)->location,
20187 "selector %qs does not accept any properties",
20188 IDENTIFIER_POINTER (selector));
20189 return error_mark_node;
20192 matching_parens parens;
20193 parens.require_open (parser);
20195 c_token *token = c_parser_peek_token (parser);
20196 if (allow_score
20197 && c_parser_next_token_is (parser, CPP_NAME)
20198 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
20199 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
20201 c_parser_consume_token (parser);
20203 matching_parens parens2;
20204 parens2.require_open (parser);
20205 tree score = c_parser_expr_no_commas (parser, NULL).value;
20206 parens2.skip_until_found_close (parser);
20207 c_parser_require (parser, CPP_COLON, "expected %<:%>");
20208 if (score != error_mark_node)
20210 mark_exp_read (score);
20211 score = c_fully_fold (score, false, NULL);
20212 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
20213 || TREE_CODE (score) != INTEGER_CST)
20214 error_at (token->location, "score argument must be "
20215 "constant integer expression");
20216 else if (tree_int_cst_sgn (score) < 0)
20217 error_at (token->location, "score argument must be "
20218 "non-negative");
20219 else
20220 properties = tree_cons (get_identifier (" score"),
20221 score, properties);
20223 token = c_parser_peek_token (parser);
20226 switch (property_kind)
20228 tree t;
20229 case CTX_PROPERTY_USER:
20232 t = c_parser_expr_no_commas (parser, NULL).value;
20233 if (TREE_CODE (t) == STRING_CST)
20234 properties = tree_cons (NULL_TREE, t, properties);
20235 else if (t != error_mark_node)
20237 mark_exp_read (t);
20238 t = c_fully_fold (t, false, NULL);
20239 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20240 || !tree_fits_shwi_p (t))
20241 error_at (token->location, "property must be "
20242 "constant integer expression or string "
20243 "literal");
20244 else
20245 properties = tree_cons (NULL_TREE, t, properties);
20247 else
20248 return error_mark_node;
20250 if (c_parser_next_token_is (parser, CPP_COMMA))
20251 c_parser_consume_token (parser);
20252 else
20253 break;
20255 while (1);
20256 break;
20257 case CTX_PROPERTY_ID:
20258 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20259 || c_parser_next_token_is (parser, CPP_NAME))
20261 tree prop = c_parser_peek_token (parser)->value;
20262 c_parser_consume_token (parser);
20263 properties = tree_cons (prop, NULL_TREE, properties);
20265 else
20267 c_parser_error (parser, "expected identifier");
20268 return error_mark_node;
20270 break;
20271 case CTX_PROPERTY_NAME_LIST:
20274 tree prop = NULL_TREE, value = NULL_TREE;
20275 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20276 || c_parser_next_token_is (parser, CPP_NAME))
20278 prop = c_parser_peek_token (parser)->value;
20279 c_parser_consume_token (parser);
20281 else if (c_parser_next_token_is (parser, CPP_STRING))
20282 value = c_parser_string_literal (parser, false,
20283 false).value;
20284 else
20286 c_parser_error (parser, "expected identifier or "
20287 "string literal");
20288 return error_mark_node;
20291 properties = tree_cons (prop, value, properties);
20293 if (c_parser_next_token_is (parser, CPP_COMMA))
20294 c_parser_consume_token (parser);
20295 else
20296 break;
20298 while (1);
20299 break;
20300 case CTX_PROPERTY_EXPR:
20301 t = c_parser_expr_no_commas (parser, NULL).value;
20302 if (t != error_mark_node)
20304 mark_exp_read (t);
20305 t = c_fully_fold (t, false, NULL);
20306 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20307 || !tree_fits_shwi_p (t))
20308 error_at (token->location, "property must be "
20309 "constant integer expression");
20310 else
20311 properties = tree_cons (NULL_TREE, t, properties);
20313 else
20314 return error_mark_node;
20315 break;
20316 case CTX_PROPERTY_SIMD:
20317 if (parms == NULL_TREE)
20319 error_at (token->location, "properties for %<simd%> "
20320 "selector may not be specified in "
20321 "%<metadirective%>");
20322 return error_mark_node;
20324 tree c;
20325 c = c_parser_omp_all_clauses (parser,
20326 OMP_DECLARE_SIMD_CLAUSE_MASK,
20327 "simd", true, 2);
20328 c = c_omp_declare_simd_clauses_to_numbers (parms
20329 == error_mark_node
20330 ? NULL_TREE : parms,
20332 properties = c;
20333 break;
20334 default:
20335 gcc_unreachable ();
20338 parens.skip_until_found_close (parser);
20339 properties = nreverse (properties);
20341 else if (property_kind == CTX_PROPERTY_NAME_LIST
20342 || property_kind == CTX_PROPERTY_ID
20343 || property_kind == CTX_PROPERTY_EXPR)
20345 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
20346 return error_mark_node;
20349 ret = tree_cons (selector, properties, ret);
20351 if (c_parser_next_token_is (parser, CPP_COMMA))
20352 c_parser_consume_token (parser);
20353 else
20354 break;
20356 while (1);
20358 return nreverse (ret);
20361 /* OpenMP 5.0:
20363 trait-set-selector[,trait-set-selector[,...]]
20365 trait-set-selector:
20366 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20368 trait-set-selector-name:
20369 constructor
20370 device
20371 implementation
20372 user */
20374 static tree
20375 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
20377 tree ret = NULL_TREE;
20380 const char *setp = "";
20381 if (c_parser_next_token_is (parser, CPP_NAME))
20382 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20383 switch (setp[0])
20385 case 'c':
20386 if (strcmp (setp, "construct") == 0)
20387 setp = NULL;
20388 break;
20389 case 'd':
20390 if (strcmp (setp, "device") == 0)
20391 setp = NULL;
20392 break;
20393 case 'i':
20394 if (strcmp (setp, "implementation") == 0)
20395 setp = NULL;
20396 break;
20397 case 'u':
20398 if (strcmp (setp, "user") == 0)
20399 setp = NULL;
20400 break;
20401 default:
20402 break;
20404 if (setp)
20406 c_parser_error (parser, "expected %<construct%>, %<device%>, "
20407 "%<implementation%> or %<user%>");
20408 return error_mark_node;
20411 tree set = c_parser_peek_token (parser)->value;
20412 c_parser_consume_token (parser);
20414 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
20415 return error_mark_node;
20417 matching_braces braces;
20418 if (!braces.require_open (parser))
20419 return error_mark_node;
20421 tree selectors = c_parser_omp_context_selector (parser, set, parms);
20422 if (selectors == error_mark_node)
20423 ret = error_mark_node;
20424 else if (ret != error_mark_node)
20425 ret = tree_cons (set, selectors, ret);
20427 braces.skip_until_found_close (parser);
20429 if (c_parser_next_token_is (parser, CPP_COMMA))
20430 c_parser_consume_token (parser);
20431 else
20432 break;
20434 while (1);
20436 if (ret == error_mark_node)
20437 return ret;
20438 return nreverse (ret);
20441 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20442 that into "omp declare variant base" attribute. */
20444 static void
20445 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
20447 matching_parens parens;
20448 if (!parens.require_open (parser))
20450 fail:
20451 c_parser_skip_to_pragma_eol (parser, false);
20452 return;
20455 if (c_parser_next_token_is_not (parser, CPP_NAME)
20456 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20458 c_parser_error (parser, "expected identifier");
20459 goto fail;
20462 c_token *token = c_parser_peek_token (parser);
20463 tree variant = lookup_name (token->value);
20465 if (variant == NULL_TREE)
20467 undeclared_variable (token->location, token->value);
20468 variant = error_mark_node;
20471 c_parser_consume_token (parser);
20473 parens.require_close (parser);
20475 const char *clause = "";
20476 location_t match_loc = c_parser_peek_token (parser)->location;
20477 if (c_parser_next_token_is (parser, CPP_NAME))
20478 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20479 if (strcmp (clause, "match"))
20481 c_parser_error (parser, "expected %<match%>");
20482 goto fail;
20485 c_parser_consume_token (parser);
20487 if (!parens.require_open (parser))
20488 goto fail;
20490 if (parms == NULL_TREE)
20491 parms = error_mark_node;
20493 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
20494 if (ctx == error_mark_node)
20495 goto fail;
20496 ctx = c_omp_check_context_selector (match_loc, ctx);
20497 if (ctx != error_mark_node && variant != error_mark_node)
20499 if (TREE_CODE (variant) != FUNCTION_DECL)
20501 error_at (token->location, "variant %qD is not a function", variant);
20502 variant = error_mark_node;
20504 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
20505 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
20507 error_at (token->location, "variant %qD and base %qD have "
20508 "incompatible types", variant, fndecl);
20509 variant = error_mark_node;
20511 else if (fndecl_built_in_p (variant)
20512 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20513 "__builtin_", strlen ("__builtin_")) == 0
20514 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20515 "__sync_", strlen ("__sync_")) == 0
20516 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20517 "__atomic_", strlen ("__atomic_")) == 0))
20519 error_at (token->location, "variant %qD is a built-in", variant);
20520 variant = error_mark_node;
20522 if (variant != error_mark_node)
20524 C_DECL_USED (variant) = 1;
20525 tree construct = omp_get_context_selector (ctx, "construct", NULL);
20526 c_omp_mark_declare_variant (match_loc, variant, construct);
20527 if (omp_context_selector_matches (ctx))
20529 tree attr
20530 = tree_cons (get_identifier ("omp declare variant base"),
20531 build_tree_list (variant, ctx),
20532 DECL_ATTRIBUTES (fndecl));
20533 DECL_ATTRIBUTES (fndecl) = attr;
20538 parens.require_close (parser);
20539 c_parser_skip_to_pragma_eol (parser);
20542 /* Finalize #pragma omp declare simd or #pragma omp declare variant
20543 clauses after FNDECL has been parsed, and put that into "omp declare simd"
20544 or "omp declare variant base" attribute. */
20546 static void
20547 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
20548 vec<c_token> clauses)
20550 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
20551 indicates error has been reported and CPP_PRAGMA that
20552 c_finish_omp_declare_simd has already processed the tokens. */
20553 if (clauses.exists () && clauses[0].type == CPP_EOF)
20554 return;
20555 const char *kind = "simd";
20556 if (clauses.exists ()
20557 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
20558 kind = IDENTIFIER_POINTER (clauses[0].value);
20559 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
20560 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
20562 error ("%<#pragma omp declare %s%> not immediately followed by "
20563 "a function declaration or definition", kind);
20564 clauses[0].type = CPP_EOF;
20565 return;
20567 if (clauses.exists () && clauses[0].type != CPP_NAME)
20569 error_at (DECL_SOURCE_LOCATION (fndecl),
20570 "%<#pragma omp declare %s%> not immediately followed by "
20571 "a single function declaration or definition", kind);
20572 clauses[0].type = CPP_EOF;
20573 return;
20576 if (parms == NULL_TREE)
20577 parms = DECL_ARGUMENTS (fndecl);
20579 unsigned int tokens_avail = parser->tokens_avail;
20580 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
20582 parser->tokens = clauses.address ();
20583 parser->tokens_avail = clauses.length ();
20585 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
20586 while (parser->tokens_avail > 3)
20588 c_token *token = c_parser_peek_token (parser);
20589 gcc_assert (token->type == CPP_NAME
20590 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
20591 c_parser_consume_token (parser);
20592 parser->in_pragma = true;
20594 if (strcmp (kind, "simd") == 0)
20596 tree c;
20597 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
20598 "#pragma omp declare simd");
20599 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
20600 if (c != NULL_TREE)
20601 c = tree_cons (NULL_TREE, c, NULL_TREE);
20602 c = build_tree_list (get_identifier ("omp declare simd"), c);
20603 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
20604 DECL_ATTRIBUTES (fndecl) = c;
20606 else
20608 gcc_assert (strcmp (kind, "variant") == 0);
20609 c_finish_omp_declare_variant (parser, fndecl, parms);
20613 parser->tokens = &parser->tokens_buf[0];
20614 parser->tokens_avail = tokens_avail;
20615 if (clauses.exists ())
20616 clauses[0].type = CPP_PRAGMA;
20620 /* OpenMP 4.0:
20621 # pragma omp declare target new-line
20622 declarations and definitions
20623 # pragma omp end declare target new-line
20625 OpenMP 4.5:
20626 # pragma omp declare target ( extended-list ) new-line
20628 # pragma omp declare target declare-target-clauses[seq] new-line */
20630 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
20631 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
20633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
20635 static void
20636 c_parser_omp_declare_target (c_parser *parser)
20638 tree clauses = NULL_TREE;
20639 int device_type = 0;
20640 bool only_device_type = true;
20641 if (c_parser_next_token_is (parser, CPP_NAME))
20642 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
20643 "#pragma omp declare target");
20644 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20646 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
20647 clauses);
20648 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
20649 c_parser_skip_to_pragma_eol (parser);
20651 else
20653 c_parser_skip_to_pragma_eol (parser);
20654 current_omp_declare_target_attribute++;
20655 return;
20657 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20658 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20659 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
20660 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20662 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20663 continue;
20664 tree t = OMP_CLAUSE_DECL (c), id;
20665 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
20666 tree at2 = lookup_attribute ("omp declare target link",
20667 DECL_ATTRIBUTES (t));
20668 only_device_type = false;
20669 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
20671 id = get_identifier ("omp declare target link");
20672 std::swap (at1, at2);
20674 else
20675 id = get_identifier ("omp declare target");
20676 if (at2)
20678 error_at (OMP_CLAUSE_LOCATION (c),
20679 "%qD specified both in declare target %<link%> and %<to%>"
20680 " clauses", t);
20681 continue;
20683 if (!at1)
20685 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20686 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
20687 continue;
20689 symtab_node *node = symtab_node::get (t);
20690 if (node != NULL)
20692 node->offloadable = 1;
20693 if (ENABLE_OFFLOADING)
20695 g->have_offload = true;
20696 if (is_a <varpool_node *> (node))
20697 vec_safe_push (offload_vars, t);
20701 if (TREE_CODE (t) != FUNCTION_DECL)
20702 continue;
20703 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
20705 tree at3 = lookup_attribute ("omp declare target host",
20706 DECL_ATTRIBUTES (t));
20707 if (at3 == NULL_TREE)
20709 id = get_identifier ("omp declare target host");
20710 DECL_ATTRIBUTES (t)
20711 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20714 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
20716 tree at3 = lookup_attribute ("omp declare target nohost",
20717 DECL_ATTRIBUTES (t));
20718 if (at3 == NULL_TREE)
20720 id = get_identifier ("omp declare target nohost");
20721 DECL_ATTRIBUTES (t)
20722 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20726 if (device_type && only_device_type)
20727 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
20728 "directive with only %<device_type%> clauses ignored");
20731 static void
20732 c_parser_omp_end_declare_target (c_parser *parser)
20734 location_t loc = c_parser_peek_token (parser)->location;
20735 c_parser_consume_pragma (parser);
20736 if (c_parser_next_token_is (parser, CPP_NAME)
20737 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20738 "declare") == 0)
20740 c_parser_consume_token (parser);
20741 if (c_parser_next_token_is (parser, CPP_NAME)
20742 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20743 "target") == 0)
20744 c_parser_consume_token (parser);
20745 else
20747 c_parser_error (parser, "expected %<target%>");
20748 c_parser_skip_to_pragma_eol (parser);
20749 return;
20752 else
20754 c_parser_error (parser, "expected %<declare%>");
20755 c_parser_skip_to_pragma_eol (parser);
20756 return;
20758 c_parser_skip_to_pragma_eol (parser);
20759 if (!current_omp_declare_target_attribute)
20760 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
20761 "%<#pragma omp declare target%>");
20762 else
20763 current_omp_declare_target_attribute--;
20767 /* OpenMP 4.0
20768 #pragma omp declare reduction (reduction-id : typename-list : expression) \
20769 initializer-clause[opt] new-line
20771 initializer-clause:
20772 initializer (omp_priv = initializer)
20773 initializer (function-name (argument-list)) */
20775 static void
20776 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
20778 unsigned int tokens_avail = 0, i;
20779 vec<tree> types = vNULL;
20780 vec<c_token> clauses = vNULL;
20781 enum tree_code reduc_code = ERROR_MARK;
20782 tree reduc_id = NULL_TREE;
20783 tree type;
20784 location_t rloc = c_parser_peek_token (parser)->location;
20786 if (context == pragma_struct || context == pragma_param)
20788 error ("%<#pragma omp declare reduction%> not at file or block scope");
20789 goto fail;
20792 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
20793 goto fail;
20795 switch (c_parser_peek_token (parser)->type)
20797 case CPP_PLUS:
20798 reduc_code = PLUS_EXPR;
20799 break;
20800 case CPP_MULT:
20801 reduc_code = MULT_EXPR;
20802 break;
20803 case CPP_MINUS:
20804 reduc_code = MINUS_EXPR;
20805 break;
20806 case CPP_AND:
20807 reduc_code = BIT_AND_EXPR;
20808 break;
20809 case CPP_XOR:
20810 reduc_code = BIT_XOR_EXPR;
20811 break;
20812 case CPP_OR:
20813 reduc_code = BIT_IOR_EXPR;
20814 break;
20815 case CPP_AND_AND:
20816 reduc_code = TRUTH_ANDIF_EXPR;
20817 break;
20818 case CPP_OR_OR:
20819 reduc_code = TRUTH_ORIF_EXPR;
20820 break;
20821 case CPP_NAME:
20822 const char *p;
20823 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20824 if (strcmp (p, "min") == 0)
20826 reduc_code = MIN_EXPR;
20827 break;
20829 if (strcmp (p, "max") == 0)
20831 reduc_code = MAX_EXPR;
20832 break;
20834 reduc_id = c_parser_peek_token (parser)->value;
20835 break;
20836 default:
20837 c_parser_error (parser,
20838 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
20839 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
20840 goto fail;
20843 tree orig_reduc_id, reduc_decl;
20844 orig_reduc_id = reduc_id;
20845 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
20846 reduc_decl = c_omp_reduction_decl (reduc_id);
20847 c_parser_consume_token (parser);
20849 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
20850 goto fail;
20852 while (true)
20854 location_t loc = c_parser_peek_token (parser)->location;
20855 struct c_type_name *ctype = c_parser_type_name (parser);
20856 if (ctype != NULL)
20858 type = groktypename (ctype, NULL, NULL);
20859 if (type == error_mark_node)
20861 else if ((INTEGRAL_TYPE_P (type)
20862 || TREE_CODE (type) == REAL_TYPE
20863 || TREE_CODE (type) == COMPLEX_TYPE)
20864 && orig_reduc_id == NULL_TREE)
20865 error_at (loc, "predeclared arithmetic type in "
20866 "%<#pragma omp declare reduction%>");
20867 else if (TREE_CODE (type) == FUNCTION_TYPE
20868 || TREE_CODE (type) == ARRAY_TYPE)
20869 error_at (loc, "function or array type in "
20870 "%<#pragma omp declare reduction%>");
20871 else if (TYPE_ATOMIC (type))
20872 error_at (loc, "%<_Atomic%> qualified type in "
20873 "%<#pragma omp declare reduction%>");
20874 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
20875 error_at (loc, "const, volatile or restrict qualified type in "
20876 "%<#pragma omp declare reduction%>");
20877 else
20879 tree t;
20880 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
20881 if (comptypes (TREE_PURPOSE (t), type))
20883 error_at (loc, "redeclaration of %qs "
20884 "%<#pragma omp declare reduction%> for "
20885 "type %qT",
20886 IDENTIFIER_POINTER (reduc_id)
20887 + sizeof ("omp declare reduction ") - 1,
20888 type);
20889 location_t ploc
20890 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
20891 0));
20892 error_at (ploc, "previous %<#pragma omp declare "
20893 "reduction%>");
20894 break;
20896 if (t == NULL_TREE)
20897 types.safe_push (type);
20899 if (c_parser_next_token_is (parser, CPP_COMMA))
20900 c_parser_consume_token (parser);
20901 else
20902 break;
20904 else
20905 break;
20908 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
20909 || types.is_empty ())
20911 fail:
20912 clauses.release ();
20913 types.release ();
20914 while (true)
20916 c_token *token = c_parser_peek_token (parser);
20917 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
20918 break;
20919 c_parser_consume_token (parser);
20921 c_parser_skip_to_pragma_eol (parser);
20922 return;
20925 if (types.length () > 1)
20927 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20929 c_token *token = c_parser_peek_token (parser);
20930 if (token->type == CPP_EOF)
20931 goto fail;
20932 clauses.safe_push (*token);
20933 c_parser_consume_token (parser);
20935 clauses.safe_push (*c_parser_peek_token (parser));
20936 c_parser_skip_to_pragma_eol (parser);
20938 /* Make sure nothing tries to read past the end of the tokens. */
20939 c_token eof_token;
20940 memset (&eof_token, 0, sizeof (eof_token));
20941 eof_token.type = CPP_EOF;
20942 clauses.safe_push (eof_token);
20943 clauses.safe_push (eof_token);
20946 int errs = errorcount;
20947 FOR_EACH_VEC_ELT (types, i, type)
20949 tokens_avail = parser->tokens_avail;
20950 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
20951 if (!clauses.is_empty ())
20953 parser->tokens = clauses.address ();
20954 parser->tokens_avail = clauses.length ();
20955 parser->in_pragma = true;
20958 bool nested = current_function_decl != NULL_TREE;
20959 if (nested)
20960 c_push_function_context ();
20961 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
20962 reduc_id, default_function_type);
20963 current_function_decl = fndecl;
20964 allocate_struct_function (fndecl, true);
20965 push_scope ();
20966 tree stmt = push_stmt_list ();
20967 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
20968 warn about these. */
20969 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
20970 get_identifier ("omp_out"), type);
20971 DECL_ARTIFICIAL (omp_out) = 1;
20972 DECL_CONTEXT (omp_out) = fndecl;
20973 pushdecl (omp_out);
20974 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
20975 get_identifier ("omp_in"), type);
20976 DECL_ARTIFICIAL (omp_in) = 1;
20977 DECL_CONTEXT (omp_in) = fndecl;
20978 pushdecl (omp_in);
20979 struct c_expr combiner = c_parser_expression (parser);
20980 struct c_expr initializer;
20981 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
20982 bool bad = false;
20983 initializer.set_error ();
20984 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20985 bad = true;
20986 else if (c_parser_next_token_is (parser, CPP_NAME)
20987 && strcmp (IDENTIFIER_POINTER
20988 (c_parser_peek_token (parser)->value),
20989 "initializer") == 0)
20991 c_parser_consume_token (parser);
20992 pop_scope ();
20993 push_scope ();
20994 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
20995 get_identifier ("omp_priv"), type);
20996 DECL_ARTIFICIAL (omp_priv) = 1;
20997 DECL_INITIAL (omp_priv) = error_mark_node;
20998 DECL_CONTEXT (omp_priv) = fndecl;
20999 pushdecl (omp_priv);
21000 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
21001 get_identifier ("omp_orig"), type);
21002 DECL_ARTIFICIAL (omp_orig) = 1;
21003 DECL_CONTEXT (omp_orig) = fndecl;
21004 pushdecl (omp_orig);
21005 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
21006 bad = true;
21007 else if (!c_parser_next_token_is (parser, CPP_NAME))
21009 c_parser_error (parser, "expected %<omp_priv%> or "
21010 "function-name");
21011 bad = true;
21013 else if (strcmp (IDENTIFIER_POINTER
21014 (c_parser_peek_token (parser)->value),
21015 "omp_priv") != 0)
21017 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
21018 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
21020 c_parser_error (parser, "expected function-name %<(%>");
21021 bad = true;
21023 else
21024 initializer = c_parser_postfix_expression (parser);
21025 if (initializer.value
21026 && TREE_CODE (initializer.value) == CALL_EXPR)
21028 int j;
21029 tree c = initializer.value;
21030 for (j = 0; j < call_expr_nargs (c); j++)
21032 tree a = CALL_EXPR_ARG (c, j);
21033 STRIP_NOPS (a);
21034 if (TREE_CODE (a) == ADDR_EXPR
21035 && TREE_OPERAND (a, 0) == omp_priv)
21036 break;
21038 if (j == call_expr_nargs (c))
21039 error ("one of the initializer call arguments should be "
21040 "%<&omp_priv%>");
21043 else
21045 c_parser_consume_token (parser);
21046 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21047 bad = true;
21048 else
21050 tree st = push_stmt_list ();
21051 location_t loc = c_parser_peek_token (parser)->location;
21052 rich_location richloc (line_table, loc);
21053 start_init (omp_priv, NULL_TREE, 0, &richloc);
21054 struct c_expr init = c_parser_initializer (parser);
21055 finish_init ();
21056 finish_decl (omp_priv, loc, init.value,
21057 init.original_type, NULL_TREE);
21058 pop_stmt_list (st);
21061 if (!bad
21062 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
21063 bad = true;
21066 if (!bad)
21068 c_parser_skip_to_pragma_eol (parser);
21070 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
21071 DECL_INITIAL (reduc_decl));
21072 DECL_INITIAL (reduc_decl) = t;
21073 DECL_SOURCE_LOCATION (omp_out) = rloc;
21074 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
21075 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
21076 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
21077 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
21078 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
21079 if (omp_priv)
21081 DECL_SOURCE_LOCATION (omp_priv) = rloc;
21082 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
21083 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
21084 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
21085 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
21086 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
21087 walk_tree (&DECL_INITIAL (omp_priv),
21088 c_check_omp_declare_reduction_r,
21089 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
21093 pop_stmt_list (stmt);
21094 pop_scope ();
21095 if (cfun->language != NULL)
21097 ggc_free (cfun->language);
21098 cfun->language = NULL;
21100 set_cfun (NULL);
21101 current_function_decl = NULL_TREE;
21102 if (nested)
21103 c_pop_function_context ();
21105 if (!clauses.is_empty ())
21107 parser->tokens = &parser->tokens_buf[0];
21108 parser->tokens_avail = tokens_avail;
21110 if (bad)
21111 goto fail;
21112 if (errs != errorcount)
21113 break;
21116 clauses.release ();
21117 types.release ();
21121 /* OpenMP 4.0
21122 #pragma omp declare simd declare-simd-clauses[optseq] new-line
21123 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21124 initializer-clause[opt] new-line
21125 #pragma omp declare target new-line
21127 OpenMP 5.0
21128 #pragma omp declare variant (identifier) match (context-selector) */
21130 static void
21131 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
21133 c_parser_consume_pragma (parser);
21134 if (c_parser_next_token_is (parser, CPP_NAME))
21136 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21137 if (strcmp (p, "simd") == 0)
21139 /* c_parser_consume_token (parser); done in
21140 c_parser_omp_declare_simd. */
21141 c_parser_omp_declare_simd (parser, context);
21142 return;
21144 if (strcmp (p, "reduction") == 0)
21146 c_parser_consume_token (parser);
21147 c_parser_omp_declare_reduction (parser, context);
21148 return;
21150 if (!flag_openmp) /* flag_openmp_simd */
21152 c_parser_skip_to_pragma_eol (parser, false);
21153 return;
21155 if (strcmp (p, "target") == 0)
21157 c_parser_consume_token (parser);
21158 c_parser_omp_declare_target (parser);
21159 return;
21161 if (strcmp (p, "variant") == 0)
21163 /* c_parser_consume_token (parser); done in
21164 c_parser_omp_declare_simd. */
21165 c_parser_omp_declare_simd (parser, context);
21166 return;
21170 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
21171 "%<target%> or %<variant%>");
21172 c_parser_skip_to_pragma_eol (parser);
21175 /* OpenMP 5.0
21176 #pragma omp requires clauses[optseq] new-line */
21178 static void
21179 c_parser_omp_requires (c_parser *parser)
21181 bool first = true;
21182 enum omp_requires new_req = (enum omp_requires) 0;
21184 c_parser_consume_pragma (parser);
21186 location_t loc = c_parser_peek_token (parser)->location;
21187 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21189 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
21190 c_parser_consume_token (parser);
21192 first = false;
21194 if (c_parser_next_token_is (parser, CPP_NAME))
21196 const char *p
21197 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21198 location_t cloc = c_parser_peek_token (parser)->location;
21199 enum omp_requires this_req = (enum omp_requires) 0;
21201 if (!strcmp (p, "unified_address"))
21202 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
21203 else if (!strcmp (p, "unified_shared_memory"))
21204 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
21205 else if (!strcmp (p, "dynamic_allocators"))
21206 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
21207 else if (!strcmp (p, "reverse_offload"))
21208 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
21209 else if (!strcmp (p, "atomic_default_mem_order"))
21211 c_parser_consume_token (parser);
21213 matching_parens parens;
21214 if (parens.require_open (parser))
21216 if (c_parser_next_token_is (parser, CPP_NAME))
21218 tree v = c_parser_peek_token (parser)->value;
21219 p = IDENTIFIER_POINTER (v);
21221 if (!strcmp (p, "seq_cst"))
21222 this_req
21223 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
21224 else if (!strcmp (p, "relaxed"))
21225 this_req
21226 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
21227 else if (!strcmp (p, "acq_rel"))
21228 this_req
21229 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
21231 if (this_req == 0)
21233 error_at (c_parser_peek_token (parser)->location,
21234 "expected %<seq_cst%>, %<relaxed%> or "
21235 "%<acq_rel%>");
21236 if (c_parser_peek_2nd_token (parser)->type
21237 == CPP_CLOSE_PAREN)
21238 c_parser_consume_token (parser);
21240 else
21241 c_parser_consume_token (parser);
21243 parens.skip_until_found_close (parser);
21244 if (this_req == 0)
21246 c_parser_skip_to_pragma_eol (parser, false);
21247 return;
21250 p = NULL;
21252 else
21254 error_at (cloc, "expected %<unified_address%>, "
21255 "%<unified_shared_memory%>, "
21256 "%<dynamic_allocators%>, "
21257 "%<reverse_offload%> "
21258 "or %<atomic_default_mem_order%> clause");
21259 c_parser_skip_to_pragma_eol (parser, false);
21260 return;
21262 if (p)
21263 sorry_at (cloc, "%qs clause on %<requires%> directive not "
21264 "supported yet", p);
21265 if (p)
21266 c_parser_consume_token (parser);
21267 if (this_req)
21269 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21271 if ((this_req & new_req) != 0)
21272 error_at (cloc, "too many %qs clauses", p);
21273 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
21274 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
21275 error_at (cloc, "%qs clause used lexically after first "
21276 "target construct or offloading API", p);
21278 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21280 error_at (cloc, "too many %qs clauses",
21281 "atomic_default_mem_order");
21282 this_req = (enum omp_requires) 0;
21284 else if ((omp_requires_mask
21285 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21287 error_at (cloc, "more than one %<atomic_default_mem_order%>"
21288 " clause in a single compilation unit");
21289 this_req
21290 = (enum omp_requires)
21291 (omp_requires_mask
21292 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
21294 else if ((omp_requires_mask
21295 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
21296 error_at (cloc, "%<atomic_default_mem_order%> clause used "
21297 "lexically after first %<atomic%> construct "
21298 "without memory order clause");
21299 new_req = (enum omp_requires) (new_req | this_req);
21300 omp_requires_mask
21301 = (enum omp_requires) (omp_requires_mask | this_req);
21302 continue;
21305 break;
21307 c_parser_skip_to_pragma_eol (parser);
21309 if (new_req == 0)
21310 error_at (loc, "%<pragma omp requires%> requires at least one clause");
21313 /* Helper function for c_parser_omp_taskloop.
21314 Disallow zero sized or potentially zero sized task reductions. */
21316 static tree
21317 c_finish_taskloop_clauses (tree clauses)
21319 tree *pc = &clauses;
21320 for (tree c = clauses; c; c = *pc)
21322 bool remove = false;
21323 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
21325 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
21326 if (integer_zerop (TYPE_SIZE_UNIT (type)))
21328 error_at (OMP_CLAUSE_LOCATION (c),
21329 "zero sized type %qT in %<reduction%> clause", type);
21330 remove = true;
21332 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
21334 error_at (OMP_CLAUSE_LOCATION (c),
21335 "variable sized type %qT in %<reduction%> clause",
21336 type);
21337 remove = true;
21340 if (remove)
21341 *pc = OMP_CLAUSE_CHAIN (c);
21342 else
21343 pc = &OMP_CLAUSE_CHAIN (c);
21345 return clauses;
21348 /* OpenMP 4.5:
21349 #pragma omp taskloop taskloop-clause[optseq] new-line
21350 for-loop
21352 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21353 for-loop */
21355 #define OMP_TASKLOOP_CLAUSE_MASK \
21356 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21357 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21358 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21360 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21361 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
21362 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
21363 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21364 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21365 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21366 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21367 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21368 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
21369 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21370 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21371 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
21373 static tree
21374 c_parser_omp_taskloop (location_t loc, c_parser *parser,
21375 char *p_name, omp_clause_mask mask, tree *cclauses,
21376 bool *if_p)
21378 tree clauses, block, ret;
21380 strcat (p_name, " taskloop");
21381 mask |= OMP_TASKLOOP_CLAUSE_MASK;
21382 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21383 clause. */
21384 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
21385 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
21387 if (c_parser_next_token_is (parser, CPP_NAME))
21389 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21391 if (strcmp (p, "simd") == 0)
21393 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21394 if (cclauses == NULL)
21395 cclauses = cclauses_buf;
21396 c_parser_consume_token (parser);
21397 if (!flag_openmp) /* flag_openmp_simd */
21398 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21399 if_p);
21400 block = c_begin_compound_stmt (true);
21401 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
21402 block = c_end_compound_stmt (loc, block, true);
21403 if (ret == NULL)
21404 return ret;
21405 ret = make_node (OMP_TASKLOOP);
21406 TREE_TYPE (ret) = void_type_node;
21407 OMP_FOR_BODY (ret) = block;
21408 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21409 OMP_FOR_CLAUSES (ret)
21410 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
21411 SET_EXPR_LOCATION (ret, loc);
21412 add_stmt (ret);
21413 return ret;
21416 if (!flag_openmp) /* flag_openmp_simd */
21418 c_parser_skip_to_pragma_eol (parser, false);
21419 return NULL_TREE;
21422 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21423 if (cclauses)
21425 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
21426 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21429 clauses = c_finish_taskloop_clauses (clauses);
21430 block = c_begin_compound_stmt (true);
21431 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
21432 block = c_end_compound_stmt (loc, block, true);
21433 add_stmt (block);
21435 return ret;
21438 /* Main entry point to parsing most OpenMP pragmas. */
21440 static void
21441 c_parser_omp_construct (c_parser *parser, bool *if_p)
21443 enum pragma_kind p_kind;
21444 location_t loc;
21445 tree stmt;
21446 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
21447 omp_clause_mask mask (0);
21449 loc = c_parser_peek_token (parser)->location;
21450 p_kind = c_parser_peek_token (parser)->pragma_kind;
21451 c_parser_consume_pragma (parser);
21453 switch (p_kind)
21455 case PRAGMA_OACC_ATOMIC:
21456 c_parser_omp_atomic (loc, parser);
21457 return;
21458 case PRAGMA_OACC_CACHE:
21459 strcpy (p_name, "#pragma acc");
21460 stmt = c_parser_oacc_cache (loc, parser);
21461 break;
21462 case PRAGMA_OACC_DATA:
21463 stmt = c_parser_oacc_data (loc, parser, if_p);
21464 break;
21465 case PRAGMA_OACC_HOST_DATA:
21466 stmt = c_parser_oacc_host_data (loc, parser, if_p);
21467 break;
21468 case PRAGMA_OACC_KERNELS:
21469 case PRAGMA_OACC_PARALLEL:
21470 case PRAGMA_OACC_SERIAL:
21471 strcpy (p_name, "#pragma acc");
21472 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
21473 break;
21474 case PRAGMA_OACC_LOOP:
21475 strcpy (p_name, "#pragma acc");
21476 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
21477 break;
21478 case PRAGMA_OACC_WAIT:
21479 strcpy (p_name, "#pragma wait");
21480 stmt = c_parser_oacc_wait (loc, parser, p_name);
21481 break;
21482 case PRAGMA_OMP_ATOMIC:
21483 c_parser_omp_atomic (loc, parser);
21484 return;
21485 case PRAGMA_OMP_CRITICAL:
21486 stmt = c_parser_omp_critical (loc, parser, if_p);
21487 break;
21488 case PRAGMA_OMP_DISTRIBUTE:
21489 strcpy (p_name, "#pragma omp");
21490 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
21491 break;
21492 case PRAGMA_OMP_FOR:
21493 strcpy (p_name, "#pragma omp");
21494 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
21495 break;
21496 case PRAGMA_OMP_LOOP:
21497 strcpy (p_name, "#pragma omp");
21498 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
21499 break;
21500 case PRAGMA_OMP_MASTER:
21501 strcpy (p_name, "#pragma omp");
21502 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
21503 break;
21504 case PRAGMA_OMP_PARALLEL:
21505 strcpy (p_name, "#pragma omp");
21506 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
21507 break;
21508 case PRAGMA_OMP_SECTIONS:
21509 strcpy (p_name, "#pragma omp");
21510 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
21511 break;
21512 case PRAGMA_OMP_SIMD:
21513 strcpy (p_name, "#pragma omp");
21514 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
21515 break;
21516 case PRAGMA_OMP_SINGLE:
21517 stmt = c_parser_omp_single (loc, parser, if_p);
21518 break;
21519 case PRAGMA_OMP_TASK:
21520 stmt = c_parser_omp_task (loc, parser, if_p);
21521 break;
21522 case PRAGMA_OMP_TASKGROUP:
21523 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
21524 break;
21525 case PRAGMA_OMP_TASKLOOP:
21526 strcpy (p_name, "#pragma omp");
21527 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
21528 break;
21529 case PRAGMA_OMP_TEAMS:
21530 strcpy (p_name, "#pragma omp");
21531 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
21532 break;
21533 default:
21534 gcc_unreachable ();
21537 if (stmt && stmt != error_mark_node)
21538 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
21542 /* OpenMP 2.5:
21543 # pragma omp threadprivate (variable-list) */
21545 static void
21546 c_parser_omp_threadprivate (c_parser *parser)
21548 tree vars, t;
21549 location_t loc;
21551 c_parser_consume_pragma (parser);
21552 loc = c_parser_peek_token (parser)->location;
21553 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
21555 /* Mark every variable in VARS to be assigned thread local storage. */
21556 for (t = vars; t; t = TREE_CHAIN (t))
21558 tree v = TREE_PURPOSE (t);
21560 /* FIXME diagnostics: Ideally we should keep individual
21561 locations for all the variables in the var list to make the
21562 following errors more precise. Perhaps
21563 c_parser_omp_var_list_parens() should construct a list of
21564 locations to go along with the var list. */
21566 /* If V had already been marked threadprivate, it doesn't matter
21567 whether it had been used prior to this point. */
21568 if (!VAR_P (v))
21569 error_at (loc, "%qD is not a variable", v);
21570 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
21571 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
21572 else if (! is_global_var (v))
21573 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
21574 else if (TREE_TYPE (v) == error_mark_node)
21576 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
21577 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
21578 else
21580 if (! DECL_THREAD_LOCAL_P (v))
21582 set_decl_tls_model (v, decl_default_tls_model (v));
21583 /* If rtl has been already set for this var, call
21584 make_decl_rtl once again, so that encode_section_info
21585 has a chance to look at the new decl flags. */
21586 if (DECL_RTL_SET_P (v))
21587 make_decl_rtl (v);
21589 C_DECL_THREADPRIVATE_P (v) = 1;
21593 c_parser_skip_to_pragma_eol (parser);
21596 /* Parse a transaction attribute (GCC Extension).
21598 transaction-attribute:
21599 gnu-attributes
21600 attribute-specifier
21603 static tree
21604 c_parser_transaction_attributes (c_parser *parser)
21606 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
21607 return c_parser_gnu_attributes (parser);
21609 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
21610 return NULL_TREE;
21611 return c_parser_std_attribute_specifier (parser, true);
21614 /* Parse a __transaction_atomic or __transaction_relaxed statement
21615 (GCC Extension).
21617 transaction-statement:
21618 __transaction_atomic transaction-attribute[opt] compound-statement
21619 __transaction_relaxed compound-statement
21621 Note that the only valid attribute is: "outer".
21624 static tree
21625 c_parser_transaction (c_parser *parser, enum rid keyword)
21627 unsigned int old_in = parser->in_transaction;
21628 unsigned int this_in = 1, new_in;
21629 location_t loc = c_parser_peek_token (parser)->location;
21630 tree stmt, attrs;
21632 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21633 || keyword == RID_TRANSACTION_RELAXED)
21634 && c_parser_next_token_is_keyword (parser, keyword));
21635 c_parser_consume_token (parser);
21637 if (keyword == RID_TRANSACTION_RELAXED)
21638 this_in |= TM_STMT_ATTR_RELAXED;
21639 else
21641 attrs = c_parser_transaction_attributes (parser);
21642 if (attrs)
21643 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
21646 /* Keep track if we're in the lexical scope of an outer transaction. */
21647 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
21649 parser->in_transaction = new_in;
21650 stmt = c_parser_compound_statement (parser);
21651 parser->in_transaction = old_in;
21653 if (flag_tm)
21654 stmt = c_finish_transaction (loc, stmt, this_in);
21655 else
21656 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21657 "%<__transaction_atomic%> without transactional memory support enabled"
21658 : "%<__transaction_relaxed %> "
21659 "without transactional memory support enabled"));
21661 return stmt;
21664 /* Parse a __transaction_atomic or __transaction_relaxed expression
21665 (GCC Extension).
21667 transaction-expression:
21668 __transaction_atomic ( expression )
21669 __transaction_relaxed ( expression )
21672 static struct c_expr
21673 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
21675 struct c_expr ret;
21676 unsigned int old_in = parser->in_transaction;
21677 unsigned int this_in = 1;
21678 location_t loc = c_parser_peek_token (parser)->location;
21679 tree attrs;
21681 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21682 || keyword == RID_TRANSACTION_RELAXED)
21683 && c_parser_next_token_is_keyword (parser, keyword));
21684 c_parser_consume_token (parser);
21686 if (keyword == RID_TRANSACTION_RELAXED)
21687 this_in |= TM_STMT_ATTR_RELAXED;
21688 else
21690 attrs = c_parser_transaction_attributes (parser);
21691 if (attrs)
21692 this_in |= parse_tm_stmt_attr (attrs, 0);
21695 parser->in_transaction = this_in;
21696 matching_parens parens;
21697 if (parens.require_open (parser))
21699 tree expr = c_parser_expression (parser).value;
21700 ret.original_type = TREE_TYPE (expr);
21701 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
21702 if (this_in & TM_STMT_ATTR_RELAXED)
21703 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
21704 SET_EXPR_LOCATION (ret.value, loc);
21705 ret.original_code = TRANSACTION_EXPR;
21706 if (!parens.require_close (parser))
21708 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
21709 goto error;
21712 else
21714 error:
21715 ret.set_error ();
21716 ret.original_code = ERROR_MARK;
21717 ret.original_type = NULL;
21719 parser->in_transaction = old_in;
21721 if (!flag_tm)
21722 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21723 "%<__transaction_atomic%> without transactional memory support enabled"
21724 : "%<__transaction_relaxed %> "
21725 "without transactional memory support enabled"));
21727 set_c_expr_source_range (&ret, loc, loc);
21729 return ret;
21732 /* Parse a __transaction_cancel statement (GCC Extension).
21734 transaction-cancel-statement:
21735 __transaction_cancel transaction-attribute[opt] ;
21737 Note that the only valid attribute is "outer".
21740 static tree
21741 c_parser_transaction_cancel (c_parser *parser)
21743 location_t loc = c_parser_peek_token (parser)->location;
21744 tree attrs;
21745 bool is_outer = false;
21747 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
21748 c_parser_consume_token (parser);
21750 attrs = c_parser_transaction_attributes (parser);
21751 if (attrs)
21752 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
21754 if (!flag_tm)
21756 error_at (loc, "%<__transaction_cancel%> without "
21757 "transactional memory support enabled");
21758 goto ret_error;
21760 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
21762 error_at (loc, "%<__transaction_cancel%> within a "
21763 "%<__transaction_relaxed%>");
21764 goto ret_error;
21766 else if (is_outer)
21768 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
21769 && !is_tm_may_cancel_outer (current_function_decl))
21771 error_at (loc, "outer %<__transaction_cancel%> not "
21772 "within outer %<__transaction_atomic%> or "
21773 "a %<transaction_may_cancel_outer%> function");
21774 goto ret_error;
21777 else if (parser->in_transaction == 0)
21779 error_at (loc, "%<__transaction_cancel%> not within "
21780 "%<__transaction_atomic%>");
21781 goto ret_error;
21784 return add_stmt (build_tm_abort_call (loc, is_outer));
21786 ret_error:
21787 return build1 (NOP_EXPR, void_type_node, error_mark_node);
21790 /* Parse a single source file. */
21792 void
21793 c_parse_file (void)
21795 /* Use local storage to begin. If the first token is a pragma, parse it.
21796 If it is #pragma GCC pch_preprocess, then this will load a PCH file
21797 which will cause garbage collection. */
21798 c_parser tparser;
21800 memset (&tparser, 0, sizeof tparser);
21801 tparser.translate_strings_p = true;
21802 tparser.tokens = &tparser.tokens_buf[0];
21803 the_parser = &tparser;
21805 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
21806 c_parser_pragma_pch_preprocess (&tparser);
21807 else
21808 c_common_no_more_pch ();
21810 the_parser = ggc_alloc<c_parser> ();
21811 *the_parser = tparser;
21812 if (tparser.tokens == &tparser.tokens_buf[0])
21813 the_parser->tokens = &the_parser->tokens_buf[0];
21815 /* Initialize EH, if we've been told to do so. */
21816 if (flag_exceptions)
21817 using_eh_for_cleanups ();
21819 c_parser_translation_unit (the_parser);
21820 the_parser = NULL;
21823 /* Parse the body of a function declaration marked with "__RTL".
21825 The RTL parser works on the level of characters read from a
21826 FILE *, whereas c_parser works at the level of tokens.
21827 Square this circle by consuming all of the tokens up to and
21828 including the closing brace, recording the start/end of the RTL
21829 fragment, and reopening the file and re-reading the relevant
21830 lines within the RTL parser.
21832 This requires the opening and closing braces of the C function
21833 to be on separate lines from the RTL they wrap.
21835 Take ownership of START_WITH_PASS, if non-NULL. */
21837 location_t
21838 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
21840 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21842 free (start_with_pass);
21843 return c_parser_peek_token (parser)->location;
21846 location_t start_loc = c_parser_peek_token (parser)->location;
21848 /* Consume all tokens, up to the closing brace, handling
21849 matching pairs of braces in the rtl dump. */
21850 int num_open_braces = 1;
21851 while (1)
21853 switch (c_parser_peek_token (parser)->type)
21855 case CPP_OPEN_BRACE:
21856 num_open_braces++;
21857 break;
21858 case CPP_CLOSE_BRACE:
21859 if (--num_open_braces == 0)
21860 goto found_closing_brace;
21861 break;
21862 case CPP_EOF:
21863 error_at (start_loc, "no closing brace");
21864 free (start_with_pass);
21865 return c_parser_peek_token (parser)->location;
21866 default:
21867 break;
21869 c_parser_consume_token (parser);
21872 found_closing_brace:
21873 /* At the closing brace; record its location. */
21874 location_t end_loc = c_parser_peek_token (parser)->location;
21876 /* Consume the closing brace. */
21877 c_parser_consume_token (parser);
21879 /* Invoke the RTL parser. */
21880 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
21882 free (start_with_pass);
21883 return end_loc;
21886 /* Run the backend on the cfun created above, transferring ownership of
21887 START_WITH_PASS. */
21888 run_rtl_passes (start_with_pass);
21889 return end_loc;
21892 #include "gt-c-c-parser.h"