Don't warn when alignment of global common data exceeds maximum alignment.
[official-gcc.git] / gcc / c / c-parser.c
blobc5783075a999737933b0695ba6689bacc5c2e64f
1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2021 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 "tree-pretty-print.h"
72 #include "memmodel.h"
73 #include "c-family/known-headers.h"
75 /* We need to walk over decls with incomplete struct/union/enum types
76 after parsing the whole translation unit.
77 In finish_decl(), if the decl is static, has incomplete
78 struct/union/enum type, it is appended to incomplete_record_decls.
79 In c_parser_translation_unit(), we iterate over incomplete_record_decls
80 and report error if any of the decls are still incomplete. */
82 vec<tree> incomplete_record_decls;
84 void
85 set_c_expr_source_range (c_expr *expr,
86 location_t start, location_t finish)
88 expr->src_range.m_start = start;
89 expr->src_range.m_finish = finish;
90 if (expr->value)
91 set_source_range (expr->value, start, finish);
94 void
95 set_c_expr_source_range (c_expr *expr,
96 source_range src_range)
98 expr->src_range = src_range;
99 if (expr->value)
100 set_source_range (expr->value, src_range);
104 /* Initialization routine for this file. */
106 void
107 c_parse_init (void)
109 /* The only initialization required is of the reserved word
110 identifiers. */
111 unsigned int i;
112 tree id;
113 int mask = 0;
115 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
116 the c_token structure. */
117 gcc_assert (RID_MAX <= 255);
119 mask |= D_CXXONLY;
120 if (!flag_isoc99)
121 mask |= D_C99;
122 if (flag_no_asm)
124 mask |= D_ASM | D_EXT;
125 if (!flag_isoc99)
126 mask |= D_EXT89;
128 if (!c_dialect_objc ())
129 mask |= D_OBJC | D_CXX_OBJC;
131 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
132 for (i = 0; i < num_c_common_reswords; i++)
134 /* If a keyword is disabled, do not enter it into the table
135 and so create a canonical spelling that isn't a keyword. */
136 if (c_common_reswords[i].disable & mask)
138 if (warn_cxx_compat
139 && (c_common_reswords[i].disable & D_CXXWARN))
141 id = get_identifier (c_common_reswords[i].word);
142 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
143 C_IS_RESERVED_WORD (id) = 1;
145 continue;
148 id = get_identifier (c_common_reswords[i].word);
149 C_SET_RID_CODE (id, c_common_reswords[i].rid);
150 C_IS_RESERVED_WORD (id) = 1;
151 ridpointers [(int) c_common_reswords[i].rid] = id;
154 for (i = 0; i < NUM_INT_N_ENTS; i++)
156 /* We always create the symbols but they aren't always supported. */
157 char name[50];
158 sprintf (name, "__int%d", int_n_data[i].bitsize);
159 id = get_identifier (name);
160 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
161 C_IS_RESERVED_WORD (id) = 1;
163 sprintf (name, "__int%d__", int_n_data[i].bitsize);
164 id = get_identifier (name);
165 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
166 C_IS_RESERVED_WORD (id) = 1;
170 /* A parser structure recording information about the state and
171 context of parsing. Includes lexer information with up to two
172 tokens of look-ahead; more are not needed for C. */
173 struct GTY(()) c_parser {
174 /* The look-ahead tokens. */
175 c_token * GTY((skip)) tokens;
176 /* Buffer for look-ahead tokens. */
177 c_token tokens_buf[4];
178 /* How many look-ahead tokens are available (0 - 4, or
179 more if parsing from pre-lexed tokens). */
180 unsigned int tokens_avail;
181 /* Raw look-ahead tokens, used only for checking in Objective-C
182 whether '[[' starts attributes. */
183 vec<c_token, va_gc> *raw_tokens;
184 /* The number of raw look-ahead tokens that have since been fully
185 lexed. */
186 unsigned int raw_tokens_used;
187 /* True if a syntax error is being recovered from; false otherwise.
188 c_parser_error sets this flag. It should clear this flag when
189 enough tokens have been consumed to recover from the error. */
190 BOOL_BITFIELD error : 1;
191 /* True if we're processing a pragma, and shouldn't automatically
192 consume CPP_PRAGMA_EOL. */
193 BOOL_BITFIELD in_pragma : 1;
194 /* True if we're parsing the outermost block of an if statement. */
195 BOOL_BITFIELD in_if_block : 1;
196 /* True if we want to lex a translated, joined string (for an
197 initial #pragma pch_preprocess). Otherwise the parser is
198 responsible for concatenating strings and translating to the
199 execution character set as needed. */
200 BOOL_BITFIELD lex_joined_string : 1;
201 /* True if, when the parser is concatenating string literals, it
202 should translate them to the execution character set (false
203 inside attributes). */
204 BOOL_BITFIELD translate_strings_p : 1;
206 /* Objective-C specific parser/lexer information. */
208 /* True if we are in a context where the Objective-C "PQ" keywords
209 are considered keywords. */
210 BOOL_BITFIELD objc_pq_context : 1;
211 /* True if we are parsing a (potential) Objective-C foreach
212 statement. This is set to true after we parsed 'for (' and while
213 we wait for 'in' or ';' to decide if it's a standard C for loop or an
214 Objective-C foreach loop. */
215 BOOL_BITFIELD objc_could_be_foreach_context : 1;
216 /* The following flag is needed to contextualize Objective-C lexical
217 analysis. In some cases (e.g., 'int NSObject;'), it is
218 undesirable to bind an identifier to an Objective-C class, even
219 if a class with that name exists. */
220 BOOL_BITFIELD objc_need_raw_identifier : 1;
221 /* Nonzero if we're processing a __transaction statement. The value
222 is 1 | TM_STMT_ATTR_*. */
223 unsigned int in_transaction : 4;
224 /* True if we are in a context where the Objective-C "Property attribute"
225 keywords are valid. */
226 BOOL_BITFIELD objc_property_attr_context : 1;
228 /* Whether we have just seen/constructed a string-literal. Set when
229 returning a string-literal from c_parser_string_literal. Reset
230 in consume_token. Useful when we get a parse error and see an
231 unknown token, which could have been a string-literal constant
232 macro. */
233 BOOL_BITFIELD seen_string_literal : 1;
235 /* Location of the last consumed token. */
236 location_t last_token_location;
239 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
241 c_token *
242 c_parser_tokens_buf (c_parser *parser, unsigned n)
244 return &parser->tokens_buf[n];
247 /* Return the error state of PARSER. */
249 bool
250 c_parser_error (c_parser *parser)
252 return parser->error;
255 /* Set the error state of PARSER to ERR. */
257 void
258 c_parser_set_error (c_parser *parser, bool err)
260 parser->error = err;
264 /* The actual parser and external interface. ??? Does this need to be
265 garbage-collected? */
267 static GTY (()) c_parser *the_parser;
269 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
270 context-sensitive postprocessing of the token is not done. */
272 static void
273 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
275 timevar_push (TV_LEX);
277 if (raw || vec_safe_length (parser->raw_tokens) == 0)
279 token->type = c_lex_with_flags (&token->value, &token->location,
280 &token->flags,
281 (parser->lex_joined_string
282 ? 0 : C_LEX_STRING_NO_JOIN));
283 token->id_kind = C_ID_NONE;
284 token->keyword = RID_MAX;
285 token->pragma_kind = PRAGMA_NONE;
287 else
289 /* Use a token previously lexed as a raw look-ahead token, and
290 complete the processing on it. */
291 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
292 ++parser->raw_tokens_used;
293 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
295 vec_free (parser->raw_tokens);
296 parser->raw_tokens_used = 0;
300 if (raw)
301 goto out;
303 switch (token->type)
305 case CPP_NAME:
307 tree decl;
309 bool objc_force_identifier = parser->objc_need_raw_identifier;
310 if (c_dialect_objc ())
311 parser->objc_need_raw_identifier = false;
313 if (C_IS_RESERVED_WORD (token->value))
315 enum rid rid_code = C_RID_CODE (token->value);
317 if (rid_code == RID_CXX_COMPAT_WARN)
319 warning_at (token->location,
320 OPT_Wc___compat,
321 "identifier %qE conflicts with C++ keyword",
322 token->value);
324 else if (rid_code >= RID_FIRST_ADDR_SPACE
325 && rid_code <= RID_LAST_ADDR_SPACE)
327 addr_space_t as;
328 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
329 targetm.addr_space.diagnose_usage (as, token->location);
330 token->id_kind = C_ID_ADDRSPACE;
331 token->keyword = rid_code;
332 break;
334 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
336 /* We found an Objective-C "pq" keyword (in, out,
337 inout, bycopy, byref, oneway). They need special
338 care because the interpretation depends on the
339 context. */
340 if (parser->objc_pq_context)
342 token->type = CPP_KEYWORD;
343 token->keyword = rid_code;
344 break;
346 else if (parser->objc_could_be_foreach_context
347 && rid_code == RID_IN)
349 /* We are in Objective-C, inside a (potential)
350 foreach context (which means after having
351 parsed 'for (', but before having parsed ';'),
352 and we found 'in'. We consider it the keyword
353 which terminates the declaration at the
354 beginning of a foreach-statement. Note that
355 this means you can't use 'in' for anything else
356 in that context; in particular, in Objective-C
357 you can't use 'in' as the name of the running
358 variable in a C for loop. We could potentially
359 try to add code here to disambiguate, but it
360 seems a reasonable limitation. */
361 token->type = CPP_KEYWORD;
362 token->keyword = rid_code;
363 break;
365 /* Else, "pq" keywords outside of the "pq" context are
366 not keywords, and we fall through to the code for
367 normal tokens. */
369 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
371 /* We found an Objective-C "property attribute"
372 keyword (getter, setter, readonly, etc). These are
373 only valid in the property context. */
374 if (parser->objc_property_attr_context)
376 token->type = CPP_KEYWORD;
377 token->keyword = rid_code;
378 break;
380 /* Else they are not special keywords.
383 else if (c_dialect_objc ()
384 && (OBJC_IS_AT_KEYWORD (rid_code)
385 || OBJC_IS_CXX_KEYWORD (rid_code)))
387 /* We found one of the Objective-C "@" keywords (defs,
388 selector, synchronized, etc) or one of the
389 Objective-C "cxx" keywords (class, private,
390 protected, public, try, catch, throw) without a
391 preceding '@' sign. Do nothing and fall through to
392 the code for normal tokens (in C++ we would still
393 consider the CXX ones keywords, but not in C). */
396 else
398 token->type = CPP_KEYWORD;
399 token->keyword = rid_code;
400 break;
404 decl = lookup_name (token->value);
405 if (decl)
407 if (TREE_CODE (decl) == TYPE_DECL)
409 token->id_kind = C_ID_TYPENAME;
410 break;
413 else if (c_dialect_objc ())
415 tree objc_interface_decl = objc_is_class_name (token->value);
416 /* Objective-C class names are in the same namespace as
417 variables and typedefs, and hence are shadowed by local
418 declarations. */
419 if (objc_interface_decl
420 && (!objc_force_identifier || global_bindings_p ()))
422 token->value = objc_interface_decl;
423 token->id_kind = C_ID_CLASSNAME;
424 break;
427 token->id_kind = C_ID_ID;
429 break;
430 case CPP_AT_NAME:
431 /* This only happens in Objective-C; it must be a keyword. */
432 token->type = CPP_KEYWORD;
433 switch (C_RID_CODE (token->value))
435 /* Replace 'class' with '@class', 'private' with '@private',
436 etc. This prevents confusion with the C++ keyword
437 'class', and makes the tokens consistent with other
438 Objective-C 'AT' keywords. For example '@class' is
439 reported as RID_AT_CLASS which is consistent with
440 '@synchronized', which is reported as
441 RID_AT_SYNCHRONIZED.
443 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
444 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
445 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
446 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
447 case RID_THROW: token->keyword = RID_AT_THROW; break;
448 case RID_TRY: token->keyword = RID_AT_TRY; break;
449 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
450 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
451 default: token->keyword = C_RID_CODE (token->value);
453 break;
454 case CPP_COLON:
455 case CPP_COMMA:
456 case CPP_CLOSE_PAREN:
457 case CPP_SEMICOLON:
458 /* These tokens may affect the interpretation of any identifiers
459 following, if doing Objective-C. */
460 if (c_dialect_objc ())
461 parser->objc_need_raw_identifier = false;
462 break;
463 case CPP_PRAGMA:
464 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
465 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
466 token->value = NULL;
467 break;
468 default:
469 break;
471 out:
472 timevar_pop (TV_LEX);
475 /* Return a pointer to the next token from PARSER, reading it in if
476 necessary. */
478 c_token *
479 c_parser_peek_token (c_parser *parser)
481 if (parser->tokens_avail == 0)
483 c_lex_one_token (parser, &parser->tokens[0]);
484 parser->tokens_avail = 1;
486 return &parser->tokens[0];
489 /* Return a pointer to the next-but-one token from PARSER, reading it
490 in if necessary. The next token is already read in. */
492 c_token *
493 c_parser_peek_2nd_token (c_parser *parser)
495 if (parser->tokens_avail >= 2)
496 return &parser->tokens[1];
497 gcc_assert (parser->tokens_avail == 1);
498 gcc_assert (parser->tokens[0].type != CPP_EOF);
499 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
500 c_lex_one_token (parser, &parser->tokens[1]);
501 parser->tokens_avail = 2;
502 return &parser->tokens[1];
505 /* Return a pointer to the Nth token from PARSER, reading it
506 in if necessary. The N-1th token is already read in. */
508 c_token *
509 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
511 /* N is 1-based, not zero-based. */
512 gcc_assert (n > 0);
514 if (parser->tokens_avail >= n)
515 return &parser->tokens[n - 1];
516 gcc_assert (parser->tokens_avail == n - 1);
517 c_lex_one_token (parser, &parser->tokens[n - 1]);
518 parser->tokens_avail = n;
519 return &parser->tokens[n - 1];
522 /* Return a pointer to the Nth token from PARSER, reading it in as a
523 raw look-ahead token if necessary. The N-1th token is already read
524 in. Raw look-ahead tokens remain available for when the non-raw
525 functions above are called. */
527 c_token *
528 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
530 /* N is 1-based, not zero-based. */
531 gcc_assert (n > 0);
533 if (parser->tokens_avail >= n)
534 return &parser->tokens[n - 1];
535 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
536 unsigned int raw_avail
537 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
538 gcc_assert (raw_avail >= n - 1);
539 if (raw_avail >= n)
540 return &(*parser->raw_tokens)[parser->raw_tokens_used
541 + n - 1 - parser->tokens_avail];
542 vec_safe_reserve (parser->raw_tokens, 1);
543 parser->raw_tokens->quick_grow (raw_len + 1);
544 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
545 return &(*parser->raw_tokens)[raw_len];
548 bool
549 c_keyword_starts_typename (enum rid keyword)
551 switch (keyword)
553 case RID_UNSIGNED:
554 case RID_LONG:
555 case RID_SHORT:
556 case RID_SIGNED:
557 case RID_COMPLEX:
558 case RID_INT:
559 case RID_CHAR:
560 case RID_FLOAT:
561 case RID_DOUBLE:
562 case RID_VOID:
563 case RID_DFLOAT32:
564 case RID_DFLOAT64:
565 case RID_DFLOAT128:
566 CASE_RID_FLOATN_NX:
567 case RID_BOOL:
568 case RID_ENUM:
569 case RID_STRUCT:
570 case RID_UNION:
571 case RID_TYPEOF:
572 case RID_CONST:
573 case RID_ATOMIC:
574 case RID_VOLATILE:
575 case RID_RESTRICT:
576 case RID_ATTRIBUTE:
577 case RID_FRACT:
578 case RID_ACCUM:
579 case RID_SAT:
580 case RID_AUTO_TYPE:
581 case RID_ALIGNAS:
582 return true;
583 default:
584 if (keyword >= RID_FIRST_INT_N
585 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
586 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
587 return true;
588 return false;
592 /* Return true if TOKEN can start a type name,
593 false otherwise. */
594 bool
595 c_token_starts_typename (c_token *token)
597 switch (token->type)
599 case CPP_NAME:
600 switch (token->id_kind)
602 case C_ID_ID:
603 return false;
604 case C_ID_ADDRSPACE:
605 return true;
606 case C_ID_TYPENAME:
607 return true;
608 case C_ID_CLASSNAME:
609 gcc_assert (c_dialect_objc ());
610 return true;
611 default:
612 gcc_unreachable ();
614 case CPP_KEYWORD:
615 return c_keyword_starts_typename (token->keyword);
616 case CPP_LESS:
617 if (c_dialect_objc ())
618 return true;
619 return false;
620 default:
621 return false;
625 /* Return true if the next token from PARSER can start a type name,
626 false otherwise. LA specifies how to do lookahead in order to
627 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
629 static inline bool
630 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
632 c_token *token = c_parser_peek_token (parser);
633 if (c_token_starts_typename (token))
634 return true;
636 /* Try a bit harder to detect an unknown typename. */
637 if (la != cla_prefer_id
638 && token->type == CPP_NAME
639 && token->id_kind == C_ID_ID
641 /* Do not try too hard when we could have "object in array". */
642 && !parser->objc_could_be_foreach_context
644 && (la == cla_prefer_type
645 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
646 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
648 /* Only unknown identifiers. */
649 && !lookup_name (token->value))
650 return true;
652 return false;
655 /* Return true if TOKEN is a type qualifier, false otherwise. */
656 static bool
657 c_token_is_qualifier (c_token *token)
659 switch (token->type)
661 case CPP_NAME:
662 switch (token->id_kind)
664 case C_ID_ADDRSPACE:
665 return true;
666 default:
667 return false;
669 case CPP_KEYWORD:
670 switch (token->keyword)
672 case RID_CONST:
673 case RID_VOLATILE:
674 case RID_RESTRICT:
675 case RID_ATTRIBUTE:
676 case RID_ATOMIC:
677 return true;
678 default:
679 return false;
681 case CPP_LESS:
682 return false;
683 default:
684 gcc_unreachable ();
688 /* Return true if the next token from PARSER is a type qualifier,
689 false otherwise. */
690 static inline bool
691 c_parser_next_token_is_qualifier (c_parser *parser)
693 c_token *token = c_parser_peek_token (parser);
694 return c_token_is_qualifier (token);
697 /* Return true if TOKEN can start declaration specifiers (not
698 including standard attributes), false otherwise. */
699 static bool
700 c_token_starts_declspecs (c_token *token)
702 switch (token->type)
704 case CPP_NAME:
705 switch (token->id_kind)
707 case C_ID_ID:
708 return false;
709 case C_ID_ADDRSPACE:
710 return true;
711 case C_ID_TYPENAME:
712 return true;
713 case C_ID_CLASSNAME:
714 gcc_assert (c_dialect_objc ());
715 return true;
716 default:
717 gcc_unreachable ();
719 case CPP_KEYWORD:
720 switch (token->keyword)
722 case RID_STATIC:
723 case RID_EXTERN:
724 case RID_REGISTER:
725 case RID_TYPEDEF:
726 case RID_INLINE:
727 case RID_NORETURN:
728 case RID_AUTO:
729 case RID_THREAD:
730 case RID_UNSIGNED:
731 case RID_LONG:
732 case RID_SHORT:
733 case RID_SIGNED:
734 case RID_COMPLEX:
735 case RID_INT:
736 case RID_CHAR:
737 case RID_FLOAT:
738 case RID_DOUBLE:
739 case RID_VOID:
740 case RID_DFLOAT32:
741 case RID_DFLOAT64:
742 case RID_DFLOAT128:
743 CASE_RID_FLOATN_NX:
744 case RID_BOOL:
745 case RID_ENUM:
746 case RID_STRUCT:
747 case RID_UNION:
748 case RID_TYPEOF:
749 case RID_CONST:
750 case RID_VOLATILE:
751 case RID_RESTRICT:
752 case RID_ATTRIBUTE:
753 case RID_FRACT:
754 case RID_ACCUM:
755 case RID_SAT:
756 case RID_ALIGNAS:
757 case RID_ATOMIC:
758 case RID_AUTO_TYPE:
759 return true;
760 default:
761 if (token->keyword >= RID_FIRST_INT_N
762 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
763 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
764 return true;
765 return false;
767 case CPP_LESS:
768 if (c_dialect_objc ())
769 return true;
770 return false;
771 default:
772 return false;
777 /* Return true if TOKEN can start declaration specifiers (not
778 including standard attributes) or a static assertion, false
779 otherwise. */
780 static bool
781 c_token_starts_declaration (c_token *token)
783 if (c_token_starts_declspecs (token)
784 || token->keyword == RID_STATIC_ASSERT)
785 return true;
786 else
787 return false;
790 /* Return true if the next token from PARSER can start declaration
791 specifiers (not including standard attributes), false
792 otherwise. */
793 bool
794 c_parser_next_token_starts_declspecs (c_parser *parser)
796 c_token *token = c_parser_peek_token (parser);
798 /* In Objective-C, a classname normally starts a declspecs unless it
799 is immediately followed by a dot. In that case, it is the
800 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
801 setter/getter on the class. c_token_starts_declspecs() can't
802 differentiate between the two cases because it only checks the
803 current token, so we have a special check here. */
804 if (c_dialect_objc ()
805 && token->type == CPP_NAME
806 && token->id_kind == C_ID_CLASSNAME
807 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
808 return false;
810 return c_token_starts_declspecs (token);
813 /* Return true if the next tokens from PARSER can start declaration
814 specifiers (not including standard attributes) or a static
815 assertion, false otherwise. */
816 bool
817 c_parser_next_tokens_start_declaration (c_parser *parser)
819 c_token *token = c_parser_peek_token (parser);
821 /* Same as above. */
822 if (c_dialect_objc ()
823 && token->type == CPP_NAME
824 && token->id_kind == C_ID_CLASSNAME
825 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
826 return false;
828 /* Labels do not start declarations. */
829 if (token->type == CPP_NAME
830 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
831 return false;
833 if (c_token_starts_declaration (token))
834 return true;
836 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
837 return true;
839 return false;
842 /* Consume the next token from PARSER. */
844 void
845 c_parser_consume_token (c_parser *parser)
847 gcc_assert (parser->tokens_avail >= 1);
848 gcc_assert (parser->tokens[0].type != CPP_EOF);
849 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
850 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
851 parser->last_token_location = parser->tokens[0].location;
852 if (parser->tokens != &parser->tokens_buf[0])
853 parser->tokens++;
854 else if (parser->tokens_avail >= 2)
856 parser->tokens[0] = parser->tokens[1];
857 if (parser->tokens_avail >= 3)
859 parser->tokens[1] = parser->tokens[2];
860 if (parser->tokens_avail >= 4)
861 parser->tokens[2] = parser->tokens[3];
864 parser->tokens_avail--;
865 parser->seen_string_literal = false;
868 /* Expect the current token to be a #pragma. Consume it and remember
869 that we've begun parsing a pragma. */
871 static void
872 c_parser_consume_pragma (c_parser *parser)
874 gcc_assert (!parser->in_pragma);
875 gcc_assert (parser->tokens_avail >= 1);
876 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
877 if (parser->tokens != &parser->tokens_buf[0])
878 parser->tokens++;
879 else if (parser->tokens_avail >= 2)
881 parser->tokens[0] = parser->tokens[1];
882 if (parser->tokens_avail >= 3)
883 parser->tokens[1] = parser->tokens[2];
885 parser->tokens_avail--;
886 parser->in_pragma = true;
889 /* Update the global input_location from TOKEN. */
890 static inline void
891 c_parser_set_source_position_from_token (c_token *token)
893 if (token->type != CPP_EOF)
895 input_location = token->location;
899 /* Helper function for c_parser_error.
900 Having peeked a token of kind TOK1_KIND that might signify
901 a conflict marker, peek successor tokens to determine
902 if we actually do have a conflict marker.
903 Specifically, we consider a run of 7 '<', '=' or '>' characters
904 at the start of a line as a conflict marker.
905 These come through the lexer as three pairs and a single,
906 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
907 If it returns true, *OUT_LOC is written to with the location/range
908 of the marker. */
910 static bool
911 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
912 location_t *out_loc)
914 c_token *token2 = c_parser_peek_2nd_token (parser);
915 if (token2->type != tok1_kind)
916 return false;
917 c_token *token3 = c_parser_peek_nth_token (parser, 3);
918 if (token3->type != tok1_kind)
919 return false;
920 c_token *token4 = c_parser_peek_nth_token (parser, 4);
921 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
922 return false;
924 /* It must be at the start of the line. */
925 location_t start_loc = c_parser_peek_token (parser)->location;
926 if (LOCATION_COLUMN (start_loc) != 1)
927 return false;
929 /* We have a conflict marker. Construct a location of the form:
930 <<<<<<<
931 ^~~~~~~
932 with start == caret, finishing at the end of the marker. */
933 location_t finish_loc = get_finish (token4->location);
934 *out_loc = make_location (start_loc, start_loc, finish_loc);
936 return true;
939 /* Issue a diagnostic of the form
940 FILE:LINE: MESSAGE before TOKEN
941 where TOKEN is the next token in the input stream of PARSER.
942 MESSAGE (specified by the caller) is usually of the form "expected
943 OTHER-TOKEN".
945 Use RICHLOC as the location of the diagnostic.
947 Do not issue a diagnostic if still recovering from an error.
949 Return true iff an error was actually emitted.
951 ??? This is taken from the C++ parser, but building up messages in
952 this way is not i18n-friendly and some other approach should be
953 used. */
955 static bool
956 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
957 rich_location *richloc)
959 c_token *token = c_parser_peek_token (parser);
960 if (parser->error)
961 return false;
962 parser->error = true;
963 if (!gmsgid)
964 return false;
966 /* If this is actually a conflict marker, report it as such. */
967 if (token->type == CPP_LSHIFT
968 || token->type == CPP_RSHIFT
969 || token->type == CPP_EQ_EQ)
971 location_t loc;
972 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
974 error_at (loc, "version control conflict marker in file");
975 return true;
979 /* If we were parsing a string-literal and there is an unknown name
980 token right after, then check to see if that could also have been
981 a literal string by checking the name against a list of known
982 standard string literal constants defined in header files. If
983 there is one, then add that as an hint to the error message. */
984 auto_diagnostic_group d;
985 name_hint h;
986 if (parser->seen_string_literal && token->type == CPP_NAME)
988 tree name = token->value;
989 const char *token_name = IDENTIFIER_POINTER (name);
990 const char *header_hint
991 = get_c_stdlib_header_for_string_macro_name (token_name);
992 if (header_hint != NULL)
993 h = name_hint (NULL, new suggest_missing_header (token->location,
994 token_name,
995 header_hint));
998 c_parse_error (gmsgid,
999 /* Because c_parse_error does not understand
1000 CPP_KEYWORD, keywords are treated like
1001 identifiers. */
1002 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1003 /* ??? The C parser does not save the cpp flags of a
1004 token, we need to pass 0 here and we will not get
1005 the source spelling of some tokens but rather the
1006 canonical spelling. */
1007 token->value, /*flags=*/0, richloc);
1008 return true;
1011 /* As c_parser_error_richloc, but issue the message at the
1012 location of PARSER's next token, or at input_location
1013 if the next token is EOF. */
1015 bool
1016 c_parser_error (c_parser *parser, const char *gmsgid)
1018 c_token *token = c_parser_peek_token (parser);
1019 c_parser_set_source_position_from_token (token);
1020 rich_location richloc (line_table, input_location);
1021 return c_parser_error_richloc (parser, gmsgid, &richloc);
1024 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1025 This class is for tracking such a matching pair of symbols.
1026 In particular, it tracks the location of the first token,
1027 so that if the second token is missing, we can highlight the
1028 location of the first token when notifying the user about the
1029 problem. */
1031 template <typename traits_t>
1032 class token_pair
1034 public:
1035 /* token_pair's ctor. */
1036 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1038 /* If the next token is the opening symbol for this pair, consume it and
1039 return true.
1040 Otherwise, issue an error and return false.
1041 In either case, record the location of the opening token. */
1043 bool require_open (c_parser *parser)
1045 c_token *token = c_parser_peek_token (parser);
1046 if (token)
1047 m_open_loc = token->location;
1049 return c_parser_require (parser, traits_t::open_token_type,
1050 traits_t::open_gmsgid);
1053 /* Consume the next token from PARSER, recording its location as
1054 that of the opening token within the pair. */
1056 void consume_open (c_parser *parser)
1058 c_token *token = c_parser_peek_token (parser);
1059 gcc_assert (token->type == traits_t::open_token_type);
1060 m_open_loc = token->location;
1061 c_parser_consume_token (parser);
1064 /* If the next token is the closing symbol for this pair, consume it
1065 and return true.
1066 Otherwise, issue an error, highlighting the location of the
1067 corresponding opening token, and return false. */
1069 bool require_close (c_parser *parser) const
1071 return c_parser_require (parser, traits_t::close_token_type,
1072 traits_t::close_gmsgid, m_open_loc);
1075 /* Like token_pair::require_close, except that tokens will be skipped
1076 until the desired token is found. An error message is still produced
1077 if the next token is not as expected. */
1079 void skip_until_found_close (c_parser *parser) const
1081 c_parser_skip_until_found (parser, traits_t::close_token_type,
1082 traits_t::close_gmsgid, m_open_loc);
1085 private:
1086 location_t m_open_loc;
1089 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1091 struct matching_paren_traits
1093 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1094 static const char * const open_gmsgid;
1095 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1096 static const char * const close_gmsgid;
1099 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1100 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1102 /* "matching_parens" is a token_pair<T> class for tracking matching
1103 pairs of parentheses. */
1105 typedef token_pair<matching_paren_traits> matching_parens;
1107 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1109 struct matching_brace_traits
1111 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1112 static const char * const open_gmsgid;
1113 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1114 static const char * const close_gmsgid;
1117 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1118 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1120 /* "matching_braces" is a token_pair<T> class for tracking matching
1121 pairs of braces. */
1123 typedef token_pair<matching_brace_traits> matching_braces;
1125 /* Get a description of the matching symbol to TYPE e.g. "(" for
1126 CPP_CLOSE_PAREN. */
1128 static const char *
1129 get_matching_symbol (enum cpp_ttype type)
1131 switch (type)
1133 default:
1134 gcc_unreachable ();
1135 return "";
1136 case CPP_CLOSE_PAREN:
1137 return "(";
1138 case CPP_CLOSE_BRACE:
1139 return "{";
1143 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1144 issue the error MSGID. If MSGID is NULL then a message has already
1145 been produced and no message will be produced this time. Returns
1146 true if found, false otherwise.
1148 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1149 within any error as the location of an "opening" token matching
1150 the close token TYPE (e.g. the location of the '(' when TYPE is
1151 CPP_CLOSE_PAREN).
1153 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1154 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1155 attempt to generate a fix-it hint for the problem.
1156 Otherwise msgid describes multiple token types (e.g.
1157 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1158 generate a fix-it hint. */
1160 bool
1161 c_parser_require (c_parser *parser,
1162 enum cpp_ttype type,
1163 const char *msgid,
1164 location_t matching_location,
1165 bool type_is_unique)
1167 if (c_parser_next_token_is (parser, type))
1169 c_parser_consume_token (parser);
1170 return true;
1172 else
1174 location_t next_token_loc = c_parser_peek_token (parser)->location;
1175 gcc_rich_location richloc (next_token_loc);
1177 /* Potentially supply a fix-it hint, suggesting to add the
1178 missing token immediately after the *previous* token.
1179 This may move the primary location within richloc. */
1180 if (!parser->error && type_is_unique)
1181 maybe_suggest_missing_token_insertion (&richloc, type,
1182 parser->last_token_location);
1184 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1185 Attempt to consolidate diagnostics by printing it as a
1186 secondary range within the main diagnostic. */
1187 bool added_matching_location = false;
1188 if (matching_location != UNKNOWN_LOCATION)
1189 added_matching_location
1190 = richloc.add_location_if_nearby (matching_location);
1192 if (c_parser_error_richloc (parser, msgid, &richloc))
1193 /* If we weren't able to consolidate matching_location, then
1194 print it as a secondary diagnostic. */
1195 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1196 inform (matching_location, "to match this %qs",
1197 get_matching_symbol (type));
1199 return false;
1203 /* If the next token is the indicated keyword, consume it. Otherwise,
1204 issue the error MSGID. Returns true if found, false otherwise. */
1206 static bool
1207 c_parser_require_keyword (c_parser *parser,
1208 enum rid keyword,
1209 const char *msgid)
1211 if (c_parser_next_token_is_keyword (parser, keyword))
1213 c_parser_consume_token (parser);
1214 return true;
1216 else
1218 c_parser_error (parser, msgid);
1219 return false;
1223 /* Like c_parser_require, except that tokens will be skipped until the
1224 desired token is found. An error message is still produced if the
1225 next token is not as expected. If MSGID is NULL then a message has
1226 already been produced and no message will be produced this
1227 time.
1229 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1230 within any error as the location of an "opening" token matching
1231 the close token TYPE (e.g. the location of the '(' when TYPE is
1232 CPP_CLOSE_PAREN). */
1234 void
1235 c_parser_skip_until_found (c_parser *parser,
1236 enum cpp_ttype type,
1237 const char *msgid,
1238 location_t matching_location)
1240 unsigned nesting_depth = 0;
1242 if (c_parser_require (parser, type, msgid, matching_location))
1243 return;
1245 /* Skip tokens until the desired token is found. */
1246 while (true)
1248 /* Peek at the next token. */
1249 c_token *token = c_parser_peek_token (parser);
1250 /* If we've reached the token we want, consume it and stop. */
1251 if (token->type == type && !nesting_depth)
1253 c_parser_consume_token (parser);
1254 break;
1257 /* If we've run out of tokens, stop. */
1258 if (token->type == CPP_EOF)
1259 return;
1260 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1261 return;
1262 if (token->type == CPP_OPEN_BRACE
1263 || token->type == CPP_OPEN_PAREN
1264 || token->type == CPP_OPEN_SQUARE)
1265 ++nesting_depth;
1266 else if (token->type == CPP_CLOSE_BRACE
1267 || token->type == CPP_CLOSE_PAREN
1268 || token->type == CPP_CLOSE_SQUARE)
1270 if (nesting_depth-- == 0)
1271 break;
1273 /* Consume this token. */
1274 c_parser_consume_token (parser);
1276 parser->error = false;
1279 /* Skip tokens until the end of a parameter is found, but do not
1280 consume the comma, semicolon or closing delimiter. */
1282 static void
1283 c_parser_skip_to_end_of_parameter (c_parser *parser)
1285 unsigned nesting_depth = 0;
1287 while (true)
1289 c_token *token = c_parser_peek_token (parser);
1290 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1291 && !nesting_depth)
1292 break;
1293 /* If we've run out of tokens, stop. */
1294 if (token->type == CPP_EOF)
1295 return;
1296 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1297 return;
1298 if (token->type == CPP_OPEN_BRACE
1299 || token->type == CPP_OPEN_PAREN
1300 || token->type == CPP_OPEN_SQUARE)
1301 ++nesting_depth;
1302 else if (token->type == CPP_CLOSE_BRACE
1303 || token->type == CPP_CLOSE_PAREN
1304 || token->type == CPP_CLOSE_SQUARE)
1306 if (nesting_depth-- == 0)
1307 break;
1309 /* Consume this token. */
1310 c_parser_consume_token (parser);
1312 parser->error = false;
1315 /* Expect to be at the end of the pragma directive and consume an
1316 end of line marker. */
1318 static void
1319 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1321 gcc_assert (parser->in_pragma);
1322 parser->in_pragma = false;
1324 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1325 c_parser_error (parser, "expected end of line");
1327 cpp_ttype token_type;
1330 c_token *token = c_parser_peek_token (parser);
1331 token_type = token->type;
1332 if (token_type == CPP_EOF)
1333 break;
1334 c_parser_consume_token (parser);
1336 while (token_type != CPP_PRAGMA_EOL);
1338 parser->error = false;
1341 /* Skip tokens until we have consumed an entire block, or until we
1342 have consumed a non-nested ';'. */
1344 static void
1345 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1347 unsigned nesting_depth = 0;
1348 bool save_error = parser->error;
1350 while (true)
1352 c_token *token;
1354 /* Peek at the next token. */
1355 token = c_parser_peek_token (parser);
1357 switch (token->type)
1359 case CPP_EOF:
1360 return;
1362 case CPP_PRAGMA_EOL:
1363 if (parser->in_pragma)
1364 return;
1365 break;
1367 case CPP_SEMICOLON:
1368 /* If the next token is a ';', we have reached the
1369 end of the statement. */
1370 if (!nesting_depth)
1372 /* Consume the ';'. */
1373 c_parser_consume_token (parser);
1374 goto finished;
1376 break;
1378 case CPP_CLOSE_BRACE:
1379 /* If the next token is a non-nested '}', then we have
1380 reached the end of the current block. */
1381 if (nesting_depth == 0 || --nesting_depth == 0)
1383 c_parser_consume_token (parser);
1384 goto finished;
1386 break;
1388 case CPP_OPEN_BRACE:
1389 /* If it the next token is a '{', then we are entering a new
1390 block. Consume the entire block. */
1391 ++nesting_depth;
1392 break;
1394 case CPP_PRAGMA:
1395 /* If we see a pragma, consume the whole thing at once. We
1396 have some safeguards against consuming pragmas willy-nilly.
1397 Normally, we'd expect to be here with parser->error set,
1398 which disables these safeguards. But it's possible to get
1399 here for secondary error recovery, after parser->error has
1400 been cleared. */
1401 c_parser_consume_pragma (parser);
1402 c_parser_skip_to_pragma_eol (parser);
1403 parser->error = save_error;
1404 continue;
1406 default:
1407 break;
1410 c_parser_consume_token (parser);
1413 finished:
1414 parser->error = false;
1417 /* CPP's options (initialized by c-opts.c). */
1418 extern cpp_options *cpp_opts;
1420 /* Save the warning flags which are controlled by __extension__. */
1422 static inline int
1423 disable_extension_diagnostics (void)
1425 int ret = (pedantic
1426 | (warn_pointer_arith << 1)
1427 | (warn_traditional << 2)
1428 | (flag_iso << 3)
1429 | (warn_long_long << 4)
1430 | (warn_cxx_compat << 5)
1431 | (warn_overlength_strings << 6)
1432 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1433 play tricks to properly restore it. */
1434 | ((warn_c90_c99_compat == 1) << 7)
1435 | ((warn_c90_c99_compat == -1) << 8)
1436 /* Similarly for warn_c99_c11_compat. */
1437 | ((warn_c99_c11_compat == 1) << 9)
1438 | ((warn_c99_c11_compat == -1) << 10)
1439 /* Similarly for warn_c11_c2x_compat. */
1440 | ((warn_c11_c2x_compat == 1) << 11)
1441 | ((warn_c11_c2x_compat == -1) << 12)
1443 cpp_opts->cpp_pedantic = pedantic = 0;
1444 warn_pointer_arith = 0;
1445 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1446 flag_iso = 0;
1447 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1448 warn_cxx_compat = 0;
1449 warn_overlength_strings = 0;
1450 warn_c90_c99_compat = 0;
1451 warn_c99_c11_compat = 0;
1452 warn_c11_c2x_compat = 0;
1453 return ret;
1456 /* Restore the warning flags which are controlled by __extension__.
1457 FLAGS is the return value from disable_extension_diagnostics. */
1459 static inline void
1460 restore_extension_diagnostics (int flags)
1462 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1463 warn_pointer_arith = (flags >> 1) & 1;
1464 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1465 flag_iso = (flags >> 3) & 1;
1466 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1467 warn_cxx_compat = (flags >> 5) & 1;
1468 warn_overlength_strings = (flags >> 6) & 1;
1469 /* See above for why is this needed. */
1470 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1471 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1472 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1475 /* Helper data structure for parsing #pragma acc routine. */
1476 struct oacc_routine_data {
1477 bool error_seen; /* Set if error has been reported. */
1478 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1479 tree clauses;
1480 location_t loc;
1483 /* Used for parsing objc foreach statements. */
1484 static tree objc_foreach_break_label, objc_foreach_continue_label;
1486 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1487 unsigned int);
1488 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1489 static void c_parser_external_declaration (c_parser *);
1490 static void c_parser_asm_definition (c_parser *);
1491 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1492 bool, bool, tree * = NULL,
1493 vec<c_token> * = NULL,
1494 bool have_attrs = false,
1495 tree attrs = NULL,
1496 struct oacc_routine_data * = NULL,
1497 bool * = NULL);
1498 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1499 static void c_parser_static_assert_declaration (c_parser *);
1500 static struct c_typespec c_parser_enum_specifier (c_parser *);
1501 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1502 static tree c_parser_struct_declaration (c_parser *);
1503 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1504 static tree c_parser_alignas_specifier (c_parser *);
1505 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1506 c_dtr_syn, bool *);
1507 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1508 bool,
1509 struct c_declarator *);
1510 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1511 bool);
1512 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1513 tree, bool);
1514 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1515 static tree c_parser_simple_asm_expr (c_parser *);
1516 static tree c_parser_gnu_attributes (c_parser *);
1517 static struct c_expr c_parser_initializer (c_parser *);
1518 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1519 struct obstack *);
1520 static void c_parser_initelt (c_parser *, struct obstack *);
1521 static void c_parser_initval (c_parser *, struct c_expr *,
1522 struct obstack *);
1523 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1524 static location_t c_parser_compound_statement_nostart (c_parser *);
1525 static void c_parser_label (c_parser *, tree);
1526 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1527 static void c_parser_statement_after_labels (c_parser *, bool *,
1528 vec<tree> * = NULL);
1529 static tree c_parser_c99_block_statement (c_parser *, bool *,
1530 location_t * = NULL);
1531 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1532 static void c_parser_switch_statement (c_parser *, bool *);
1533 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1534 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1535 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1536 static tree c_parser_asm_statement (c_parser *);
1537 static tree c_parser_asm_operands (c_parser *);
1538 static tree c_parser_asm_goto_operands (c_parser *);
1539 static tree c_parser_asm_clobbers (c_parser *);
1540 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1541 tree = NULL_TREE);
1542 static struct c_expr c_parser_conditional_expression (c_parser *,
1543 struct c_expr *, tree);
1544 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1545 tree);
1546 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1547 static struct c_expr c_parser_unary_expression (c_parser *);
1548 static struct c_expr c_parser_sizeof_expression (c_parser *);
1549 static struct c_expr c_parser_alignof_expression (c_parser *);
1550 static struct c_expr c_parser_postfix_expression (c_parser *);
1551 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1552 struct c_type_name *,
1553 location_t);
1554 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1555 location_t loc,
1556 struct c_expr);
1557 static tree c_parser_transaction (c_parser *, enum rid);
1558 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1559 static tree c_parser_transaction_cancel (c_parser *);
1560 static struct c_expr c_parser_expression (c_parser *);
1561 static struct c_expr c_parser_expression_conv (c_parser *);
1562 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1563 vec<tree, va_gc> **, location_t *,
1564 tree *, vec<location_t> *,
1565 unsigned int * = NULL);
1566 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1568 static void c_parser_oacc_declare (c_parser *);
1569 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1570 static void c_parser_oacc_update (c_parser *);
1571 static void c_parser_omp_construct (c_parser *, bool *);
1572 static void c_parser_omp_threadprivate (c_parser *);
1573 static void c_parser_omp_barrier (c_parser *);
1574 static void c_parser_omp_depobj (c_parser *);
1575 static void c_parser_omp_flush (c_parser *);
1576 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1577 tree, tree *, bool *);
1578 static void c_parser_omp_taskwait (c_parser *);
1579 static void c_parser_omp_taskyield (c_parser *);
1580 static void c_parser_omp_cancel (c_parser *);
1581 static void c_parser_omp_nothing (c_parser *);
1583 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1584 pragma_stmt, pragma_compound };
1585 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1586 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1587 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1588 static void c_parser_omp_end_declare_target (c_parser *);
1589 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1590 static void c_parser_omp_requires (c_parser *);
1591 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1592 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1593 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1595 /* These Objective-C parser functions are only ever called when
1596 compiling Objective-C. */
1597 static void c_parser_objc_class_definition (c_parser *, tree);
1598 static void c_parser_objc_class_instance_variables (c_parser *);
1599 static void c_parser_objc_class_declaration (c_parser *);
1600 static void c_parser_objc_alias_declaration (c_parser *);
1601 static void c_parser_objc_protocol_definition (c_parser *, tree);
1602 static bool c_parser_objc_method_type (c_parser *);
1603 static void c_parser_objc_method_definition (c_parser *);
1604 static void c_parser_objc_methodprotolist (c_parser *);
1605 static void c_parser_objc_methodproto (c_parser *);
1606 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1607 static tree c_parser_objc_type_name (c_parser *);
1608 static tree c_parser_objc_protocol_refs (c_parser *);
1609 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1610 static void c_parser_objc_synchronized_statement (c_parser *);
1611 static tree c_parser_objc_selector (c_parser *);
1612 static tree c_parser_objc_selector_arg (c_parser *);
1613 static tree c_parser_objc_receiver (c_parser *);
1614 static tree c_parser_objc_message_args (c_parser *);
1615 static tree c_parser_objc_keywordexpr (c_parser *);
1616 static void c_parser_objc_at_property_declaration (c_parser *);
1617 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1618 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1619 static bool c_parser_objc_diagnose_bad_element_prefix
1620 (c_parser *, struct c_declspecs *);
1621 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1623 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1625 translation-unit:
1626 external-declarations
1628 external-declarations:
1629 external-declaration
1630 external-declarations external-declaration
1632 GNU extensions:
1634 translation-unit:
1635 empty
1638 static void
1639 c_parser_translation_unit (c_parser *parser)
1641 if (c_parser_next_token_is (parser, CPP_EOF))
1643 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1644 "ISO C forbids an empty translation unit");
1646 else
1648 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1649 mark_valid_location_for_stdc_pragma (false);
1652 ggc_collect ();
1653 c_parser_external_declaration (parser);
1654 obstack_free (&parser_obstack, obstack_position);
1656 while (c_parser_next_token_is_not (parser, CPP_EOF));
1659 unsigned int i;
1660 tree decl;
1661 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1662 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1663 error ("storage size of %q+D isn%'t known", decl);
1665 if (current_omp_declare_target_attribute)
1667 if (!errorcount)
1668 error ("%<#pragma omp declare target%> without corresponding "
1669 "%<#pragma omp end declare target%>");
1670 current_omp_declare_target_attribute = 0;
1674 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1676 external-declaration:
1677 function-definition
1678 declaration
1680 GNU extensions:
1682 external-declaration:
1683 asm-definition
1685 __extension__ external-declaration
1687 Objective-C:
1689 external-declaration:
1690 objc-class-definition
1691 objc-class-declaration
1692 objc-alias-declaration
1693 objc-protocol-definition
1694 objc-method-definition
1695 @end
1698 static void
1699 c_parser_external_declaration (c_parser *parser)
1701 int ext;
1702 switch (c_parser_peek_token (parser)->type)
1704 case CPP_KEYWORD:
1705 switch (c_parser_peek_token (parser)->keyword)
1707 case RID_EXTENSION:
1708 ext = disable_extension_diagnostics ();
1709 c_parser_consume_token (parser);
1710 c_parser_external_declaration (parser);
1711 restore_extension_diagnostics (ext);
1712 break;
1713 case RID_ASM:
1714 c_parser_asm_definition (parser);
1715 break;
1716 case RID_AT_INTERFACE:
1717 case RID_AT_IMPLEMENTATION:
1718 gcc_assert (c_dialect_objc ());
1719 c_parser_objc_class_definition (parser, NULL_TREE);
1720 break;
1721 case RID_AT_CLASS:
1722 gcc_assert (c_dialect_objc ());
1723 c_parser_objc_class_declaration (parser);
1724 break;
1725 case RID_AT_ALIAS:
1726 gcc_assert (c_dialect_objc ());
1727 c_parser_objc_alias_declaration (parser);
1728 break;
1729 case RID_AT_PROTOCOL:
1730 gcc_assert (c_dialect_objc ());
1731 c_parser_objc_protocol_definition (parser, NULL_TREE);
1732 break;
1733 case RID_AT_PROPERTY:
1734 gcc_assert (c_dialect_objc ());
1735 c_parser_objc_at_property_declaration (parser);
1736 break;
1737 case RID_AT_SYNTHESIZE:
1738 gcc_assert (c_dialect_objc ());
1739 c_parser_objc_at_synthesize_declaration (parser);
1740 break;
1741 case RID_AT_DYNAMIC:
1742 gcc_assert (c_dialect_objc ());
1743 c_parser_objc_at_dynamic_declaration (parser);
1744 break;
1745 case RID_AT_END:
1746 gcc_assert (c_dialect_objc ());
1747 c_parser_consume_token (parser);
1748 objc_finish_implementation ();
1749 break;
1750 default:
1751 goto decl_or_fndef;
1753 break;
1754 case CPP_SEMICOLON:
1755 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1756 "ISO C does not allow extra %<;%> outside of a function");
1757 c_parser_consume_token (parser);
1758 break;
1759 case CPP_PRAGMA:
1760 mark_valid_location_for_stdc_pragma (true);
1761 c_parser_pragma (parser, pragma_external, NULL);
1762 mark_valid_location_for_stdc_pragma (false);
1763 break;
1764 case CPP_PLUS:
1765 case CPP_MINUS:
1766 if (c_dialect_objc ())
1768 c_parser_objc_method_definition (parser);
1769 break;
1771 /* Else fall through, and yield a syntax error trying to parse
1772 as a declaration or function definition. */
1773 /* FALLTHRU */
1774 default:
1775 decl_or_fndef:
1776 /* A declaration or a function definition (or, in Objective-C,
1777 an @interface or @protocol with prefix attributes). We can
1778 only tell which after parsing the declaration specifiers, if
1779 any, and the first declarator. */
1780 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1781 break;
1785 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1786 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1788 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1790 static void
1791 add_debug_begin_stmt (location_t loc)
1793 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1794 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1795 return;
1797 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1798 SET_EXPR_LOCATION (stmt, loc);
1799 add_stmt (stmt);
1802 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1803 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1804 is accepted; otherwise (old-style parameter declarations) only other
1805 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1806 assertion is accepted; otherwise (old-style parameter declarations)
1807 it is not. If NESTED is true, we are inside a function or parsing
1808 old-style parameter declarations; any functions encountered are
1809 nested functions and declaration specifiers are required; otherwise
1810 we are at top level and functions are normal functions and
1811 declaration specifiers may be optional. If EMPTY_OK is true, empty
1812 declarations are OK (subject to all other constraints); otherwise
1813 (old-style parameter declarations) they are diagnosed. If
1814 START_ATTR_OK is true, the declaration specifiers may start with
1815 attributes (GNU or standard); otherwise they may not.
1816 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1817 declaration when parsing an Objective-C foreach statement.
1818 FALLTHRU_ATTR_P is used to signal whether this function parsed
1819 "__attribute__((fallthrough));". ATTRS are any standard attributes
1820 parsed in the caller (in contexts where such attributes had to be
1821 parsed to determine whether what follows is a declaration or a
1822 statement); HAVE_ATTRS says whether there were any such attributes
1823 (even empty).
1825 declaration:
1826 declaration-specifiers init-declarator-list[opt] ;
1827 static_assert-declaration
1829 function-definition:
1830 declaration-specifiers[opt] declarator declaration-list[opt]
1831 compound-statement
1833 declaration-list:
1834 declaration
1835 declaration-list declaration
1837 init-declarator-list:
1838 init-declarator
1839 init-declarator-list , init-declarator
1841 init-declarator:
1842 declarator simple-asm-expr[opt] gnu-attributes[opt]
1843 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1845 GNU extensions:
1847 nested-function-definition:
1848 declaration-specifiers declarator declaration-list[opt]
1849 compound-statement
1851 attribute ;
1853 Objective-C:
1854 gnu-attributes objc-class-definition
1855 gnu-attributes objc-category-definition
1856 gnu-attributes objc-protocol-definition
1858 The simple-asm-expr and gnu-attributes are GNU extensions.
1860 This function does not handle __extension__; that is handled in its
1861 callers. ??? Following the old parser, __extension__ may start
1862 external declarations, declarations in functions and declarations
1863 at the start of "for" loops, but not old-style parameter
1864 declarations.
1866 C99 requires declaration specifiers in a function definition; the
1867 absence is diagnosed through the diagnosis of implicit int. In GNU
1868 C we also allow but diagnose declarations without declaration
1869 specifiers, but only at top level (elsewhere they conflict with
1870 other syntax).
1872 In Objective-C, declarations of the looping variable in a foreach
1873 statement are exceptionally terminated by 'in' (for example, 'for
1874 (NSObject *object in array) { ... }').
1876 OpenMP:
1878 declaration:
1879 threadprivate-directive
1881 GIMPLE:
1883 gimple-function-definition:
1884 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1885 declaration-list[opt] compound-statement
1887 rtl-function-definition:
1888 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1889 declaration-list[opt] compound-statement */
1891 static void
1892 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1893 bool static_assert_ok, bool empty_ok,
1894 bool nested, bool start_attr_ok,
1895 tree *objc_foreach_object_declaration
1896 /* = NULL */,
1897 vec<c_token> *omp_declare_simd_clauses
1898 /* = NULL */,
1899 bool have_attrs /* = false */,
1900 tree attrs /* = NULL_TREE */,
1901 struct oacc_routine_data *oacc_routine_data
1902 /* = NULL */,
1903 bool *fallthru_attr_p /* = NULL */)
1905 struct c_declspecs *specs;
1906 tree prefix_attrs;
1907 tree all_prefix_attrs;
1908 bool diagnosed_no_specs = false;
1909 location_t here = c_parser_peek_token (parser)->location;
1911 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1913 if (static_assert_ok
1914 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1916 c_parser_static_assert_declaration (parser);
1917 return;
1919 specs = build_null_declspecs ();
1921 /* Handle any standard attributes parsed in the caller. */
1922 if (have_attrs)
1924 declspecs_add_attrs (here, specs, attrs);
1925 specs->non_std_attrs_seen_p = false;
1928 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1929 if (c_parser_peek_token (parser)->type == CPP_NAME
1930 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1931 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1932 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1933 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1935 tree name = c_parser_peek_token (parser)->value;
1937 /* Issue a warning about NAME being an unknown type name, perhaps
1938 with some kind of hint.
1939 If the user forgot a "struct" etc, suggest inserting
1940 it. Otherwise, attempt to look for misspellings. */
1941 gcc_rich_location richloc (here);
1942 if (tag_exists_p (RECORD_TYPE, name))
1944 /* This is not C++ with its implicit typedef. */
1945 richloc.add_fixit_insert_before ("struct ");
1946 error_at (&richloc,
1947 "unknown type name %qE;"
1948 " use %<struct%> keyword to refer to the type",
1949 name);
1951 else if (tag_exists_p (UNION_TYPE, name))
1953 richloc.add_fixit_insert_before ("union ");
1954 error_at (&richloc,
1955 "unknown type name %qE;"
1956 " use %<union%> keyword to refer to the type",
1957 name);
1959 else if (tag_exists_p (ENUMERAL_TYPE, name))
1961 richloc.add_fixit_insert_before ("enum ");
1962 error_at (&richloc,
1963 "unknown type name %qE;"
1964 " use %<enum%> keyword to refer to the type",
1965 name);
1967 else
1969 auto_diagnostic_group d;
1970 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1971 here);
1972 if (const char *suggestion = hint.suggestion ())
1974 richloc.add_fixit_replace (suggestion);
1975 error_at (&richloc,
1976 "unknown type name %qE; did you mean %qs?",
1977 name, suggestion);
1979 else
1980 error_at (here, "unknown type name %qE", name);
1983 /* Parse declspecs normally to get a correct pointer type, but avoid
1984 a further "fails to be a type name" error. Refuse nested functions
1985 since it is not how the user likely wants us to recover. */
1986 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1987 c_parser_peek_token (parser)->keyword = RID_VOID;
1988 c_parser_peek_token (parser)->value = error_mark_node;
1989 fndef_ok = !nested;
1992 /* When there are standard attributes at the start of the
1993 declaration (to apply to the entity being declared), an
1994 init-declarator-list or function definition must be present. */
1995 if (c_parser_nth_token_starts_std_attributes (parser, 1))
1996 have_attrs = true;
1998 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1999 true, true, start_attr_ok, true, cla_nonabstract_decl);
2000 if (parser->error)
2002 c_parser_skip_to_end_of_block_or_statement (parser);
2003 return;
2005 if (nested && !specs->declspecs_seen_p)
2007 c_parser_error (parser, "expected declaration specifiers");
2008 c_parser_skip_to_end_of_block_or_statement (parser);
2009 return;
2012 finish_declspecs (specs);
2013 bool auto_type_p = specs->typespec_word == cts_auto_type;
2014 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2016 if (auto_type_p)
2017 error_at (here, "%<__auto_type%> in empty declaration");
2018 else if (specs->typespec_kind == ctsk_none
2019 && attribute_fallthrough_p (specs->attrs))
2021 if (fallthru_attr_p != NULL)
2022 *fallthru_attr_p = true;
2023 if (nested)
2025 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2026 void_type_node, 0);
2027 add_stmt (fn);
2029 else
2030 pedwarn (here, OPT_Wattributes,
2031 "%<fallthrough%> attribute at top level");
2033 else if (empty_ok && !(have_attrs
2034 && specs->non_std_attrs_seen_p))
2035 shadow_tag (specs);
2036 else
2038 shadow_tag_warned (specs, 1);
2039 pedwarn (here, 0, "empty declaration");
2041 c_parser_consume_token (parser);
2042 if (oacc_routine_data)
2043 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2044 return;
2047 /* Provide better error recovery. Note that a type name here is usually
2048 better diagnosed as a redeclaration. */
2049 if (empty_ok
2050 && specs->typespec_kind == ctsk_tagdef
2051 && c_parser_next_token_starts_declspecs (parser)
2052 && !c_parser_next_token_is (parser, CPP_NAME))
2054 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2055 parser->error = false;
2056 shadow_tag_warned (specs, 1);
2057 return;
2059 else if (c_dialect_objc () && !auto_type_p)
2061 /* Prefix attributes are an error on method decls. */
2062 switch (c_parser_peek_token (parser)->type)
2064 case CPP_PLUS:
2065 case CPP_MINUS:
2066 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2067 return;
2068 if (specs->attrs)
2070 warning_at (c_parser_peek_token (parser)->location,
2071 OPT_Wattributes,
2072 "prefix attributes are ignored for methods");
2073 specs->attrs = NULL_TREE;
2075 if (fndef_ok)
2076 c_parser_objc_method_definition (parser);
2077 else
2078 c_parser_objc_methodproto (parser);
2079 return;
2080 break;
2081 default:
2082 break;
2084 /* This is where we parse 'attributes @interface ...',
2085 'attributes @implementation ...', 'attributes @protocol ...'
2086 (where attributes could be, for example, __attribute__
2087 ((deprecated)).
2089 switch (c_parser_peek_token (parser)->keyword)
2091 case RID_AT_INTERFACE:
2093 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2094 return;
2095 c_parser_objc_class_definition (parser, specs->attrs);
2096 return;
2098 break;
2099 case RID_AT_IMPLEMENTATION:
2101 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2102 return;
2103 if (specs->attrs)
2105 warning_at (c_parser_peek_token (parser)->location,
2106 OPT_Wattributes,
2107 "prefix attributes are ignored for implementations");
2108 specs->attrs = NULL_TREE;
2110 c_parser_objc_class_definition (parser, NULL_TREE);
2111 return;
2113 break;
2114 case RID_AT_PROTOCOL:
2116 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2117 return;
2118 c_parser_objc_protocol_definition (parser, specs->attrs);
2119 return;
2121 break;
2122 case RID_AT_ALIAS:
2123 case RID_AT_CLASS:
2124 case RID_AT_END:
2125 case RID_AT_PROPERTY:
2126 if (specs->attrs)
2128 c_parser_error (parser, "unexpected attribute");
2129 specs->attrs = NULL;
2131 break;
2132 default:
2133 break;
2136 else if (attribute_fallthrough_p (specs->attrs))
2137 warning_at (here, OPT_Wattributes,
2138 "%<fallthrough%> attribute not followed by %<;%>");
2140 pending_xref_error ();
2141 prefix_attrs = specs->attrs;
2142 all_prefix_attrs = prefix_attrs;
2143 specs->attrs = NULL_TREE;
2144 while (true)
2146 struct c_declarator *declarator;
2147 bool dummy = false;
2148 timevar_id_t tv;
2149 tree fnbody = NULL_TREE;
2150 /* Declaring either one or more declarators (in which case we
2151 should diagnose if there were no declaration specifiers) or a
2152 function definition (in which case the diagnostic for
2153 implicit int suffices). */
2154 declarator = c_parser_declarator (parser,
2155 specs->typespec_kind != ctsk_none,
2156 C_DTR_NORMAL, &dummy);
2157 if (declarator == NULL)
2159 if (omp_declare_simd_clauses)
2160 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2161 omp_declare_simd_clauses);
2162 if (oacc_routine_data)
2163 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2164 c_parser_skip_to_end_of_block_or_statement (parser);
2165 return;
2167 if (auto_type_p && declarator->kind != cdk_id)
2169 error_at (here,
2170 "%<__auto_type%> requires a plain identifier"
2171 " as declarator");
2172 c_parser_skip_to_end_of_block_or_statement (parser);
2173 return;
2175 if (c_parser_next_token_is (parser, CPP_EQ)
2176 || c_parser_next_token_is (parser, CPP_COMMA)
2177 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2178 || c_parser_next_token_is_keyword (parser, RID_ASM)
2179 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2180 || c_parser_next_token_is_keyword (parser, RID_IN))
2182 tree asm_name = NULL_TREE;
2183 tree postfix_attrs = NULL_TREE;
2184 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2186 diagnosed_no_specs = true;
2187 pedwarn (here, 0, "data definition has no type or storage class");
2189 /* Having seen a data definition, there cannot now be a
2190 function definition. */
2191 fndef_ok = false;
2192 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2193 asm_name = c_parser_simple_asm_expr (parser);
2194 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2196 postfix_attrs = c_parser_gnu_attributes (parser);
2197 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2199 /* This means there is an attribute specifier after
2200 the declarator in a function definition. Provide
2201 some more information for the user. */
2202 error_at (here, "attributes should be specified before the "
2203 "declarator in a function definition");
2204 c_parser_skip_to_end_of_block_or_statement (parser);
2205 return;
2208 if (c_parser_next_token_is (parser, CPP_EQ))
2210 tree d;
2211 struct c_expr init;
2212 location_t init_loc;
2213 c_parser_consume_token (parser);
2214 if (auto_type_p)
2216 init_loc = c_parser_peek_token (parser)->location;
2217 rich_location richloc (line_table, init_loc);
2218 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2219 /* A parameter is initialized, which is invalid. Don't
2220 attempt to instrument the initializer. */
2221 int flag_sanitize_save = flag_sanitize;
2222 if (nested && !empty_ok)
2223 flag_sanitize = 0;
2224 init = c_parser_expr_no_commas (parser, NULL);
2225 flag_sanitize = flag_sanitize_save;
2226 if (TREE_CODE (init.value) == COMPONENT_REF
2227 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2228 error_at (here,
2229 "%<__auto_type%> used with a bit-field"
2230 " initializer");
2231 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2232 tree init_type = TREE_TYPE (init.value);
2233 bool vm_type = variably_modified_type_p (init_type,
2234 NULL_TREE);
2235 if (vm_type)
2236 init.value = save_expr (init.value);
2237 finish_init ();
2238 specs->typespec_kind = ctsk_typeof;
2239 specs->locations[cdw_typedef] = init_loc;
2240 specs->typedef_p = true;
2241 specs->type = init_type;
2242 if (vm_type)
2244 bool maybe_const = true;
2245 tree type_expr = c_fully_fold (init.value, false,
2246 &maybe_const);
2247 specs->expr_const_operands &= maybe_const;
2248 if (specs->expr)
2249 specs->expr = build2 (COMPOUND_EXPR,
2250 TREE_TYPE (type_expr),
2251 specs->expr, type_expr);
2252 else
2253 specs->expr = type_expr;
2255 d = start_decl (declarator, specs, true,
2256 chainon (postfix_attrs, all_prefix_attrs));
2257 if (!d)
2258 d = error_mark_node;
2259 if (omp_declare_simd_clauses)
2260 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2261 omp_declare_simd_clauses);
2263 else
2265 /* The declaration of the variable is in effect while
2266 its initializer is parsed. */
2267 d = start_decl (declarator, specs, true,
2268 chainon (postfix_attrs, all_prefix_attrs));
2269 if (!d)
2270 d = error_mark_node;
2271 if (omp_declare_simd_clauses)
2272 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2273 omp_declare_simd_clauses);
2274 init_loc = c_parser_peek_token (parser)->location;
2275 rich_location richloc (line_table, init_loc);
2276 start_init (d, asm_name, global_bindings_p (), &richloc);
2277 /* A parameter is initialized, which is invalid. Don't
2278 attempt to instrument the initializer. */
2279 int flag_sanitize_save = flag_sanitize;
2280 if (TREE_CODE (d) == PARM_DECL)
2281 flag_sanitize = 0;
2282 init = c_parser_initializer (parser);
2283 flag_sanitize = flag_sanitize_save;
2284 finish_init ();
2286 if (oacc_routine_data)
2287 c_finish_oacc_routine (oacc_routine_data, d, false);
2288 if (d != error_mark_node)
2290 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2291 finish_decl (d, init_loc, init.value,
2292 init.original_type, asm_name);
2295 else
2297 if (auto_type_p)
2299 error_at (here,
2300 "%<__auto_type%> requires an initialized "
2301 "data declaration");
2302 c_parser_skip_to_end_of_block_or_statement (parser);
2303 return;
2306 location_t lastloc = UNKNOWN_LOCATION;
2307 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2308 tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2309 if (d && TREE_CODE (d) == FUNCTION_DECL)
2311 /* Find the innermost declarator that is neither cdk_id
2312 nor cdk_attrs. */
2313 const struct c_declarator *decl = declarator;
2314 const struct c_declarator *last_non_id_attrs = NULL;
2316 while (decl)
2317 switch (decl->kind)
2319 case cdk_array:
2320 case cdk_function:
2321 case cdk_pointer:
2322 last_non_id_attrs = decl;
2323 decl = decl->declarator;
2324 break;
2326 case cdk_attrs:
2327 decl = decl->declarator;
2328 break;
2330 case cdk_id:
2331 decl = 0;
2332 break;
2334 default:
2335 gcc_unreachable ();
2338 /* If it exists and is cdk_function declaration whose
2339 arguments have not been set yet, use its arguments. */
2340 if (last_non_id_attrs
2341 && last_non_id_attrs->kind == cdk_function)
2343 tree parms = last_non_id_attrs->u.arg_info->parms;
2344 if (DECL_ARGUMENTS (d) == NULL_TREE
2345 && DECL_INITIAL (d) == NULL_TREE)
2346 DECL_ARGUMENTS (d) = parms;
2348 warn_parm_array_mismatch (lastloc, d, parms);
2351 if (omp_declare_simd_clauses)
2353 tree parms = NULL_TREE;
2354 if (d && TREE_CODE (d) == FUNCTION_DECL)
2356 struct c_declarator *ce = declarator;
2357 while (ce != NULL)
2358 if (ce->kind == cdk_function)
2360 parms = ce->u.arg_info->parms;
2361 break;
2363 else
2364 ce = ce->declarator;
2366 if (parms)
2367 temp_store_parm_decls (d, parms);
2368 c_finish_omp_declare_simd (parser, d, parms,
2369 omp_declare_simd_clauses);
2370 if (parms)
2371 temp_pop_parm_decls ();
2373 if (oacc_routine_data)
2374 c_finish_oacc_routine (oacc_routine_data, d, false);
2375 if (d)
2376 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2377 NULL_TREE, asm_name);
2379 if (c_parser_next_token_is_keyword (parser, RID_IN))
2381 if (d)
2382 *objc_foreach_object_declaration = d;
2383 else
2384 *objc_foreach_object_declaration = error_mark_node;
2387 if (c_parser_next_token_is (parser, CPP_COMMA))
2389 if (auto_type_p)
2391 error_at (here,
2392 "%<__auto_type%> may only be used with"
2393 " a single declarator");
2394 c_parser_skip_to_end_of_block_or_statement (parser);
2395 return;
2397 c_parser_consume_token (parser);
2398 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2399 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2400 prefix_attrs);
2401 else
2402 all_prefix_attrs = prefix_attrs;
2403 continue;
2405 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2407 c_parser_consume_token (parser);
2408 return;
2410 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2412 /* This can only happen in Objective-C: we found the
2413 'in' that terminates the declaration inside an
2414 Objective-C foreach statement. Do not consume the
2415 token, so that the caller can use it to determine
2416 that this indeed is a foreach context. */
2417 return;
2419 else
2421 c_parser_error (parser, "expected %<,%> or %<;%>");
2422 c_parser_skip_to_end_of_block_or_statement (parser);
2423 return;
2426 else if (auto_type_p)
2428 error_at (here,
2429 "%<__auto_type%> requires an initialized data declaration");
2430 c_parser_skip_to_end_of_block_or_statement (parser);
2431 return;
2433 else if (!fndef_ok)
2435 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2436 "%<asm%> or %<__attribute__%>");
2437 c_parser_skip_to_end_of_block_or_statement (parser);
2438 return;
2440 /* Function definition (nested or otherwise). */
2441 if (nested)
2443 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2444 c_push_function_context ();
2446 if (!start_function (specs, declarator, all_prefix_attrs))
2448 /* At this point we've consumed:
2449 declaration-specifiers declarator
2450 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2451 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2452 but the
2453 declaration-specifiers declarator
2454 aren't grokkable as a function definition, so we have
2455 an error. */
2456 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2457 if (c_parser_next_token_starts_declspecs (parser))
2459 /* If we have
2460 declaration-specifiers declarator decl-specs
2461 then assume we have a missing semicolon, which would
2462 give us:
2463 declaration-specifiers declarator decl-specs
2466 <~~~~~~~~~ declaration ~~~~~~~~~~>
2467 Use c_parser_require to get an error with a fix-it hint. */
2468 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2469 parser->error = false;
2471 else
2473 /* This can appear in many cases looking nothing like a
2474 function definition, so we don't give a more specific
2475 error suggesting there was one. */
2476 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2477 "or %<__attribute__%>");
2479 if (nested)
2480 c_pop_function_context ();
2481 break;
2484 if (DECL_DECLARED_INLINE_P (current_function_decl))
2485 tv = TV_PARSE_INLINE;
2486 else
2487 tv = TV_PARSE_FUNC;
2488 auto_timevar at (g_timer, tv);
2490 /* Parse old-style parameter declarations. ??? Attributes are
2491 not allowed to start declaration specifiers here because of a
2492 syntax conflict between a function declaration with attribute
2493 suffix and a function definition with an attribute prefix on
2494 first old-style parameter declaration. Following the old
2495 parser, they are not accepted on subsequent old-style
2496 parameter declarations either. However, there is no
2497 ambiguity after the first declaration, nor indeed on the
2498 first as long as we don't allow postfix attributes after a
2499 declarator with a nonempty identifier list in a definition;
2500 and postfix attributes have never been accepted here in
2501 function definitions either. */
2502 while (c_parser_next_token_is_not (parser, CPP_EOF)
2503 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2504 c_parser_declaration_or_fndef (parser, false, false, false,
2505 true, false);
2506 store_parm_decls ();
2507 if (omp_declare_simd_clauses)
2508 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2509 omp_declare_simd_clauses);
2510 if (oacc_routine_data)
2511 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2512 location_t startloc = c_parser_peek_token (parser)->location;
2513 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2514 = startloc;
2515 location_t endloc = startloc;
2517 /* If the definition was marked with __RTL, use the RTL parser now,
2518 consuming the function body. */
2519 if (specs->declspec_il == cdil_rtl)
2521 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2523 /* Normally, store_parm_decls sets next_is_function_body,
2524 anticipating a function body. We need a push_scope/pop_scope
2525 pair to flush out this state, or subsequent function parsing
2526 will go wrong. */
2527 push_scope ();
2528 pop_scope ();
2530 finish_function (endloc);
2531 return;
2533 /* If the definition was marked with __GIMPLE then parse the
2534 function body as GIMPLE. */
2535 else if (specs->declspec_il != cdil_none)
2537 bool saved = in_late_binary_op;
2538 in_late_binary_op = true;
2539 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2540 specs->declspec_il,
2541 specs->entry_bb_count);
2542 in_late_binary_op = saved;
2544 else
2545 fnbody = c_parser_compound_statement (parser, &endloc);
2546 tree fndecl = current_function_decl;
2547 if (nested)
2549 tree decl = current_function_decl;
2550 /* Mark nested functions as needing static-chain initially.
2551 lower_nested_functions will recompute it but the
2552 DECL_STATIC_CHAIN flag is also used before that happens,
2553 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2554 DECL_STATIC_CHAIN (decl) = 1;
2555 add_stmt (fnbody);
2556 finish_function (endloc);
2557 c_pop_function_context ();
2558 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2560 else
2562 if (fnbody)
2563 add_stmt (fnbody);
2564 finish_function (endloc);
2566 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2567 if (specs->declspec_il != cdil_none)
2568 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2570 break;
2574 /* Parse an asm-definition (asm() outside a function body). This is a
2575 GNU extension.
2577 asm-definition:
2578 simple-asm-expr ;
2581 static void
2582 c_parser_asm_definition (c_parser *parser)
2584 tree asm_str = c_parser_simple_asm_expr (parser);
2585 if (asm_str)
2586 symtab->finalize_toplevel_asm (asm_str);
2587 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2590 /* Parse a static assertion (C11 6.7.10).
2592 static_assert-declaration:
2593 static_assert-declaration-no-semi ;
2596 static void
2597 c_parser_static_assert_declaration (c_parser *parser)
2599 c_parser_static_assert_declaration_no_semi (parser);
2600 if (parser->error
2601 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2602 c_parser_skip_to_end_of_block_or_statement (parser);
2605 /* Parse a static assertion (C11 6.7.10), without the trailing
2606 semicolon.
2608 static_assert-declaration-no-semi:
2609 _Static_assert ( constant-expression , string-literal )
2611 C2X:
2612 static_assert-declaration-no-semi:
2613 _Static_assert ( constant-expression )
2616 static void
2617 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2619 location_t assert_loc, value_loc;
2620 tree value;
2621 tree string = NULL_TREE;
2623 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2624 assert_loc = c_parser_peek_token (parser)->location;
2625 if (flag_isoc99)
2626 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2627 "ISO C99 does not support %<_Static_assert%>");
2628 else
2629 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2630 "ISO C90 does not support %<_Static_assert%>");
2631 c_parser_consume_token (parser);
2632 matching_parens parens;
2633 if (!parens.require_open (parser))
2634 return;
2635 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2636 value = c_parser_expr_no_commas (parser, NULL).value;
2637 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2638 if (c_parser_next_token_is (parser, CPP_COMMA))
2640 c_parser_consume_token (parser);
2641 switch (c_parser_peek_token (parser)->type)
2643 case CPP_STRING:
2644 case CPP_STRING16:
2645 case CPP_STRING32:
2646 case CPP_WSTRING:
2647 case CPP_UTF8STRING:
2648 string = c_parser_string_literal (parser, false, true).value;
2649 break;
2650 default:
2651 c_parser_error (parser, "expected string literal");
2652 return;
2655 else if (flag_isoc11)
2656 /* If pedantic for pre-C11, the use of _Static_assert itself will
2657 have been diagnosed, so do not also diagnose the use of this
2658 new C2X feature of _Static_assert. */
2659 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2660 "ISO C11 does not support omitting the string in "
2661 "%<_Static_assert%>");
2662 parens.require_close (parser);
2664 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2666 error_at (value_loc, "expression in static assertion is not an integer");
2667 return;
2669 if (TREE_CODE (value) != INTEGER_CST)
2671 value = c_fully_fold (value, false, NULL);
2672 /* Strip no-op conversions. */
2673 STRIP_TYPE_NOPS (value);
2674 if (TREE_CODE (value) == INTEGER_CST)
2675 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2676 "is not an integer constant expression");
2678 if (TREE_CODE (value) != INTEGER_CST)
2680 error_at (value_loc, "expression in static assertion is not constant");
2681 return;
2683 constant_expression_warning (value);
2684 if (integer_zerop (value))
2686 if (string)
2687 error_at (assert_loc, "static assertion failed: %E", string);
2688 else
2689 error_at (assert_loc, "static assertion failed");
2693 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2694 6.7, C11 6.7), adding them to SPECS (which may already include some).
2695 Storage class specifiers are accepted iff SCSPEC_OK; type
2696 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2697 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2698 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2699 addition to the syntax shown, standard attributes are accepted at
2700 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2701 unlike gnu-attributes, they are not accepted in the middle of the
2702 list. (This combines various different syntax productions in the C
2703 standard, and in some cases gnu-attributes and standard attributes
2704 at the start may already have been parsed before this function is
2705 called.)
2707 declaration-specifiers:
2708 storage-class-specifier declaration-specifiers[opt]
2709 type-specifier declaration-specifiers[opt]
2710 type-qualifier declaration-specifiers[opt]
2711 function-specifier declaration-specifiers[opt]
2712 alignment-specifier declaration-specifiers[opt]
2714 Function specifiers (inline) are from C99, and are currently
2715 handled as storage class specifiers, as is __thread. Alignment
2716 specifiers are from C11.
2718 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2719 storage-class-specifier:
2720 typedef
2721 extern
2722 static
2723 auto
2724 register
2725 _Thread_local
2727 (_Thread_local is new in C11.)
2729 C99 6.7.4, C11 6.7.4:
2730 function-specifier:
2731 inline
2732 _Noreturn
2734 (_Noreturn is new in C11.)
2736 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2737 type-specifier:
2738 void
2739 char
2740 short
2742 long
2743 float
2744 double
2745 signed
2746 unsigned
2747 _Bool
2748 _Complex
2749 [_Imaginary removed in C99 TC2]
2750 struct-or-union-specifier
2751 enum-specifier
2752 typedef-name
2753 atomic-type-specifier
2755 (_Bool and _Complex are new in C99.)
2756 (atomic-type-specifier is new in C11.)
2758 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2760 type-qualifier:
2761 const
2762 restrict
2763 volatile
2764 address-space-qualifier
2765 _Atomic
2767 (restrict is new in C99.)
2768 (_Atomic is new in C11.)
2770 GNU extensions:
2772 declaration-specifiers:
2773 gnu-attributes declaration-specifiers[opt]
2775 type-qualifier:
2776 address-space
2778 address-space:
2779 identifier recognized by the target
2781 storage-class-specifier:
2782 __thread
2784 type-specifier:
2785 typeof-specifier
2786 __auto_type
2787 __intN
2788 _Decimal32
2789 _Decimal64
2790 _Decimal128
2791 _Fract
2792 _Accum
2793 _Sat
2795 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2796 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2798 atomic-type-specifier
2799 _Atomic ( type-name )
2801 Objective-C:
2803 type-specifier:
2804 class-name objc-protocol-refs[opt]
2805 typedef-name objc-protocol-refs
2806 objc-protocol-refs
2809 void
2810 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2811 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2812 bool alignspec_ok, bool auto_type_ok,
2813 bool start_std_attr_ok, bool end_std_attr_ok,
2814 enum c_lookahead_kind la)
2816 bool attrs_ok = start_attr_ok;
2817 bool seen_type = specs->typespec_kind != ctsk_none;
2819 if (!typespec_ok)
2820 gcc_assert (la == cla_prefer_id);
2822 if (start_std_attr_ok
2823 && c_parser_nth_token_starts_std_attributes (parser, 1))
2825 gcc_assert (!specs->non_std_attrs_seen_p);
2826 location_t loc = c_parser_peek_token (parser)->location;
2827 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2828 declspecs_add_attrs (loc, specs, attrs);
2829 specs->non_std_attrs_seen_p = false;
2832 while (c_parser_next_token_is (parser, CPP_NAME)
2833 || c_parser_next_token_is (parser, CPP_KEYWORD)
2834 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2836 struct c_typespec t;
2837 tree attrs;
2838 tree align;
2839 location_t loc = c_parser_peek_token (parser)->location;
2841 /* If we cannot accept a type, exit if the next token must start
2842 one. Also, if we already have seen a tagged definition,
2843 a typename would be an error anyway and likely the user
2844 has simply forgotten a semicolon, so we exit. */
2845 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2846 && c_parser_next_tokens_start_typename (parser, la)
2847 && !c_parser_next_token_is_qualifier (parser)
2848 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2849 break;
2851 if (c_parser_next_token_is (parser, CPP_NAME))
2853 c_token *name_token = c_parser_peek_token (parser);
2854 tree value = name_token->value;
2855 c_id_kind kind = name_token->id_kind;
2857 if (kind == C_ID_ADDRSPACE)
2859 addr_space_t as
2860 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2861 declspecs_add_addrspace (name_token->location, specs, as);
2862 c_parser_consume_token (parser);
2863 attrs_ok = true;
2864 continue;
2867 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2869 /* If we cannot accept a type, and the next token must start one,
2870 exit. Do the same if we already have seen a tagged definition,
2871 since it would be an error anyway and likely the user has simply
2872 forgotten a semicolon. */
2873 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2874 break;
2876 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2877 a C_ID_CLASSNAME. */
2878 c_parser_consume_token (parser);
2879 seen_type = true;
2880 attrs_ok = true;
2881 if (kind == C_ID_ID)
2883 error_at (loc, "unknown type name %qE", value);
2884 t.kind = ctsk_typedef;
2885 t.spec = error_mark_node;
2887 else if (kind == C_ID_TYPENAME
2888 && (!c_dialect_objc ()
2889 || c_parser_next_token_is_not (parser, CPP_LESS)))
2891 t.kind = ctsk_typedef;
2892 /* For a typedef name, record the meaning, not the name.
2893 In case of 'foo foo, bar;'. */
2894 t.spec = lookup_name (value);
2896 else
2898 tree proto = NULL_TREE;
2899 gcc_assert (c_dialect_objc ());
2900 t.kind = ctsk_objc;
2901 if (c_parser_next_token_is (parser, CPP_LESS))
2902 proto = c_parser_objc_protocol_refs (parser);
2903 t.spec = objc_get_protocol_qualified_type (value, proto);
2905 t.expr = NULL_TREE;
2906 t.expr_const_operands = true;
2907 declspecs_add_type (name_token->location, specs, t);
2908 continue;
2910 if (c_parser_next_token_is (parser, CPP_LESS))
2912 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2913 nisse@lysator.liu.se. */
2914 tree proto;
2915 gcc_assert (c_dialect_objc ());
2916 if (!typespec_ok || seen_type)
2917 break;
2918 proto = c_parser_objc_protocol_refs (parser);
2919 t.kind = ctsk_objc;
2920 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2921 t.expr = NULL_TREE;
2922 t.expr_const_operands = true;
2923 declspecs_add_type (loc, specs, t);
2924 continue;
2926 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2927 switch (c_parser_peek_token (parser)->keyword)
2929 case RID_STATIC:
2930 case RID_EXTERN:
2931 case RID_REGISTER:
2932 case RID_TYPEDEF:
2933 case RID_INLINE:
2934 case RID_NORETURN:
2935 case RID_AUTO:
2936 case RID_THREAD:
2937 if (!scspec_ok)
2938 goto out;
2939 attrs_ok = true;
2940 /* TODO: Distinguish between function specifiers (inline, noreturn)
2941 and storage class specifiers, either here or in
2942 declspecs_add_scspec. */
2943 declspecs_add_scspec (loc, specs,
2944 c_parser_peek_token (parser)->value);
2945 c_parser_consume_token (parser);
2946 break;
2947 case RID_AUTO_TYPE:
2948 if (!auto_type_ok)
2949 goto out;
2950 /* Fall through. */
2951 case RID_UNSIGNED:
2952 case RID_LONG:
2953 case RID_SHORT:
2954 case RID_SIGNED:
2955 case RID_COMPLEX:
2956 case RID_INT:
2957 case RID_CHAR:
2958 case RID_FLOAT:
2959 case RID_DOUBLE:
2960 case RID_VOID:
2961 case RID_DFLOAT32:
2962 case RID_DFLOAT64:
2963 case RID_DFLOAT128:
2964 CASE_RID_FLOATN_NX:
2965 case RID_BOOL:
2966 case RID_FRACT:
2967 case RID_ACCUM:
2968 case RID_SAT:
2969 case RID_INT_N_0:
2970 case RID_INT_N_1:
2971 case RID_INT_N_2:
2972 case RID_INT_N_3:
2973 if (!typespec_ok)
2974 goto out;
2975 attrs_ok = true;
2976 seen_type = true;
2977 if (c_dialect_objc ())
2978 parser->objc_need_raw_identifier = true;
2979 t.kind = ctsk_resword;
2980 t.spec = c_parser_peek_token (parser)->value;
2981 t.expr = NULL_TREE;
2982 t.expr_const_operands = true;
2983 declspecs_add_type (loc, specs, t);
2984 c_parser_consume_token (parser);
2985 break;
2986 case RID_ENUM:
2987 if (!typespec_ok)
2988 goto out;
2989 attrs_ok = true;
2990 seen_type = true;
2991 t = c_parser_enum_specifier (parser);
2992 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2993 declspecs_add_type (loc, specs, t);
2994 break;
2995 case RID_STRUCT:
2996 case RID_UNION:
2997 if (!typespec_ok)
2998 goto out;
2999 attrs_ok = true;
3000 seen_type = true;
3001 t = c_parser_struct_or_union_specifier (parser);
3002 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3003 declspecs_add_type (loc, specs, t);
3004 break;
3005 case RID_TYPEOF:
3006 /* ??? The old parser rejected typeof after other type
3007 specifiers, but is a syntax error the best way of
3008 handling this? */
3009 if (!typespec_ok || seen_type)
3010 goto out;
3011 attrs_ok = true;
3012 seen_type = true;
3013 t = c_parser_typeof_specifier (parser);
3014 declspecs_add_type (loc, specs, t);
3015 break;
3016 case RID_ATOMIC:
3017 /* C parser handling of Objective-C constructs needs
3018 checking for correct lvalue-to-rvalue conversions, and
3019 the code in build_modify_expr handling various
3020 Objective-C cases, and that in build_unary_op handling
3021 Objective-C cases for increment / decrement, also needs
3022 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3023 and objc_types_are_equivalent may also need updates. */
3024 if (c_dialect_objc ())
3025 sorry ("%<_Atomic%> in Objective-C");
3026 if (flag_isoc99)
3027 pedwarn_c99 (loc, OPT_Wpedantic,
3028 "ISO C99 does not support the %<_Atomic%> qualifier");
3029 else
3030 pedwarn_c99 (loc, OPT_Wpedantic,
3031 "ISO C90 does not support the %<_Atomic%> qualifier");
3032 attrs_ok = true;
3033 tree value;
3034 value = c_parser_peek_token (parser)->value;
3035 c_parser_consume_token (parser);
3036 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3038 /* _Atomic ( type-name ). */
3039 seen_type = true;
3040 c_parser_consume_token (parser);
3041 struct c_type_name *type = c_parser_type_name (parser);
3042 t.kind = ctsk_typeof;
3043 t.spec = error_mark_node;
3044 t.expr = NULL_TREE;
3045 t.expr_const_operands = true;
3046 if (type != NULL)
3047 t.spec = groktypename (type, &t.expr,
3048 &t.expr_const_operands);
3049 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3050 "expected %<)%>");
3051 if (t.spec != error_mark_node)
3053 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3054 error_at (loc, "%<_Atomic%>-qualified array type");
3055 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3056 error_at (loc, "%<_Atomic%>-qualified function type");
3057 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3058 error_at (loc, "%<_Atomic%> applied to a qualified type");
3059 else
3060 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3062 declspecs_add_type (loc, specs, t);
3064 else
3065 declspecs_add_qual (loc, specs, value);
3066 break;
3067 case RID_CONST:
3068 case RID_VOLATILE:
3069 case RID_RESTRICT:
3070 attrs_ok = true;
3071 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3072 c_parser_consume_token (parser);
3073 break;
3074 case RID_ATTRIBUTE:
3075 if (!attrs_ok)
3076 goto out;
3077 attrs = c_parser_gnu_attributes (parser);
3078 declspecs_add_attrs (loc, specs, attrs);
3079 break;
3080 case RID_ALIGNAS:
3081 if (!alignspec_ok)
3082 goto out;
3083 align = c_parser_alignas_specifier (parser);
3084 declspecs_add_alignas (loc, specs, align);
3085 break;
3086 case RID_GIMPLE:
3087 if (! flag_gimple)
3088 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3089 c_parser_consume_token (parser);
3090 specs->declspec_il = cdil_gimple;
3091 specs->locations[cdw_gimple] = loc;
3092 c_parser_gimple_or_rtl_pass_list (parser, specs);
3093 break;
3094 case RID_RTL:
3095 c_parser_consume_token (parser);
3096 specs->declspec_il = cdil_rtl;
3097 specs->locations[cdw_rtl] = loc;
3098 c_parser_gimple_or_rtl_pass_list (parser, specs);
3099 break;
3100 default:
3101 goto out;
3104 out:
3105 if (end_std_attr_ok
3106 && c_parser_nth_token_starts_std_attributes (parser, 1))
3107 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3110 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3112 enum-specifier:
3113 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3114 gnu-attributes[opt]
3115 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3116 gnu-attributes[opt]
3117 enum gnu-attributes[opt] identifier
3119 The form with trailing comma is new in C99. The forms with
3120 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3121 without commas in the syntax (assignment expressions, not just
3122 conditional expressions); assignment expressions will be diagnosed
3123 as non-constant.
3125 enumerator-list:
3126 enumerator
3127 enumerator-list , enumerator
3129 enumerator:
3130 enumeration-constant attribute-specifier-sequence[opt]
3131 enumeration-constant attribute-specifier-sequence[opt]
3132 = constant-expression
3134 GNU Extensions:
3136 enumerator:
3137 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3138 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3139 = constant-expression
3143 static struct c_typespec
3144 c_parser_enum_specifier (c_parser *parser)
3146 struct c_typespec ret;
3147 bool have_std_attrs;
3148 tree std_attrs = NULL_TREE;
3149 tree attrs;
3150 tree ident = NULL_TREE;
3151 location_t enum_loc;
3152 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3153 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3154 c_parser_consume_token (parser);
3155 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3156 if (have_std_attrs)
3157 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3158 attrs = c_parser_gnu_attributes (parser);
3159 enum_loc = c_parser_peek_token (parser)->location;
3160 /* Set the location in case we create a decl now. */
3161 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3162 if (c_parser_next_token_is (parser, CPP_NAME))
3164 ident = c_parser_peek_token (parser)->value;
3165 ident_loc = c_parser_peek_token (parser)->location;
3166 enum_loc = ident_loc;
3167 c_parser_consume_token (parser);
3169 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3171 /* Parse an enum definition. */
3172 struct c_enum_contents the_enum;
3173 tree type;
3174 tree postfix_attrs;
3175 /* We chain the enumerators in reverse order, then put them in
3176 forward order at the end. */
3177 tree values;
3178 timevar_push (TV_PARSE_ENUM);
3179 type = start_enum (enum_loc, &the_enum, ident);
3180 values = NULL_TREE;
3181 c_parser_consume_token (parser);
3182 while (true)
3184 tree enum_id;
3185 tree enum_value;
3186 tree enum_decl;
3187 bool seen_comma;
3188 c_token *token;
3189 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3190 location_t decl_loc, value_loc;
3191 if (c_parser_next_token_is_not (parser, CPP_NAME))
3193 /* Give a nicer error for "enum {}". */
3194 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3195 && !parser->error)
3197 error_at (c_parser_peek_token (parser)->location,
3198 "empty enum is invalid");
3199 parser->error = true;
3201 else
3202 c_parser_error (parser, "expected identifier");
3203 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3204 values = error_mark_node;
3205 break;
3207 token = c_parser_peek_token (parser);
3208 enum_id = token->value;
3209 /* Set the location in case we create a decl now. */
3210 c_parser_set_source_position_from_token (token);
3211 decl_loc = value_loc = token->location;
3212 c_parser_consume_token (parser);
3213 /* Parse any specified attributes. */
3214 tree std_attrs = NULL_TREE;
3215 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3216 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3217 tree enum_attrs = chainon (std_attrs,
3218 c_parser_gnu_attributes (parser));
3219 if (c_parser_next_token_is (parser, CPP_EQ))
3221 c_parser_consume_token (parser);
3222 value_loc = c_parser_peek_token (parser)->location;
3223 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3225 else
3226 enum_value = NULL_TREE;
3227 enum_decl = build_enumerator (decl_loc, value_loc,
3228 &the_enum, enum_id, enum_value);
3229 if (enum_attrs)
3230 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3231 TREE_CHAIN (enum_decl) = values;
3232 values = enum_decl;
3233 seen_comma = false;
3234 if (c_parser_next_token_is (parser, CPP_COMMA))
3236 comma_loc = c_parser_peek_token (parser)->location;
3237 seen_comma = true;
3238 c_parser_consume_token (parser);
3240 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3242 if (seen_comma)
3243 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3244 "comma at end of enumerator list");
3245 c_parser_consume_token (parser);
3246 break;
3248 if (!seen_comma)
3250 c_parser_error (parser, "expected %<,%> or %<}%>");
3251 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3252 values = error_mark_node;
3253 break;
3256 postfix_attrs = c_parser_gnu_attributes (parser);
3257 ret.spec = finish_enum (type, nreverse (values),
3258 chainon (std_attrs,
3259 chainon (attrs, postfix_attrs)));
3260 ret.kind = ctsk_tagdef;
3261 ret.expr = NULL_TREE;
3262 ret.expr_const_operands = true;
3263 timevar_pop (TV_PARSE_ENUM);
3264 return ret;
3266 else if (!ident)
3268 c_parser_error (parser, "expected %<{%>");
3269 ret.spec = error_mark_node;
3270 ret.kind = ctsk_tagref;
3271 ret.expr = NULL_TREE;
3272 ret.expr_const_operands = true;
3273 return ret;
3275 /* Attributes may only appear when the members are defined or in
3276 certain forward declarations (treat enum forward declarations in
3277 GNU C analogously to struct and union forward declarations in
3278 standard C). */
3279 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3280 c_parser_error (parser, "expected %<;%>");
3281 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3282 std_attrs);
3283 /* In ISO C, enumerated types can be referred to only if already
3284 defined. */
3285 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3287 gcc_assert (ident);
3288 pedwarn (enum_loc, OPT_Wpedantic,
3289 "ISO C forbids forward references to %<enum%> types");
3291 return ret;
3294 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3296 struct-or-union-specifier:
3297 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3298 identifier[opt] { struct-contents } gnu-attributes[opt]
3299 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3300 identifier
3302 struct-contents:
3303 struct-declaration-list
3305 struct-declaration-list:
3306 struct-declaration ;
3307 struct-declaration-list struct-declaration ;
3309 GNU extensions:
3311 struct-contents:
3312 empty
3313 struct-declaration
3314 struct-declaration-list struct-declaration
3316 struct-declaration-list:
3317 struct-declaration-list ;
3320 (Note that in the syntax here, unlike that in ISO C, the semicolons
3321 are included here rather than in struct-declaration, in order to
3322 describe the syntax with extra semicolons and missing semicolon at
3323 end.)
3325 Objective-C:
3327 struct-declaration-list:
3328 @defs ( class-name )
3330 (Note this does not include a trailing semicolon, but can be
3331 followed by further declarations, and gets a pedwarn-if-pedantic
3332 when followed by a semicolon.) */
3334 static struct c_typespec
3335 c_parser_struct_or_union_specifier (c_parser *parser)
3337 struct c_typespec ret;
3338 bool have_std_attrs;
3339 tree std_attrs = NULL_TREE;
3340 tree attrs;
3341 tree ident = NULL_TREE;
3342 location_t struct_loc;
3343 location_t ident_loc = UNKNOWN_LOCATION;
3344 enum tree_code code;
3345 switch (c_parser_peek_token (parser)->keyword)
3347 case RID_STRUCT:
3348 code = RECORD_TYPE;
3349 break;
3350 case RID_UNION:
3351 code = UNION_TYPE;
3352 break;
3353 default:
3354 gcc_unreachable ();
3356 struct_loc = c_parser_peek_token (parser)->location;
3357 c_parser_consume_token (parser);
3358 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3359 if (have_std_attrs)
3360 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3361 attrs = c_parser_gnu_attributes (parser);
3363 /* Set the location in case we create a decl now. */
3364 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3366 if (c_parser_next_token_is (parser, CPP_NAME))
3368 ident = c_parser_peek_token (parser)->value;
3369 ident_loc = c_parser_peek_token (parser)->location;
3370 struct_loc = ident_loc;
3371 c_parser_consume_token (parser);
3373 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3375 /* Parse a struct or union definition. Start the scope of the
3376 tag before parsing components. */
3377 class c_struct_parse_info *struct_info;
3378 tree type = start_struct (struct_loc, code, ident, &struct_info);
3379 tree postfix_attrs;
3380 /* We chain the components in reverse order, then put them in
3381 forward order at the end. Each struct-declaration may
3382 declare multiple components (comma-separated), so we must use
3383 chainon to join them, although when parsing each
3384 struct-declaration we can use TREE_CHAIN directly.
3386 The theory behind all this is that there will be more
3387 semicolon separated fields than comma separated fields, and
3388 so we'll be minimizing the number of node traversals required
3389 by chainon. */
3390 tree contents;
3391 timevar_push (TV_PARSE_STRUCT);
3392 contents = NULL_TREE;
3393 c_parser_consume_token (parser);
3394 /* Handle the Objective-C @defs construct,
3395 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3396 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3398 tree name;
3399 gcc_assert (c_dialect_objc ());
3400 c_parser_consume_token (parser);
3401 matching_parens parens;
3402 if (!parens.require_open (parser))
3403 goto end_at_defs;
3404 if (c_parser_next_token_is (parser, CPP_NAME)
3405 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3407 name = c_parser_peek_token (parser)->value;
3408 c_parser_consume_token (parser);
3410 else
3412 c_parser_error (parser, "expected class name");
3413 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3414 goto end_at_defs;
3416 parens.skip_until_found_close (parser);
3417 contents = nreverse (objc_get_class_ivars (name));
3419 end_at_defs:
3420 /* Parse the struct-declarations and semicolons. Problems with
3421 semicolons are diagnosed here; empty structures are diagnosed
3422 elsewhere. */
3423 while (true)
3425 tree decls;
3426 /* Parse any stray semicolon. */
3427 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3429 location_t semicolon_loc
3430 = c_parser_peek_token (parser)->location;
3431 gcc_rich_location richloc (semicolon_loc);
3432 richloc.add_fixit_remove ();
3433 pedwarn (&richloc, OPT_Wpedantic,
3434 "extra semicolon in struct or union specified");
3435 c_parser_consume_token (parser);
3436 continue;
3438 /* Stop if at the end of the struct or union contents. */
3439 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3441 c_parser_consume_token (parser);
3442 break;
3444 /* Accept #pragmas at struct scope. */
3445 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3447 c_parser_pragma (parser, pragma_struct, NULL);
3448 continue;
3450 /* Parse some comma-separated declarations, but not the
3451 trailing semicolon if any. */
3452 decls = c_parser_struct_declaration (parser);
3453 contents = chainon (decls, contents);
3454 /* If no semicolon follows, either we have a parse error or
3455 are at the end of the struct or union and should
3456 pedwarn. */
3457 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3458 c_parser_consume_token (parser);
3459 else
3461 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3462 pedwarn (c_parser_peek_token (parser)->location, 0,
3463 "no semicolon at end of struct or union");
3464 else if (parser->error
3465 || !c_parser_next_token_starts_declspecs (parser))
3467 c_parser_error (parser, "expected %<;%>");
3468 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3469 break;
3472 /* If we come here, we have already emitted an error
3473 for an expected `;', identifier or `(', and we also
3474 recovered already. Go on with the next field. */
3477 postfix_attrs = c_parser_gnu_attributes (parser);
3478 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3479 chainon (std_attrs,
3480 chainon (attrs, postfix_attrs)),
3481 struct_info);
3482 ret.kind = ctsk_tagdef;
3483 ret.expr = NULL_TREE;
3484 ret.expr_const_operands = true;
3485 timevar_pop (TV_PARSE_STRUCT);
3486 return ret;
3488 else if (!ident)
3490 c_parser_error (parser, "expected %<{%>");
3491 ret.spec = error_mark_node;
3492 ret.kind = ctsk_tagref;
3493 ret.expr = NULL_TREE;
3494 ret.expr_const_operands = true;
3495 return ret;
3497 /* Attributes may only appear when the members are defined or in
3498 certain forward declarations. */
3499 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3500 c_parser_error (parser, "expected %<;%>");
3501 /* ??? Existing practice is that GNU attributes are ignored after
3502 the struct or union keyword when not defining the members. */
3503 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3504 return ret;
3507 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3508 *without* the trailing semicolon.
3510 struct-declaration:
3511 attribute-specifier-sequence[opt] specifier-qualifier-list
3512 attribute-specifier-sequence[opt] struct-declarator-list
3513 static_assert-declaration-no-semi
3515 specifier-qualifier-list:
3516 type-specifier specifier-qualifier-list[opt]
3517 type-qualifier specifier-qualifier-list[opt]
3518 alignment-specifier specifier-qualifier-list[opt]
3519 gnu-attributes specifier-qualifier-list[opt]
3521 struct-declarator-list:
3522 struct-declarator
3523 struct-declarator-list , gnu-attributes[opt] struct-declarator
3525 struct-declarator:
3526 declarator gnu-attributes[opt]
3527 declarator[opt] : constant-expression gnu-attributes[opt]
3529 GNU extensions:
3531 struct-declaration:
3532 __extension__ struct-declaration
3533 specifier-qualifier-list
3535 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3536 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3537 any expression without commas in the syntax (assignment
3538 expressions, not just conditional expressions); assignment
3539 expressions will be diagnosed as non-constant. */
3541 static tree
3542 c_parser_struct_declaration (c_parser *parser)
3544 struct c_declspecs *specs;
3545 tree prefix_attrs;
3546 tree all_prefix_attrs;
3547 tree decls;
3548 location_t decl_loc;
3549 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3551 int ext;
3552 tree decl;
3553 ext = disable_extension_diagnostics ();
3554 c_parser_consume_token (parser);
3555 decl = c_parser_struct_declaration (parser);
3556 restore_extension_diagnostics (ext);
3557 return decl;
3559 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3561 c_parser_static_assert_declaration_no_semi (parser);
3562 return NULL_TREE;
3564 specs = build_null_declspecs ();
3565 decl_loc = c_parser_peek_token (parser)->location;
3566 /* Strictly by the standard, we shouldn't allow _Alignas here,
3567 but it appears to have been intended to allow it there, so
3568 we're keeping it as it is until WG14 reaches a conclusion
3569 of N1731.
3570 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3571 c_parser_declspecs (parser, specs, false, true, true,
3572 true, false, true, true, cla_nonabstract_decl);
3573 if (parser->error)
3574 return NULL_TREE;
3575 if (!specs->declspecs_seen_p)
3577 c_parser_error (parser, "expected specifier-qualifier-list");
3578 return NULL_TREE;
3580 finish_declspecs (specs);
3581 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3582 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3584 tree ret;
3585 if (specs->typespec_kind == ctsk_none)
3587 pedwarn (decl_loc, OPT_Wpedantic,
3588 "ISO C forbids member declarations with no members");
3589 shadow_tag_warned (specs, pedantic);
3590 ret = NULL_TREE;
3592 else
3594 /* Support for unnamed structs or unions as members of
3595 structs or unions (which is [a] useful and [b] supports
3596 MS P-SDK). */
3597 tree attrs = NULL;
3599 ret = grokfield (c_parser_peek_token (parser)->location,
3600 build_id_declarator (NULL_TREE), specs,
3601 NULL_TREE, &attrs);
3602 if (ret)
3603 decl_attributes (&ret, attrs, 0);
3605 return ret;
3608 /* Provide better error recovery. Note that a type name here is valid,
3609 and will be treated as a field name. */
3610 if (specs->typespec_kind == ctsk_tagdef
3611 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3612 && c_parser_next_token_starts_declspecs (parser)
3613 && !c_parser_next_token_is (parser, CPP_NAME))
3615 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3616 parser->error = false;
3617 return NULL_TREE;
3620 pending_xref_error ();
3621 prefix_attrs = specs->attrs;
3622 all_prefix_attrs = prefix_attrs;
3623 specs->attrs = NULL_TREE;
3624 decls = NULL_TREE;
3625 while (true)
3627 /* Declaring one or more declarators or un-named bit-fields. */
3628 struct c_declarator *declarator;
3629 bool dummy = false;
3630 if (c_parser_next_token_is (parser, CPP_COLON))
3631 declarator = build_id_declarator (NULL_TREE);
3632 else
3633 declarator = c_parser_declarator (parser,
3634 specs->typespec_kind != ctsk_none,
3635 C_DTR_NORMAL, &dummy);
3636 if (declarator == NULL)
3638 c_parser_skip_to_end_of_block_or_statement (parser);
3639 break;
3641 if (c_parser_next_token_is (parser, CPP_COLON)
3642 || c_parser_next_token_is (parser, CPP_COMMA)
3643 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3644 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3645 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3647 tree postfix_attrs = NULL_TREE;
3648 tree width = NULL_TREE;
3649 tree d;
3650 if (c_parser_next_token_is (parser, CPP_COLON))
3652 c_parser_consume_token (parser);
3653 width = c_parser_expr_no_commas (parser, NULL).value;
3655 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3656 postfix_attrs = c_parser_gnu_attributes (parser);
3657 d = grokfield (c_parser_peek_token (parser)->location,
3658 declarator, specs, width, &all_prefix_attrs);
3659 decl_attributes (&d, chainon (postfix_attrs,
3660 all_prefix_attrs), 0);
3661 DECL_CHAIN (d) = decls;
3662 decls = d;
3663 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3664 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3665 prefix_attrs);
3666 else
3667 all_prefix_attrs = prefix_attrs;
3668 if (c_parser_next_token_is (parser, CPP_COMMA))
3669 c_parser_consume_token (parser);
3670 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3671 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3673 /* Semicolon consumed in caller. */
3674 break;
3676 else
3678 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3679 break;
3682 else
3684 c_parser_error (parser,
3685 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3686 "%<__attribute__%>");
3687 break;
3690 return decls;
3693 /* Parse a typeof specifier (a GNU extension).
3695 typeof-specifier:
3696 typeof ( expression )
3697 typeof ( type-name )
3700 static struct c_typespec
3701 c_parser_typeof_specifier (c_parser *parser)
3703 struct c_typespec ret;
3704 ret.kind = ctsk_typeof;
3705 ret.spec = error_mark_node;
3706 ret.expr = NULL_TREE;
3707 ret.expr_const_operands = true;
3708 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3709 c_parser_consume_token (parser);
3710 c_inhibit_evaluation_warnings++;
3711 in_typeof++;
3712 matching_parens parens;
3713 if (!parens.require_open (parser))
3715 c_inhibit_evaluation_warnings--;
3716 in_typeof--;
3717 return ret;
3719 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3721 struct c_type_name *type = c_parser_type_name (parser);
3722 c_inhibit_evaluation_warnings--;
3723 in_typeof--;
3724 if (type != NULL)
3726 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3727 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3730 else
3732 bool was_vm;
3733 location_t here = c_parser_peek_token (parser)->location;
3734 struct c_expr expr = c_parser_expression (parser);
3735 c_inhibit_evaluation_warnings--;
3736 in_typeof--;
3737 if (TREE_CODE (expr.value) == COMPONENT_REF
3738 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3739 error_at (here, "%<typeof%> applied to a bit-field");
3740 mark_exp_read (expr.value);
3741 ret.spec = TREE_TYPE (expr.value);
3742 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3743 /* This is returned with the type so that when the type is
3744 evaluated, this can be evaluated. */
3745 if (was_vm)
3746 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3747 pop_maybe_used (was_vm);
3749 parens.skip_until_found_close (parser);
3750 return ret;
3753 /* Parse an alignment-specifier.
3755 C11 6.7.5:
3757 alignment-specifier:
3758 _Alignas ( type-name )
3759 _Alignas ( constant-expression )
3762 static tree
3763 c_parser_alignas_specifier (c_parser * parser)
3765 tree ret = error_mark_node;
3766 location_t loc = c_parser_peek_token (parser)->location;
3767 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3768 c_parser_consume_token (parser);
3769 if (flag_isoc99)
3770 pedwarn_c99 (loc, OPT_Wpedantic,
3771 "ISO C99 does not support %<_Alignas%>");
3772 else
3773 pedwarn_c99 (loc, OPT_Wpedantic,
3774 "ISO C90 does not support %<_Alignas%>");
3775 matching_parens parens;
3776 if (!parens.require_open (parser))
3777 return ret;
3778 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3780 struct c_type_name *type = c_parser_type_name (parser);
3781 if (type != NULL)
3782 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3783 false, true, 1);
3785 else
3786 ret = c_parser_expr_no_commas (parser, NULL).value;
3787 parens.skip_until_found_close (parser);
3788 return ret;
3791 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3792 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3793 a typedef name may be redeclared; otherwise it may not. KIND
3794 indicates which kind of declarator is wanted. Returns a valid
3795 declarator except in the case of a syntax error in which case NULL is
3796 returned. *SEEN_ID is set to true if an identifier being declared is
3797 seen; this is used to diagnose bad forms of abstract array declarators
3798 and to determine whether an identifier list is syntactically permitted.
3800 declarator:
3801 pointer[opt] direct-declarator
3803 direct-declarator:
3804 identifier
3805 ( gnu-attributes[opt] declarator )
3806 direct-declarator array-declarator
3807 direct-declarator ( parameter-type-list )
3808 direct-declarator ( identifier-list[opt] )
3810 pointer:
3811 * type-qualifier-list[opt]
3812 * type-qualifier-list[opt] pointer
3814 type-qualifier-list:
3815 type-qualifier
3816 gnu-attributes
3817 type-qualifier-list type-qualifier
3818 type-qualifier-list gnu-attributes
3820 array-declarator:
3821 [ type-qualifier-list[opt] assignment-expression[opt] ]
3822 [ static type-qualifier-list[opt] assignment-expression ]
3823 [ type-qualifier-list static assignment-expression ]
3824 [ type-qualifier-list[opt] * ]
3826 parameter-type-list:
3827 parameter-list
3828 parameter-list , ...
3830 parameter-list:
3831 parameter-declaration
3832 parameter-list , parameter-declaration
3834 parameter-declaration:
3835 declaration-specifiers declarator gnu-attributes[opt]
3836 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3838 identifier-list:
3839 identifier
3840 identifier-list , identifier
3842 abstract-declarator:
3843 pointer
3844 pointer[opt] direct-abstract-declarator
3846 direct-abstract-declarator:
3847 ( gnu-attributes[opt] abstract-declarator )
3848 direct-abstract-declarator[opt] array-declarator
3849 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3851 GNU extensions:
3853 direct-declarator:
3854 direct-declarator ( parameter-forward-declarations
3855 parameter-type-list[opt] )
3857 direct-abstract-declarator:
3858 direct-abstract-declarator[opt] ( parameter-forward-declarations
3859 parameter-type-list[opt] )
3861 parameter-forward-declarations:
3862 parameter-list ;
3863 parameter-forward-declarations parameter-list ;
3865 The uses of gnu-attributes shown above are GNU extensions.
3867 Some forms of array declarator are not included in C99 in the
3868 syntax for abstract declarators; these are disallowed elsewhere.
3869 This may be a defect (DR#289).
3871 This function also accepts an omitted abstract declarator as being
3872 an abstract declarator, although not part of the formal syntax. */
3874 struct c_declarator *
3875 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3876 bool *seen_id)
3878 /* Parse any initial pointer part. */
3879 if (c_parser_next_token_is (parser, CPP_MULT))
3881 struct c_declspecs *quals_attrs = build_null_declspecs ();
3882 struct c_declarator *inner;
3883 c_parser_consume_token (parser);
3884 c_parser_declspecs (parser, quals_attrs, false, false, true,
3885 false, false, true, false, cla_prefer_id);
3886 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3887 if (inner == NULL)
3888 return NULL;
3889 else
3890 return make_pointer_declarator (quals_attrs, inner);
3892 /* Now we have a direct declarator, direct abstract declarator or
3893 nothing (which counts as a direct abstract declarator here). */
3894 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3897 /* Parse a direct declarator or direct abstract declarator; arguments
3898 as c_parser_declarator. */
3900 static struct c_declarator *
3901 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3902 bool *seen_id)
3904 /* The direct declarator must start with an identifier (possibly
3905 omitted) or a parenthesized declarator (possibly abstract). In
3906 an ordinary declarator, initial parentheses must start a
3907 parenthesized declarator. In an abstract declarator or parameter
3908 declarator, they could start a parenthesized declarator or a
3909 parameter list. To tell which, the open parenthesis and any
3910 following gnu-attributes must be read. If a declaration
3911 specifier or standard attributes follow, then it is a parameter
3912 list; if the specifier is a typedef name, there might be an
3913 ambiguity about redeclaring it, which is resolved in the
3914 direction of treating it as a typedef name. If a close
3915 parenthesis follows, it is also an empty parameter list, as the
3916 syntax does not permit empty abstract declarators. Otherwise, it
3917 is a parenthesized declarator (in which case the analysis may be
3918 repeated inside it, recursively).
3920 ??? There is an ambiguity in a parameter declaration "int
3921 (__attribute__((foo)) x)", where x is not a typedef name: it
3922 could be an abstract declarator for a function, or declare x with
3923 parentheses. The proper resolution of this ambiguity needs
3924 documenting. At present we follow an accident of the old
3925 parser's implementation, whereby the first parameter must have
3926 some declaration specifiers other than just gnu-attributes. Thus as
3927 a parameter declaration it is treated as a parenthesized
3928 parameter named x, and as an abstract declarator it is
3929 rejected.
3931 ??? Also following the old parser, gnu-attributes inside an empty
3932 parameter list are ignored, making it a list not yielding a
3933 prototype, rather than giving an error or making it have one
3934 parameter with implicit type int.
3936 ??? Also following the old parser, typedef names may be
3937 redeclared in declarators, but not Objective-C class names. */
3939 if (kind != C_DTR_ABSTRACT
3940 && c_parser_next_token_is (parser, CPP_NAME)
3941 && ((type_seen_p
3942 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3943 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3944 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3946 struct c_declarator *inner
3947 = build_id_declarator (c_parser_peek_token (parser)->value);
3948 *seen_id = true;
3949 inner->id_loc = c_parser_peek_token (parser)->location;
3950 c_parser_consume_token (parser);
3951 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3952 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3953 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3956 if (kind != C_DTR_NORMAL
3957 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3958 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3960 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3961 inner->id_loc = c_parser_peek_token (parser)->location;
3962 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3965 /* Either we are at the end of an abstract declarator, or we have
3966 parentheses. */
3968 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3970 tree attrs;
3971 struct c_declarator *inner;
3972 c_parser_consume_token (parser);
3973 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3974 RID_ATTRIBUTE);
3975 attrs = c_parser_gnu_attributes (parser);
3976 if (kind != C_DTR_NORMAL
3977 && (c_parser_next_token_starts_declspecs (parser)
3978 || (!have_gnu_attrs
3979 && c_parser_nth_token_starts_std_attributes (parser, 1))
3980 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3982 struct c_arg_info *args
3983 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3984 attrs, have_gnu_attrs);
3985 if (args == NULL)
3986 return NULL;
3987 else
3989 inner = build_id_declarator (NULL_TREE);
3990 if (!(args->types
3991 && args->types != error_mark_node
3992 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
3993 && c_parser_nth_token_starts_std_attributes (parser, 1))
3995 tree std_attrs
3996 = c_parser_std_attribute_specifier_sequence (parser);
3997 if (std_attrs)
3998 inner = build_attrs_declarator (std_attrs, inner);
4000 inner = build_function_declarator (args, inner);
4001 return c_parser_direct_declarator_inner (parser, *seen_id,
4002 inner);
4005 /* A parenthesized declarator. */
4006 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4007 if (inner != NULL && attrs != NULL)
4008 inner = build_attrs_declarator (attrs, inner);
4009 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4011 c_parser_consume_token (parser);
4012 if (inner == NULL)
4013 return NULL;
4014 else
4015 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4017 else
4019 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4020 "expected %<)%>");
4021 return NULL;
4024 else
4026 if (kind == C_DTR_NORMAL)
4028 c_parser_error (parser, "expected identifier or %<(%>");
4029 return NULL;
4031 else
4032 return build_id_declarator (NULL_TREE);
4036 /* Parse part of a direct declarator or direct abstract declarator,
4037 given that some (in INNER) has already been parsed; ID_PRESENT is
4038 true if an identifier is present, false for an abstract
4039 declarator. */
4041 static struct c_declarator *
4042 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4043 struct c_declarator *inner)
4045 /* Parse a sequence of array declarators and parameter lists. */
4046 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4047 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4049 location_t brace_loc = c_parser_peek_token (parser)->location;
4050 struct c_declarator *declarator;
4051 struct c_declspecs *quals_attrs = build_null_declspecs ();
4052 bool static_seen;
4053 bool star_seen;
4054 struct c_expr dimen;
4055 dimen.value = NULL_TREE;
4056 dimen.original_code = ERROR_MARK;
4057 dimen.original_type = NULL_TREE;
4058 c_parser_consume_token (parser);
4059 c_parser_declspecs (parser, quals_attrs, false, false, true,
4060 false, false, false, false, cla_prefer_id);
4061 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4062 if (static_seen)
4063 c_parser_consume_token (parser);
4064 if (static_seen && !quals_attrs->declspecs_seen_p)
4065 c_parser_declspecs (parser, quals_attrs, false, false, true,
4066 false, false, false, false, cla_prefer_id);
4067 if (!quals_attrs->declspecs_seen_p)
4068 quals_attrs = NULL;
4069 /* If "static" is present, there must be an array dimension.
4070 Otherwise, there may be a dimension, "*", or no
4071 dimension. */
4072 if (static_seen)
4074 star_seen = false;
4075 dimen = c_parser_expr_no_commas (parser, NULL);
4077 else
4079 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4081 dimen.value = NULL_TREE;
4082 star_seen = false;
4084 else if (c_parser_next_token_is (parser, CPP_MULT))
4086 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4088 dimen.value = NULL_TREE;
4089 star_seen = true;
4090 c_parser_consume_token (parser);
4092 else
4094 star_seen = false;
4095 dimen = c_parser_expr_no_commas (parser, NULL);
4098 else
4100 star_seen = false;
4101 dimen = c_parser_expr_no_commas (parser, NULL);
4104 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4105 c_parser_consume_token (parser);
4106 else
4108 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4109 "expected %<]%>");
4110 return NULL;
4112 if (dimen.value)
4113 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4114 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4115 static_seen, star_seen);
4116 if (declarator == NULL)
4117 return NULL;
4118 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4120 tree std_attrs
4121 = c_parser_std_attribute_specifier_sequence (parser);
4122 if (std_attrs)
4123 inner = build_attrs_declarator (std_attrs, inner);
4125 inner = set_array_declarator_inner (declarator, inner);
4126 return c_parser_direct_declarator_inner (parser, id_present, inner);
4128 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4130 tree attrs;
4131 struct c_arg_info *args;
4132 c_parser_consume_token (parser);
4133 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4134 RID_ATTRIBUTE);
4135 attrs = c_parser_gnu_attributes (parser);
4136 args = c_parser_parms_declarator (parser, id_present, attrs,
4137 have_gnu_attrs);
4138 if (args == NULL)
4139 return NULL;
4140 else
4142 if (!(args->types
4143 && args->types != error_mark_node
4144 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4145 && c_parser_nth_token_starts_std_attributes (parser, 1))
4147 tree std_attrs
4148 = c_parser_std_attribute_specifier_sequence (parser);
4149 if (std_attrs)
4150 inner = build_attrs_declarator (std_attrs, inner);
4152 inner = build_function_declarator (args, inner);
4153 return c_parser_direct_declarator_inner (parser, id_present, inner);
4156 return inner;
4159 /* Parse a parameter list or identifier list, including the closing
4160 parenthesis but not the opening one. ATTRS are the gnu-attributes
4161 at the start of the list. ID_LIST_OK is true if an identifier list
4162 is acceptable; such a list must not have attributes at the start.
4163 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4164 attributes) were present (in which case standard attributes cannot
4165 occur). */
4167 static struct c_arg_info *
4168 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4169 bool have_gnu_attrs)
4171 push_scope ();
4172 declare_parm_level ();
4173 /* If the list starts with an identifier, it is an identifier list.
4174 Otherwise, it is either a prototype list or an empty list. */
4175 if (id_list_ok
4176 && !attrs
4177 && c_parser_next_token_is (parser, CPP_NAME)
4178 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4180 /* Look ahead to detect typos in type names. */
4181 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4182 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4183 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4184 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4185 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4187 tree list = NULL_TREE, *nextp = &list;
4188 while (c_parser_next_token_is (parser, CPP_NAME)
4189 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4191 *nextp = build_tree_list (NULL_TREE,
4192 c_parser_peek_token (parser)->value);
4193 nextp = & TREE_CHAIN (*nextp);
4194 c_parser_consume_token (parser);
4195 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4196 break;
4197 c_parser_consume_token (parser);
4198 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4200 c_parser_error (parser, "expected identifier");
4201 break;
4204 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4206 struct c_arg_info *ret = build_arg_info ();
4207 ret->types = list;
4208 c_parser_consume_token (parser);
4209 pop_scope ();
4210 return ret;
4212 else
4214 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4215 "expected %<)%>");
4216 pop_scope ();
4217 return NULL;
4220 else
4222 struct c_arg_info *ret
4223 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4224 pop_scope ();
4225 return ret;
4229 /* Parse a parameter list (possibly empty), including the closing
4230 parenthesis but not the opening one. ATTRS are the gnu-attributes
4231 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4232 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4233 which means standard attributes cannot start the list. EXPR is
4234 NULL or an expression that needs to be evaluated for the side
4235 effects of array size expressions in the parameters. */
4237 static struct c_arg_info *
4238 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4239 bool have_gnu_attrs)
4241 bool bad_parm = false;
4243 /* ??? Following the old parser, forward parameter declarations may
4244 use abstract declarators, and if no real parameter declarations
4245 follow the forward declarations then this is not diagnosed. Also
4246 note as above that gnu-attributes are ignored as the only contents of
4247 the parentheses, or as the only contents after forward
4248 declarations. */
4249 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4251 struct c_arg_info *ret = build_arg_info ();
4252 c_parser_consume_token (parser);
4253 return ret;
4255 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4257 struct c_arg_info *ret = build_arg_info ();
4259 if (flag_allow_parameterless_variadic_functions)
4261 /* F (...) is allowed. */
4262 ret->types = NULL_TREE;
4264 else
4266 /* Suppress -Wold-style-definition for this case. */
4267 ret->types = error_mark_node;
4268 error_at (c_parser_peek_token (parser)->location,
4269 "ISO C requires a named argument before %<...%>");
4271 c_parser_consume_token (parser);
4272 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4274 c_parser_consume_token (parser);
4275 return ret;
4277 else
4279 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4280 "expected %<)%>");
4281 return NULL;
4284 /* Nonempty list of parameters, either terminated with semicolon
4285 (forward declarations; recurse) or with close parenthesis (normal
4286 function) or with ", ... )" (variadic function). */
4287 while (true)
4289 /* Parse a parameter. */
4290 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4291 have_gnu_attrs);
4292 attrs = NULL_TREE;
4293 have_gnu_attrs = false;
4294 if (parm == NULL)
4295 bad_parm = true;
4296 else
4297 push_parm_decl (parm, &expr);
4298 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4300 tree new_attrs;
4301 c_parser_consume_token (parser);
4302 mark_forward_parm_decls ();
4303 bool new_have_gnu_attrs
4304 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4305 new_attrs = c_parser_gnu_attributes (parser);
4306 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4307 new_have_gnu_attrs);
4309 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4311 c_parser_consume_token (parser);
4312 if (bad_parm)
4313 return NULL;
4314 else
4315 return get_parm_info (false, expr);
4317 if (!c_parser_require (parser, CPP_COMMA,
4318 "expected %<;%>, %<,%> or %<)%>",
4319 UNKNOWN_LOCATION, false))
4321 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4322 return NULL;
4324 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4326 c_parser_consume_token (parser);
4327 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4329 c_parser_consume_token (parser);
4330 if (bad_parm)
4331 return NULL;
4332 else
4333 return get_parm_info (true, expr);
4335 else
4337 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4338 "expected %<)%>");
4339 return NULL;
4345 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4346 start of the declaration if it is the first parameter;
4347 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4348 empty) there. */
4350 static struct c_parm *
4351 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4352 bool have_gnu_attrs)
4354 struct c_declspecs *specs;
4355 struct c_declarator *declarator;
4356 tree prefix_attrs;
4357 tree postfix_attrs = NULL_TREE;
4358 bool dummy = false;
4360 /* Accept #pragmas between parameter declarations. */
4361 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4362 c_parser_pragma (parser, pragma_param, NULL);
4364 if (!c_parser_next_token_starts_declspecs (parser)
4365 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4367 c_token *token = c_parser_peek_token (parser);
4368 if (parser->error)
4369 return NULL;
4370 c_parser_set_source_position_from_token (token);
4371 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4373 auto_diagnostic_group d;
4374 name_hint hint = lookup_name_fuzzy (token->value,
4375 FUZZY_LOOKUP_TYPENAME,
4376 token->location);
4377 if (const char *suggestion = hint.suggestion ())
4379 gcc_rich_location richloc (token->location);
4380 richloc.add_fixit_replace (suggestion);
4381 error_at (&richloc,
4382 "unknown type name %qE; did you mean %qs?",
4383 token->value, suggestion);
4385 else
4386 error_at (token->location, "unknown type name %qE", token->value);
4387 parser->error = true;
4389 /* ??? In some Objective-C cases '...' isn't applicable so there
4390 should be a different message. */
4391 else
4392 c_parser_error (parser,
4393 "expected declaration specifiers or %<...%>");
4394 c_parser_skip_to_end_of_parameter (parser);
4395 return NULL;
4398 location_t start_loc = c_parser_peek_token (parser)->location;
4400 specs = build_null_declspecs ();
4401 if (attrs)
4403 declspecs_add_attrs (input_location, specs, attrs);
4404 attrs = NULL_TREE;
4406 c_parser_declspecs (parser, specs, true, true, true, true, false,
4407 !have_gnu_attrs, true, cla_nonabstract_decl);
4408 finish_declspecs (specs);
4409 pending_xref_error ();
4410 prefix_attrs = specs->attrs;
4411 specs->attrs = NULL_TREE;
4412 declarator = c_parser_declarator (parser,
4413 specs->typespec_kind != ctsk_none,
4414 C_DTR_PARM, &dummy);
4415 if (declarator == NULL)
4417 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4418 return NULL;
4420 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4421 postfix_attrs = c_parser_gnu_attributes (parser);
4423 /* Generate a location for the parameter, ranging from the start of the
4424 initial token to the end of the final token.
4426 If we have a identifier, then use it for the caret location, e.g.
4428 extern int callee (int one, int (*two)(int, int), float three);
4429 ~~~~~~^~~~~~~~~~~~~~
4431 otherwise, reuse the start location for the caret location e.g.:
4433 extern int callee (int one, int (*)(int, int), float three);
4434 ^~~~~~~~~~~~~~~~~
4436 location_t end_loc = parser->last_token_location;
4438 /* Find any cdk_id declarator; determine if we have an identifier. */
4439 c_declarator *id_declarator = declarator;
4440 while (id_declarator && id_declarator->kind != cdk_id)
4441 id_declarator = id_declarator->declarator;
4442 location_t caret_loc = (id_declarator->u.id.id
4443 ? id_declarator->id_loc
4444 : start_loc);
4445 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4447 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4448 declarator, param_loc);
4451 /* Parse a string literal in an asm expression. It should not be
4452 translated, and wide string literals are an error although
4453 permitted by the syntax. This is a GNU extension.
4455 asm-string-literal:
4456 string-literal
4459 static tree
4460 c_parser_asm_string_literal (c_parser *parser)
4462 tree str;
4463 int save_flag = warn_overlength_strings;
4464 warn_overlength_strings = 0;
4465 str = c_parser_string_literal (parser, false, false).value;
4466 warn_overlength_strings = save_flag;
4467 return str;
4470 /* Parse a simple asm expression. This is used in restricted
4471 contexts, where a full expression with inputs and outputs does not
4472 make sense. This is a GNU extension.
4474 simple-asm-expr:
4475 asm ( asm-string-literal )
4478 static tree
4479 c_parser_simple_asm_expr (c_parser *parser)
4481 tree str;
4482 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4483 c_parser_consume_token (parser);
4484 matching_parens parens;
4485 if (!parens.require_open (parser))
4486 return NULL_TREE;
4487 str = c_parser_asm_string_literal (parser);
4488 if (!parens.require_close (parser))
4490 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4491 return NULL_TREE;
4493 return str;
4496 static tree
4497 c_parser_gnu_attribute_any_word (c_parser *parser)
4499 tree attr_name = NULL_TREE;
4501 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4503 /* ??? See comment above about what keywords are accepted here. */
4504 bool ok;
4505 switch (c_parser_peek_token (parser)->keyword)
4507 case RID_STATIC:
4508 case RID_UNSIGNED:
4509 case RID_LONG:
4510 case RID_CONST:
4511 case RID_EXTERN:
4512 case RID_REGISTER:
4513 case RID_TYPEDEF:
4514 case RID_SHORT:
4515 case RID_INLINE:
4516 case RID_NORETURN:
4517 case RID_VOLATILE:
4518 case RID_SIGNED:
4519 case RID_AUTO:
4520 case RID_RESTRICT:
4521 case RID_COMPLEX:
4522 case RID_THREAD:
4523 case RID_INT:
4524 case RID_CHAR:
4525 case RID_FLOAT:
4526 case RID_DOUBLE:
4527 case RID_VOID:
4528 case RID_DFLOAT32:
4529 case RID_DFLOAT64:
4530 case RID_DFLOAT128:
4531 CASE_RID_FLOATN_NX:
4532 case RID_BOOL:
4533 case RID_FRACT:
4534 case RID_ACCUM:
4535 case RID_SAT:
4536 case RID_TRANSACTION_ATOMIC:
4537 case RID_TRANSACTION_CANCEL:
4538 case RID_ATOMIC:
4539 case RID_AUTO_TYPE:
4540 case RID_INT_N_0:
4541 case RID_INT_N_1:
4542 case RID_INT_N_2:
4543 case RID_INT_N_3:
4544 ok = true;
4545 break;
4546 default:
4547 ok = false;
4548 break;
4550 if (!ok)
4551 return NULL_TREE;
4553 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4554 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4556 else if (c_parser_next_token_is (parser, CPP_NAME))
4557 attr_name = c_parser_peek_token (parser)->value;
4559 return attr_name;
4562 /* Parse attribute arguments. This is a common form of syntax
4563 covering all currently valid GNU and standard attributes.
4565 gnu-attribute-arguments:
4566 identifier
4567 identifier , nonempty-expr-list
4568 expr-list
4570 where the "identifier" must not be declared as a type. ??? Why not
4571 allow identifiers declared as types to start the arguments? */
4573 static tree
4574 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4575 bool require_string, bool allow_empty_args)
4577 vec<tree, va_gc> *expr_list;
4578 tree attr_args;
4579 /* Parse the attribute contents. If they start with an
4580 identifier which is followed by a comma or close
4581 parenthesis, then the arguments start with that
4582 identifier; otherwise they are an expression list.
4583 In objective-c the identifier may be a classname. */
4584 if (c_parser_next_token_is (parser, CPP_NAME)
4585 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4586 || (c_dialect_objc ()
4587 && c_parser_peek_token (parser)->id_kind
4588 == C_ID_CLASSNAME))
4589 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4590 || (c_parser_peek_2nd_token (parser)->type
4591 == CPP_CLOSE_PAREN))
4592 && (takes_identifier
4593 || (c_dialect_objc ()
4594 && c_parser_peek_token (parser)->id_kind
4595 == C_ID_CLASSNAME)))
4597 tree arg1 = c_parser_peek_token (parser)->value;
4598 c_parser_consume_token (parser);
4599 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4600 attr_args = build_tree_list (NULL_TREE, arg1);
4601 else
4603 tree tree_list;
4604 c_parser_consume_token (parser);
4605 expr_list = c_parser_expr_list (parser, false, true,
4606 NULL, NULL, NULL, NULL);
4607 tree_list = build_tree_list_vec (expr_list);
4608 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4609 release_tree_vector (expr_list);
4612 else
4614 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4616 if (!allow_empty_args)
4617 error_at (c_parser_peek_token (parser)->location,
4618 "parentheses must be omitted if "
4619 "attribute argument list is empty");
4620 attr_args = NULL_TREE;
4622 else if (require_string)
4624 /* The only valid argument for this attribute is a string
4625 literal. Handle this specially here to avoid accepting
4626 string literals with excess parentheses. */
4627 tree string = c_parser_string_literal (parser, false, true).value;
4628 attr_args = build_tree_list (NULL_TREE, string);
4630 else
4632 expr_list = c_parser_expr_list (parser, false, true,
4633 NULL, NULL, NULL, NULL);
4634 attr_args = build_tree_list_vec (expr_list);
4635 release_tree_vector (expr_list);
4638 return attr_args;
4641 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4643 gnu-attributes:
4644 empty
4645 gnu-attributes gnu-attribute
4647 gnu-attribute:
4648 __attribute__ ( ( gnu-attribute-list ) )
4650 gnu-attribute-list:
4651 gnu-attrib
4652 gnu-attribute_list , gnu-attrib
4654 gnu-attrib:
4655 empty
4656 any-word
4657 any-word ( gnu-attribute-arguments )
4659 where "any-word" may be any identifier (including one declared as a
4660 type), a reserved word storage class specifier, type specifier or
4661 type qualifier. ??? This still leaves out most reserved keywords
4662 (following the old parser), shouldn't we include them?
4663 When EXPECT_COMMA is true, expect the attribute to be preceded
4664 by a comma and fail if it isn't.
4665 When EMPTY_OK is true, allow and consume any number of consecutive
4666 commas with no attributes in between. */
4668 static tree
4669 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4670 bool expect_comma = false, bool empty_ok = true)
4672 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4673 if (!comma_first
4674 && !c_parser_next_token_is (parser, CPP_NAME)
4675 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4676 return NULL_TREE;
4678 while (c_parser_next_token_is (parser, CPP_COMMA))
4680 c_parser_consume_token (parser);
4681 if (!empty_ok)
4682 return attrs;
4685 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4686 if (attr_name == NULL_TREE)
4687 return NULL_TREE;
4689 attr_name = canonicalize_attr_name (attr_name);
4690 c_parser_consume_token (parser);
4692 tree attr;
4693 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4695 if (expect_comma && !comma_first)
4697 /* A comma is missing between the last attribute on the chain
4698 and this one. */
4699 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4700 "expected %<)%>");
4701 return error_mark_node;
4703 attr = build_tree_list (attr_name, NULL_TREE);
4704 /* Add this attribute to the list. */
4705 attrs = chainon (attrs, attr);
4706 return attrs;
4708 c_parser_consume_token (parser);
4710 tree attr_args
4711 = c_parser_attribute_arguments (parser,
4712 attribute_takes_identifier_p (attr_name),
4713 false, true);
4715 attr = build_tree_list (attr_name, attr_args);
4716 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4717 c_parser_consume_token (parser);
4718 else
4720 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4721 "expected %<)%>");
4722 return error_mark_node;
4725 if (expect_comma && !comma_first)
4727 /* A comma is missing between the last attribute on the chain
4728 and this one. */
4729 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4730 "expected %<)%>");
4731 return error_mark_node;
4734 /* Add this attribute to the list. */
4735 attrs = chainon (attrs, attr);
4736 return attrs;
4739 static tree
4740 c_parser_gnu_attributes (c_parser *parser)
4742 tree attrs = NULL_TREE;
4743 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4745 bool save_translate_strings_p = parser->translate_strings_p;
4746 parser->translate_strings_p = false;
4747 /* Consume the `__attribute__' keyword. */
4748 c_parser_consume_token (parser);
4749 /* Look for the two `(' tokens. */
4750 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4752 parser->translate_strings_p = save_translate_strings_p;
4753 return attrs;
4755 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4757 parser->translate_strings_p = save_translate_strings_p;
4758 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4759 return attrs;
4761 /* Parse the attribute list. Require a comma between successive
4762 (possibly empty) attributes. */
4763 for (bool expect_comma = false; ; expect_comma = true)
4765 /* Parse a single attribute. */
4766 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4767 if (attr == error_mark_node)
4768 return attrs;
4769 if (!attr)
4770 break;
4771 attrs = attr;
4774 /* Look for the two `)' tokens. */
4775 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4776 c_parser_consume_token (parser);
4777 else
4779 parser->translate_strings_p = save_translate_strings_p;
4780 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4781 "expected %<)%>");
4782 return attrs;
4784 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4785 c_parser_consume_token (parser);
4786 else
4788 parser->translate_strings_p = save_translate_strings_p;
4789 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4790 "expected %<)%>");
4791 return attrs;
4793 parser->translate_strings_p = save_translate_strings_p;
4796 return attrs;
4799 /* Parse an optional balanced token sequence.
4801 balanced-token-sequence:
4802 balanced-token
4803 balanced-token-sequence balanced-token
4805 balanced-token:
4806 ( balanced-token-sequence[opt] )
4807 [ balanced-token-sequence[opt] ]
4808 { balanced-token-sequence[opt] }
4809 any token other than ()[]{}
4812 static void
4813 c_parser_balanced_token_sequence (c_parser *parser)
4815 while (true)
4817 c_token *token = c_parser_peek_token (parser);
4818 switch (token->type)
4820 case CPP_OPEN_BRACE:
4822 matching_braces braces;
4823 braces.consume_open (parser);
4824 c_parser_balanced_token_sequence (parser);
4825 braces.require_close (parser);
4826 break;
4829 case CPP_OPEN_PAREN:
4831 matching_parens parens;
4832 parens.consume_open (parser);
4833 c_parser_balanced_token_sequence (parser);
4834 parens.require_close (parser);
4835 break;
4838 case CPP_OPEN_SQUARE:
4839 c_parser_consume_token (parser);
4840 c_parser_balanced_token_sequence (parser);
4841 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4842 break;
4844 case CPP_CLOSE_BRACE:
4845 case CPP_CLOSE_PAREN:
4846 case CPP_CLOSE_SQUARE:
4847 case CPP_EOF:
4848 return;
4850 default:
4851 c_parser_consume_token (parser);
4852 break;
4857 /* Parse standard (C2X) attributes (including GNU attributes in the
4858 gnu:: namespace).
4860 attribute-specifier-sequence:
4861 attribute-specifier-sequence[opt] attribute-specifier
4863 attribute-specifier:
4864 [ [ attribute-list ] ]
4866 attribute-list:
4867 attribute[opt]
4868 attribute-list, attribute[opt]
4870 attribute:
4871 attribute-token attribute-argument-clause[opt]
4873 attribute-token:
4874 standard-attribute
4875 attribute-prefixed-token
4877 standard-attribute:
4878 identifier
4880 attribute-prefixed-token:
4881 attribute-prefix :: identifier
4883 attribute-prefix:
4884 identifier
4886 attribute-argument-clause:
4887 ( balanced-token-sequence[opt] )
4889 Keywords are accepted as identifiers for this purpose.
4892 static tree
4893 c_parser_std_attribute (c_parser *parser, bool for_tm)
4895 c_token *token = c_parser_peek_token (parser);
4896 tree ns, name, attribute;
4898 /* Parse the attribute-token. */
4899 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4901 c_parser_error (parser, "expected identifier");
4902 return error_mark_node;
4904 name = canonicalize_attr_name (token->value);
4905 c_parser_consume_token (parser);
4906 if (c_parser_next_token_is (parser, CPP_SCOPE))
4908 ns = name;
4909 c_parser_consume_token (parser);
4910 token = c_parser_peek_token (parser);
4911 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4913 c_parser_error (parser, "expected identifier");
4914 return error_mark_node;
4916 name = canonicalize_attr_name (token->value);
4917 c_parser_consume_token (parser);
4919 else
4920 ns = NULL_TREE;
4921 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4923 /* Parse the arguments, if any. */
4924 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4925 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4926 goto out;
4928 location_t open_loc = c_parser_peek_token (parser)->location;
4929 matching_parens parens;
4930 parens.consume_open (parser);
4931 if ((as && as->max_length == 0)
4932 /* Special-case the transactional-memory attribute "outer",
4933 which is specially handled but not registered as an
4934 attribute, to avoid allowing arbitrary balanced token
4935 sequences as arguments. */
4936 || is_attribute_p ("outer", name))
4938 error_at (open_loc, "%qE attribute does not take any arguments", name);
4939 parens.skip_until_found_close (parser);
4940 return error_mark_node;
4942 if (as)
4944 bool takes_identifier
4945 = (ns != NULL_TREE
4946 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4947 && attribute_takes_identifier_p (name));
4948 bool require_string
4949 = (ns == NULL_TREE
4950 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4951 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4952 TREE_VALUE (attribute)
4953 = c_parser_attribute_arguments (parser, takes_identifier,
4954 require_string, false);
4956 else
4957 c_parser_balanced_token_sequence (parser);
4958 parens.require_close (parser);
4960 out:
4961 if (ns == NULL_TREE && !for_tm && !as)
4963 /* An attribute with standard syntax and no namespace specified
4964 is a constraint violation if it is not one of the known
4965 standard attributes. Diagnose it here with a pedwarn and
4966 then discard it to prevent a duplicate warning later. */
4967 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4968 name);
4969 return error_mark_node;
4971 return attribute;
4974 static tree
4975 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4977 location_t loc = c_parser_peek_token (parser)->location;
4978 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4979 return NULL_TREE;
4980 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4982 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4983 return NULL_TREE;
4985 if (!for_tm)
4986 pedwarn_c11 (loc, OPT_Wpedantic,
4987 "ISO C does not support %<[[]]%> attributes before C2X");
4988 tree attributes = NULL_TREE;
4989 while (true)
4991 c_token *token = c_parser_peek_token (parser);
4992 if (token->type == CPP_CLOSE_SQUARE)
4993 break;
4994 if (token->type == CPP_COMMA)
4996 c_parser_consume_token (parser);
4997 continue;
4999 tree attribute = c_parser_std_attribute (parser, for_tm);
5000 if (attribute != error_mark_node)
5002 TREE_CHAIN (attribute) = attributes;
5003 attributes = attribute;
5005 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5006 break;
5008 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5009 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5010 return nreverse (attributes);
5013 /* Look past an optional balanced token sequence of raw look-ahead
5014 tokens starting with the *Nth token. *N is updated to point to the
5015 following token. Return true if such a sequence was found, false
5016 if the tokens parsed were not balanced. */
5018 static bool
5019 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5021 while (true)
5023 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5024 switch (token->type)
5026 case CPP_OPEN_BRACE:
5028 ++*n;
5029 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5031 token = c_parser_peek_nth_token_raw (parser, *n);
5032 if (token->type == CPP_CLOSE_BRACE)
5033 ++*n;
5034 else
5035 return false;
5037 else
5038 return false;
5039 break;
5042 case CPP_OPEN_PAREN:
5044 ++*n;
5045 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5047 token = c_parser_peek_nth_token_raw (parser, *n);
5048 if (token->type == CPP_CLOSE_PAREN)
5049 ++*n;
5050 else
5051 return false;
5053 else
5054 return false;
5055 break;
5058 case CPP_OPEN_SQUARE:
5060 ++*n;
5061 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5063 token = c_parser_peek_nth_token_raw (parser, *n);
5064 if (token->type == CPP_CLOSE_SQUARE)
5065 ++*n;
5066 else
5067 return false;
5069 else
5070 return false;
5071 break;
5074 case CPP_CLOSE_BRACE:
5075 case CPP_CLOSE_PAREN:
5076 case CPP_CLOSE_SQUARE:
5077 case CPP_EOF:
5078 return true;
5080 default:
5081 ++*n;
5082 break;
5087 /* Return whether standard attributes start with the Nth token. */
5089 static bool
5090 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5092 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5093 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5094 return false;
5095 /* In C, '[[' must start attributes. In Objective-C, we need to
5096 check whether '[[' is matched by ']]'. */
5097 if (!c_dialect_objc ())
5098 return true;
5099 n += 2;
5100 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5101 return false;
5102 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5103 if (token->type != CPP_CLOSE_SQUARE)
5104 return false;
5105 token = c_parser_peek_nth_token_raw (parser, n + 1);
5106 return token->type == CPP_CLOSE_SQUARE;
5109 static tree
5110 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5112 tree attributes = NULL_TREE;
5115 tree attrs = c_parser_std_attribute_specifier (parser, false);
5116 attributes = chainon (attributes, attrs);
5118 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5119 return attributes;
5122 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5123 says whether alignment specifiers are OK (only in cases that might
5124 be the type name of a compound literal).
5126 type-name:
5127 specifier-qualifier-list abstract-declarator[opt]
5130 struct c_type_name *
5131 c_parser_type_name (c_parser *parser, bool alignas_ok)
5133 struct c_declspecs *specs = build_null_declspecs ();
5134 struct c_declarator *declarator;
5135 struct c_type_name *ret;
5136 bool dummy = false;
5137 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5138 false, true, cla_prefer_type);
5139 if (!specs->declspecs_seen_p)
5141 c_parser_error (parser, "expected specifier-qualifier-list");
5142 return NULL;
5144 if (specs->type != error_mark_node)
5146 pending_xref_error ();
5147 finish_declspecs (specs);
5149 declarator = c_parser_declarator (parser,
5150 specs->typespec_kind != ctsk_none,
5151 C_DTR_ABSTRACT, &dummy);
5152 if (declarator == NULL)
5153 return NULL;
5154 ret = XOBNEW (&parser_obstack, struct c_type_name);
5155 ret->specs = specs;
5156 ret->declarator = declarator;
5157 return ret;
5160 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5162 initializer:
5163 assignment-expression
5164 { initializer-list }
5165 { initializer-list , }
5167 initializer-list:
5168 designation[opt] initializer
5169 initializer-list , designation[opt] initializer
5171 designation:
5172 designator-list =
5174 designator-list:
5175 designator
5176 designator-list designator
5178 designator:
5179 array-designator
5180 . identifier
5182 array-designator:
5183 [ constant-expression ]
5185 GNU extensions:
5187 initializer:
5190 designation:
5191 array-designator
5192 identifier :
5194 array-designator:
5195 [ constant-expression ... constant-expression ]
5197 Any expression without commas is accepted in the syntax for the
5198 constant-expressions, with non-constant expressions rejected later.
5200 This function is only used for top-level initializers; for nested
5201 ones, see c_parser_initval. */
5203 static struct c_expr
5204 c_parser_initializer (c_parser *parser)
5206 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5207 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5208 else
5210 struct c_expr ret;
5211 location_t loc = c_parser_peek_token (parser)->location;
5212 ret = c_parser_expr_no_commas (parser, NULL);
5213 if (TREE_CODE (ret.value) != STRING_CST
5214 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5215 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5216 return ret;
5220 /* The location of the last comma within the current initializer list,
5221 or UNKNOWN_LOCATION if not within one. */
5223 location_t last_init_list_comma;
5225 /* Parse a braced initializer list. TYPE is the type specified for a
5226 compound literal, and NULL_TREE for other initializers and for
5227 nested braced lists. NESTED_P is true for nested braced lists,
5228 false for the list of a compound literal or the list that is the
5229 top-level initializer in a declaration. */
5231 static struct c_expr
5232 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5233 struct obstack *outer_obstack)
5235 struct c_expr ret;
5236 struct obstack braced_init_obstack;
5237 location_t brace_loc = c_parser_peek_token (parser)->location;
5238 gcc_obstack_init (&braced_init_obstack);
5239 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5240 matching_braces braces;
5241 braces.consume_open (parser);
5242 if (nested_p)
5244 finish_implicit_inits (brace_loc, outer_obstack);
5245 push_init_level (brace_loc, 0, &braced_init_obstack);
5247 else
5248 really_start_incremental_init (type);
5249 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5251 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5253 else
5255 /* Parse a non-empty initializer list, possibly with a trailing
5256 comma. */
5257 while (true)
5259 c_parser_initelt (parser, &braced_init_obstack);
5260 if (parser->error)
5261 break;
5262 if (c_parser_next_token_is (parser, CPP_COMMA))
5264 last_init_list_comma = c_parser_peek_token (parser)->location;
5265 c_parser_consume_token (parser);
5267 else
5268 break;
5269 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5270 break;
5273 c_token *next_tok = c_parser_peek_token (parser);
5274 if (next_tok->type != CPP_CLOSE_BRACE)
5276 ret.set_error ();
5277 ret.original_code = ERROR_MARK;
5278 ret.original_type = NULL;
5279 braces.skip_until_found_close (parser);
5280 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5281 obstack_free (&braced_init_obstack, NULL);
5282 return ret;
5284 location_t close_loc = next_tok->location;
5285 c_parser_consume_token (parser);
5286 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5287 obstack_free (&braced_init_obstack, NULL);
5288 set_c_expr_source_range (&ret, brace_loc, close_loc);
5289 return ret;
5292 /* Parse a nested initializer, including designators. */
5294 static void
5295 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5297 /* Parse any designator or designator list. A single array
5298 designator may have the subsequent "=" omitted in GNU C, but a
5299 longer list or a structure member designator may not. */
5300 if (c_parser_next_token_is (parser, CPP_NAME)
5301 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5303 /* Old-style structure member designator. */
5304 set_init_label (c_parser_peek_token (parser)->location,
5305 c_parser_peek_token (parser)->value,
5306 c_parser_peek_token (parser)->location,
5307 braced_init_obstack);
5308 /* Use the colon as the error location. */
5309 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5310 "obsolete use of designated initializer with %<:%>");
5311 c_parser_consume_token (parser);
5312 c_parser_consume_token (parser);
5314 else
5316 /* des_seen is 0 if there have been no designators, 1 if there
5317 has been a single array designator and 2 otherwise. */
5318 int des_seen = 0;
5319 /* Location of a designator. */
5320 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5321 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5322 || c_parser_next_token_is (parser, CPP_DOT))
5324 int des_prev = des_seen;
5325 if (!des_seen)
5326 des_loc = c_parser_peek_token (parser)->location;
5327 if (des_seen < 2)
5328 des_seen++;
5329 if (c_parser_next_token_is (parser, CPP_DOT))
5331 des_seen = 2;
5332 c_parser_consume_token (parser);
5333 if (c_parser_next_token_is (parser, CPP_NAME))
5335 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5336 c_parser_peek_token (parser)->location,
5337 braced_init_obstack);
5338 c_parser_consume_token (parser);
5340 else
5342 struct c_expr init;
5343 init.set_error ();
5344 init.original_code = ERROR_MARK;
5345 init.original_type = NULL;
5346 c_parser_error (parser, "expected identifier");
5347 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5348 process_init_element (input_location, init, false,
5349 braced_init_obstack);
5350 return;
5353 else
5355 tree first, second;
5356 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5357 location_t array_index_loc = UNKNOWN_LOCATION;
5358 /* ??? Following the old parser, [ objc-receiver
5359 objc-message-args ] is accepted as an initializer,
5360 being distinguished from a designator by what follows
5361 the first assignment expression inside the square
5362 brackets, but after a first array designator a
5363 subsequent square bracket is for Objective-C taken to
5364 start an expression, using the obsolete form of
5365 designated initializer without '=', rather than
5366 possibly being a second level of designation: in LALR
5367 terms, the '[' is shifted rather than reducing
5368 designator to designator-list. */
5369 if (des_prev == 1 && c_dialect_objc ())
5371 des_seen = des_prev;
5372 break;
5374 if (des_prev == 0 && c_dialect_objc ())
5376 /* This might be an array designator or an
5377 Objective-C message expression. If the former,
5378 continue parsing here; if the latter, parse the
5379 remainder of the initializer given the starting
5380 primary-expression. ??? It might make sense to
5381 distinguish when des_prev == 1 as well; see
5382 previous comment. */
5383 tree rec, args;
5384 struct c_expr mexpr;
5385 c_parser_consume_token (parser);
5386 if (c_parser_peek_token (parser)->type == CPP_NAME
5387 && ((c_parser_peek_token (parser)->id_kind
5388 == C_ID_TYPENAME)
5389 || (c_parser_peek_token (parser)->id_kind
5390 == C_ID_CLASSNAME)))
5392 /* Type name receiver. */
5393 tree id = c_parser_peek_token (parser)->value;
5394 c_parser_consume_token (parser);
5395 rec = objc_get_class_reference (id);
5396 goto parse_message_args;
5398 first = c_parser_expr_no_commas (parser, NULL).value;
5399 mark_exp_read (first);
5400 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5401 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5402 goto array_desig_after_first;
5403 /* Expression receiver. So far only one part
5404 without commas has been parsed; there might be
5405 more of the expression. */
5406 rec = first;
5407 while (c_parser_next_token_is (parser, CPP_COMMA))
5409 struct c_expr next;
5410 location_t comma_loc, exp_loc;
5411 comma_loc = c_parser_peek_token (parser)->location;
5412 c_parser_consume_token (parser);
5413 exp_loc = c_parser_peek_token (parser)->location;
5414 next = c_parser_expr_no_commas (parser, NULL);
5415 next = convert_lvalue_to_rvalue (exp_loc, next,
5416 true, true);
5417 rec = build_compound_expr (comma_loc, rec, next.value);
5419 parse_message_args:
5420 /* Now parse the objc-message-args. */
5421 args = c_parser_objc_message_args (parser);
5422 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5423 "expected %<]%>");
5424 mexpr.value
5425 = objc_build_message_expr (rec, args);
5426 mexpr.original_code = ERROR_MARK;
5427 mexpr.original_type = NULL;
5428 /* Now parse and process the remainder of the
5429 initializer, starting with this message
5430 expression as a primary-expression. */
5431 c_parser_initval (parser, &mexpr, braced_init_obstack);
5432 return;
5434 c_parser_consume_token (parser);
5435 array_index_loc = c_parser_peek_token (parser)->location;
5436 first = c_parser_expr_no_commas (parser, NULL).value;
5437 mark_exp_read (first);
5438 array_desig_after_first:
5439 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5441 ellipsis_loc = c_parser_peek_token (parser)->location;
5442 c_parser_consume_token (parser);
5443 second = c_parser_expr_no_commas (parser, NULL).value;
5444 mark_exp_read (second);
5446 else
5447 second = NULL_TREE;
5448 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5450 c_parser_consume_token (parser);
5451 set_init_index (array_index_loc, first, second,
5452 braced_init_obstack);
5453 if (second)
5454 pedwarn (ellipsis_loc, OPT_Wpedantic,
5455 "ISO C forbids specifying range of elements to initialize");
5457 else
5458 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5459 "expected %<]%>");
5462 if (des_seen >= 1)
5464 if (c_parser_next_token_is (parser, CPP_EQ))
5466 pedwarn_c90 (des_loc, OPT_Wpedantic,
5467 "ISO C90 forbids specifying subobject "
5468 "to initialize");
5469 c_parser_consume_token (parser);
5471 else
5473 if (des_seen == 1)
5474 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5475 "obsolete use of designated initializer without %<=%>");
5476 else
5478 struct c_expr init;
5479 init.set_error ();
5480 init.original_code = ERROR_MARK;
5481 init.original_type = NULL;
5482 c_parser_error (parser, "expected %<=%>");
5483 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5484 process_init_element (input_location, init, false,
5485 braced_init_obstack);
5486 return;
5491 c_parser_initval (parser, NULL, braced_init_obstack);
5494 /* Parse a nested initializer; as c_parser_initializer but parses
5495 initializers within braced lists, after any designators have been
5496 applied. If AFTER is not NULL then it is an Objective-C message
5497 expression which is the primary-expression starting the
5498 initializer. */
5500 static void
5501 c_parser_initval (c_parser *parser, struct c_expr *after,
5502 struct obstack * braced_init_obstack)
5504 struct c_expr init;
5505 gcc_assert (!after || c_dialect_objc ());
5506 location_t loc = c_parser_peek_token (parser)->location;
5508 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5509 init = c_parser_braced_init (parser, NULL_TREE, true,
5510 braced_init_obstack);
5511 else
5513 init = c_parser_expr_no_commas (parser, after);
5514 if (init.value != NULL_TREE
5515 && TREE_CODE (init.value) != STRING_CST
5516 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5517 init = convert_lvalue_to_rvalue (loc, init, true, true);
5519 process_init_element (loc, init, false, braced_init_obstack);
5522 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5523 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5525 compound-statement:
5526 { block-item-list[opt] }
5527 { label-declarations block-item-list }
5529 block-item-list:
5530 block-item
5531 block-item-list block-item
5533 block-item:
5534 label
5535 nested-declaration
5536 statement
5538 nested-declaration:
5539 declaration
5541 GNU extensions:
5543 compound-statement:
5544 { label-declarations block-item-list }
5546 nested-declaration:
5547 __extension__ nested-declaration
5548 nested-function-definition
5550 label-declarations:
5551 label-declaration
5552 label-declarations label-declaration
5554 label-declaration:
5555 __label__ identifier-list ;
5557 Allowing the mixing of declarations and code is new in C99. The
5558 GNU syntax also permits (not shown above) labels at the end of
5559 compound statements, which yield an error. We don't allow labels
5560 on declarations; this might seem like a natural extension, but
5561 there would be a conflict between gnu-attributes on the label and
5562 prefix gnu-attributes on the declaration. ??? The syntax follows the
5563 old parser in requiring something after label declarations.
5564 Although they are erroneous if the labels declared aren't defined,
5565 is it useful for the syntax to be this way?
5567 OpenACC:
5569 block-item:
5570 openacc-directive
5572 openacc-directive:
5573 update-directive
5575 OpenMP:
5577 block-item:
5578 openmp-directive
5580 openmp-directive:
5581 barrier-directive
5582 flush-directive
5583 taskwait-directive
5584 taskyield-directive
5585 cancel-directive
5586 cancellation-point-directive */
5588 static tree
5589 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5591 tree stmt;
5592 location_t brace_loc;
5593 brace_loc = c_parser_peek_token (parser)->location;
5594 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5596 /* Ensure a scope is entered and left anyway to avoid confusion
5597 if we have just prepared to enter a function body. */
5598 stmt = c_begin_compound_stmt (true);
5599 c_end_compound_stmt (brace_loc, stmt, true);
5600 return error_mark_node;
5602 stmt = c_begin_compound_stmt (true);
5603 location_t end_loc = c_parser_compound_statement_nostart (parser);
5604 if (endlocp)
5605 *endlocp = end_loc;
5607 return c_end_compound_stmt (brace_loc, stmt, true);
5610 /* Parse a compound statement except for the opening brace. This is
5611 used for parsing both compound statements and statement expressions
5612 (which follow different paths to handling the opening). */
5614 static location_t
5615 c_parser_compound_statement_nostart (c_parser *parser)
5617 bool last_stmt = false;
5618 bool last_label = false;
5619 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5620 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5621 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5623 location_t endloc = c_parser_peek_token (parser)->location;
5624 add_debug_begin_stmt (endloc);
5625 c_parser_consume_token (parser);
5626 return endloc;
5628 mark_valid_location_for_stdc_pragma (true);
5629 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5631 /* Read zero or more forward-declarations for labels that nested
5632 functions can jump to. */
5633 mark_valid_location_for_stdc_pragma (false);
5634 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5636 label_loc = c_parser_peek_token (parser)->location;
5637 c_parser_consume_token (parser);
5638 /* Any identifiers, including those declared as type names,
5639 are OK here. */
5640 while (true)
5642 tree label;
5643 if (c_parser_next_token_is_not (parser, CPP_NAME))
5645 c_parser_error (parser, "expected identifier");
5646 break;
5648 label
5649 = declare_label (c_parser_peek_token (parser)->value);
5650 C_DECLARED_LABEL_FLAG (label) = 1;
5651 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5652 c_parser_consume_token (parser);
5653 if (c_parser_next_token_is (parser, CPP_COMMA))
5654 c_parser_consume_token (parser);
5655 else
5656 break;
5658 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5660 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5662 /* We must now have at least one statement, label or declaration. */
5663 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5665 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5666 c_parser_error (parser, "expected declaration or statement");
5667 location_t endloc = c_parser_peek_token (parser)->location;
5668 c_parser_consume_token (parser);
5669 return endloc;
5671 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5673 location_t loc = c_parser_peek_token (parser)->location;
5674 loc = expansion_point_location_if_in_system_header (loc);
5675 /* Standard attributes may start a label, statement or declaration. */
5676 bool have_std_attrs
5677 = c_parser_nth_token_starts_std_attributes (parser, 1);
5678 tree std_attrs = NULL_TREE;
5679 if (have_std_attrs)
5680 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5681 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5682 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5683 || (c_parser_next_token_is (parser, CPP_NAME)
5684 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5686 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5687 label_loc = c_parser_peek_2nd_token (parser)->location;
5688 else
5689 label_loc = c_parser_peek_token (parser)->location;
5690 last_label = true;
5691 last_stmt = false;
5692 mark_valid_location_for_stdc_pragma (false);
5693 c_parser_label (parser, std_attrs);
5695 else if (c_parser_next_tokens_start_declaration (parser)
5696 || (have_std_attrs
5697 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5699 if (last_label)
5700 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5701 "a label can only be part of a statement and "
5702 "a declaration is not a statement");
5704 mark_valid_location_for_stdc_pragma (false);
5705 bool fallthru_attr_p = false;
5706 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5707 true, true, true, NULL,
5708 NULL, have_std_attrs, std_attrs,
5709 NULL, &fallthru_attr_p);
5711 if (last_stmt && !fallthru_attr_p)
5712 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5713 "ISO C90 forbids mixed declarations and code");
5714 last_stmt = fallthru_attr_p;
5715 last_label = false;
5717 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5719 /* __extension__ can start a declaration, but is also an
5720 unary operator that can start an expression. Consume all
5721 but the last of a possible series of __extension__ to
5722 determine which. If standard attributes have already
5723 been seen, it must start a statement, not a declaration,
5724 but standard attributes starting a declaration may appear
5725 after __extension__. */
5726 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5727 && (c_parser_peek_2nd_token (parser)->keyword
5728 == RID_EXTENSION))
5729 c_parser_consume_token (parser);
5730 if (!have_std_attrs
5731 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5732 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5734 int ext;
5735 ext = disable_extension_diagnostics ();
5736 c_parser_consume_token (parser);
5737 last_label = false;
5738 mark_valid_location_for_stdc_pragma (false);
5739 c_parser_declaration_or_fndef (parser, true, true, true, true,
5740 true);
5741 /* Following the old parser, __extension__ does not
5742 disable this diagnostic. */
5743 restore_extension_diagnostics (ext);
5744 if (last_stmt)
5745 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5746 "ISO C90 forbids mixed declarations and code");
5747 last_stmt = false;
5749 else
5750 goto statement;
5752 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5754 if (have_std_attrs)
5755 c_parser_error (parser, "expected declaration or statement");
5756 /* External pragmas, and some omp pragmas, are not associated
5757 with regular c code, and so are not to be considered statements
5758 syntactically. This ensures that the user doesn't put them
5759 places that would turn into syntax errors if the directive
5760 were ignored. */
5761 if (c_parser_pragma (parser,
5762 last_label ? pragma_stmt : pragma_compound,
5763 NULL))
5764 last_label = false, last_stmt = true;
5766 else if (c_parser_next_token_is (parser, CPP_EOF))
5768 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5769 c_parser_error (parser, "expected declaration or statement");
5770 return c_parser_peek_token (parser)->location;
5772 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5774 if (parser->in_if_block)
5776 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5777 error_at (loc, "expected %<}%> before %<else%>");
5778 return c_parser_peek_token (parser)->location;
5780 else
5782 error_at (loc, "%<else%> without a previous %<if%>");
5783 c_parser_consume_token (parser);
5784 continue;
5787 else
5789 statement:
5790 c_warn_unused_attributes (std_attrs);
5791 last_label = false;
5792 last_stmt = true;
5793 mark_valid_location_for_stdc_pragma (false);
5794 c_parser_statement_after_labels (parser, NULL);
5797 parser->error = false;
5799 if (last_label)
5800 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5801 location_t endloc = c_parser_peek_token (parser)->location;
5802 c_parser_consume_token (parser);
5803 /* Restore the value we started with. */
5804 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5805 return endloc;
5808 /* Parse all consecutive labels, possibly preceded by standard
5809 attributes. In this context, a statement is required, not a
5810 declaration, so attributes must be followed by a statement that is
5811 not just a semicolon. */
5813 static void
5814 c_parser_all_labels (c_parser *parser)
5816 tree std_attrs = NULL;
5817 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5819 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5820 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5821 c_parser_error (parser, "expected statement");
5823 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5824 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5825 || (c_parser_next_token_is (parser, CPP_NAME)
5826 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5828 c_parser_label (parser, std_attrs);
5829 std_attrs = NULL;
5830 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5832 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5833 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5834 c_parser_error (parser, "expected statement");
5837 if (std_attrs)
5838 c_warn_unused_attributes (std_attrs);
5841 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5843 label:
5844 identifier : gnu-attributes[opt]
5845 case constant-expression :
5846 default :
5848 GNU extensions:
5850 label:
5851 case constant-expression ... constant-expression :
5853 The use of gnu-attributes on labels is a GNU extension. The syntax in
5854 GNU C accepts any expressions without commas, non-constant
5855 expressions being rejected later. Any standard
5856 attribute-specifier-sequence before the first label has been parsed
5857 in the caller, to distinguish statements from declarations. Any
5858 attribute-specifier-sequence after the label is parsed in this
5859 function. */
5860 static void
5861 c_parser_label (c_parser *parser, tree std_attrs)
5863 location_t loc1 = c_parser_peek_token (parser)->location;
5864 tree label = NULL_TREE;
5866 /* Remember whether this case or a user-defined label is allowed to fall
5867 through to. */
5868 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5870 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5872 tree exp1, exp2;
5873 c_parser_consume_token (parser);
5874 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5875 if (c_parser_next_token_is (parser, CPP_COLON))
5877 c_parser_consume_token (parser);
5878 label = do_case (loc1, exp1, NULL_TREE);
5880 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5882 c_parser_consume_token (parser);
5883 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5884 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5885 label = do_case (loc1, exp1, exp2);
5887 else
5888 c_parser_error (parser, "expected %<:%> or %<...%>");
5890 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5892 c_parser_consume_token (parser);
5893 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5894 label = do_case (loc1, NULL_TREE, NULL_TREE);
5896 else
5898 tree name = c_parser_peek_token (parser)->value;
5899 tree tlab;
5900 tree attrs;
5901 location_t loc2 = c_parser_peek_token (parser)->location;
5902 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5903 c_parser_consume_token (parser);
5904 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5905 c_parser_consume_token (parser);
5906 attrs = c_parser_gnu_attributes (parser);
5907 tlab = define_label (loc2, name);
5908 if (tlab)
5910 decl_attributes (&tlab, attrs, 0);
5911 decl_attributes (&tlab, std_attrs, 0);
5912 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5914 if (attrs
5915 && c_parser_next_tokens_start_declaration (parser))
5916 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5917 " label and declaration appertains to the label");
5919 if (label)
5921 if (TREE_CODE (label) == LABEL_EXPR)
5922 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5923 else
5924 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5928 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5930 statement:
5931 labeled-statement
5932 attribute-specifier-sequence[opt] compound-statement
5933 expression-statement
5934 attribute-specifier-sequence[opt] selection-statement
5935 attribute-specifier-sequence[opt] iteration-statement
5936 attribute-specifier-sequence[opt] jump-statement
5938 labeled-statement:
5939 attribute-specifier-sequence[opt] label statement
5941 expression-statement:
5942 expression[opt] ;
5943 attribute-specifier-sequence expression ;
5945 selection-statement:
5946 if-statement
5947 switch-statement
5949 iteration-statement:
5950 while-statement
5951 do-statement
5952 for-statement
5954 jump-statement:
5955 goto identifier ;
5956 continue ;
5957 break ;
5958 return expression[opt] ;
5960 GNU extensions:
5962 statement:
5963 attribute-specifier-sequence[opt] asm-statement
5965 jump-statement:
5966 goto * expression ;
5968 expression-statement:
5969 gnu-attributes ;
5971 Objective-C:
5973 statement:
5974 attribute-specifier-sequence[opt] objc-throw-statement
5975 attribute-specifier-sequence[opt] objc-try-catch-statement
5976 attribute-specifier-sequence[opt] objc-synchronized-statement
5978 objc-throw-statement:
5979 @throw expression ;
5980 @throw ;
5982 OpenACC:
5984 statement:
5985 attribute-specifier-sequence[opt] openacc-construct
5987 openacc-construct:
5988 parallel-construct
5989 kernels-construct
5990 data-construct
5991 loop-construct
5993 parallel-construct:
5994 parallel-directive structured-block
5996 kernels-construct:
5997 kernels-directive structured-block
5999 data-construct:
6000 data-directive structured-block
6002 loop-construct:
6003 loop-directive structured-block
6005 OpenMP:
6007 statement:
6008 attribute-specifier-sequence[opt] openmp-construct
6010 openmp-construct:
6011 parallel-construct
6012 for-construct
6013 simd-construct
6014 for-simd-construct
6015 sections-construct
6016 single-construct
6017 parallel-for-construct
6018 parallel-for-simd-construct
6019 parallel-sections-construct
6020 master-construct
6021 critical-construct
6022 atomic-construct
6023 ordered-construct
6025 parallel-construct:
6026 parallel-directive structured-block
6028 for-construct:
6029 for-directive iteration-statement
6031 simd-construct:
6032 simd-directive iteration-statements
6034 for-simd-construct:
6035 for-simd-directive iteration-statements
6037 sections-construct:
6038 sections-directive section-scope
6040 single-construct:
6041 single-directive structured-block
6043 parallel-for-construct:
6044 parallel-for-directive iteration-statement
6046 parallel-for-simd-construct:
6047 parallel-for-simd-directive iteration-statement
6049 parallel-sections-construct:
6050 parallel-sections-directive section-scope
6052 master-construct:
6053 master-directive structured-block
6055 critical-construct:
6056 critical-directive structured-block
6058 atomic-construct:
6059 atomic-directive expression-statement
6061 ordered-construct:
6062 ordered-directive structured-block
6064 Transactional Memory:
6066 statement:
6067 attribute-specifier-sequence[opt] transaction-statement
6068 attribute-specifier-sequence[opt] transaction-cancel-statement
6070 IF_P is used to track whether there's a (possibly labeled) if statement
6071 which is not enclosed in braces and has an else clause. This is used to
6072 implement -Wparentheses. */
6074 static void
6075 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6077 c_parser_all_labels (parser);
6078 if (loc_after_labels)
6079 *loc_after_labels = c_parser_peek_token (parser)->location;
6080 c_parser_statement_after_labels (parser, if_p, NULL);
6083 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6084 of if-else-if conditions. All labels and standard attributes have
6085 been parsed in the caller.
6087 IF_P is used to track whether there's a (possibly labeled) if statement
6088 which is not enclosed in braces and has an else clause. This is used to
6089 implement -Wparentheses. */
6091 static void
6092 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6093 vec<tree> *chain)
6095 location_t loc = c_parser_peek_token (parser)->location;
6096 tree stmt = NULL_TREE;
6097 bool in_if_block = parser->in_if_block;
6098 parser->in_if_block = false;
6099 if (if_p != NULL)
6100 *if_p = false;
6102 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6103 add_debug_begin_stmt (loc);
6105 restart:
6106 switch (c_parser_peek_token (parser)->type)
6108 case CPP_OPEN_BRACE:
6109 add_stmt (c_parser_compound_statement (parser));
6110 break;
6111 case CPP_KEYWORD:
6112 switch (c_parser_peek_token (parser)->keyword)
6114 case RID_IF:
6115 c_parser_if_statement (parser, if_p, chain);
6116 break;
6117 case RID_SWITCH:
6118 c_parser_switch_statement (parser, if_p);
6119 break;
6120 case RID_WHILE:
6121 c_parser_while_statement (parser, false, 0, if_p);
6122 break;
6123 case RID_DO:
6124 c_parser_do_statement (parser, false, 0);
6125 break;
6126 case RID_FOR:
6127 c_parser_for_statement (parser, false, 0, if_p);
6128 break;
6129 case RID_GOTO:
6130 c_parser_consume_token (parser);
6131 if (c_parser_next_token_is (parser, CPP_NAME))
6133 stmt = c_finish_goto_label (loc,
6134 c_parser_peek_token (parser)->value);
6135 c_parser_consume_token (parser);
6137 else if (c_parser_next_token_is (parser, CPP_MULT))
6139 struct c_expr val;
6141 c_parser_consume_token (parser);
6142 val = c_parser_expression (parser);
6143 val = convert_lvalue_to_rvalue (loc, val, false, true);
6144 stmt = c_finish_goto_ptr (loc, val.value);
6146 else
6147 c_parser_error (parser, "expected identifier or %<*%>");
6148 goto expect_semicolon;
6149 case RID_CONTINUE:
6150 c_parser_consume_token (parser);
6151 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6152 goto expect_semicolon;
6153 case RID_BREAK:
6154 c_parser_consume_token (parser);
6155 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6156 goto expect_semicolon;
6157 case RID_RETURN:
6158 c_parser_consume_token (parser);
6159 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6161 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6162 c_parser_consume_token (parser);
6164 else
6166 location_t xloc = c_parser_peek_token (parser)->location;
6167 struct c_expr expr = c_parser_expression_conv (parser);
6168 mark_exp_read (expr.value);
6169 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6170 expr.value, expr.original_type);
6171 goto expect_semicolon;
6173 break;
6174 case RID_ASM:
6175 stmt = c_parser_asm_statement (parser);
6176 break;
6177 case RID_TRANSACTION_ATOMIC:
6178 case RID_TRANSACTION_RELAXED:
6179 stmt = c_parser_transaction (parser,
6180 c_parser_peek_token (parser)->keyword);
6181 break;
6182 case RID_TRANSACTION_CANCEL:
6183 stmt = c_parser_transaction_cancel (parser);
6184 goto expect_semicolon;
6185 case RID_AT_THROW:
6186 gcc_assert (c_dialect_objc ());
6187 c_parser_consume_token (parser);
6188 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6190 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6191 c_parser_consume_token (parser);
6193 else
6195 struct c_expr expr = c_parser_expression (parser);
6196 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6197 expr.value = c_fully_fold (expr.value, false, NULL);
6198 stmt = objc_build_throw_stmt (loc, expr.value);
6199 goto expect_semicolon;
6201 break;
6202 case RID_AT_TRY:
6203 gcc_assert (c_dialect_objc ());
6204 c_parser_objc_try_catch_finally_statement (parser);
6205 break;
6206 case RID_AT_SYNCHRONIZED:
6207 gcc_assert (c_dialect_objc ());
6208 c_parser_objc_synchronized_statement (parser);
6209 break;
6210 case RID_ATTRIBUTE:
6212 /* Allow '__attribute__((fallthrough));'. */
6213 tree attrs = c_parser_gnu_attributes (parser);
6214 if (attribute_fallthrough_p (attrs))
6216 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6218 tree fn = build_call_expr_internal_loc (loc,
6219 IFN_FALLTHROUGH,
6220 void_type_node, 0);
6221 add_stmt (fn);
6222 /* Eat the ';'. */
6223 c_parser_consume_token (parser);
6225 else
6226 warning_at (loc, OPT_Wattributes,
6227 "%<fallthrough%> attribute not followed "
6228 "by %<;%>");
6230 else if (attrs != NULL_TREE)
6231 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6232 " can be applied to a null statement");
6233 break;
6235 default:
6236 goto expr_stmt;
6238 break;
6239 case CPP_SEMICOLON:
6240 c_parser_consume_token (parser);
6241 break;
6242 case CPP_CLOSE_PAREN:
6243 case CPP_CLOSE_SQUARE:
6244 /* Avoid infinite loop in error recovery:
6245 c_parser_skip_until_found stops at a closing nesting
6246 delimiter without consuming it, but here we need to consume
6247 it to proceed further. */
6248 c_parser_error (parser, "expected statement");
6249 c_parser_consume_token (parser);
6250 break;
6251 case CPP_PRAGMA:
6252 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6253 goto restart;
6254 break;
6255 default:
6256 expr_stmt:
6257 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6258 expect_semicolon:
6259 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6260 break;
6262 /* Two cases cannot and do not have line numbers associated: If stmt
6263 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6264 cannot hold line numbers. But that's OK because the statement
6265 will either be changed to a MODIFY_EXPR during gimplification of
6266 the statement expr, or discarded. If stmt was compound, but
6267 without new variables, we will have skipped the creation of a
6268 BIND and will have a bare STATEMENT_LIST. But that's OK because
6269 (recursively) all of the component statements should already have
6270 line numbers assigned. ??? Can we discard no-op statements
6271 earlier? */
6272 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6273 protected_set_expr_location (stmt, loc);
6275 parser->in_if_block = in_if_block;
6278 /* Parse the condition from an if, do, while or for statements. */
6280 static tree
6281 c_parser_condition (c_parser *parser)
6283 location_t loc = c_parser_peek_token (parser)->location;
6284 tree cond;
6285 cond = c_parser_expression_conv (parser).value;
6286 cond = c_objc_common_truthvalue_conversion (loc, cond);
6287 cond = c_fully_fold (cond, false, NULL);
6288 if (warn_sequence_point)
6289 verify_sequence_points (cond);
6290 return cond;
6293 /* Parse a parenthesized condition from an if, do or while statement.
6295 condition:
6296 ( expression )
6298 static tree
6299 c_parser_paren_condition (c_parser *parser)
6301 tree cond;
6302 matching_parens parens;
6303 if (!parens.require_open (parser))
6304 return error_mark_node;
6305 cond = c_parser_condition (parser);
6306 parens.skip_until_found_close (parser);
6307 return cond;
6310 /* Parse a statement which is a block in C99.
6312 IF_P is used to track whether there's a (possibly labeled) if statement
6313 which is not enclosed in braces and has an else clause. This is used to
6314 implement -Wparentheses. */
6316 static tree
6317 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6318 location_t *loc_after_labels)
6320 tree block = c_begin_compound_stmt (flag_isoc99);
6321 location_t loc = c_parser_peek_token (parser)->location;
6322 c_parser_statement (parser, if_p, loc_after_labels);
6323 return c_end_compound_stmt (loc, block, flag_isoc99);
6326 /* Parse the body of an if statement. This is just parsing a
6327 statement but (a) it is a block in C99, (b) we track whether the
6328 body is an if statement for the sake of -Wparentheses warnings, (c)
6329 we handle an empty body specially for the sake of -Wempty-body
6330 warnings, and (d) we call parser_compound_statement directly
6331 because c_parser_statement_after_labels resets
6332 parser->in_if_block.
6334 IF_P is used to track whether there's a (possibly labeled) if statement
6335 which is not enclosed in braces and has an else clause. This is used to
6336 implement -Wparentheses. */
6338 static tree
6339 c_parser_if_body (c_parser *parser, bool *if_p,
6340 const token_indent_info &if_tinfo)
6342 tree block = c_begin_compound_stmt (flag_isoc99);
6343 location_t body_loc = c_parser_peek_token (parser)->location;
6344 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6345 token_indent_info body_tinfo
6346 = get_token_indent_info (c_parser_peek_token (parser));
6348 c_parser_all_labels (parser);
6349 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6351 location_t loc = c_parser_peek_token (parser)->location;
6352 add_stmt (build_empty_stmt (loc));
6353 c_parser_consume_token (parser);
6354 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6355 warning_at (loc, OPT_Wempty_body,
6356 "suggest braces around empty body in an %<if%> statement");
6358 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6359 add_stmt (c_parser_compound_statement (parser));
6360 else
6362 body_loc_after_labels = c_parser_peek_token (parser)->location;
6363 c_parser_statement_after_labels (parser, if_p);
6366 token_indent_info next_tinfo
6367 = get_token_indent_info (c_parser_peek_token (parser));
6368 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6369 if (body_loc_after_labels != UNKNOWN_LOCATION
6370 && next_tinfo.type != CPP_SEMICOLON)
6371 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6372 if_tinfo.location, RID_IF);
6374 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6377 /* Parse the else body of an if statement. This is just parsing a
6378 statement but (a) it is a block in C99, (b) we handle an empty body
6379 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6380 of if-else-if conditions. */
6382 static tree
6383 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6384 vec<tree> *chain)
6386 location_t body_loc = c_parser_peek_token (parser)->location;
6387 tree block = c_begin_compound_stmt (flag_isoc99);
6388 token_indent_info body_tinfo
6389 = get_token_indent_info (c_parser_peek_token (parser));
6390 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6392 c_parser_all_labels (parser);
6393 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6395 location_t loc = c_parser_peek_token (parser)->location;
6396 warning_at (loc,
6397 OPT_Wempty_body,
6398 "suggest braces around empty body in an %<else%> statement");
6399 add_stmt (build_empty_stmt (loc));
6400 c_parser_consume_token (parser);
6402 else
6404 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6405 body_loc_after_labels = c_parser_peek_token (parser)->location;
6406 c_parser_statement_after_labels (parser, NULL, chain);
6409 token_indent_info next_tinfo
6410 = get_token_indent_info (c_parser_peek_token (parser));
6411 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6412 if (body_loc_after_labels != UNKNOWN_LOCATION
6413 && next_tinfo.type != CPP_SEMICOLON)
6414 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6415 else_tinfo.location, RID_ELSE);
6417 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6420 /* We might need to reclassify any previously-lexed identifier, e.g.
6421 when we've left a for loop with an if-statement without else in the
6422 body - we might have used a wrong scope for the token. See PR67784. */
6424 static void
6425 c_parser_maybe_reclassify_token (c_parser *parser)
6427 if (c_parser_next_token_is (parser, CPP_NAME))
6429 c_token *token = c_parser_peek_token (parser);
6431 if (token->id_kind != C_ID_CLASSNAME)
6433 tree decl = lookup_name (token->value);
6435 token->id_kind = C_ID_ID;
6436 if (decl)
6438 if (TREE_CODE (decl) == TYPE_DECL)
6439 token->id_kind = C_ID_TYPENAME;
6441 else if (c_dialect_objc ())
6443 tree objc_interface_decl = objc_is_class_name (token->value);
6444 /* Objective-C class names are in the same namespace as
6445 variables and typedefs, and hence are shadowed by local
6446 declarations. */
6447 if (objc_interface_decl)
6449 token->value = objc_interface_decl;
6450 token->id_kind = C_ID_CLASSNAME;
6457 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6459 if-statement:
6460 if ( expression ) statement
6461 if ( expression ) statement else statement
6463 CHAIN is a vector of if-else-if conditions.
6464 IF_P is used to track whether there's a (possibly labeled) if statement
6465 which is not enclosed in braces and has an else clause. This is used to
6466 implement -Wparentheses. */
6468 static void
6469 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6471 tree block;
6472 location_t loc;
6473 tree cond;
6474 bool nested_if = false;
6475 tree first_body, second_body;
6476 bool in_if_block;
6478 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6479 token_indent_info if_tinfo
6480 = get_token_indent_info (c_parser_peek_token (parser));
6481 c_parser_consume_token (parser);
6482 block = c_begin_compound_stmt (flag_isoc99);
6483 loc = c_parser_peek_token (parser)->location;
6484 cond = c_parser_paren_condition (parser);
6485 in_if_block = parser->in_if_block;
6486 parser->in_if_block = true;
6487 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6488 parser->in_if_block = in_if_block;
6490 if (warn_duplicated_cond)
6491 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6493 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6495 token_indent_info else_tinfo
6496 = get_token_indent_info (c_parser_peek_token (parser));
6497 c_parser_consume_token (parser);
6498 if (warn_duplicated_cond)
6500 if (c_parser_next_token_is_keyword (parser, RID_IF)
6501 && chain == NULL)
6503 /* We've got "if (COND) else if (COND2)". Start the
6504 condition chain and add COND as the first element. */
6505 chain = new vec<tree> ();
6506 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6507 chain->safe_push (cond);
6509 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6510 /* This is if-else without subsequent if. Zap the condition
6511 chain; we would have already warned at this point. */
6512 vec_free (chain);
6514 second_body = c_parser_else_body (parser, else_tinfo, chain);
6515 /* Set IF_P to true to indicate that this if statement has an
6516 else clause. This may trigger the Wparentheses warning
6517 below when we get back up to the parent if statement. */
6518 if (if_p != NULL)
6519 *if_p = true;
6521 else
6523 second_body = NULL_TREE;
6525 /* Diagnose an ambiguous else if if-then-else is nested inside
6526 if-then. */
6527 if (nested_if)
6528 warning_at (loc, OPT_Wdangling_else,
6529 "suggest explicit braces to avoid ambiguous %<else%>");
6531 if (warn_duplicated_cond)
6532 /* This if statement does not have an else clause. We don't
6533 need the condition chain anymore. */
6534 vec_free (chain);
6536 c_finish_if_stmt (loc, cond, first_body, second_body);
6537 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6539 c_parser_maybe_reclassify_token (parser);
6542 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6544 switch-statement:
6545 switch (expression) statement
6548 static void
6549 c_parser_switch_statement (c_parser *parser, bool *if_p)
6551 struct c_expr ce;
6552 tree block, expr, body;
6553 unsigned char save_in_statement;
6554 location_t switch_loc = c_parser_peek_token (parser)->location;
6555 location_t switch_cond_loc;
6556 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6557 c_parser_consume_token (parser);
6558 block = c_begin_compound_stmt (flag_isoc99);
6559 bool explicit_cast_p = false;
6560 matching_parens parens;
6561 if (parens.require_open (parser))
6563 switch_cond_loc = c_parser_peek_token (parser)->location;
6564 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6565 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6566 explicit_cast_p = true;
6567 ce = c_parser_expression (parser);
6568 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6569 expr = ce.value;
6570 /* ??? expr has no valid location? */
6571 parens.skip_until_found_close (parser);
6573 else
6575 switch_cond_loc = UNKNOWN_LOCATION;
6576 expr = error_mark_node;
6577 ce.original_type = error_mark_node;
6579 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6580 save_in_statement = in_statement;
6581 in_statement |= IN_SWITCH_STMT;
6582 location_t loc_after_labels;
6583 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6584 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6585 location_t next_loc = c_parser_peek_token (parser)->location;
6586 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6587 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6588 RID_SWITCH);
6589 c_finish_switch (body, ce.original_type);
6590 in_statement = save_in_statement;
6591 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6592 c_parser_maybe_reclassify_token (parser);
6595 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6597 while-statement:
6598 while (expression) statement
6600 IF_P is used to track whether there's a (possibly labeled) if statement
6601 which is not enclosed in braces and has an else clause. This is used to
6602 implement -Wparentheses. */
6604 static void
6605 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6606 bool *if_p)
6608 tree block, cond, body;
6609 unsigned char save_in_statement;
6610 location_t loc;
6611 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6612 token_indent_info while_tinfo
6613 = get_token_indent_info (c_parser_peek_token (parser));
6614 c_parser_consume_token (parser);
6615 block = c_begin_compound_stmt (flag_isoc99);
6616 loc = c_parser_peek_token (parser)->location;
6617 cond = c_parser_paren_condition (parser);
6618 if (ivdep && cond != error_mark_node)
6619 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6620 build_int_cst (integer_type_node,
6621 annot_expr_ivdep_kind),
6622 integer_zero_node);
6623 if (unroll && cond != error_mark_node)
6624 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6625 build_int_cst (integer_type_node,
6626 annot_expr_unroll_kind),
6627 build_int_cst (integer_type_node, unroll));
6628 save_in_statement = in_statement;
6629 in_statement = IN_ITERATION_STMT;
6631 token_indent_info body_tinfo
6632 = get_token_indent_info (c_parser_peek_token (parser));
6634 location_t loc_after_labels;
6635 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6636 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6637 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6638 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6639 c_parser_maybe_reclassify_token (parser);
6641 token_indent_info next_tinfo
6642 = get_token_indent_info (c_parser_peek_token (parser));
6643 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6645 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6646 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6647 while_tinfo.location, RID_WHILE);
6649 in_statement = save_in_statement;
6652 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6654 do-statement:
6655 do statement while ( expression ) ;
6658 static void
6659 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6661 tree block, cond, body;
6662 unsigned char save_in_statement;
6663 location_t loc;
6664 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6665 c_parser_consume_token (parser);
6666 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6667 warning_at (c_parser_peek_token (parser)->location,
6668 OPT_Wempty_body,
6669 "suggest braces around empty body in %<do%> statement");
6670 block = c_begin_compound_stmt (flag_isoc99);
6671 loc = c_parser_peek_token (parser)->location;
6672 save_in_statement = in_statement;
6673 in_statement = IN_ITERATION_STMT;
6674 body = c_parser_c99_block_statement (parser, NULL);
6675 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6676 in_statement = save_in_statement;
6677 cond = c_parser_paren_condition (parser);
6678 if (ivdep && cond != error_mark_node)
6679 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6680 build_int_cst (integer_type_node,
6681 annot_expr_ivdep_kind),
6682 integer_zero_node);
6683 if (unroll && cond != error_mark_node)
6684 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6685 build_int_cst (integer_type_node,
6686 annot_expr_unroll_kind),
6687 build_int_cst (integer_type_node, unroll));
6688 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6689 c_parser_skip_to_end_of_block_or_statement (parser);
6691 add_stmt (build_stmt (loc, DO_STMT, cond, body));
6692 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6695 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6697 for-statement:
6698 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6699 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6701 The form with a declaration is new in C99.
6703 ??? In accordance with the old parser, the declaration may be a
6704 nested function, which is then rejected in check_for_loop_decls,
6705 but does it make any sense for this to be included in the grammar?
6706 Note in particular that the nested function does not include a
6707 trailing ';', whereas the "declaration" production includes one.
6708 Also, can we reject bad declarations earlier and cheaper than
6709 check_for_loop_decls?
6711 In Objective-C, there are two additional variants:
6713 foreach-statement:
6714 for ( expression in expresssion ) statement
6715 for ( declaration in expression ) statement
6717 This is inconsistent with C, because the second variant is allowed
6718 even if c99 is not enabled.
6720 The rest of the comment documents these Objective-C foreach-statement.
6722 Here is the canonical example of the first variant:
6723 for (object in array) { do something with object }
6724 we call the first expression ("object") the "object_expression" and
6725 the second expression ("array") the "collection_expression".
6726 object_expression must be an lvalue of type "id" (a generic Objective-C
6727 object) because the loop works by assigning to object_expression the
6728 various objects from the collection_expression. collection_expression
6729 must evaluate to something of type "id" which responds to the method
6730 countByEnumeratingWithState:objects:count:.
6732 The canonical example of the second variant is:
6733 for (id object in array) { do something with object }
6734 which is completely equivalent to
6736 id object;
6737 for (object in array) { do something with object }
6739 Note that initizializing 'object' in some way (eg, "for ((object =
6740 xxx) in array) { do something with object }") is possibly
6741 technically valid, but completely pointless as 'object' will be
6742 assigned to something else as soon as the loop starts. We should
6743 most likely reject it (TODO).
6745 The beginning of the Objective-C foreach-statement looks exactly
6746 like the beginning of the for-statement, and we can tell it is a
6747 foreach-statement only because the initial declaration or
6748 expression is terminated by 'in' instead of ';'.
6750 IF_P is used to track whether there's a (possibly labeled) if statement
6751 which is not enclosed in braces and has an else clause. This is used to
6752 implement -Wparentheses. */
6754 static void
6755 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6756 bool *if_p)
6758 tree block, cond, incr, body;
6759 unsigned char save_in_statement;
6760 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6761 /* The following are only used when parsing an ObjC foreach statement. */
6762 tree object_expression;
6763 /* Silence the bogus uninitialized warning. */
6764 tree collection_expression = NULL;
6765 location_t loc = c_parser_peek_token (parser)->location;
6766 location_t for_loc = loc;
6767 bool is_foreach_statement = false;
6768 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6769 token_indent_info for_tinfo
6770 = get_token_indent_info (c_parser_peek_token (parser));
6771 c_parser_consume_token (parser);
6772 /* Open a compound statement in Objective-C as well, just in case this is
6773 as foreach expression. */
6774 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6775 cond = error_mark_node;
6776 incr = error_mark_node;
6777 matching_parens parens;
6778 if (parens.require_open (parser))
6780 /* Parse the initialization declaration or expression. */
6781 object_expression = error_mark_node;
6782 parser->objc_could_be_foreach_context = c_dialect_objc ();
6783 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6785 parser->objc_could_be_foreach_context = false;
6786 c_parser_consume_token (parser);
6787 c_finish_expr_stmt (loc, NULL_TREE);
6789 else if (c_parser_next_tokens_start_declaration (parser)
6790 || c_parser_nth_token_starts_std_attributes (parser, 1))
6792 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6793 &object_expression);
6794 parser->objc_could_be_foreach_context = false;
6796 if (c_parser_next_token_is_keyword (parser, RID_IN))
6798 c_parser_consume_token (parser);
6799 is_foreach_statement = true;
6800 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6801 c_parser_error (parser, "multiple iterating variables in "
6802 "fast enumeration");
6804 else
6805 check_for_loop_decls (for_loc, flag_isoc99);
6807 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6809 /* __extension__ can start a declaration, but is also an
6810 unary operator that can start an expression. Consume all
6811 but the last of a possible series of __extension__ to
6812 determine which. */
6813 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6814 && (c_parser_peek_2nd_token (parser)->keyword
6815 == RID_EXTENSION))
6816 c_parser_consume_token (parser);
6817 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6818 || c_parser_nth_token_starts_std_attributes (parser, 2))
6820 int ext;
6821 ext = disable_extension_diagnostics ();
6822 c_parser_consume_token (parser);
6823 c_parser_declaration_or_fndef (parser, true, true, true, true,
6824 true, &object_expression);
6825 parser->objc_could_be_foreach_context = false;
6827 restore_extension_diagnostics (ext);
6828 if (c_parser_next_token_is_keyword (parser, RID_IN))
6830 c_parser_consume_token (parser);
6831 is_foreach_statement = true;
6832 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6833 c_parser_error (parser, "multiple iterating variables in "
6834 "fast enumeration");
6836 else
6837 check_for_loop_decls (for_loc, flag_isoc99);
6839 else
6840 goto init_expr;
6842 else
6844 init_expr:
6846 struct c_expr ce;
6847 tree init_expression;
6848 ce = c_parser_expression (parser);
6849 init_expression = ce.value;
6850 parser->objc_could_be_foreach_context = false;
6851 if (c_parser_next_token_is_keyword (parser, RID_IN))
6853 c_parser_consume_token (parser);
6854 is_foreach_statement = true;
6855 if (! lvalue_p (init_expression))
6856 c_parser_error (parser, "invalid iterating variable in "
6857 "fast enumeration");
6858 object_expression
6859 = c_fully_fold (init_expression, false, NULL);
6861 else
6863 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6864 init_expression = ce.value;
6865 c_finish_expr_stmt (loc, init_expression);
6866 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6867 "expected %<;%>");
6871 /* Parse the loop condition. In the case of a foreach
6872 statement, there is no loop condition. */
6873 gcc_assert (!parser->objc_could_be_foreach_context);
6874 if (!is_foreach_statement)
6876 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6878 if (ivdep)
6880 c_parser_error (parser, "missing loop condition in loop "
6881 "with %<GCC ivdep%> pragma");
6882 cond = error_mark_node;
6884 else if (unroll)
6886 c_parser_error (parser, "missing loop condition in loop "
6887 "with %<GCC unroll%> pragma");
6888 cond = error_mark_node;
6890 else
6892 c_parser_consume_token (parser);
6893 cond = NULL_TREE;
6896 else
6898 cond = c_parser_condition (parser);
6899 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6900 "expected %<;%>");
6902 if (ivdep && cond != error_mark_node)
6903 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6904 build_int_cst (integer_type_node,
6905 annot_expr_ivdep_kind),
6906 integer_zero_node);
6907 if (unroll && cond != error_mark_node)
6908 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6909 build_int_cst (integer_type_node,
6910 annot_expr_unroll_kind),
6911 build_int_cst (integer_type_node, unroll));
6913 /* Parse the increment expression (the third expression in a
6914 for-statement). In the case of a foreach-statement, this is
6915 the expression that follows the 'in'. */
6916 loc = c_parser_peek_token (parser)->location;
6917 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6919 if (is_foreach_statement)
6921 c_parser_error (parser,
6922 "missing collection in fast enumeration");
6923 collection_expression = error_mark_node;
6925 else
6926 incr = c_process_expr_stmt (loc, NULL_TREE);
6928 else
6930 if (is_foreach_statement)
6931 collection_expression
6932 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6933 else
6935 struct c_expr ce = c_parser_expression (parser);
6936 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6937 incr = c_process_expr_stmt (loc, ce.value);
6940 parens.skip_until_found_close (parser);
6942 save_in_statement = in_statement;
6943 if (is_foreach_statement)
6945 in_statement = IN_OBJC_FOREACH;
6946 save_objc_foreach_break_label = objc_foreach_break_label;
6947 save_objc_foreach_continue_label = objc_foreach_continue_label;
6948 objc_foreach_break_label = create_artificial_label (loc);
6949 objc_foreach_continue_label = create_artificial_label (loc);
6951 else
6952 in_statement = IN_ITERATION_STMT;
6954 token_indent_info body_tinfo
6955 = get_token_indent_info (c_parser_peek_token (parser));
6957 location_t loc_after_labels;
6958 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6959 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6961 if (is_foreach_statement)
6962 objc_finish_foreach_loop (for_loc, object_expression,
6963 collection_expression, body,
6964 objc_foreach_break_label,
6965 objc_foreach_continue_label);
6966 else
6967 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
6968 body, NULL_TREE));
6969 add_stmt (c_end_compound_stmt (for_loc, block,
6970 flag_isoc99 || c_dialect_objc ()));
6971 c_parser_maybe_reclassify_token (parser);
6973 token_indent_info next_tinfo
6974 = get_token_indent_info (c_parser_peek_token (parser));
6975 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
6977 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6978 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6979 for_tinfo.location, RID_FOR);
6981 in_statement = save_in_statement;
6982 if (is_foreach_statement)
6984 objc_foreach_break_label = save_objc_foreach_break_label;
6985 objc_foreach_continue_label = save_objc_foreach_continue_label;
6989 /* Parse an asm statement, a GNU extension. This is a full-blown asm
6990 statement with inputs, outputs, clobbers, and volatile, inline, and goto
6991 tags allowed.
6993 asm-qualifier:
6994 volatile
6995 inline
6996 goto
6998 asm-qualifier-list:
6999 asm-qualifier-list asm-qualifier
7000 asm-qualifier
7002 asm-statement:
7003 asm asm-qualifier-list[opt] ( asm-argument ) ;
7005 asm-argument:
7006 asm-string-literal
7007 asm-string-literal : asm-operands[opt]
7008 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7009 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7010 : asm-clobbers[opt]
7011 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7012 : asm-goto-operands
7014 The form with asm-goto-operands is valid if and only if the
7015 asm-qualifier-list contains goto, and is the only allowed form in that case.
7016 Duplicate asm-qualifiers are not allowed.
7018 The :: token is considered equivalent to two consecutive : tokens. */
7020 static tree
7021 c_parser_asm_statement (c_parser *parser)
7023 tree str, outputs, inputs, clobbers, labels, ret;
7024 bool simple;
7025 location_t asm_loc = c_parser_peek_token (parser)->location;
7026 int section, nsections;
7028 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7029 c_parser_consume_token (parser);
7031 /* Handle the asm-qualifier-list. */
7032 location_t volatile_loc = UNKNOWN_LOCATION;
7033 location_t inline_loc = UNKNOWN_LOCATION;
7034 location_t goto_loc = UNKNOWN_LOCATION;
7035 for (;;)
7037 c_token *token = c_parser_peek_token (parser);
7038 location_t loc = token->location;
7039 switch (token->keyword)
7041 case RID_VOLATILE:
7042 if (volatile_loc)
7044 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7045 inform (volatile_loc, "first seen here");
7047 else
7048 volatile_loc = loc;
7049 c_parser_consume_token (parser);
7050 continue;
7052 case RID_INLINE:
7053 if (inline_loc)
7055 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7056 inform (inline_loc, "first seen here");
7058 else
7059 inline_loc = loc;
7060 c_parser_consume_token (parser);
7061 continue;
7063 case RID_GOTO:
7064 if (goto_loc)
7066 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7067 inform (goto_loc, "first seen here");
7069 else
7070 goto_loc = loc;
7071 c_parser_consume_token (parser);
7072 continue;
7074 case RID_CONST:
7075 case RID_RESTRICT:
7076 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7077 c_parser_consume_token (parser);
7078 continue;
7080 default:
7081 break;
7083 break;
7086 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7087 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7088 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7090 ret = NULL;
7092 matching_parens parens;
7093 if (!parens.require_open (parser))
7094 goto error;
7096 str = c_parser_asm_string_literal (parser);
7097 if (str == NULL_TREE)
7098 goto error_close_paren;
7100 simple = true;
7101 outputs = NULL_TREE;
7102 inputs = NULL_TREE;
7103 clobbers = NULL_TREE;
7104 labels = NULL_TREE;
7106 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7107 goto done_asm;
7109 /* Parse each colon-delimited section of operands. */
7110 nsections = 3 + is_goto;
7111 for (section = 0; section < nsections; ++section)
7113 if (c_parser_next_token_is (parser, CPP_SCOPE))
7115 ++section;
7116 if (section == nsections)
7118 c_parser_error (parser, "expected %<)%>");
7119 goto error_close_paren;
7121 c_parser_consume_token (parser);
7123 else if (!c_parser_require (parser, CPP_COLON,
7124 is_goto
7125 ? G_("expected %<:%>")
7126 : G_("expected %<:%> or %<)%>"),
7127 UNKNOWN_LOCATION, is_goto))
7128 goto error_close_paren;
7130 /* Once past any colon, we're no longer a simple asm. */
7131 simple = false;
7133 if ((!c_parser_next_token_is (parser, CPP_COLON)
7134 && !c_parser_next_token_is (parser, CPP_SCOPE)
7135 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7136 || section == 3)
7137 switch (section)
7139 case 0:
7140 outputs = c_parser_asm_operands (parser);
7141 break;
7142 case 1:
7143 inputs = c_parser_asm_operands (parser);
7144 break;
7145 case 2:
7146 clobbers = c_parser_asm_clobbers (parser);
7147 break;
7148 case 3:
7149 labels = c_parser_asm_goto_operands (parser);
7150 break;
7151 default:
7152 gcc_unreachable ();
7155 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7156 goto done_asm;
7159 done_asm:
7160 if (!parens.require_close (parser))
7162 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7163 goto error;
7166 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7167 c_parser_skip_to_end_of_block_or_statement (parser);
7169 ret = build_asm_stmt (is_volatile,
7170 build_asm_expr (asm_loc, str, outputs, inputs,
7171 clobbers, labels, simple, is_inline));
7173 error:
7174 return ret;
7176 error_close_paren:
7177 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7178 goto error;
7181 /* Parse asm operands, a GNU extension.
7183 asm-operands:
7184 asm-operand
7185 asm-operands , asm-operand
7187 asm-operand:
7188 asm-string-literal ( expression )
7189 [ identifier ] asm-string-literal ( expression )
7192 static tree
7193 c_parser_asm_operands (c_parser *parser)
7195 tree list = NULL_TREE;
7196 while (true)
7198 tree name, str;
7199 struct c_expr expr;
7200 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7202 c_parser_consume_token (parser);
7203 if (c_parser_next_token_is (parser, CPP_NAME))
7205 tree id = c_parser_peek_token (parser)->value;
7206 c_parser_consume_token (parser);
7207 name = build_string (IDENTIFIER_LENGTH (id),
7208 IDENTIFIER_POINTER (id));
7210 else
7212 c_parser_error (parser, "expected identifier");
7213 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7214 return NULL_TREE;
7216 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7217 "expected %<]%>");
7219 else
7220 name = NULL_TREE;
7221 str = c_parser_asm_string_literal (parser);
7222 if (str == NULL_TREE)
7223 return NULL_TREE;
7224 matching_parens parens;
7225 if (!parens.require_open (parser))
7226 return NULL_TREE;
7227 expr = c_parser_expression (parser);
7228 mark_exp_read (expr.value);
7229 if (!parens.require_close (parser))
7231 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7232 return NULL_TREE;
7234 list = chainon (list, build_tree_list (build_tree_list (name, str),
7235 expr.value));
7236 if (c_parser_next_token_is (parser, CPP_COMMA))
7237 c_parser_consume_token (parser);
7238 else
7239 break;
7241 return list;
7244 /* Parse asm clobbers, a GNU extension.
7246 asm-clobbers:
7247 asm-string-literal
7248 asm-clobbers , asm-string-literal
7251 static tree
7252 c_parser_asm_clobbers (c_parser *parser)
7254 tree list = NULL_TREE;
7255 while (true)
7257 tree str = c_parser_asm_string_literal (parser);
7258 if (str)
7259 list = tree_cons (NULL_TREE, str, list);
7260 else
7261 return NULL_TREE;
7262 if (c_parser_next_token_is (parser, CPP_COMMA))
7263 c_parser_consume_token (parser);
7264 else
7265 break;
7267 return list;
7270 /* Parse asm goto labels, a GNU extension.
7272 asm-goto-operands:
7273 identifier
7274 asm-goto-operands , identifier
7277 static tree
7278 c_parser_asm_goto_operands (c_parser *parser)
7280 tree list = NULL_TREE;
7281 while (true)
7283 tree name, label;
7285 if (c_parser_next_token_is (parser, CPP_NAME))
7287 c_token *tok = c_parser_peek_token (parser);
7288 name = tok->value;
7289 label = lookup_label_for_goto (tok->location, name);
7290 c_parser_consume_token (parser);
7291 TREE_USED (label) = 1;
7293 else
7295 c_parser_error (parser, "expected identifier");
7296 return NULL_TREE;
7299 name = build_string (IDENTIFIER_LENGTH (name),
7300 IDENTIFIER_POINTER (name));
7301 list = tree_cons (name, label, list);
7302 if (c_parser_next_token_is (parser, CPP_COMMA))
7303 c_parser_consume_token (parser);
7304 else
7305 return nreverse (list);
7309 /* Parse a possibly concatenated sequence of string literals.
7310 TRANSLATE says whether to translate them to the execution character
7311 set; WIDE_OK says whether any kind of prefixed string literal is
7312 permitted in this context. This code is based on that in
7313 lex_string. */
7315 struct c_expr
7316 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7318 struct c_expr ret;
7319 size_t count;
7320 struct obstack str_ob;
7321 struct obstack loc_ob;
7322 cpp_string str, istr, *strs;
7323 c_token *tok;
7324 location_t loc, last_tok_loc;
7325 enum cpp_ttype type;
7326 tree value, string_tree;
7328 tok = c_parser_peek_token (parser);
7329 loc = tok->location;
7330 last_tok_loc = linemap_resolve_location (line_table, loc,
7331 LRK_MACRO_DEFINITION_LOCATION,
7332 NULL);
7333 type = tok->type;
7334 switch (type)
7336 case CPP_STRING:
7337 case CPP_WSTRING:
7338 case CPP_STRING16:
7339 case CPP_STRING32:
7340 case CPP_UTF8STRING:
7341 string_tree = tok->value;
7342 break;
7344 default:
7345 c_parser_error (parser, "expected string literal");
7346 ret.set_error ();
7347 ret.value = NULL_TREE;
7348 ret.original_code = ERROR_MARK;
7349 ret.original_type = NULL_TREE;
7350 return ret;
7353 /* Try to avoid the overhead of creating and destroying an obstack
7354 for the common case of just one string. */
7355 switch (c_parser_peek_2nd_token (parser)->type)
7357 default:
7358 c_parser_consume_token (parser);
7359 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7360 str.len = TREE_STRING_LENGTH (string_tree);
7361 count = 1;
7362 strs = &str;
7363 break;
7365 case CPP_STRING:
7366 case CPP_WSTRING:
7367 case CPP_STRING16:
7368 case CPP_STRING32:
7369 case CPP_UTF8STRING:
7370 gcc_obstack_init (&str_ob);
7371 gcc_obstack_init (&loc_ob);
7372 count = 0;
7375 c_parser_consume_token (parser);
7376 count++;
7377 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7378 str.len = TREE_STRING_LENGTH (string_tree);
7379 if (type != tok->type)
7381 if (type == CPP_STRING)
7382 type = tok->type;
7383 else if (tok->type != CPP_STRING)
7384 error ("unsupported non-standard concatenation "
7385 "of string literals");
7387 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7388 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7389 tok = c_parser_peek_token (parser);
7390 string_tree = tok->value;
7391 last_tok_loc
7392 = linemap_resolve_location (line_table, tok->location,
7393 LRK_MACRO_DEFINITION_LOCATION, NULL);
7395 while (tok->type == CPP_STRING
7396 || tok->type == CPP_WSTRING
7397 || tok->type == CPP_STRING16
7398 || tok->type == CPP_STRING32
7399 || tok->type == CPP_UTF8STRING);
7400 strs = (cpp_string *) obstack_finish (&str_ob);
7403 if (count > 1 && !in_system_header_at (input_location))
7404 warning (OPT_Wtraditional,
7405 "traditional C rejects string constant concatenation");
7407 if ((type == CPP_STRING || wide_ok)
7408 && ((translate
7409 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7410 (parse_in, strs, count, &istr, type)))
7412 value = build_string (istr.len, (const char *) istr.text);
7413 free (CONST_CAST (unsigned char *, istr.text));
7414 if (count > 1)
7416 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7417 gcc_assert (g_string_concat_db);
7418 g_string_concat_db->record_string_concatenation (count, locs);
7421 else
7423 if (type != CPP_STRING && !wide_ok)
7425 error_at (loc, "a wide string is invalid in this context");
7426 type = CPP_STRING;
7428 /* Callers cannot generally handle error_mark_node in this
7429 context, so return the empty string instead. An error has
7430 been issued, either above or from cpp_interpret_string. */
7431 switch (type)
7433 default:
7434 case CPP_STRING:
7435 case CPP_UTF8STRING:
7436 value = build_string (1, "");
7437 break;
7438 case CPP_STRING16:
7439 value = build_string (TYPE_PRECISION (char16_type_node)
7440 / TYPE_PRECISION (char_type_node),
7441 "\0"); /* char16_t is 16 bits */
7442 break;
7443 case CPP_STRING32:
7444 value = build_string (TYPE_PRECISION (char32_type_node)
7445 / TYPE_PRECISION (char_type_node),
7446 "\0\0\0"); /* char32_t is 32 bits */
7447 break;
7448 case CPP_WSTRING:
7449 value = build_string (TYPE_PRECISION (wchar_type_node)
7450 / TYPE_PRECISION (char_type_node),
7451 "\0\0\0"); /* widest supported wchar_t
7452 is 32 bits */
7453 break;
7457 switch (type)
7459 default:
7460 case CPP_STRING:
7461 case CPP_UTF8STRING:
7462 TREE_TYPE (value) = char_array_type_node;
7463 break;
7464 case CPP_STRING16:
7465 TREE_TYPE (value) = char16_array_type_node;
7466 break;
7467 case CPP_STRING32:
7468 TREE_TYPE (value) = char32_array_type_node;
7469 break;
7470 case CPP_WSTRING:
7471 TREE_TYPE (value) = wchar_array_type_node;
7473 value = fix_string_type (value);
7475 if (count > 1)
7477 obstack_free (&str_ob, 0);
7478 obstack_free (&loc_ob, 0);
7481 ret.value = value;
7482 ret.original_code = STRING_CST;
7483 ret.original_type = NULL_TREE;
7484 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7485 parser->seen_string_literal = true;
7486 return ret;
7489 /* Parse an expression other than a compound expression; that is, an
7490 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7491 AFTER is not NULL then it is an Objective-C message expression which
7492 is the primary-expression starting the expression as an initializer.
7494 assignment-expression:
7495 conditional-expression
7496 unary-expression assignment-operator assignment-expression
7498 assignment-operator: one of
7499 = *= /= %= += -= <<= >>= &= ^= |=
7501 In GNU C we accept any conditional expression on the LHS and
7502 diagnose the invalid lvalue rather than producing a syntax
7503 error. */
7505 static struct c_expr
7506 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7507 tree omp_atomic_lhs)
7509 struct c_expr lhs, rhs, ret;
7510 enum tree_code code;
7511 location_t op_location, exp_location;
7512 bool save_in_omp_for = c_in_omp_for;
7513 c_in_omp_for = false;
7514 gcc_assert (!after || c_dialect_objc ());
7515 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7516 op_location = c_parser_peek_token (parser)->location;
7517 switch (c_parser_peek_token (parser)->type)
7519 case CPP_EQ:
7520 code = NOP_EXPR;
7521 break;
7522 case CPP_MULT_EQ:
7523 code = MULT_EXPR;
7524 break;
7525 case CPP_DIV_EQ:
7526 code = TRUNC_DIV_EXPR;
7527 break;
7528 case CPP_MOD_EQ:
7529 code = TRUNC_MOD_EXPR;
7530 break;
7531 case CPP_PLUS_EQ:
7532 code = PLUS_EXPR;
7533 break;
7534 case CPP_MINUS_EQ:
7535 code = MINUS_EXPR;
7536 break;
7537 case CPP_LSHIFT_EQ:
7538 code = LSHIFT_EXPR;
7539 break;
7540 case CPP_RSHIFT_EQ:
7541 code = RSHIFT_EXPR;
7542 break;
7543 case CPP_AND_EQ:
7544 code = BIT_AND_EXPR;
7545 break;
7546 case CPP_XOR_EQ:
7547 code = BIT_XOR_EXPR;
7548 break;
7549 case CPP_OR_EQ:
7550 code = BIT_IOR_EXPR;
7551 break;
7552 default:
7553 c_in_omp_for = save_in_omp_for;
7554 return lhs;
7556 c_parser_consume_token (parser);
7557 exp_location = c_parser_peek_token (parser)->location;
7558 rhs = c_parser_expr_no_commas (parser, NULL);
7559 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7561 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7562 code, exp_location, rhs.value,
7563 rhs.original_type);
7564 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7565 if (code == NOP_EXPR)
7566 ret.original_code = MODIFY_EXPR;
7567 else
7569 suppress_warning (ret.value, OPT_Wparentheses);
7570 ret.original_code = ERROR_MARK;
7572 ret.original_type = NULL;
7573 c_in_omp_for = save_in_omp_for;
7574 return ret;
7577 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7578 AFTER is not NULL then it is an Objective-C message expression which is
7579 the primary-expression starting the expression as an initializer.
7581 conditional-expression:
7582 logical-OR-expression
7583 logical-OR-expression ? expression : conditional-expression
7585 GNU extensions:
7587 conditional-expression:
7588 logical-OR-expression ? : conditional-expression
7591 static struct c_expr
7592 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7593 tree omp_atomic_lhs)
7595 struct c_expr cond, exp1, exp2, ret;
7596 location_t start, cond_loc, colon_loc;
7598 gcc_assert (!after || c_dialect_objc ());
7600 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7602 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7603 return cond;
7604 if (cond.value != error_mark_node)
7605 start = cond.get_start ();
7606 else
7607 start = UNKNOWN_LOCATION;
7608 cond_loc = c_parser_peek_token (parser)->location;
7609 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7610 c_parser_consume_token (parser);
7611 if (c_parser_next_token_is (parser, CPP_COLON))
7613 tree eptype = NULL_TREE;
7615 location_t middle_loc = c_parser_peek_token (parser)->location;
7616 pedwarn (middle_loc, OPT_Wpedantic,
7617 "ISO C forbids omitting the middle term of a %<?:%> expression");
7618 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7620 eptype = TREE_TYPE (cond.value);
7621 cond.value = TREE_OPERAND (cond.value, 0);
7623 tree e = cond.value;
7624 while (TREE_CODE (e) == COMPOUND_EXPR)
7625 e = TREE_OPERAND (e, 1);
7626 warn_for_omitted_condop (middle_loc, e);
7627 /* Make sure first operand is calculated only once. */
7628 exp1.value = save_expr (default_conversion (cond.value));
7629 if (eptype)
7630 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7631 exp1.original_type = NULL;
7632 exp1.src_range = cond.src_range;
7633 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7634 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7636 else
7638 cond.value
7639 = c_objc_common_truthvalue_conversion
7640 (cond_loc, default_conversion (cond.value));
7641 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7642 exp1 = c_parser_expression_conv (parser);
7643 mark_exp_read (exp1.value);
7644 c_inhibit_evaluation_warnings +=
7645 ((cond.value == truthvalue_true_node)
7646 - (cond.value == truthvalue_false_node));
7649 colon_loc = c_parser_peek_token (parser)->location;
7650 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7652 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7653 ret.set_error ();
7654 ret.original_code = ERROR_MARK;
7655 ret.original_type = NULL;
7656 return ret;
7659 location_t exp2_loc = c_parser_peek_token (parser)->location;
7660 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7661 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7663 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7664 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7665 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7666 ret.value = build_conditional_expr (colon_loc, cond.value,
7667 cond.original_code == C_MAYBE_CONST_EXPR,
7668 exp1.value, exp1.original_type, loc1,
7669 exp2.value, exp2.original_type, loc2);
7670 ret.original_code = ERROR_MARK;
7671 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7672 ret.original_type = NULL;
7673 else
7675 tree t1, t2;
7677 /* If both sides are enum type, the default conversion will have
7678 made the type of the result be an integer type. We want to
7679 remember the enum types we started with. */
7680 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7681 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7682 ret.original_type = ((t1 != error_mark_node
7683 && t2 != error_mark_node
7684 && (TYPE_MAIN_VARIANT (t1)
7685 == TYPE_MAIN_VARIANT (t2)))
7686 ? t1
7687 : NULL);
7689 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7690 return ret;
7693 /* Parse a binary expression; that is, a logical-OR-expression (C90
7694 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7695 NULL then it is an Objective-C message expression which is the
7696 primary-expression starting the expression as an initializer.
7698 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7699 when it should be the unfolded lhs. In a valid OpenMP source,
7700 one of the operands of the toplevel binary expression must be equal
7701 to it. In that case, just return a build2 created binary operation
7702 rather than result of parser_build_binary_op.
7704 multiplicative-expression:
7705 cast-expression
7706 multiplicative-expression * cast-expression
7707 multiplicative-expression / cast-expression
7708 multiplicative-expression % cast-expression
7710 additive-expression:
7711 multiplicative-expression
7712 additive-expression + multiplicative-expression
7713 additive-expression - multiplicative-expression
7715 shift-expression:
7716 additive-expression
7717 shift-expression << additive-expression
7718 shift-expression >> additive-expression
7720 relational-expression:
7721 shift-expression
7722 relational-expression < shift-expression
7723 relational-expression > shift-expression
7724 relational-expression <= shift-expression
7725 relational-expression >= shift-expression
7727 equality-expression:
7728 relational-expression
7729 equality-expression == relational-expression
7730 equality-expression != relational-expression
7732 AND-expression:
7733 equality-expression
7734 AND-expression & equality-expression
7736 exclusive-OR-expression:
7737 AND-expression
7738 exclusive-OR-expression ^ AND-expression
7740 inclusive-OR-expression:
7741 exclusive-OR-expression
7742 inclusive-OR-expression | exclusive-OR-expression
7744 logical-AND-expression:
7745 inclusive-OR-expression
7746 logical-AND-expression && inclusive-OR-expression
7748 logical-OR-expression:
7749 logical-AND-expression
7750 logical-OR-expression || logical-AND-expression
7753 static struct c_expr
7754 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7755 tree omp_atomic_lhs)
7757 /* A binary expression is parsed using operator-precedence parsing,
7758 with the operands being cast expressions. All the binary
7759 operators are left-associative. Thus a binary expression is of
7760 form:
7762 E0 op1 E1 op2 E2 ...
7764 which we represent on a stack. On the stack, the precedence
7765 levels are strictly increasing. When a new operator is
7766 encountered of higher precedence than that at the top of the
7767 stack, it is pushed; its LHS is the top expression, and its RHS
7768 is everything parsed until it is popped. When a new operator is
7769 encountered with precedence less than or equal to that at the top
7770 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7771 by the result of the operation until the operator at the top of
7772 the stack has lower precedence than the new operator or there is
7773 only one element on the stack; then the top expression is the LHS
7774 of the new operator. In the case of logical AND and OR
7775 expressions, we also need to adjust c_inhibit_evaluation_warnings
7776 as appropriate when the operators are pushed and popped. */
7778 struct {
7779 /* The expression at this stack level. */
7780 struct c_expr expr;
7781 /* The precedence of the operator on its left, PREC_NONE at the
7782 bottom of the stack. */
7783 enum c_parser_prec prec;
7784 /* The operation on its left. */
7785 enum tree_code op;
7786 /* The source location of this operation. */
7787 location_t loc;
7788 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7789 tree sizeof_arg;
7790 } stack[NUM_PRECS];
7791 int sp;
7792 /* Location of the binary operator. */
7793 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7794 #define POP \
7795 do { \
7796 switch (stack[sp].op) \
7798 case TRUTH_ANDIF_EXPR: \
7799 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7800 == truthvalue_false_node); \
7801 break; \
7802 case TRUTH_ORIF_EXPR: \
7803 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7804 == truthvalue_true_node); \
7805 break; \
7806 case TRUNC_DIV_EXPR: \
7807 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7808 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7809 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7810 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7812 tree type0 = stack[sp - 1].sizeof_arg; \
7813 tree type1 = stack[sp].sizeof_arg; \
7814 tree first_arg = type0; \
7815 if (!TYPE_P (type0)) \
7816 type0 = TREE_TYPE (type0); \
7817 if (!TYPE_P (type1)) \
7818 type1 = TREE_TYPE (type1); \
7819 if (POINTER_TYPE_P (type0) \
7820 && comptypes (TREE_TYPE (type0), type1) \
7821 && !(TREE_CODE (first_arg) == PARM_DECL \
7822 && C_ARRAY_PARAMETER (first_arg) \
7823 && warn_sizeof_array_argument)) \
7825 auto_diagnostic_group d; \
7826 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7827 "division %<sizeof (%T) / sizeof (%T)%> " \
7828 "does not compute the number of array " \
7829 "elements", \
7830 type0, type1)) \
7831 if (DECL_P (first_arg)) \
7832 inform (DECL_SOURCE_LOCATION (first_arg), \
7833 "first %<sizeof%> operand was declared here"); \
7835 else if (TREE_CODE (type0) == ARRAY_TYPE \
7836 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7837 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7838 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7839 stack[sp].sizeof_arg, type1); \
7841 break; \
7842 default: \
7843 break; \
7845 stack[sp - 1].expr \
7846 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7847 stack[sp - 1].expr, true, true); \
7848 stack[sp].expr \
7849 = convert_lvalue_to_rvalue (stack[sp].loc, \
7850 stack[sp].expr, true, true); \
7851 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7852 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7853 && ((1 << stack[sp].prec) \
7854 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7855 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7856 && stack[sp].op != TRUNC_MOD_EXPR \
7857 && stack[0].expr.value != error_mark_node \
7858 && stack[1].expr.value != error_mark_node \
7859 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7860 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7862 tree t = make_node (stack[1].op); \
7863 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7864 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7865 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7866 stack[0].expr.value = t; \
7868 else \
7869 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7870 stack[sp].op, \
7871 stack[sp - 1].expr, \
7872 stack[sp].expr); \
7873 sp--; \
7874 } while (0)
7875 gcc_assert (!after || c_dialect_objc ());
7876 stack[0].loc = c_parser_peek_token (parser)->location;
7877 stack[0].expr = c_parser_cast_expression (parser, after);
7878 stack[0].prec = PREC_NONE;
7879 stack[0].sizeof_arg = c_last_sizeof_arg;
7880 sp = 0;
7881 while (true)
7883 enum c_parser_prec oprec;
7884 enum tree_code ocode;
7885 source_range src_range;
7886 if (parser->error)
7887 goto out;
7888 switch (c_parser_peek_token (parser)->type)
7890 case CPP_MULT:
7891 oprec = PREC_MULT;
7892 ocode = MULT_EXPR;
7893 break;
7894 case CPP_DIV:
7895 oprec = PREC_MULT;
7896 ocode = TRUNC_DIV_EXPR;
7897 break;
7898 case CPP_MOD:
7899 oprec = PREC_MULT;
7900 ocode = TRUNC_MOD_EXPR;
7901 break;
7902 case CPP_PLUS:
7903 oprec = PREC_ADD;
7904 ocode = PLUS_EXPR;
7905 break;
7906 case CPP_MINUS:
7907 oprec = PREC_ADD;
7908 ocode = MINUS_EXPR;
7909 break;
7910 case CPP_LSHIFT:
7911 oprec = PREC_SHIFT;
7912 ocode = LSHIFT_EXPR;
7913 break;
7914 case CPP_RSHIFT:
7915 oprec = PREC_SHIFT;
7916 ocode = RSHIFT_EXPR;
7917 break;
7918 case CPP_LESS:
7919 oprec = PREC_REL;
7920 ocode = LT_EXPR;
7921 break;
7922 case CPP_GREATER:
7923 oprec = PREC_REL;
7924 ocode = GT_EXPR;
7925 break;
7926 case CPP_LESS_EQ:
7927 oprec = PREC_REL;
7928 ocode = LE_EXPR;
7929 break;
7930 case CPP_GREATER_EQ:
7931 oprec = PREC_REL;
7932 ocode = GE_EXPR;
7933 break;
7934 case CPP_EQ_EQ:
7935 oprec = PREC_EQ;
7936 ocode = EQ_EXPR;
7937 break;
7938 case CPP_NOT_EQ:
7939 oprec = PREC_EQ;
7940 ocode = NE_EXPR;
7941 break;
7942 case CPP_AND:
7943 oprec = PREC_BITAND;
7944 ocode = BIT_AND_EXPR;
7945 break;
7946 case CPP_XOR:
7947 oprec = PREC_BITXOR;
7948 ocode = BIT_XOR_EXPR;
7949 break;
7950 case CPP_OR:
7951 oprec = PREC_BITOR;
7952 ocode = BIT_IOR_EXPR;
7953 break;
7954 case CPP_AND_AND:
7955 oprec = PREC_LOGAND;
7956 ocode = TRUTH_ANDIF_EXPR;
7957 break;
7958 case CPP_OR_OR:
7959 oprec = PREC_LOGOR;
7960 ocode = TRUTH_ORIF_EXPR;
7961 break;
7962 default:
7963 /* Not a binary operator, so end of the binary
7964 expression. */
7965 goto out;
7967 binary_loc = c_parser_peek_token (parser)->location;
7968 while (oprec <= stack[sp].prec)
7969 POP;
7970 c_parser_consume_token (parser);
7971 switch (ocode)
7973 case TRUTH_ANDIF_EXPR:
7974 src_range = stack[sp].expr.src_range;
7975 stack[sp].expr
7976 = convert_lvalue_to_rvalue (stack[sp].loc,
7977 stack[sp].expr, true, true);
7978 stack[sp].expr.value = c_objc_common_truthvalue_conversion
7979 (stack[sp].loc, default_conversion (stack[sp].expr.value));
7980 c_inhibit_evaluation_warnings += (stack[sp].expr.value
7981 == truthvalue_false_node);
7982 set_c_expr_source_range (&stack[sp].expr, src_range);
7983 break;
7984 case TRUTH_ORIF_EXPR:
7985 src_range = stack[sp].expr.src_range;
7986 stack[sp].expr
7987 = convert_lvalue_to_rvalue (stack[sp].loc,
7988 stack[sp].expr, true, true);
7989 stack[sp].expr.value = c_objc_common_truthvalue_conversion
7990 (stack[sp].loc, default_conversion (stack[sp].expr.value));
7991 c_inhibit_evaluation_warnings += (stack[sp].expr.value
7992 == truthvalue_true_node);
7993 set_c_expr_source_range (&stack[sp].expr, src_range);
7994 break;
7995 default:
7996 break;
7998 sp++;
7999 stack[sp].loc = binary_loc;
8000 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8001 stack[sp].prec = oprec;
8002 stack[sp].op = ocode;
8003 stack[sp].sizeof_arg = c_last_sizeof_arg;
8005 out:
8006 while (sp > 0)
8007 POP;
8008 return stack[0].expr;
8009 #undef POP
8012 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8013 is not NULL then it is an Objective-C message expression which is the
8014 primary-expression starting the expression as an initializer.
8016 cast-expression:
8017 unary-expression
8018 ( type-name ) unary-expression
8021 static struct c_expr
8022 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8024 location_t cast_loc = c_parser_peek_token (parser)->location;
8025 gcc_assert (!after || c_dialect_objc ());
8026 if (after)
8027 return c_parser_postfix_expression_after_primary (parser,
8028 cast_loc, *after);
8029 /* If the expression begins with a parenthesized type name, it may
8030 be either a cast or a compound literal; we need to see whether
8031 the next character is '{' to tell the difference. If not, it is
8032 an unary expression. Full detection of unknown typenames here
8033 would require a 3-token lookahead. */
8034 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8035 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8037 struct c_type_name *type_name;
8038 struct c_expr ret;
8039 struct c_expr expr;
8040 matching_parens parens;
8041 parens.consume_open (parser);
8042 type_name = c_parser_type_name (parser, true);
8043 parens.skip_until_found_close (parser);
8044 if (type_name == NULL)
8046 ret.set_error ();
8047 ret.original_code = ERROR_MARK;
8048 ret.original_type = NULL;
8049 return ret;
8052 /* Save casted types in the function's used types hash table. */
8053 used_types_insert (type_name->specs->type);
8055 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8056 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8057 cast_loc);
8058 if (type_name->specs->alignas_p)
8059 error_at (type_name->specs->locations[cdw_alignas],
8060 "alignment specified for type name in cast");
8062 location_t expr_loc = c_parser_peek_token (parser)->location;
8063 expr = c_parser_cast_expression (parser, NULL);
8064 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8066 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8067 if (ret.value && expr.value)
8068 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8069 ret.original_code = ERROR_MARK;
8070 ret.original_type = NULL;
8071 return ret;
8073 else
8074 return c_parser_unary_expression (parser);
8077 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8079 unary-expression:
8080 postfix-expression
8081 ++ unary-expression
8082 -- unary-expression
8083 unary-operator cast-expression
8084 sizeof unary-expression
8085 sizeof ( type-name )
8087 unary-operator: one of
8088 & * + - ~ !
8090 GNU extensions:
8092 unary-expression:
8093 __alignof__ unary-expression
8094 __alignof__ ( type-name )
8095 && identifier
8097 (C11 permits _Alignof with type names only.)
8099 unary-operator: one of
8100 __extension__ __real__ __imag__
8102 Transactional Memory:
8104 unary-expression:
8105 transaction-expression
8107 In addition, the GNU syntax treats ++ and -- as unary operators, so
8108 they may be applied to cast expressions with errors for non-lvalues
8109 given later. */
8111 static struct c_expr
8112 c_parser_unary_expression (c_parser *parser)
8114 int ext;
8115 struct c_expr ret, op;
8116 location_t op_loc = c_parser_peek_token (parser)->location;
8117 location_t exp_loc;
8118 location_t finish;
8119 ret.original_code = ERROR_MARK;
8120 ret.original_type = NULL;
8121 switch (c_parser_peek_token (parser)->type)
8123 case CPP_PLUS_PLUS:
8124 c_parser_consume_token (parser);
8125 exp_loc = c_parser_peek_token (parser)->location;
8126 op = c_parser_cast_expression (parser, NULL);
8128 op = default_function_array_read_conversion (exp_loc, op);
8129 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8130 case CPP_MINUS_MINUS:
8131 c_parser_consume_token (parser);
8132 exp_loc = c_parser_peek_token (parser)->location;
8133 op = c_parser_cast_expression (parser, NULL);
8135 op = default_function_array_read_conversion (exp_loc, op);
8136 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8137 case CPP_AND:
8138 c_parser_consume_token (parser);
8139 op = c_parser_cast_expression (parser, NULL);
8140 mark_exp_read (op.value);
8141 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8142 case CPP_MULT:
8144 c_parser_consume_token (parser);
8145 exp_loc = c_parser_peek_token (parser)->location;
8146 op = c_parser_cast_expression (parser, NULL);
8147 finish = op.get_finish ();
8148 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8149 location_t combined_loc = make_location (op_loc, op_loc, finish);
8150 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8151 ret.src_range.m_start = op_loc;
8152 ret.src_range.m_finish = finish;
8153 return ret;
8155 case CPP_PLUS:
8156 if (!c_dialect_objc () && !in_system_header_at (input_location))
8157 warning_at (op_loc,
8158 OPT_Wtraditional,
8159 "traditional C rejects the unary plus operator");
8160 c_parser_consume_token (parser);
8161 exp_loc = c_parser_peek_token (parser)->location;
8162 op = c_parser_cast_expression (parser, NULL);
8163 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8164 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8165 case CPP_MINUS:
8166 c_parser_consume_token (parser);
8167 exp_loc = c_parser_peek_token (parser)->location;
8168 op = c_parser_cast_expression (parser, NULL);
8169 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8170 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8171 case CPP_COMPL:
8172 c_parser_consume_token (parser);
8173 exp_loc = c_parser_peek_token (parser)->location;
8174 op = c_parser_cast_expression (parser, NULL);
8175 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8176 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8177 case CPP_NOT:
8178 c_parser_consume_token (parser);
8179 exp_loc = c_parser_peek_token (parser)->location;
8180 op = c_parser_cast_expression (parser, NULL);
8181 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8182 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8183 case CPP_AND_AND:
8184 /* Refer to the address of a label as a pointer. */
8185 c_parser_consume_token (parser);
8186 if (c_parser_next_token_is (parser, CPP_NAME))
8188 ret.value = finish_label_address_expr
8189 (c_parser_peek_token (parser)->value, op_loc);
8190 set_c_expr_source_range (&ret, op_loc,
8191 c_parser_peek_token (parser)->get_finish ());
8192 c_parser_consume_token (parser);
8194 else
8196 c_parser_error (parser, "expected identifier");
8197 ret.set_error ();
8199 return ret;
8200 case CPP_KEYWORD:
8201 switch (c_parser_peek_token (parser)->keyword)
8203 case RID_SIZEOF:
8204 return c_parser_sizeof_expression (parser);
8205 case RID_ALIGNOF:
8206 return c_parser_alignof_expression (parser);
8207 case RID_BUILTIN_HAS_ATTRIBUTE:
8208 return c_parser_has_attribute_expression (parser);
8209 case RID_EXTENSION:
8210 c_parser_consume_token (parser);
8211 ext = disable_extension_diagnostics ();
8212 ret = c_parser_cast_expression (parser, NULL);
8213 restore_extension_diagnostics (ext);
8214 return ret;
8215 case RID_REALPART:
8216 c_parser_consume_token (parser);
8217 exp_loc = c_parser_peek_token (parser)->location;
8218 op = c_parser_cast_expression (parser, NULL);
8219 op = default_function_array_conversion (exp_loc, op);
8220 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8221 case RID_IMAGPART:
8222 c_parser_consume_token (parser);
8223 exp_loc = c_parser_peek_token (parser)->location;
8224 op = c_parser_cast_expression (parser, NULL);
8225 op = default_function_array_conversion (exp_loc, op);
8226 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8227 case RID_TRANSACTION_ATOMIC:
8228 case RID_TRANSACTION_RELAXED:
8229 return c_parser_transaction_expression (parser,
8230 c_parser_peek_token (parser)->keyword);
8231 default:
8232 return c_parser_postfix_expression (parser);
8234 default:
8235 return c_parser_postfix_expression (parser);
8239 /* Parse a sizeof expression. */
8241 static struct c_expr
8242 c_parser_sizeof_expression (c_parser *parser)
8244 struct c_expr expr;
8245 struct c_expr result;
8246 location_t expr_loc;
8247 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8249 location_t start;
8250 location_t finish = UNKNOWN_LOCATION;
8252 start = c_parser_peek_token (parser)->location;
8254 c_parser_consume_token (parser);
8255 c_inhibit_evaluation_warnings++;
8256 in_sizeof++;
8257 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8258 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8260 /* Either sizeof ( type-name ) or sizeof unary-expression
8261 starting with a compound literal. */
8262 struct c_type_name *type_name;
8263 matching_parens parens;
8264 parens.consume_open (parser);
8265 expr_loc = c_parser_peek_token (parser)->location;
8266 type_name = c_parser_type_name (parser, true);
8267 parens.skip_until_found_close (parser);
8268 finish = parser->tokens_buf[0].location;
8269 if (type_name == NULL)
8271 struct c_expr ret;
8272 c_inhibit_evaluation_warnings--;
8273 in_sizeof--;
8274 ret.set_error ();
8275 ret.original_code = ERROR_MARK;
8276 ret.original_type = NULL;
8277 return ret;
8279 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8281 expr = c_parser_postfix_expression_after_paren_type (parser,
8282 type_name,
8283 expr_loc);
8284 finish = expr.get_finish ();
8285 goto sizeof_expr;
8287 /* sizeof ( type-name ). */
8288 if (type_name->specs->alignas_p)
8289 error_at (type_name->specs->locations[cdw_alignas],
8290 "alignment specified for type name in %<sizeof%>");
8291 c_inhibit_evaluation_warnings--;
8292 in_sizeof--;
8293 result = c_expr_sizeof_type (expr_loc, type_name);
8295 else
8297 expr_loc = c_parser_peek_token (parser)->location;
8298 expr = c_parser_unary_expression (parser);
8299 finish = expr.get_finish ();
8300 sizeof_expr:
8301 c_inhibit_evaluation_warnings--;
8302 in_sizeof--;
8303 mark_exp_read (expr.value);
8304 if (TREE_CODE (expr.value) == COMPONENT_REF
8305 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8306 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8307 result = c_expr_sizeof_expr (expr_loc, expr);
8309 if (finish == UNKNOWN_LOCATION)
8310 finish = start;
8311 set_c_expr_source_range (&result, start, finish);
8312 return result;
8315 /* Parse an alignof expression. */
8317 static struct c_expr
8318 c_parser_alignof_expression (c_parser *parser)
8320 struct c_expr expr;
8321 location_t start_loc = c_parser_peek_token (parser)->location;
8322 location_t end_loc;
8323 tree alignof_spelling = c_parser_peek_token (parser)->value;
8324 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8325 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8326 "_Alignof") == 0;
8327 /* A diagnostic is not required for the use of this identifier in
8328 the implementation namespace; only diagnose it for the C11
8329 spelling because of existing code using the other spellings. */
8330 if (is_c11_alignof)
8332 if (flag_isoc99)
8333 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8334 alignof_spelling);
8335 else
8336 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8337 alignof_spelling);
8339 c_parser_consume_token (parser);
8340 c_inhibit_evaluation_warnings++;
8341 in_alignof++;
8342 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8343 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8345 /* Either __alignof__ ( type-name ) or __alignof__
8346 unary-expression starting with a compound literal. */
8347 location_t loc;
8348 struct c_type_name *type_name;
8349 struct c_expr ret;
8350 matching_parens parens;
8351 parens.consume_open (parser);
8352 loc = c_parser_peek_token (parser)->location;
8353 type_name = c_parser_type_name (parser, true);
8354 end_loc = c_parser_peek_token (parser)->location;
8355 parens.skip_until_found_close (parser);
8356 if (type_name == NULL)
8358 struct c_expr ret;
8359 c_inhibit_evaluation_warnings--;
8360 in_alignof--;
8361 ret.set_error ();
8362 ret.original_code = ERROR_MARK;
8363 ret.original_type = NULL;
8364 return ret;
8366 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8368 expr = c_parser_postfix_expression_after_paren_type (parser,
8369 type_name,
8370 loc);
8371 goto alignof_expr;
8373 /* alignof ( type-name ). */
8374 if (type_name->specs->alignas_p)
8375 error_at (type_name->specs->locations[cdw_alignas],
8376 "alignment specified for type name in %qE",
8377 alignof_spelling);
8378 c_inhibit_evaluation_warnings--;
8379 in_alignof--;
8380 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8381 NULL, NULL),
8382 false, is_c11_alignof, 1);
8383 ret.original_code = ERROR_MARK;
8384 ret.original_type = NULL;
8385 set_c_expr_source_range (&ret, start_loc, end_loc);
8386 return ret;
8388 else
8390 struct c_expr ret;
8391 expr = c_parser_unary_expression (parser);
8392 end_loc = expr.src_range.m_finish;
8393 alignof_expr:
8394 mark_exp_read (expr.value);
8395 c_inhibit_evaluation_warnings--;
8396 in_alignof--;
8397 if (is_c11_alignof)
8398 pedwarn (start_loc,
8399 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8400 alignof_spelling);
8401 ret.value = c_alignof_expr (start_loc, expr.value);
8402 ret.original_code = ERROR_MARK;
8403 ret.original_type = NULL;
8404 set_c_expr_source_range (&ret, start_loc, end_loc);
8405 return ret;
8409 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8410 expression. */
8412 static struct c_expr
8413 c_parser_has_attribute_expression (c_parser *parser)
8415 gcc_assert (c_parser_next_token_is_keyword (parser,
8416 RID_BUILTIN_HAS_ATTRIBUTE));
8417 location_t start = c_parser_peek_token (parser)->location;
8418 c_parser_consume_token (parser);
8420 c_inhibit_evaluation_warnings++;
8422 matching_parens parens;
8423 if (!parens.require_open (parser))
8425 c_inhibit_evaluation_warnings--;
8426 in_typeof--;
8428 struct c_expr result;
8429 result.set_error ();
8430 result.original_code = ERROR_MARK;
8431 result.original_type = NULL;
8432 return result;
8435 /* Treat the type argument the same way as in typeof for the purposes
8436 of warnings. FIXME: Generalize this so the warning refers to
8437 __builtin_has_attribute rather than typeof. */
8438 in_typeof++;
8440 /* The first operand: one of DECL, EXPR, or TYPE. */
8441 tree oper = NULL_TREE;
8442 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8444 struct c_type_name *tname = c_parser_type_name (parser);
8445 in_typeof--;
8446 if (tname)
8448 oper = groktypename (tname, NULL, NULL);
8449 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8452 else
8454 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8455 c_inhibit_evaluation_warnings--;
8456 in_typeof--;
8457 if (cexpr.value != error_mark_node)
8459 mark_exp_read (cexpr.value);
8460 oper = cexpr.value;
8461 tree etype = TREE_TYPE (oper);
8462 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8463 /* This is returned with the type so that when the type is
8464 evaluated, this can be evaluated. */
8465 if (was_vm)
8466 oper = c_fully_fold (oper, false, NULL);
8467 pop_maybe_used (was_vm);
8471 struct c_expr result;
8472 result.original_code = ERROR_MARK;
8473 result.original_type = NULL;
8475 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8477 /* Consume the closing parenthesis if that's the next token
8478 in the likely case the built-in was invoked with fewer
8479 than two arguments. */
8480 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8481 c_parser_consume_token (parser);
8482 c_inhibit_evaluation_warnings--;
8483 result.set_error ();
8484 return result;
8487 bool save_translate_strings_p = parser->translate_strings_p;
8489 location_t atloc = c_parser_peek_token (parser)->location;
8490 /* Parse a single attribute. Require no leading comma and do not
8491 allow empty attributes. */
8492 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8494 parser->translate_strings_p = save_translate_strings_p;
8496 location_t finish = c_parser_peek_token (parser)->location;
8497 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8498 c_parser_consume_token (parser);
8499 else
8501 c_parser_error (parser, "expected identifier");
8502 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8504 result.set_error ();
8505 return result;
8508 if (!attr)
8510 error_at (atloc, "expected identifier");
8511 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8512 "expected %<)%>");
8513 result.set_error ();
8514 return result;
8517 result.original_code = INTEGER_CST;
8518 result.original_type = boolean_type_node;
8520 if (has_attribute (atloc, oper, attr, default_conversion))
8521 result.value = boolean_true_node;
8522 else
8523 result.value = boolean_false_node;
8525 set_c_expr_source_range (&result, start, finish);
8526 return result;
8529 /* Helper function to read arguments of builtins which are interfaces
8530 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8531 others. The name of the builtin is passed using BNAME parameter.
8532 Function returns true if there were no errors while parsing and
8533 stores the arguments in CEXPR_LIST. If it returns true,
8534 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8535 parenthesis. */
8536 static bool
8537 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8538 vec<c_expr_t, va_gc> **ret_cexpr_list,
8539 bool choose_expr_p,
8540 location_t *out_close_paren_loc)
8542 location_t loc = c_parser_peek_token (parser)->location;
8543 vec<c_expr_t, va_gc> *cexpr_list;
8544 c_expr_t expr;
8545 bool saved_force_folding_builtin_constant_p;
8547 *ret_cexpr_list = NULL;
8548 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8550 error_at (loc, "cannot take address of %qs", bname);
8551 return false;
8554 c_parser_consume_token (parser);
8556 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8558 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8559 c_parser_consume_token (parser);
8560 return true;
8563 saved_force_folding_builtin_constant_p
8564 = force_folding_builtin_constant_p;
8565 force_folding_builtin_constant_p |= choose_expr_p;
8566 expr = c_parser_expr_no_commas (parser, NULL);
8567 force_folding_builtin_constant_p
8568 = saved_force_folding_builtin_constant_p;
8569 vec_alloc (cexpr_list, 1);
8570 vec_safe_push (cexpr_list, expr);
8571 while (c_parser_next_token_is (parser, CPP_COMMA))
8573 c_parser_consume_token (parser);
8574 expr = c_parser_expr_no_commas (parser, NULL);
8575 vec_safe_push (cexpr_list, expr);
8578 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8579 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8580 return false;
8582 *ret_cexpr_list = cexpr_list;
8583 return true;
8586 /* This represents a single generic-association. */
8588 struct c_generic_association
8590 /* The location of the starting token of the type. */
8591 location_t type_location;
8592 /* The association's type, or NULL_TREE for 'default'. */
8593 tree type;
8594 /* The association's expression. */
8595 struct c_expr expression;
8598 /* Parse a generic-selection. (C11 6.5.1.1).
8600 generic-selection:
8601 _Generic ( assignment-expression , generic-assoc-list )
8603 generic-assoc-list:
8604 generic-association
8605 generic-assoc-list , generic-association
8607 generic-association:
8608 type-name : assignment-expression
8609 default : assignment-expression
8612 static struct c_expr
8613 c_parser_generic_selection (c_parser *parser)
8615 struct c_expr selector, error_expr;
8616 tree selector_type;
8617 struct c_generic_association matched_assoc;
8618 int match_found = -1;
8619 location_t generic_loc, selector_loc;
8621 error_expr.original_code = ERROR_MARK;
8622 error_expr.original_type = NULL;
8623 error_expr.set_error ();
8624 matched_assoc.type_location = UNKNOWN_LOCATION;
8625 matched_assoc.type = NULL_TREE;
8626 matched_assoc.expression = error_expr;
8628 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8629 generic_loc = c_parser_peek_token (parser)->location;
8630 c_parser_consume_token (parser);
8631 if (flag_isoc99)
8632 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8633 "ISO C99 does not support %<_Generic%>");
8634 else
8635 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8636 "ISO C90 does not support %<_Generic%>");
8638 matching_parens parens;
8639 if (!parens.require_open (parser))
8640 return error_expr;
8642 c_inhibit_evaluation_warnings++;
8643 selector_loc = c_parser_peek_token (parser)->location;
8644 selector = c_parser_expr_no_commas (parser, NULL);
8645 selector = default_function_array_conversion (selector_loc, selector);
8646 c_inhibit_evaluation_warnings--;
8648 if (selector.value == error_mark_node)
8650 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8651 return selector;
8653 mark_exp_read (selector.value);
8654 selector_type = TREE_TYPE (selector.value);
8655 /* In ISO C terms, rvalues (including the controlling expression of
8656 _Generic) do not have qualified types. */
8657 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8658 selector_type = TYPE_MAIN_VARIANT (selector_type);
8659 /* In ISO C terms, _Noreturn is not part of the type of expressions
8660 such as &abort, but in GCC it is represented internally as a type
8661 qualifier. */
8662 if (FUNCTION_POINTER_TYPE_P (selector_type)
8663 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8664 selector_type
8665 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8667 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8669 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8670 return error_expr;
8673 auto_vec<c_generic_association> associations;
8674 while (1)
8676 struct c_generic_association assoc, *iter;
8677 unsigned int ix;
8678 c_token *token = c_parser_peek_token (parser);
8680 assoc.type_location = token->location;
8681 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8683 c_parser_consume_token (parser);
8684 assoc.type = NULL_TREE;
8686 else
8688 struct c_type_name *type_name;
8690 type_name = c_parser_type_name (parser);
8691 if (type_name == NULL)
8693 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8694 return error_expr;
8696 assoc.type = groktypename (type_name, NULL, NULL);
8697 if (assoc.type == error_mark_node)
8699 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8700 return error_expr;
8703 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8704 error_at (assoc.type_location,
8705 "%<_Generic%> association has function type");
8706 else if (!COMPLETE_TYPE_P (assoc.type))
8707 error_at (assoc.type_location,
8708 "%<_Generic%> association has incomplete type");
8710 if (variably_modified_type_p (assoc.type, NULL_TREE))
8711 error_at (assoc.type_location,
8712 "%<_Generic%> association has "
8713 "variable length type");
8716 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8718 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8719 return error_expr;
8722 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8723 if (assoc.expression.value == error_mark_node)
8725 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8726 return error_expr;
8729 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8731 if (assoc.type == NULL_TREE)
8733 if (iter->type == NULL_TREE)
8735 error_at (assoc.type_location,
8736 "duplicate %<default%> case in %<_Generic%>");
8737 inform (iter->type_location, "original %<default%> is here");
8740 else if (iter->type != NULL_TREE)
8742 if (comptypes (assoc.type, iter->type))
8744 error_at (assoc.type_location,
8745 "%<_Generic%> specifies two compatible types");
8746 inform (iter->type_location, "compatible type is here");
8751 if (assoc.type == NULL_TREE)
8753 if (match_found < 0)
8755 matched_assoc = assoc;
8756 match_found = associations.length ();
8759 else if (comptypes (assoc.type, selector_type))
8761 if (match_found < 0 || matched_assoc.type == NULL_TREE)
8763 matched_assoc = assoc;
8764 match_found = associations.length ();
8766 else
8768 error_at (assoc.type_location,
8769 "%<_Generic%> selector matches multiple associations");
8770 inform (matched_assoc.type_location,
8771 "other match is here");
8775 associations.safe_push (assoc);
8777 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8778 break;
8779 c_parser_consume_token (parser);
8782 unsigned int ix;
8783 struct c_generic_association *iter;
8784 FOR_EACH_VEC_ELT (associations, ix, iter)
8785 if (ix != (unsigned) match_found)
8786 mark_exp_read (iter->expression.value);
8788 if (!parens.require_close (parser))
8790 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8791 return error_expr;
8794 if (match_found < 0)
8796 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8797 "compatible with any association",
8798 selector_type);
8799 return error_expr;
8802 return matched_assoc.expression;
8805 /* Check the validity of a function pointer argument *EXPR (argument
8806 position POS) to __builtin_tgmath. Return the number of function
8807 arguments if possibly valid; return 0 having reported an error if
8808 not valid. */
8810 static unsigned int
8811 check_tgmath_function (c_expr *expr, unsigned int pos)
8813 tree type = TREE_TYPE (expr->value);
8814 if (!FUNCTION_POINTER_TYPE_P (type))
8816 error_at (expr->get_location (),
8817 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8818 pos);
8819 return 0;
8821 type = TREE_TYPE (type);
8822 if (!prototype_p (type))
8824 error_at (expr->get_location (),
8825 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8826 return 0;
8828 if (stdarg_p (type))
8830 error_at (expr->get_location (),
8831 "argument %u of %<__builtin_tgmath%> has variable arguments",
8832 pos);
8833 return 0;
8835 unsigned int nargs = 0;
8836 function_args_iterator iter;
8837 tree t;
8838 FOREACH_FUNCTION_ARGS (type, t, iter)
8840 if (t == void_type_node)
8841 break;
8842 nargs++;
8844 if (nargs == 0)
8846 error_at (expr->get_location (),
8847 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8848 return 0;
8850 return nargs;
8853 /* Ways in which a parameter or return value of a type-generic macro
8854 may vary between the different functions the macro may call. */
8855 enum tgmath_parm_kind
8857 tgmath_fixed, tgmath_real, tgmath_complex
8860 /* Helper function for c_parser_postfix_expression. Parse predefined
8861 identifiers. */
8863 static struct c_expr
8864 c_parser_predefined_identifier (c_parser *parser)
8866 location_t loc = c_parser_peek_token (parser)->location;
8867 switch (c_parser_peek_token (parser)->keyword)
8869 case RID_FUNCTION_NAME:
8870 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8871 "identifier", "__FUNCTION__");
8872 break;
8873 case RID_PRETTY_FUNCTION_NAME:
8874 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8875 "identifier", "__PRETTY_FUNCTION__");
8876 break;
8877 case RID_C99_FUNCTION_NAME:
8878 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8879 "%<__func__%> predefined identifier");
8880 break;
8881 default:
8882 gcc_unreachable ();
8885 struct c_expr expr;
8886 expr.original_code = ERROR_MARK;
8887 expr.original_type = NULL;
8888 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8889 c_parser_peek_token (parser)->value);
8890 set_c_expr_source_range (&expr, loc, loc);
8891 c_parser_consume_token (parser);
8892 return expr;
8895 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8896 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8897 call c_parser_postfix_expression_after_paren_type on encountering them.
8899 postfix-expression:
8900 primary-expression
8901 postfix-expression [ expression ]
8902 postfix-expression ( argument-expression-list[opt] )
8903 postfix-expression . identifier
8904 postfix-expression -> identifier
8905 postfix-expression ++
8906 postfix-expression --
8907 ( type-name ) { initializer-list }
8908 ( type-name ) { initializer-list , }
8910 argument-expression-list:
8911 argument-expression
8912 argument-expression-list , argument-expression
8914 primary-expression:
8915 identifier
8916 constant
8917 string-literal
8918 ( expression )
8919 generic-selection
8921 GNU extensions:
8923 primary-expression:
8924 __func__
8925 (treated as a keyword in GNU C)
8926 __FUNCTION__
8927 __PRETTY_FUNCTION__
8928 ( compound-statement )
8929 __builtin_va_arg ( assignment-expression , type-name )
8930 __builtin_offsetof ( type-name , offsetof-member-designator )
8931 __builtin_choose_expr ( assignment-expression ,
8932 assignment-expression ,
8933 assignment-expression )
8934 __builtin_types_compatible_p ( type-name , type-name )
8935 __builtin_tgmath ( expr-list )
8936 __builtin_complex ( assignment-expression , assignment-expression )
8937 __builtin_shuffle ( assignment-expression , assignment-expression )
8938 __builtin_shuffle ( assignment-expression ,
8939 assignment-expression ,
8940 assignment-expression, )
8941 __builtin_convertvector ( assignment-expression , type-name )
8943 offsetof-member-designator:
8944 identifier
8945 offsetof-member-designator . identifier
8946 offsetof-member-designator [ expression ]
8948 Objective-C:
8950 primary-expression:
8951 [ objc-receiver objc-message-args ]
8952 @selector ( objc-selector-arg )
8953 @protocol ( identifier )
8954 @encode ( type-name )
8955 objc-string-literal
8956 Classname . identifier
8959 static struct c_expr
8960 c_parser_postfix_expression (c_parser *parser)
8962 struct c_expr expr, e1;
8963 struct c_type_name *t1, *t2;
8964 location_t loc = c_parser_peek_token (parser)->location;
8965 source_range tok_range = c_parser_peek_token (parser)->get_range ();
8966 expr.original_code = ERROR_MARK;
8967 expr.original_type = NULL;
8968 switch (c_parser_peek_token (parser)->type)
8970 case CPP_NUMBER:
8971 expr.value = c_parser_peek_token (parser)->value;
8972 set_c_expr_source_range (&expr, tok_range);
8973 loc = c_parser_peek_token (parser)->location;
8974 c_parser_consume_token (parser);
8975 if (TREE_CODE (expr.value) == FIXED_CST
8976 && !targetm.fixed_point_supported_p ())
8978 error_at (loc, "fixed-point types not supported for this target");
8979 expr.set_error ();
8981 break;
8982 case CPP_CHAR:
8983 case CPP_CHAR16:
8984 case CPP_CHAR32:
8985 case CPP_UTF8CHAR:
8986 case CPP_WCHAR:
8987 expr.value = c_parser_peek_token (parser)->value;
8988 /* For the purpose of warning when a pointer is compared with
8989 a zero character constant. */
8990 expr.original_type = char_type_node;
8991 set_c_expr_source_range (&expr, tok_range);
8992 c_parser_consume_token (parser);
8993 break;
8994 case CPP_STRING:
8995 case CPP_STRING16:
8996 case CPP_STRING32:
8997 case CPP_WSTRING:
8998 case CPP_UTF8STRING:
8999 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9000 true);
9001 break;
9002 case CPP_OBJC_STRING:
9003 gcc_assert (c_dialect_objc ());
9004 expr.value
9005 = objc_build_string_object (c_parser_peek_token (parser)->value);
9006 set_c_expr_source_range (&expr, tok_range);
9007 c_parser_consume_token (parser);
9008 break;
9009 case CPP_NAME:
9010 switch (c_parser_peek_token (parser)->id_kind)
9012 case C_ID_ID:
9014 tree id = c_parser_peek_token (parser)->value;
9015 c_parser_consume_token (parser);
9016 expr.value = build_external_ref (loc, id,
9017 (c_parser_peek_token (parser)->type
9018 == CPP_OPEN_PAREN),
9019 &expr.original_type);
9020 set_c_expr_source_range (&expr, tok_range);
9021 break;
9023 case C_ID_CLASSNAME:
9025 /* Here we parse the Objective-C 2.0 Class.name dot
9026 syntax. */
9027 tree class_name = c_parser_peek_token (parser)->value;
9028 tree component;
9029 c_parser_consume_token (parser);
9030 gcc_assert (c_dialect_objc ());
9031 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9033 expr.set_error ();
9034 break;
9036 if (c_parser_next_token_is_not (parser, CPP_NAME))
9038 c_parser_error (parser, "expected identifier");
9039 expr.set_error ();
9040 break;
9042 c_token *component_tok = c_parser_peek_token (parser);
9043 component = component_tok->value;
9044 location_t end_loc = component_tok->get_finish ();
9045 c_parser_consume_token (parser);
9046 expr.value = objc_build_class_component_ref (class_name,
9047 component);
9048 set_c_expr_source_range (&expr, loc, end_loc);
9049 break;
9051 default:
9052 c_parser_error (parser, "expected expression");
9053 expr.set_error ();
9054 break;
9056 break;
9057 case CPP_OPEN_PAREN:
9058 /* A parenthesized expression, statement expression or compound
9059 literal. */
9060 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9062 /* A statement expression. */
9063 tree stmt;
9064 location_t brace_loc;
9065 c_parser_consume_token (parser);
9066 brace_loc = c_parser_peek_token (parser)->location;
9067 c_parser_consume_token (parser);
9068 /* If we've not yet started the current function's statement list,
9069 or we're in the parameter scope of an old-style function
9070 declaration, statement expressions are not allowed. */
9071 if (!building_stmt_list_p () || old_style_parameter_scope ())
9073 error_at (loc, "braced-group within expression allowed "
9074 "only inside a function");
9075 parser->error = true;
9076 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9077 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9078 expr.set_error ();
9079 break;
9081 stmt = c_begin_stmt_expr ();
9082 c_parser_compound_statement_nostart (parser);
9083 location_t close_loc = c_parser_peek_token (parser)->location;
9084 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9085 "expected %<)%>");
9086 pedwarn (loc, OPT_Wpedantic,
9087 "ISO C forbids braced-groups within expressions");
9088 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9089 set_c_expr_source_range (&expr, loc, close_loc);
9090 mark_exp_read (expr.value);
9092 else
9094 /* A parenthesized expression. */
9095 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9096 c_parser_consume_token (parser);
9097 expr = c_parser_expression (parser);
9098 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9099 suppress_warning (expr.value, OPT_Wparentheses);
9100 if (expr.original_code != C_MAYBE_CONST_EXPR
9101 && expr.original_code != SIZEOF_EXPR)
9102 expr.original_code = ERROR_MARK;
9103 /* Remember that we saw ( ) around the sizeof. */
9104 if (expr.original_code == SIZEOF_EXPR)
9105 expr.original_code = PAREN_SIZEOF_EXPR;
9106 /* Don't change EXPR.ORIGINAL_TYPE. */
9107 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9108 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9109 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9110 "expected %<)%>", loc_open_paren);
9112 break;
9113 case CPP_KEYWORD:
9114 switch (c_parser_peek_token (parser)->keyword)
9116 case RID_FUNCTION_NAME:
9117 case RID_PRETTY_FUNCTION_NAME:
9118 case RID_C99_FUNCTION_NAME:
9119 expr = c_parser_predefined_identifier (parser);
9120 break;
9121 case RID_VA_ARG:
9123 location_t start_loc = loc;
9124 c_parser_consume_token (parser);
9125 matching_parens parens;
9126 if (!parens.require_open (parser))
9128 expr.set_error ();
9129 break;
9131 e1 = c_parser_expr_no_commas (parser, NULL);
9132 mark_exp_read (e1.value);
9133 e1.value = c_fully_fold (e1.value, false, NULL);
9134 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9136 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9137 expr.set_error ();
9138 break;
9140 loc = c_parser_peek_token (parser)->location;
9141 t1 = c_parser_type_name (parser);
9142 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9143 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9144 "expected %<)%>");
9145 if (t1 == NULL)
9147 expr.set_error ();
9149 else
9151 tree type_expr = NULL_TREE;
9152 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9153 groktypename (t1, &type_expr, NULL));
9154 if (type_expr)
9156 expr.value = build2 (C_MAYBE_CONST_EXPR,
9157 TREE_TYPE (expr.value), type_expr,
9158 expr.value);
9159 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9161 set_c_expr_source_range (&expr, start_loc, end_loc);
9164 break;
9165 case RID_OFFSETOF:
9167 c_parser_consume_token (parser);
9168 matching_parens parens;
9169 if (!parens.require_open (parser))
9171 expr.set_error ();
9172 break;
9174 t1 = c_parser_type_name (parser);
9175 if (t1 == NULL)
9176 parser->error = true;
9177 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9178 gcc_assert (parser->error);
9179 if (parser->error)
9181 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9182 expr.set_error ();
9183 break;
9185 tree type = groktypename (t1, NULL, NULL);
9186 tree offsetof_ref;
9187 if (type == error_mark_node)
9188 offsetof_ref = error_mark_node;
9189 else
9191 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9192 SET_EXPR_LOCATION (offsetof_ref, loc);
9194 /* Parse the second argument to __builtin_offsetof. We
9195 must have one identifier, and beyond that we want to
9196 accept sub structure and sub array references. */
9197 if (c_parser_next_token_is (parser, CPP_NAME))
9199 c_token *comp_tok = c_parser_peek_token (parser);
9200 offsetof_ref = build_component_ref
9201 (loc, offsetof_ref, comp_tok->value, comp_tok->location);
9202 c_parser_consume_token (parser);
9203 while (c_parser_next_token_is (parser, CPP_DOT)
9204 || c_parser_next_token_is (parser,
9205 CPP_OPEN_SQUARE)
9206 || c_parser_next_token_is (parser,
9207 CPP_DEREF))
9209 if (c_parser_next_token_is (parser, CPP_DEREF))
9211 loc = c_parser_peek_token (parser)->location;
9212 offsetof_ref = build_array_ref (loc,
9213 offsetof_ref,
9214 integer_zero_node);
9215 goto do_dot;
9217 else if (c_parser_next_token_is (parser, CPP_DOT))
9219 do_dot:
9220 c_parser_consume_token (parser);
9221 if (c_parser_next_token_is_not (parser,
9222 CPP_NAME))
9224 c_parser_error (parser, "expected identifier");
9225 break;
9227 c_token *comp_tok = c_parser_peek_token (parser);
9228 offsetof_ref = build_component_ref
9229 (loc, offsetof_ref, comp_tok->value,
9230 comp_tok->location);
9231 c_parser_consume_token (parser);
9233 else
9235 struct c_expr ce;
9236 tree idx;
9237 loc = c_parser_peek_token (parser)->location;
9238 c_parser_consume_token (parser);
9239 ce = c_parser_expression (parser);
9240 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9241 idx = ce.value;
9242 idx = c_fully_fold (idx, false, NULL);
9243 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9244 "expected %<]%>");
9245 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9249 else
9250 c_parser_error (parser, "expected identifier");
9251 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9252 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9253 "expected %<)%>");
9254 expr.value = fold_offsetof (offsetof_ref);
9255 set_c_expr_source_range (&expr, loc, end_loc);
9257 break;
9258 case RID_CHOOSE_EXPR:
9260 vec<c_expr_t, va_gc> *cexpr_list;
9261 c_expr_t *e1_p, *e2_p, *e3_p;
9262 tree c;
9263 location_t close_paren_loc;
9265 c_parser_consume_token (parser);
9266 if (!c_parser_get_builtin_args (parser,
9267 "__builtin_choose_expr",
9268 &cexpr_list, true,
9269 &close_paren_loc))
9271 expr.set_error ();
9272 break;
9275 if (vec_safe_length (cexpr_list) != 3)
9277 error_at (loc, "wrong number of arguments to "
9278 "%<__builtin_choose_expr%>");
9279 expr.set_error ();
9280 break;
9283 e1_p = &(*cexpr_list)[0];
9284 e2_p = &(*cexpr_list)[1];
9285 e3_p = &(*cexpr_list)[2];
9287 c = e1_p->value;
9288 mark_exp_read (e2_p->value);
9289 mark_exp_read (e3_p->value);
9290 if (TREE_CODE (c) != INTEGER_CST
9291 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9292 error_at (loc,
9293 "first argument to %<__builtin_choose_expr%> not"
9294 " a constant");
9295 constant_expression_warning (c);
9296 expr = integer_zerop (c) ? *e3_p : *e2_p;
9297 set_c_expr_source_range (&expr, loc, close_paren_loc);
9298 break;
9300 case RID_TYPES_COMPATIBLE_P:
9302 c_parser_consume_token (parser);
9303 matching_parens parens;
9304 if (!parens.require_open (parser))
9306 expr.set_error ();
9307 break;
9309 t1 = c_parser_type_name (parser);
9310 if (t1 == NULL)
9312 expr.set_error ();
9313 break;
9315 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9317 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9318 expr.set_error ();
9319 break;
9321 t2 = c_parser_type_name (parser);
9322 if (t2 == NULL)
9324 expr.set_error ();
9325 break;
9327 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9328 parens.skip_until_found_close (parser);
9329 tree e1, e2;
9330 e1 = groktypename (t1, NULL, NULL);
9331 e2 = groktypename (t2, NULL, NULL);
9332 if (e1 == error_mark_node || e2 == error_mark_node)
9334 expr.set_error ();
9335 break;
9338 e1 = TYPE_MAIN_VARIANT (e1);
9339 e2 = TYPE_MAIN_VARIANT (e2);
9341 expr.value
9342 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9343 set_c_expr_source_range (&expr, loc, close_paren_loc);
9345 break;
9346 case RID_BUILTIN_TGMATH:
9348 vec<c_expr_t, va_gc> *cexpr_list;
9349 location_t close_paren_loc;
9351 c_parser_consume_token (parser);
9352 if (!c_parser_get_builtin_args (parser,
9353 "__builtin_tgmath",
9354 &cexpr_list, false,
9355 &close_paren_loc))
9357 expr.set_error ();
9358 break;
9361 if (vec_safe_length (cexpr_list) < 3)
9363 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9364 expr.set_error ();
9365 break;
9368 unsigned int i;
9369 c_expr_t *p;
9370 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9371 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9372 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9373 if (nargs == 0)
9375 expr.set_error ();
9376 break;
9378 if (vec_safe_length (cexpr_list) < nargs)
9380 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9381 expr.set_error ();
9382 break;
9384 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9385 if (num_functions < 2)
9387 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9388 expr.set_error ();
9389 break;
9392 /* The first NUM_FUNCTIONS expressions are the function
9393 pointers. The remaining NARGS expressions are the
9394 arguments that are to be passed to one of those
9395 functions, chosen following <tgmath.h> rules. */
9396 for (unsigned int j = 1; j < num_functions; j++)
9398 unsigned int this_nargs
9399 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9400 if (this_nargs == 0)
9402 expr.set_error ();
9403 goto out;
9405 if (this_nargs != nargs)
9407 error_at ((*cexpr_list)[j].get_location (),
9408 "argument %u of %<__builtin_tgmath%> has "
9409 "wrong number of arguments", j + 1);
9410 expr.set_error ();
9411 goto out;
9415 /* The functions all have the same number of arguments.
9416 Determine whether arguments and return types vary in
9417 ways permitted for <tgmath.h> functions. */
9418 /* The first entry in each of these vectors is for the
9419 return type, subsequent entries for parameter
9420 types. */
9421 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9422 auto_vec<tree> parm_first (nargs + 1);
9423 auto_vec<bool> parm_complex (nargs + 1);
9424 auto_vec<bool> parm_varies (nargs + 1);
9425 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9426 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9427 parm_first.quick_push (first_ret);
9428 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9429 parm_varies.quick_push (false);
9430 function_args_iterator iter;
9431 tree t;
9432 unsigned int argpos;
9433 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9435 if (t == void_type_node)
9436 break;
9437 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9438 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9439 parm_varies.quick_push (false);
9441 for (unsigned int j = 1; j < num_functions; j++)
9443 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9444 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9445 if (ret != parm_first[0])
9447 parm_varies[0] = true;
9448 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9449 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9451 error_at ((*cexpr_list)[0].get_location (),
9452 "invalid type-generic return type for "
9453 "argument %u of %<__builtin_tgmath%>",
9455 expr.set_error ();
9456 goto out;
9458 if (!SCALAR_FLOAT_TYPE_P (ret)
9459 && !COMPLEX_FLOAT_TYPE_P (ret))
9461 error_at ((*cexpr_list)[j].get_location (),
9462 "invalid type-generic return type for "
9463 "argument %u of %<__builtin_tgmath%>",
9464 j + 1);
9465 expr.set_error ();
9466 goto out;
9469 if (TREE_CODE (ret) == COMPLEX_TYPE)
9470 parm_complex[0] = true;
9471 argpos = 1;
9472 FOREACH_FUNCTION_ARGS (type, t, iter)
9474 if (t == void_type_node)
9475 break;
9476 t = TYPE_MAIN_VARIANT (t);
9477 if (t != parm_first[argpos])
9479 parm_varies[argpos] = true;
9480 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9481 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9483 error_at ((*cexpr_list)[0].get_location (),
9484 "invalid type-generic type for "
9485 "argument %u of argument %u of "
9486 "%<__builtin_tgmath%>", argpos, 1);
9487 expr.set_error ();
9488 goto out;
9490 if (!SCALAR_FLOAT_TYPE_P (t)
9491 && !COMPLEX_FLOAT_TYPE_P (t))
9493 error_at ((*cexpr_list)[j].get_location (),
9494 "invalid type-generic type for "
9495 "argument %u of argument %u of "
9496 "%<__builtin_tgmath%>", argpos, j + 1);
9497 expr.set_error ();
9498 goto out;
9501 if (TREE_CODE (t) == COMPLEX_TYPE)
9502 parm_complex[argpos] = true;
9503 argpos++;
9506 enum tgmath_parm_kind max_variation = tgmath_fixed;
9507 for (unsigned int j = 0; j <= nargs; j++)
9509 enum tgmath_parm_kind this_kind;
9510 if (parm_varies[j])
9512 if (parm_complex[j])
9513 max_variation = this_kind = tgmath_complex;
9514 else
9516 this_kind = tgmath_real;
9517 if (max_variation != tgmath_complex)
9518 max_variation = tgmath_real;
9521 else
9522 this_kind = tgmath_fixed;
9523 parm_kind.quick_push (this_kind);
9525 if (max_variation == tgmath_fixed)
9527 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9528 "all have the same type");
9529 expr.set_error ();
9530 break;
9533 /* Identify a parameter (not the return type) that varies,
9534 including with complex types if any variation includes
9535 complex types; there must be at least one such
9536 parameter. */
9537 unsigned int tgarg = 0;
9538 for (unsigned int j = 1; j <= nargs; j++)
9539 if (parm_kind[j] == max_variation)
9541 tgarg = j;
9542 break;
9544 if (tgarg == 0)
9546 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9547 "lack type-generic parameter");
9548 expr.set_error ();
9549 break;
9552 /* Determine the type of the relevant parameter for each
9553 function. */
9554 auto_vec<tree> tg_type (num_functions);
9555 for (unsigned int j = 0; j < num_functions; j++)
9557 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9558 argpos = 1;
9559 FOREACH_FUNCTION_ARGS (type, t, iter)
9561 if (argpos == tgarg)
9563 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9564 break;
9566 argpos++;
9570 /* Verify that the corresponding types are different for
9571 all the listed functions. Also determine whether all
9572 the types are complex, whether all the types are
9573 standard or binary, and whether all the types are
9574 decimal. */
9575 bool all_complex = true;
9576 bool all_binary = true;
9577 bool all_decimal = true;
9578 hash_set<tree> tg_types;
9579 FOR_EACH_VEC_ELT (tg_type, i, t)
9581 if (TREE_CODE (t) == COMPLEX_TYPE)
9582 all_decimal = false;
9583 else
9585 all_complex = false;
9586 if (DECIMAL_FLOAT_TYPE_P (t))
9587 all_binary = false;
9588 else
9589 all_decimal = false;
9591 if (tg_types.add (t))
9593 error_at ((*cexpr_list)[i].get_location (),
9594 "duplicate type-generic parameter type for "
9595 "function argument %u of %<__builtin_tgmath%>",
9596 i + 1);
9597 expr.set_error ();
9598 goto out;
9602 /* Verify that other parameters and the return type whose
9603 types vary have their types varying in the correct
9604 way. */
9605 for (unsigned int j = 0; j < num_functions; j++)
9607 tree exp_type = tg_type[j];
9608 tree exp_real_type = exp_type;
9609 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9610 exp_real_type = TREE_TYPE (exp_type);
9611 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9612 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9613 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9614 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9616 error_at ((*cexpr_list)[j].get_location (),
9617 "bad return type for function argument %u "
9618 "of %<__builtin_tgmath%>", j + 1);
9619 expr.set_error ();
9620 goto out;
9622 argpos = 1;
9623 FOREACH_FUNCTION_ARGS (type, t, iter)
9625 if (t == void_type_node)
9626 break;
9627 t = TYPE_MAIN_VARIANT (t);
9628 if ((parm_kind[argpos] == tgmath_complex
9629 && t != exp_type)
9630 || (parm_kind[argpos] == tgmath_real
9631 && t != exp_real_type))
9633 error_at ((*cexpr_list)[j].get_location (),
9634 "bad type for argument %u of "
9635 "function argument %u of "
9636 "%<__builtin_tgmath%>", argpos, j + 1);
9637 expr.set_error ();
9638 goto out;
9640 argpos++;
9644 /* The functions listed are a valid set of functions for a
9645 <tgmath.h> macro to select between. Identify the
9646 matching function, if any. First, the argument types
9647 must be combined following <tgmath.h> rules. Integer
9648 types are treated as _Decimal64 if any type-generic
9649 argument is decimal, or if the only alternatives for
9650 type-generic arguments are of decimal types, and are
9651 otherwise treated as double (or _Complex double for
9652 complex integer types, or _Float64 or _Complex _Float64
9653 if all the return types are the same _FloatN or
9654 _FloatNx type). After that adjustment, types are
9655 combined following the usual arithmetic conversions.
9656 If the function only accepts complex arguments, a
9657 complex type is produced. */
9658 bool arg_complex = all_complex;
9659 bool arg_binary = all_binary;
9660 bool arg_int_decimal = all_decimal;
9661 for (unsigned int j = 1; j <= nargs; j++)
9663 if (parm_kind[j] == tgmath_fixed)
9664 continue;
9665 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9666 tree type = TREE_TYPE (ce->value);
9667 if (!INTEGRAL_TYPE_P (type)
9668 && !SCALAR_FLOAT_TYPE_P (type)
9669 && TREE_CODE (type) != COMPLEX_TYPE)
9671 error_at (ce->get_location (),
9672 "invalid type of argument %u of type-generic "
9673 "function", j);
9674 expr.set_error ();
9675 goto out;
9677 if (DECIMAL_FLOAT_TYPE_P (type))
9679 arg_int_decimal = true;
9680 if (all_complex)
9682 error_at (ce->get_location (),
9683 "decimal floating-point argument %u to "
9684 "complex-only type-generic function", j);
9685 expr.set_error ();
9686 goto out;
9688 else if (all_binary)
9690 error_at (ce->get_location (),
9691 "decimal floating-point argument %u to "
9692 "binary-only type-generic function", j);
9693 expr.set_error ();
9694 goto out;
9696 else if (arg_complex)
9698 error_at (ce->get_location (),
9699 "both complex and decimal floating-point "
9700 "arguments to type-generic function");
9701 expr.set_error ();
9702 goto out;
9704 else if (arg_binary)
9706 error_at (ce->get_location (),
9707 "both binary and decimal floating-point "
9708 "arguments to type-generic function");
9709 expr.set_error ();
9710 goto out;
9713 else if (TREE_CODE (type) == COMPLEX_TYPE)
9715 arg_complex = true;
9716 if (COMPLEX_FLOAT_TYPE_P (type))
9717 arg_binary = true;
9718 if (all_decimal)
9720 error_at (ce->get_location (),
9721 "complex argument %u to "
9722 "decimal-only type-generic function", j);
9723 expr.set_error ();
9724 goto out;
9726 else if (arg_int_decimal)
9728 error_at (ce->get_location (),
9729 "both complex and decimal floating-point "
9730 "arguments to type-generic function");
9731 expr.set_error ();
9732 goto out;
9735 else if (SCALAR_FLOAT_TYPE_P (type))
9737 arg_binary = true;
9738 if (all_decimal)
9740 error_at (ce->get_location (),
9741 "binary argument %u to "
9742 "decimal-only type-generic function", j);
9743 expr.set_error ();
9744 goto out;
9746 else if (arg_int_decimal)
9748 error_at (ce->get_location (),
9749 "both binary and decimal floating-point "
9750 "arguments to type-generic function");
9751 expr.set_error ();
9752 goto out;
9756 /* For a macro rounding its result to a narrower type, map
9757 integer types to _Float64 not double if the return type
9758 is a _FloatN or _FloatNx type. */
9759 bool arg_int_float64 = false;
9760 if (parm_kind[0] == tgmath_fixed
9761 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9762 && float64_type_node != NULL_TREE)
9763 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9764 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9766 arg_int_float64 = true;
9767 break;
9769 tree arg_real = NULL_TREE;
9770 for (unsigned int j = 1; j <= nargs; j++)
9772 if (parm_kind[j] == tgmath_fixed)
9773 continue;
9774 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9775 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9776 if (TREE_CODE (type) == COMPLEX_TYPE)
9777 type = TREE_TYPE (type);
9778 if (INTEGRAL_TYPE_P (type))
9779 type = (arg_int_decimal
9780 ? dfloat64_type_node
9781 : arg_int_float64
9782 ? float64_type_node
9783 : double_type_node);
9784 if (arg_real == NULL_TREE)
9785 arg_real = type;
9786 else
9787 arg_real = common_type (arg_real, type);
9788 if (arg_real == error_mark_node)
9790 expr.set_error ();
9791 goto out;
9794 tree arg_type = (arg_complex
9795 ? build_complex_type (arg_real)
9796 : arg_real);
9798 /* Look for a function to call with type-generic parameter
9799 type ARG_TYPE. */
9800 c_expr_t *fn = NULL;
9801 for (unsigned int j = 0; j < num_functions; j++)
9803 if (tg_type[j] == arg_type)
9805 fn = &(*cexpr_list)[j];
9806 break;
9809 if (fn == NULL
9810 && parm_kind[0] == tgmath_fixed
9811 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9813 /* Presume this is a macro that rounds its result to a
9814 narrower type, and look for the first function with
9815 at least the range and precision of the argument
9816 type. */
9817 for (unsigned int j = 0; j < num_functions; j++)
9819 if (arg_complex
9820 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9821 continue;
9822 tree real_tg_type = (arg_complex
9823 ? TREE_TYPE (tg_type[j])
9824 : tg_type[j]);
9825 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9826 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9827 continue;
9828 scalar_float_mode arg_mode
9829 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9830 scalar_float_mode tg_mode
9831 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9832 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9833 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9834 if (arg_fmt->b == tg_fmt->b
9835 && arg_fmt->p <= tg_fmt->p
9836 && arg_fmt->emax <= tg_fmt->emax
9837 && (arg_fmt->emin - arg_fmt->p
9838 >= tg_fmt->emin - tg_fmt->p))
9840 fn = &(*cexpr_list)[j];
9841 break;
9845 if (fn == NULL)
9847 error_at (loc, "no matching function for type-generic call");
9848 expr.set_error ();
9849 break;
9852 /* Construct a call to FN. */
9853 vec<tree, va_gc> *args;
9854 vec_alloc (args, nargs);
9855 vec<tree, va_gc> *origtypes;
9856 vec_alloc (origtypes, nargs);
9857 auto_vec<location_t> arg_loc (nargs);
9858 for (unsigned int j = 0; j < nargs; j++)
9860 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9861 args->quick_push (ce->value);
9862 arg_loc.quick_push (ce->get_location ());
9863 origtypes->quick_push (ce->original_type);
9865 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9866 args, origtypes);
9867 set_c_expr_source_range (&expr, loc, close_paren_loc);
9868 break;
9870 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9872 vec<c_expr_t, va_gc> *cexpr_list;
9873 c_expr_t *e2_p;
9874 tree chain_value;
9875 location_t close_paren_loc;
9877 c_parser_consume_token (parser);
9878 if (!c_parser_get_builtin_args (parser,
9879 "__builtin_call_with_static_chain",
9880 &cexpr_list, false,
9881 &close_paren_loc))
9883 expr.set_error ();
9884 break;
9886 if (vec_safe_length (cexpr_list) != 2)
9888 error_at (loc, "wrong number of arguments to "
9889 "%<__builtin_call_with_static_chain%>");
9890 expr.set_error ();
9891 break;
9894 expr = (*cexpr_list)[0];
9895 e2_p = &(*cexpr_list)[1];
9896 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9897 chain_value = e2_p->value;
9898 mark_exp_read (chain_value);
9900 if (TREE_CODE (expr.value) != CALL_EXPR)
9901 error_at (loc, "first argument to "
9902 "%<__builtin_call_with_static_chain%> "
9903 "must be a call expression");
9904 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9905 error_at (loc, "second argument to "
9906 "%<__builtin_call_with_static_chain%> "
9907 "must be a pointer type");
9908 else
9909 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9910 set_c_expr_source_range (&expr, loc, close_paren_loc);
9911 break;
9913 case RID_BUILTIN_COMPLEX:
9915 vec<c_expr_t, va_gc> *cexpr_list;
9916 c_expr_t *e1_p, *e2_p;
9917 location_t close_paren_loc;
9919 c_parser_consume_token (parser);
9920 if (!c_parser_get_builtin_args (parser,
9921 "__builtin_complex",
9922 &cexpr_list, false,
9923 &close_paren_loc))
9925 expr.set_error ();
9926 break;
9929 if (vec_safe_length (cexpr_list) != 2)
9931 error_at (loc, "wrong number of arguments to "
9932 "%<__builtin_complex%>");
9933 expr.set_error ();
9934 break;
9937 e1_p = &(*cexpr_list)[0];
9938 e2_p = &(*cexpr_list)[1];
9940 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9941 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9942 e1_p->value = convert (TREE_TYPE (e1_p->value),
9943 TREE_OPERAND (e1_p->value, 0));
9944 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9945 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9946 e2_p->value = convert (TREE_TYPE (e2_p->value),
9947 TREE_OPERAND (e2_p->value, 0));
9948 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9949 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9950 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9951 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9953 error_at (loc, "%<__builtin_complex%> operand "
9954 "not of real binary floating-point type");
9955 expr.set_error ();
9956 break;
9958 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
9959 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
9961 error_at (loc,
9962 "%<__builtin_complex%> operands of different types");
9963 expr.set_error ();
9964 break;
9966 pedwarn_c90 (loc, OPT_Wpedantic,
9967 "ISO C90 does not support complex types");
9968 expr.value = build2_loc (loc, COMPLEX_EXPR,
9969 build_complex_type
9970 (TYPE_MAIN_VARIANT
9971 (TREE_TYPE (e1_p->value))),
9972 e1_p->value, e2_p->value);
9973 set_c_expr_source_range (&expr, loc, close_paren_loc);
9974 break;
9976 case RID_BUILTIN_SHUFFLE:
9978 vec<c_expr_t, va_gc> *cexpr_list;
9979 unsigned int i;
9980 c_expr_t *p;
9981 location_t close_paren_loc;
9983 c_parser_consume_token (parser);
9984 if (!c_parser_get_builtin_args (parser,
9985 "__builtin_shuffle",
9986 &cexpr_list, false,
9987 &close_paren_loc))
9989 expr.set_error ();
9990 break;
9993 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
9994 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9996 if (vec_safe_length (cexpr_list) == 2)
9997 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
9998 NULL_TREE,
9999 (*cexpr_list)[1].value);
10001 else if (vec_safe_length (cexpr_list) == 3)
10002 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10003 (*cexpr_list)[1].value,
10004 (*cexpr_list)[2].value);
10005 else
10007 error_at (loc, "wrong number of arguments to "
10008 "%<__builtin_shuffle%>");
10009 expr.set_error ();
10011 set_c_expr_source_range (&expr, loc, close_paren_loc);
10012 break;
10014 case RID_BUILTIN_SHUFFLEVECTOR:
10016 vec<c_expr_t, va_gc> *cexpr_list;
10017 unsigned int i;
10018 c_expr_t *p;
10019 location_t close_paren_loc;
10021 c_parser_consume_token (parser);
10022 if (!c_parser_get_builtin_args (parser,
10023 "__builtin_shufflevector",
10024 &cexpr_list, false,
10025 &close_paren_loc))
10027 expr.set_error ();
10028 break;
10031 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10032 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10034 if (vec_safe_length (cexpr_list) < 3)
10036 error_at (loc, "wrong number of arguments to "
10037 "%<__builtin_shuffle%>");
10038 expr.set_error ();
10040 else
10042 auto_vec<tree, 16> mask;
10043 for (i = 2; i < cexpr_list->length (); ++i)
10044 mask.safe_push ((*cexpr_list)[i].value);
10045 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10046 (*cexpr_list)[1].value,
10047 mask);
10049 set_c_expr_source_range (&expr, loc, close_paren_loc);
10050 break;
10052 case RID_BUILTIN_CONVERTVECTOR:
10054 location_t start_loc = loc;
10055 c_parser_consume_token (parser);
10056 matching_parens parens;
10057 if (!parens.require_open (parser))
10059 expr.set_error ();
10060 break;
10062 e1 = c_parser_expr_no_commas (parser, NULL);
10063 mark_exp_read (e1.value);
10064 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10066 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10067 expr.set_error ();
10068 break;
10070 loc = c_parser_peek_token (parser)->location;
10071 t1 = c_parser_type_name (parser);
10072 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10073 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10074 "expected %<)%>");
10075 if (t1 == NULL)
10076 expr.set_error ();
10077 else
10079 tree type_expr = NULL_TREE;
10080 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10081 groktypename (t1, &type_expr,
10082 NULL));
10083 set_c_expr_source_range (&expr, start_loc, end_loc);
10086 break;
10087 case RID_AT_SELECTOR:
10089 gcc_assert (c_dialect_objc ());
10090 c_parser_consume_token (parser);
10091 matching_parens parens;
10092 if (!parens.require_open (parser))
10094 expr.set_error ();
10095 break;
10097 tree sel = c_parser_objc_selector_arg (parser);
10098 location_t close_loc = c_parser_peek_token (parser)->location;
10099 parens.skip_until_found_close (parser);
10100 expr.value = objc_build_selector_expr (loc, sel);
10101 set_c_expr_source_range (&expr, loc, close_loc);
10103 break;
10104 case RID_AT_PROTOCOL:
10106 gcc_assert (c_dialect_objc ());
10107 c_parser_consume_token (parser);
10108 matching_parens parens;
10109 if (!parens.require_open (parser))
10111 expr.set_error ();
10112 break;
10114 if (c_parser_next_token_is_not (parser, CPP_NAME))
10116 c_parser_error (parser, "expected identifier");
10117 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10118 expr.set_error ();
10119 break;
10121 tree id = c_parser_peek_token (parser)->value;
10122 c_parser_consume_token (parser);
10123 location_t close_loc = c_parser_peek_token (parser)->location;
10124 parens.skip_until_found_close (parser);
10125 expr.value = objc_build_protocol_expr (id);
10126 set_c_expr_source_range (&expr, loc, close_loc);
10128 break;
10129 case RID_AT_ENCODE:
10131 /* Extension to support C-structures in the archiver. */
10132 gcc_assert (c_dialect_objc ());
10133 c_parser_consume_token (parser);
10134 matching_parens parens;
10135 if (!parens.require_open (parser))
10137 expr.set_error ();
10138 break;
10140 t1 = c_parser_type_name (parser);
10141 if (t1 == NULL)
10143 expr.set_error ();
10144 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10145 break;
10147 location_t close_loc = c_parser_peek_token (parser)->location;
10148 parens.skip_until_found_close (parser);
10149 tree type = groktypename (t1, NULL, NULL);
10150 expr.value = objc_build_encode_expr (type);
10151 set_c_expr_source_range (&expr, loc, close_loc);
10153 break;
10154 case RID_GENERIC:
10155 expr = c_parser_generic_selection (parser);
10156 break;
10157 default:
10158 c_parser_error (parser, "expected expression");
10159 expr.set_error ();
10160 break;
10162 break;
10163 case CPP_OPEN_SQUARE:
10164 if (c_dialect_objc ())
10166 tree receiver, args;
10167 c_parser_consume_token (parser);
10168 receiver = c_parser_objc_receiver (parser);
10169 args = c_parser_objc_message_args (parser);
10170 location_t close_loc = c_parser_peek_token (parser)->location;
10171 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10172 "expected %<]%>");
10173 expr.value = objc_build_message_expr (receiver, args);
10174 set_c_expr_source_range (&expr, loc, close_loc);
10175 break;
10177 /* Else fall through to report error. */
10178 /* FALLTHRU */
10179 default:
10180 c_parser_error (parser, "expected expression");
10181 expr.set_error ();
10182 break;
10184 out:
10185 return c_parser_postfix_expression_after_primary
10186 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10189 /* Parse a postfix expression after a parenthesized type name: the
10190 brace-enclosed initializer of a compound literal, possibly followed
10191 by some postfix operators. This is separate because it is not
10192 possible to tell until after the type name whether a cast
10193 expression has a cast or a compound literal, or whether the operand
10194 of sizeof is a parenthesized type name or starts with a compound
10195 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10196 location of the first token after the parentheses around the type
10197 name. */
10199 static struct c_expr
10200 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10201 struct c_type_name *type_name,
10202 location_t type_loc)
10204 tree type;
10205 struct c_expr init;
10206 bool non_const;
10207 struct c_expr expr;
10208 location_t start_loc;
10209 tree type_expr = NULL_TREE;
10210 bool type_expr_const = true;
10211 check_compound_literal_type (type_loc, type_name);
10212 rich_location richloc (line_table, type_loc);
10213 start_init (NULL_TREE, NULL, 0, &richloc);
10214 type = groktypename (type_name, &type_expr, &type_expr_const);
10215 start_loc = c_parser_peek_token (parser)->location;
10216 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10218 error_at (type_loc, "compound literal has variable size");
10219 type = error_mark_node;
10221 init = c_parser_braced_init (parser, type, false, NULL);
10222 finish_init ();
10223 maybe_warn_string_init (type_loc, type, init);
10225 if (type != error_mark_node
10226 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10227 && current_function_decl)
10229 error ("compound literal qualified by address-space qualifier");
10230 type = error_mark_node;
10233 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10234 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10235 ? CONSTRUCTOR_NON_CONST (init.value)
10236 : init.original_code == C_MAYBE_CONST_EXPR);
10237 non_const |= !type_expr_const;
10238 unsigned int alignas_align = 0;
10239 if (type != error_mark_node
10240 && type_name->specs->align_log != -1)
10242 alignas_align = 1U << type_name->specs->align_log;
10243 if (alignas_align < min_align_of_type (type))
10245 error_at (type_name->specs->locations[cdw_alignas],
10246 "%<_Alignas%> specifiers cannot reduce "
10247 "alignment of compound literal");
10248 alignas_align = 0;
10251 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10252 alignas_align);
10253 set_c_expr_source_range (&expr, init.src_range);
10254 expr.original_code = ERROR_MARK;
10255 expr.original_type = NULL;
10256 if (type != error_mark_node
10257 && expr.value != error_mark_node
10258 && type_expr)
10260 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10262 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10263 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10265 else
10267 gcc_assert (!non_const);
10268 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10269 type_expr, expr.value);
10272 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10275 /* Callback function for sizeof_pointer_memaccess_warning to compare
10276 types. */
10278 static bool
10279 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10281 return comptypes (type1, type2) == 1;
10284 /* Warn for patterns where abs-like function appears to be used incorrectly,
10285 gracefully ignore any non-abs-like function. The warning location should
10286 be LOC. FNDECL is the declaration of called function, it must be a
10287 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10288 call. */
10290 static void
10291 warn_for_abs (location_t loc, tree fndecl, tree arg)
10293 /* Avoid warning in unreachable subexpressions. */
10294 if (c_inhibit_evaluation_warnings)
10295 return;
10297 tree atype = TREE_TYPE (arg);
10299 /* Casts from pointers (and thus arrays and fndecls) will generate
10300 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10301 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10302 types and possibly other exotic types. */
10303 if (!INTEGRAL_TYPE_P (atype)
10304 && !SCALAR_FLOAT_TYPE_P (atype)
10305 && TREE_CODE (atype) != COMPLEX_TYPE)
10306 return;
10308 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10310 switch (fcode)
10312 case BUILT_IN_ABS:
10313 case BUILT_IN_LABS:
10314 case BUILT_IN_LLABS:
10315 case BUILT_IN_IMAXABS:
10316 if (!INTEGRAL_TYPE_P (atype))
10318 if (SCALAR_FLOAT_TYPE_P (atype))
10319 warning_at (loc, OPT_Wabsolute_value,
10320 "using integer absolute value function %qD when "
10321 "argument is of floating-point type %qT",
10322 fndecl, atype);
10323 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10324 warning_at (loc, OPT_Wabsolute_value,
10325 "using integer absolute value function %qD when "
10326 "argument is of complex type %qT", fndecl, atype);
10327 else
10328 gcc_unreachable ();
10329 return;
10331 if (TYPE_UNSIGNED (atype))
10332 warning_at (loc, OPT_Wabsolute_value,
10333 "taking the absolute value of unsigned type %qT "
10334 "has no effect", atype);
10335 break;
10337 CASE_FLT_FN (BUILT_IN_FABS):
10338 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10339 if (!SCALAR_FLOAT_TYPE_P (atype)
10340 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10342 if (INTEGRAL_TYPE_P (atype))
10343 warning_at (loc, OPT_Wabsolute_value,
10344 "using floating-point absolute value function %qD "
10345 "when argument is of integer type %qT", fndecl, atype);
10346 else if (DECIMAL_FLOAT_TYPE_P (atype))
10347 warning_at (loc, OPT_Wabsolute_value,
10348 "using floating-point absolute value function %qD "
10349 "when argument is of decimal floating-point type %qT",
10350 fndecl, atype);
10351 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10352 warning_at (loc, OPT_Wabsolute_value,
10353 "using floating-point absolute value function %qD when "
10354 "argument is of complex type %qT", fndecl, atype);
10355 else
10356 gcc_unreachable ();
10357 return;
10359 break;
10361 CASE_FLT_FN (BUILT_IN_CABS):
10362 if (TREE_CODE (atype) != COMPLEX_TYPE)
10364 if (INTEGRAL_TYPE_P (atype))
10365 warning_at (loc, OPT_Wabsolute_value,
10366 "using complex absolute value function %qD when "
10367 "argument is of integer type %qT", fndecl, atype);
10368 else if (SCALAR_FLOAT_TYPE_P (atype))
10369 warning_at (loc, OPT_Wabsolute_value,
10370 "using complex absolute value function %qD when "
10371 "argument is of floating-point type %qT",
10372 fndecl, atype);
10373 else
10374 gcc_unreachable ();
10376 return;
10378 break;
10380 case BUILT_IN_FABSD32:
10381 case BUILT_IN_FABSD64:
10382 case BUILT_IN_FABSD128:
10383 if (!DECIMAL_FLOAT_TYPE_P (atype))
10385 if (INTEGRAL_TYPE_P (atype))
10386 warning_at (loc, OPT_Wabsolute_value,
10387 "using decimal floating-point absolute value "
10388 "function %qD when argument is of integer type %qT",
10389 fndecl, atype);
10390 else if (SCALAR_FLOAT_TYPE_P (atype))
10391 warning_at (loc, OPT_Wabsolute_value,
10392 "using decimal floating-point absolute value "
10393 "function %qD when argument is of floating-point "
10394 "type %qT", fndecl, atype);
10395 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10396 warning_at (loc, OPT_Wabsolute_value,
10397 "using decimal floating-point absolute value "
10398 "function %qD when argument is of complex type %qT",
10399 fndecl, atype);
10400 else
10401 gcc_unreachable ();
10402 return;
10404 break;
10406 default:
10407 return;
10410 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10411 return;
10413 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10414 if (TREE_CODE (atype) == COMPLEX_TYPE)
10416 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10417 atype = TREE_TYPE (atype);
10418 ftype = TREE_TYPE (ftype);
10421 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10422 warning_at (loc, OPT_Wabsolute_value,
10423 "absolute value function %qD given an argument of type %qT "
10424 "but has parameter of type %qT which may cause truncation "
10425 "of value", fndecl, atype, ftype);
10429 /* Parse a postfix expression after the initial primary or compound
10430 literal; that is, parse a series of postfix operators.
10432 EXPR_LOC is the location of the primary expression. */
10434 static struct c_expr
10435 c_parser_postfix_expression_after_primary (c_parser *parser,
10436 location_t expr_loc,
10437 struct c_expr expr)
10439 struct c_expr orig_expr;
10440 tree ident, idx;
10441 location_t sizeof_arg_loc[3], comp_loc;
10442 tree sizeof_arg[3];
10443 unsigned int literal_zero_mask;
10444 unsigned int i;
10445 vec<tree, va_gc> *exprlist;
10446 vec<tree, va_gc> *origtypes = NULL;
10447 vec<location_t> arg_loc = vNULL;
10448 location_t start;
10449 location_t finish;
10451 while (true)
10453 location_t op_loc = c_parser_peek_token (parser)->location;
10454 switch (c_parser_peek_token (parser)->type)
10456 case CPP_OPEN_SQUARE:
10457 /* Array reference. */
10458 c_parser_consume_token (parser);
10459 idx = c_parser_expression (parser).value;
10460 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10461 "expected %<]%>");
10462 start = expr.get_start ();
10463 finish = parser->tokens_buf[0].location;
10464 expr.value = build_array_ref (op_loc, expr.value, idx);
10465 set_c_expr_source_range (&expr, start, finish);
10466 expr.original_code = ERROR_MARK;
10467 expr.original_type = NULL;
10468 break;
10469 case CPP_OPEN_PAREN:
10470 /* Function call. */
10472 matching_parens parens;
10473 parens.consume_open (parser);
10474 for (i = 0; i < 3; i++)
10476 sizeof_arg[i] = NULL_TREE;
10477 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10479 literal_zero_mask = 0;
10480 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10481 exprlist = NULL;
10482 else
10483 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10484 sizeof_arg_loc, sizeof_arg,
10485 &arg_loc, &literal_zero_mask);
10486 parens.skip_until_found_close (parser);
10488 orig_expr = expr;
10489 mark_exp_read (expr.value);
10490 if (warn_sizeof_pointer_memaccess)
10491 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10492 expr.value, exprlist,
10493 sizeof_arg,
10494 sizeof_ptr_memacc_comptypes);
10495 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10497 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10498 && vec_safe_length (exprlist) == 3)
10500 tree arg0 = (*exprlist)[0];
10501 tree arg2 = (*exprlist)[2];
10502 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10504 if (warn_absolute_value
10505 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10506 && vec_safe_length (exprlist) == 1)
10507 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10510 start = expr.get_start ();
10511 finish = parser->tokens_buf[0].get_finish ();
10512 expr.value
10513 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10514 exprlist, origtypes);
10515 set_c_expr_source_range (&expr, start, finish);
10517 expr.original_code = ERROR_MARK;
10518 if (TREE_CODE (expr.value) == INTEGER_CST
10519 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10520 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10521 expr.original_code = C_MAYBE_CONST_EXPR;
10522 expr.original_type = NULL;
10523 if (exprlist)
10525 release_tree_vector (exprlist);
10526 release_tree_vector (origtypes);
10528 arg_loc.release ();
10529 break;
10530 case CPP_DOT:
10531 /* Structure element reference. */
10532 c_parser_consume_token (parser);
10533 expr = default_function_array_conversion (expr_loc, expr);
10534 if (c_parser_next_token_is (parser, CPP_NAME))
10536 c_token *comp_tok = c_parser_peek_token (parser);
10537 ident = comp_tok->value;
10538 comp_loc = comp_tok->location;
10540 else
10542 c_parser_error (parser, "expected identifier");
10543 expr.set_error ();
10544 expr.original_code = ERROR_MARK;
10545 expr.original_type = NULL;
10546 return expr;
10548 start = expr.get_start ();
10549 finish = c_parser_peek_token (parser)->get_finish ();
10550 c_parser_consume_token (parser);
10551 expr.value = build_component_ref (op_loc, expr.value, ident,
10552 comp_loc);
10553 set_c_expr_source_range (&expr, start, finish);
10554 expr.original_code = ERROR_MARK;
10555 if (TREE_CODE (expr.value) != COMPONENT_REF)
10556 expr.original_type = NULL;
10557 else
10559 /* Remember the original type of a bitfield. */
10560 tree field = TREE_OPERAND (expr.value, 1);
10561 if (TREE_CODE (field) != FIELD_DECL)
10562 expr.original_type = NULL;
10563 else
10564 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10566 break;
10567 case CPP_DEREF:
10568 /* Structure element reference. */
10569 c_parser_consume_token (parser);
10570 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10571 if (c_parser_next_token_is (parser, CPP_NAME))
10573 c_token *comp_tok = c_parser_peek_token (parser);
10574 ident = comp_tok->value;
10575 comp_loc = comp_tok->location;
10577 else
10579 c_parser_error (parser, "expected identifier");
10580 expr.set_error ();
10581 expr.original_code = ERROR_MARK;
10582 expr.original_type = NULL;
10583 return expr;
10585 start = expr.get_start ();
10586 finish = c_parser_peek_token (parser)->get_finish ();
10587 c_parser_consume_token (parser);
10588 expr.value = build_component_ref (op_loc,
10589 build_indirect_ref (op_loc,
10590 expr.value,
10591 RO_ARROW),
10592 ident, comp_loc);
10593 set_c_expr_source_range (&expr, start, finish);
10594 expr.original_code = ERROR_MARK;
10595 if (TREE_CODE (expr.value) != COMPONENT_REF)
10596 expr.original_type = NULL;
10597 else
10599 /* Remember the original type of a bitfield. */
10600 tree field = TREE_OPERAND (expr.value, 1);
10601 if (TREE_CODE (field) != FIELD_DECL)
10602 expr.original_type = NULL;
10603 else
10604 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10606 break;
10607 case CPP_PLUS_PLUS:
10608 /* Postincrement. */
10609 start = expr.get_start ();
10610 finish = c_parser_peek_token (parser)->get_finish ();
10611 c_parser_consume_token (parser);
10612 expr = default_function_array_read_conversion (expr_loc, expr);
10613 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10614 expr.value, false);
10615 set_c_expr_source_range (&expr, start, finish);
10616 expr.original_code = ERROR_MARK;
10617 expr.original_type = NULL;
10618 break;
10619 case CPP_MINUS_MINUS:
10620 /* Postdecrement. */
10621 start = expr.get_start ();
10622 finish = c_parser_peek_token (parser)->get_finish ();
10623 c_parser_consume_token (parser);
10624 expr = default_function_array_read_conversion (expr_loc, expr);
10625 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10626 expr.value, false);
10627 set_c_expr_source_range (&expr, start, finish);
10628 expr.original_code = ERROR_MARK;
10629 expr.original_type = NULL;
10630 break;
10631 default:
10632 return expr;
10637 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10639 expression:
10640 assignment-expression
10641 expression , assignment-expression
10644 static struct c_expr
10645 c_parser_expression (c_parser *parser)
10647 location_t tloc = c_parser_peek_token (parser)->location;
10648 struct c_expr expr;
10649 expr = c_parser_expr_no_commas (parser, NULL);
10650 if (c_parser_next_token_is (parser, CPP_COMMA))
10651 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10652 while (c_parser_next_token_is (parser, CPP_COMMA))
10654 struct c_expr next;
10655 tree lhsval;
10656 location_t loc = c_parser_peek_token (parser)->location;
10657 location_t expr_loc;
10658 c_parser_consume_token (parser);
10659 expr_loc = c_parser_peek_token (parser)->location;
10660 lhsval = expr.value;
10661 while (TREE_CODE (lhsval) == COMPOUND_EXPR
10662 || TREE_CODE (lhsval) == NOP_EXPR)
10664 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10665 lhsval = TREE_OPERAND (lhsval, 1);
10666 else
10667 lhsval = TREE_OPERAND (lhsval, 0);
10669 if (DECL_P (lhsval) || handled_component_p (lhsval))
10670 mark_exp_read (lhsval);
10671 next = c_parser_expr_no_commas (parser, NULL);
10672 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10673 expr.value = build_compound_expr (loc, expr.value, next.value);
10674 expr.original_code = COMPOUND_EXPR;
10675 expr.original_type = next.original_type;
10677 return expr;
10680 /* Parse an expression and convert functions or arrays to pointers and
10681 lvalues to rvalues. */
10683 static struct c_expr
10684 c_parser_expression_conv (c_parser *parser)
10686 struct c_expr expr;
10687 location_t loc = c_parser_peek_token (parser)->location;
10688 expr = c_parser_expression (parser);
10689 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10690 return expr;
10693 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10694 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10696 static inline void
10697 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10698 unsigned int idx)
10700 if (idx >= HOST_BITS_PER_INT)
10701 return;
10703 c_token *tok = c_parser_peek_token (parser);
10704 switch (tok->type)
10706 case CPP_NUMBER:
10707 case CPP_CHAR:
10708 case CPP_WCHAR:
10709 case CPP_CHAR16:
10710 case CPP_CHAR32:
10711 case CPP_UTF8CHAR:
10712 /* If a parameter is literal zero alone, remember it
10713 for -Wmemset-transposed-args warning. */
10714 if (integer_zerop (tok->value)
10715 && !TREE_OVERFLOW (tok->value)
10716 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10717 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10718 *literal_zero_mask |= 1U << idx;
10719 default:
10720 break;
10724 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10725 functions and arrays to pointers and lvalues to rvalues. If
10726 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10727 locations of function arguments into this vector.
10729 nonempty-expr-list:
10730 assignment-expression
10731 nonempty-expr-list , assignment-expression
10734 static vec<tree, va_gc> *
10735 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10736 vec<tree, va_gc> **p_orig_types,
10737 location_t *sizeof_arg_loc, tree *sizeof_arg,
10738 vec<location_t> *locations,
10739 unsigned int *literal_zero_mask)
10741 vec<tree, va_gc> *ret;
10742 vec<tree, va_gc> *orig_types;
10743 struct c_expr expr;
10744 unsigned int idx = 0;
10746 ret = make_tree_vector ();
10747 if (p_orig_types == NULL)
10748 orig_types = NULL;
10749 else
10750 orig_types = make_tree_vector ();
10752 if (literal_zero_mask)
10753 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10754 expr = c_parser_expr_no_commas (parser, NULL);
10755 if (convert_p)
10756 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10757 if (fold_p)
10758 expr.value = c_fully_fold (expr.value, false, NULL);
10759 ret->quick_push (expr.value);
10760 if (orig_types)
10761 orig_types->quick_push (expr.original_type);
10762 if (locations)
10763 locations->safe_push (expr.get_location ());
10764 if (sizeof_arg != NULL
10765 && (expr.original_code == SIZEOF_EXPR
10766 || expr.original_code == PAREN_SIZEOF_EXPR))
10768 sizeof_arg[0] = c_last_sizeof_arg;
10769 sizeof_arg_loc[0] = c_last_sizeof_loc;
10771 while (c_parser_next_token_is (parser, CPP_COMMA))
10773 c_parser_consume_token (parser);
10774 if (literal_zero_mask)
10775 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10776 expr = c_parser_expr_no_commas (parser, NULL);
10777 if (convert_p)
10778 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10779 true);
10780 if (fold_p)
10781 expr.value = c_fully_fold (expr.value, false, NULL);
10782 vec_safe_push (ret, expr.value);
10783 if (orig_types)
10784 vec_safe_push (orig_types, expr.original_type);
10785 if (locations)
10786 locations->safe_push (expr.get_location ());
10787 if (++idx < 3
10788 && sizeof_arg != NULL
10789 && (expr.original_code == SIZEOF_EXPR
10790 || expr.original_code == PAREN_SIZEOF_EXPR))
10792 sizeof_arg[idx] = c_last_sizeof_arg;
10793 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10796 if (orig_types)
10797 *p_orig_types = orig_types;
10798 return ret;
10801 /* Parse Objective-C-specific constructs. */
10803 /* Parse an objc-class-definition.
10805 objc-class-definition:
10806 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10807 objc-class-instance-variables[opt] objc-methodprotolist @end
10808 @implementation identifier objc-superclass[opt]
10809 objc-class-instance-variables[opt]
10810 @interface identifier ( identifier ) objc-protocol-refs[opt]
10811 objc-methodprotolist @end
10812 @interface identifier ( ) objc-protocol-refs[opt]
10813 objc-methodprotolist @end
10814 @implementation identifier ( identifier )
10816 objc-superclass:
10817 : identifier
10819 "@interface identifier (" must start "@interface identifier (
10820 identifier ) ...": objc-methodprotolist in the first production may
10821 not start with a parenthesized identifier as a declarator of a data
10822 definition with no declaration specifiers if the objc-superclass,
10823 objc-protocol-refs and objc-class-instance-variables are omitted. */
10825 static void
10826 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10828 bool iface_p;
10829 tree id1;
10830 tree superclass;
10831 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10832 iface_p = true;
10833 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10834 iface_p = false;
10835 else
10836 gcc_unreachable ();
10838 c_parser_consume_token (parser);
10839 if (c_parser_next_token_is_not (parser, CPP_NAME))
10841 c_parser_error (parser, "expected identifier");
10842 return;
10844 id1 = c_parser_peek_token (parser)->value;
10845 location_t loc1 = c_parser_peek_token (parser)->location;
10846 c_parser_consume_token (parser);
10847 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10849 /* We have a category or class extension. */
10850 tree id2;
10851 tree proto = NULL_TREE;
10852 matching_parens parens;
10853 parens.consume_open (parser);
10854 if (c_parser_next_token_is_not (parser, CPP_NAME))
10856 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10858 /* We have a class extension. */
10859 id2 = NULL_TREE;
10861 else
10863 c_parser_error (parser, "expected identifier or %<)%>");
10864 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10865 return;
10868 else
10870 id2 = c_parser_peek_token (parser)->value;
10871 c_parser_consume_token (parser);
10873 parens.skip_until_found_close (parser);
10874 if (!iface_p)
10876 objc_start_category_implementation (id1, id2);
10877 return;
10879 if (c_parser_next_token_is (parser, CPP_LESS))
10880 proto = c_parser_objc_protocol_refs (parser);
10881 objc_start_category_interface (id1, id2, proto, attributes);
10882 c_parser_objc_methodprotolist (parser);
10883 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10884 objc_finish_interface ();
10885 return;
10887 if (c_parser_next_token_is (parser, CPP_COLON))
10889 c_parser_consume_token (parser);
10890 if (c_parser_next_token_is_not (parser, CPP_NAME))
10892 c_parser_error (parser, "expected identifier");
10893 return;
10895 superclass = c_parser_peek_token (parser)->value;
10896 c_parser_consume_token (parser);
10898 else
10899 superclass = NULL_TREE;
10900 if (iface_p)
10902 tree proto = NULL_TREE;
10903 if (c_parser_next_token_is (parser, CPP_LESS))
10904 proto = c_parser_objc_protocol_refs (parser);
10905 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
10907 else
10908 objc_start_class_implementation (id1, superclass);
10909 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10910 c_parser_objc_class_instance_variables (parser);
10911 if (iface_p)
10913 objc_continue_interface ();
10914 c_parser_objc_methodprotolist (parser);
10915 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10916 objc_finish_interface ();
10918 else
10920 objc_continue_implementation ();
10921 return;
10925 /* Parse objc-class-instance-variables.
10927 objc-class-instance-variables:
10928 { objc-instance-variable-decl-list[opt] }
10930 objc-instance-variable-decl-list:
10931 objc-visibility-spec
10932 objc-instance-variable-decl ;
10934 objc-instance-variable-decl-list objc-visibility-spec
10935 objc-instance-variable-decl-list objc-instance-variable-decl ;
10936 objc-instance-variable-decl-list ;
10938 objc-visibility-spec:
10939 @private
10940 @protected
10941 @public
10943 objc-instance-variable-decl:
10944 struct-declaration
10947 static void
10948 c_parser_objc_class_instance_variables (c_parser *parser)
10950 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
10951 c_parser_consume_token (parser);
10952 while (c_parser_next_token_is_not (parser, CPP_EOF))
10954 tree decls;
10955 /* Parse any stray semicolon. */
10956 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10958 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
10959 "extra semicolon");
10960 c_parser_consume_token (parser);
10961 continue;
10963 /* Stop if at the end of the instance variables. */
10964 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10966 c_parser_consume_token (parser);
10967 break;
10969 /* Parse any objc-visibility-spec. */
10970 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
10972 c_parser_consume_token (parser);
10973 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
10974 continue;
10976 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
10978 c_parser_consume_token (parser);
10979 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
10980 continue;
10982 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
10984 c_parser_consume_token (parser);
10985 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
10986 continue;
10988 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
10990 c_parser_consume_token (parser);
10991 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
10992 continue;
10994 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
10996 c_parser_pragma (parser, pragma_external, NULL);
10997 continue;
11000 /* Parse some comma-separated declarations. */
11001 decls = c_parser_struct_declaration (parser);
11002 if (decls == NULL)
11004 /* There is a syntax error. We want to skip the offending
11005 tokens up to the next ';' (included) or '}'
11006 (excluded). */
11008 /* First, skip manually a ')' or ']'. This is because they
11009 reduce the nesting level, so c_parser_skip_until_found()
11010 wouldn't be able to skip past them. */
11011 c_token *token = c_parser_peek_token (parser);
11012 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11013 c_parser_consume_token (parser);
11015 /* Then, do the standard skipping. */
11016 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11018 /* We hopefully recovered. Start normal parsing again. */
11019 parser->error = false;
11020 continue;
11022 else
11024 /* Comma-separated instance variables are chained together
11025 in reverse order; add them one by one. */
11026 tree ivar = nreverse (decls);
11027 for (; ivar; ivar = DECL_CHAIN (ivar))
11028 objc_add_instance_variable (copy_node (ivar));
11030 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11034 /* Parse an objc-class-declaration.
11036 objc-class-declaration:
11037 @class identifier-list ;
11040 static void
11041 c_parser_objc_class_declaration (c_parser *parser)
11043 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11044 c_parser_consume_token (parser);
11045 /* Any identifiers, including those declared as type names, are OK
11046 here. */
11047 while (true)
11049 tree id;
11050 if (c_parser_next_token_is_not (parser, CPP_NAME))
11052 c_parser_error (parser, "expected identifier");
11053 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11054 parser->error = false;
11055 return;
11057 id = c_parser_peek_token (parser)->value;
11058 objc_declare_class (id);
11059 c_parser_consume_token (parser);
11060 if (c_parser_next_token_is (parser, CPP_COMMA))
11061 c_parser_consume_token (parser);
11062 else
11063 break;
11065 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11068 /* Parse an objc-alias-declaration.
11070 objc-alias-declaration:
11071 @compatibility_alias identifier identifier ;
11074 static void
11075 c_parser_objc_alias_declaration (c_parser *parser)
11077 tree id1, id2;
11078 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11079 c_parser_consume_token (parser);
11080 if (c_parser_next_token_is_not (parser, CPP_NAME))
11082 c_parser_error (parser, "expected identifier");
11083 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11084 return;
11086 id1 = c_parser_peek_token (parser)->value;
11087 c_parser_consume_token (parser);
11088 if (c_parser_next_token_is_not (parser, CPP_NAME))
11090 c_parser_error (parser, "expected identifier");
11091 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11092 return;
11094 id2 = c_parser_peek_token (parser)->value;
11095 c_parser_consume_token (parser);
11096 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11097 objc_declare_alias (id1, id2);
11100 /* Parse an objc-protocol-definition.
11102 objc-protocol-definition:
11103 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11104 @protocol identifier-list ;
11106 "@protocol identifier ;" should be resolved as "@protocol
11107 identifier-list ;": objc-methodprotolist may not start with a
11108 semicolon in the first alternative if objc-protocol-refs are
11109 omitted. */
11111 static void
11112 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11114 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11116 c_parser_consume_token (parser);
11117 if (c_parser_next_token_is_not (parser, CPP_NAME))
11119 c_parser_error (parser, "expected identifier");
11120 return;
11122 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11123 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11125 /* Any identifiers, including those declared as type names, are
11126 OK here. */
11127 while (true)
11129 tree id;
11130 if (c_parser_next_token_is_not (parser, CPP_NAME))
11132 c_parser_error (parser, "expected identifier");
11133 break;
11135 id = c_parser_peek_token (parser)->value;
11136 objc_declare_protocol (id, attributes);
11137 c_parser_consume_token (parser);
11138 if (c_parser_next_token_is (parser, CPP_COMMA))
11139 c_parser_consume_token (parser);
11140 else
11141 break;
11143 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11145 else
11147 tree id = c_parser_peek_token (parser)->value;
11148 tree proto = NULL_TREE;
11149 c_parser_consume_token (parser);
11150 if (c_parser_next_token_is (parser, CPP_LESS))
11151 proto = c_parser_objc_protocol_refs (parser);
11152 parser->objc_pq_context = true;
11153 objc_start_protocol (id, proto, attributes);
11154 c_parser_objc_methodprotolist (parser);
11155 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11156 parser->objc_pq_context = false;
11157 objc_finish_interface ();
11161 /* Parse an objc-method-type.
11163 objc-method-type:
11167 Return true if it is a class method (+) and false if it is
11168 an instance method (-).
11170 static inline bool
11171 c_parser_objc_method_type (c_parser *parser)
11173 switch (c_parser_peek_token (parser)->type)
11175 case CPP_PLUS:
11176 c_parser_consume_token (parser);
11177 return true;
11178 case CPP_MINUS:
11179 c_parser_consume_token (parser);
11180 return false;
11181 default:
11182 gcc_unreachable ();
11186 /* Parse an objc-method-definition.
11188 objc-method-definition:
11189 objc-method-type objc-method-decl ;[opt] compound-statement
11192 static void
11193 c_parser_objc_method_definition (c_parser *parser)
11195 bool is_class_method = c_parser_objc_method_type (parser);
11196 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11197 parser->objc_pq_context = true;
11198 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11199 &expr);
11200 if (decl == error_mark_node)
11201 return; /* Bail here. */
11203 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11205 c_parser_consume_token (parser);
11206 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11207 "extra semicolon in method definition specified");
11210 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11212 c_parser_error (parser, "expected %<{%>");
11213 return;
11216 parser->objc_pq_context = false;
11217 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11219 add_stmt (c_parser_compound_statement (parser));
11220 objc_finish_method_definition (current_function_decl);
11222 else
11224 /* This code is executed when we find a method definition
11225 outside of an @implementation context (or invalid for other
11226 reasons). Parse the method (to keep going) but do not emit
11227 any code.
11229 c_parser_compound_statement (parser);
11233 /* Parse an objc-methodprotolist.
11235 objc-methodprotolist:
11236 empty
11237 objc-methodprotolist objc-methodproto
11238 objc-methodprotolist declaration
11239 objc-methodprotolist ;
11240 @optional
11241 @required
11243 The declaration is a data definition, which may be missing
11244 declaration specifiers under the same rules and diagnostics as
11245 other data definitions outside functions, and the stray semicolon
11246 is diagnosed the same way as a stray semicolon outside a
11247 function. */
11249 static void
11250 c_parser_objc_methodprotolist (c_parser *parser)
11252 while (true)
11254 /* The list is terminated by @end. */
11255 switch (c_parser_peek_token (parser)->type)
11257 case CPP_SEMICOLON:
11258 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11259 "ISO C does not allow extra %<;%> outside of a function");
11260 c_parser_consume_token (parser);
11261 break;
11262 case CPP_PLUS:
11263 case CPP_MINUS:
11264 c_parser_objc_methodproto (parser);
11265 break;
11266 case CPP_PRAGMA:
11267 c_parser_pragma (parser, pragma_external, NULL);
11268 break;
11269 case CPP_EOF:
11270 return;
11271 default:
11272 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11273 return;
11274 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11275 c_parser_objc_at_property_declaration (parser);
11276 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11278 objc_set_method_opt (true);
11279 c_parser_consume_token (parser);
11281 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11283 objc_set_method_opt (false);
11284 c_parser_consume_token (parser);
11286 else
11287 c_parser_declaration_or_fndef (parser, false, false, true,
11288 false, true);
11289 break;
11294 /* Parse an objc-methodproto.
11296 objc-methodproto:
11297 objc-method-type objc-method-decl ;
11300 static void
11301 c_parser_objc_methodproto (c_parser *parser)
11303 bool is_class_method = c_parser_objc_method_type (parser);
11304 tree decl, attributes = NULL_TREE;
11306 /* Remember protocol qualifiers in prototypes. */
11307 parser->objc_pq_context = true;
11308 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11309 NULL);
11310 /* Forget protocol qualifiers now. */
11311 parser->objc_pq_context = false;
11313 /* Do not allow the presence of attributes to hide an erroneous
11314 method implementation in the interface section. */
11315 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11317 c_parser_error (parser, "expected %<;%>");
11318 return;
11321 if (decl != error_mark_node)
11322 objc_add_method_declaration (is_class_method, decl, attributes);
11324 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11327 /* If we are at a position that method attributes may be present, check that
11328 there are not any parsed already (a syntax error) and then collect any
11329 specified at the current location. Finally, if new attributes were present,
11330 check that the next token is legal ( ';' for decls and '{' for defs). */
11332 static bool
11333 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11335 bool bad = false;
11336 if (*attributes)
11338 c_parser_error (parser,
11339 "method attributes must be specified at the end only");
11340 *attributes = NULL_TREE;
11341 bad = true;
11344 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11345 *attributes = c_parser_gnu_attributes (parser);
11347 /* If there were no attributes here, just report any earlier error. */
11348 if (*attributes == NULL_TREE || bad)
11349 return bad;
11351 /* If the attributes are followed by a ; or {, then just report any earlier
11352 error. */
11353 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11354 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11355 return bad;
11357 /* We've got attributes, but not at the end. */
11358 c_parser_error (parser,
11359 "expected %<;%> or %<{%> after method attribute definition");
11360 return true;
11363 /* Parse an objc-method-decl.
11365 objc-method-decl:
11366 ( objc-type-name ) objc-selector
11367 objc-selector
11368 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11369 objc-keyword-selector objc-optparmlist
11370 gnu-attributes
11372 objc-keyword-selector:
11373 objc-keyword-decl
11374 objc-keyword-selector objc-keyword-decl
11376 objc-keyword-decl:
11377 objc-selector : ( objc-type-name ) identifier
11378 objc-selector : identifier
11379 : ( objc-type-name ) identifier
11380 : identifier
11382 objc-optparmlist:
11383 objc-optparms objc-optellipsis
11385 objc-optparms:
11386 empty
11387 objc-opt-parms , parameter-declaration
11389 objc-optellipsis:
11390 empty
11391 , ...
11394 static tree
11395 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11396 tree *attributes, tree *expr)
11398 tree type = NULL_TREE;
11399 tree sel;
11400 tree parms = NULL_TREE;
11401 bool ellipsis = false;
11402 bool attr_err = false;
11404 *attributes = NULL_TREE;
11405 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11407 matching_parens parens;
11408 parens.consume_open (parser);
11409 type = c_parser_objc_type_name (parser);
11410 parens.skip_until_found_close (parser);
11412 sel = c_parser_objc_selector (parser);
11413 /* If there is no selector, or a colon follows, we have an
11414 objc-keyword-selector. If there is a selector, and a colon does
11415 not follow, that selector ends the objc-method-decl. */
11416 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11418 tree tsel = sel;
11419 tree list = NULL_TREE;
11420 while (true)
11422 tree atype = NULL_TREE, id, keyworddecl;
11423 tree param_attr = NULL_TREE;
11424 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11425 break;
11426 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11428 c_parser_consume_token (parser);
11429 atype = c_parser_objc_type_name (parser);
11430 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11431 "expected %<)%>");
11433 /* New ObjC allows attributes on method parameters. */
11434 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11435 param_attr = c_parser_gnu_attributes (parser);
11436 if (c_parser_next_token_is_not (parser, CPP_NAME))
11438 c_parser_error (parser, "expected identifier");
11439 return error_mark_node;
11441 id = c_parser_peek_token (parser)->value;
11442 c_parser_consume_token (parser);
11443 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11444 list = chainon (list, keyworddecl);
11445 tsel = c_parser_objc_selector (parser);
11446 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11447 break;
11450 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11452 /* Parse the optional parameter list. Optional Objective-C
11453 method parameters follow the C syntax, and may include '...'
11454 to denote a variable number of arguments. */
11455 parms = make_node (TREE_LIST);
11456 while (c_parser_next_token_is (parser, CPP_COMMA))
11458 struct c_parm *parm;
11459 c_parser_consume_token (parser);
11460 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11462 ellipsis = true;
11463 c_parser_consume_token (parser);
11464 attr_err |= c_parser_objc_maybe_method_attributes
11465 (parser, attributes) ;
11466 break;
11468 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11469 if (parm == NULL)
11470 break;
11471 parms = chainon (parms,
11472 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11474 sel = list;
11476 else
11477 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11479 if (sel == NULL)
11481 c_parser_error (parser, "objective-c method declaration is expected");
11482 return error_mark_node;
11485 if (attr_err)
11486 return error_mark_node;
11488 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11491 /* Parse an objc-type-name.
11493 objc-type-name:
11494 objc-type-qualifiers[opt] type-name
11495 objc-type-qualifiers[opt]
11497 objc-type-qualifiers:
11498 objc-type-qualifier
11499 objc-type-qualifiers objc-type-qualifier
11501 objc-type-qualifier: one of
11502 in out inout bycopy byref oneway
11505 static tree
11506 c_parser_objc_type_name (c_parser *parser)
11508 tree quals = NULL_TREE;
11509 struct c_type_name *type_name = NULL;
11510 tree type = NULL_TREE;
11511 while (true)
11513 c_token *token = c_parser_peek_token (parser);
11514 if (token->type == CPP_KEYWORD
11515 && (token->keyword == RID_IN
11516 || token->keyword == RID_OUT
11517 || token->keyword == RID_INOUT
11518 || token->keyword == RID_BYCOPY
11519 || token->keyword == RID_BYREF
11520 || token->keyword == RID_ONEWAY))
11522 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11523 c_parser_consume_token (parser);
11525 else
11526 break;
11528 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11529 type_name = c_parser_type_name (parser);
11530 if (type_name)
11531 type = groktypename (type_name, NULL, NULL);
11533 /* If the type is unknown, and error has already been produced and
11534 we need to recover from the error. In that case, use NULL_TREE
11535 for the type, as if no type had been specified; this will use the
11536 default type ('id') which is good for error recovery. */
11537 if (type == error_mark_node)
11538 type = NULL_TREE;
11540 return build_tree_list (quals, type);
11543 /* Parse objc-protocol-refs.
11545 objc-protocol-refs:
11546 < identifier-list >
11549 static tree
11550 c_parser_objc_protocol_refs (c_parser *parser)
11552 tree list = NULL_TREE;
11553 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11554 c_parser_consume_token (parser);
11555 /* Any identifiers, including those declared as type names, are OK
11556 here. */
11557 while (true)
11559 tree id;
11560 if (c_parser_next_token_is_not (parser, CPP_NAME))
11562 c_parser_error (parser, "expected identifier");
11563 break;
11565 id = c_parser_peek_token (parser)->value;
11566 list = chainon (list, build_tree_list (NULL_TREE, id));
11567 c_parser_consume_token (parser);
11568 if (c_parser_next_token_is (parser, CPP_COMMA))
11569 c_parser_consume_token (parser);
11570 else
11571 break;
11573 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11574 return list;
11577 /* Parse an objc-try-catch-finally-statement.
11579 objc-try-catch-finally-statement:
11580 @try compound-statement objc-catch-list[opt]
11581 @try compound-statement objc-catch-list[opt] @finally compound-statement
11583 objc-catch-list:
11584 @catch ( objc-catch-parameter-declaration ) compound-statement
11585 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11587 objc-catch-parameter-declaration:
11588 parameter-declaration
11589 '...'
11591 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11593 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11594 for C++. Keep them in sync. */
11596 static void
11597 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11599 location_t location;
11600 tree stmt;
11602 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11603 c_parser_consume_token (parser);
11604 location = c_parser_peek_token (parser)->location;
11605 objc_maybe_warn_exceptions (location);
11606 stmt = c_parser_compound_statement (parser);
11607 objc_begin_try_stmt (location, stmt);
11609 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11611 struct c_parm *parm;
11612 tree parameter_declaration = error_mark_node;
11613 bool seen_open_paren = false;
11615 c_parser_consume_token (parser);
11616 matching_parens parens;
11617 if (!parens.require_open (parser))
11618 seen_open_paren = true;
11619 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11621 /* We have "@catch (...)" (where the '...' are literally
11622 what is in the code). Skip the '...'.
11623 parameter_declaration is set to NULL_TREE, and
11624 objc_being_catch_clauses() knows that that means
11625 '...'. */
11626 c_parser_consume_token (parser);
11627 parameter_declaration = NULL_TREE;
11629 else
11631 /* We have "@catch (NSException *exception)" or something
11632 like that. Parse the parameter declaration. */
11633 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11634 if (parm == NULL)
11635 parameter_declaration = error_mark_node;
11636 else
11637 parameter_declaration = grokparm (parm, NULL);
11639 if (seen_open_paren)
11640 parens.require_close (parser);
11641 else
11643 /* If there was no open parenthesis, we are recovering from
11644 an error, and we are trying to figure out what mistake
11645 the user has made. */
11647 /* If there is an immediate closing parenthesis, the user
11648 probably forgot the opening one (ie, they typed "@catch
11649 NSException *e)". Parse the closing parenthesis and keep
11650 going. */
11651 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11652 c_parser_consume_token (parser);
11654 /* If these is no immediate closing parenthesis, the user
11655 probably doesn't know that parenthesis are required at
11656 all (ie, they typed "@catch NSException *e"). So, just
11657 forget about the closing parenthesis and keep going. */
11659 objc_begin_catch_clause (parameter_declaration);
11660 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11661 c_parser_compound_statement_nostart (parser);
11662 objc_finish_catch_clause ();
11664 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11666 c_parser_consume_token (parser);
11667 location = c_parser_peek_token (parser)->location;
11668 stmt = c_parser_compound_statement (parser);
11669 objc_build_finally_clause (location, stmt);
11671 objc_finish_try_stmt ();
11674 /* Parse an objc-synchronized-statement.
11676 objc-synchronized-statement:
11677 @synchronized ( expression ) compound-statement
11680 static void
11681 c_parser_objc_synchronized_statement (c_parser *parser)
11683 location_t loc;
11684 tree expr, stmt;
11685 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11686 c_parser_consume_token (parser);
11687 loc = c_parser_peek_token (parser)->location;
11688 objc_maybe_warn_exceptions (loc);
11689 matching_parens parens;
11690 if (parens.require_open (parser))
11692 struct c_expr ce = c_parser_expression (parser);
11693 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11694 expr = ce.value;
11695 expr = c_fully_fold (expr, false, NULL);
11696 parens.skip_until_found_close (parser);
11698 else
11699 expr = error_mark_node;
11700 stmt = c_parser_compound_statement (parser);
11701 objc_build_synchronized (loc, expr, stmt);
11704 /* Parse an objc-selector; return NULL_TREE without an error if the
11705 next token is not an objc-selector.
11707 objc-selector:
11708 identifier
11709 one of
11710 enum struct union if else while do for switch case default
11711 break continue return goto asm sizeof typeof __alignof
11712 unsigned long const short volatile signed restrict _Complex
11713 in out inout bycopy byref oneway int char float double void _Bool
11714 _Atomic
11716 ??? Why this selection of keywords but not, for example, storage
11717 class specifiers? */
11719 static tree
11720 c_parser_objc_selector (c_parser *parser)
11722 c_token *token = c_parser_peek_token (parser);
11723 tree value = token->value;
11724 if (token->type == CPP_NAME)
11726 c_parser_consume_token (parser);
11727 return value;
11729 if (token->type != CPP_KEYWORD)
11730 return NULL_TREE;
11731 switch (token->keyword)
11733 case RID_ENUM:
11734 case RID_STRUCT:
11735 case RID_UNION:
11736 case RID_IF:
11737 case RID_ELSE:
11738 case RID_WHILE:
11739 case RID_DO:
11740 case RID_FOR:
11741 case RID_SWITCH:
11742 case RID_CASE:
11743 case RID_DEFAULT:
11744 case RID_BREAK:
11745 case RID_CONTINUE:
11746 case RID_RETURN:
11747 case RID_GOTO:
11748 case RID_ASM:
11749 case RID_SIZEOF:
11750 case RID_TYPEOF:
11751 case RID_ALIGNOF:
11752 case RID_UNSIGNED:
11753 case RID_LONG:
11754 case RID_CONST:
11755 case RID_SHORT:
11756 case RID_VOLATILE:
11757 case RID_SIGNED:
11758 case RID_RESTRICT:
11759 case RID_COMPLEX:
11760 case RID_IN:
11761 case RID_OUT:
11762 case RID_INOUT:
11763 case RID_BYCOPY:
11764 case RID_BYREF:
11765 case RID_ONEWAY:
11766 case RID_INT:
11767 case RID_CHAR:
11768 case RID_FLOAT:
11769 case RID_DOUBLE:
11770 CASE_RID_FLOATN_NX:
11771 case RID_VOID:
11772 case RID_BOOL:
11773 case RID_ATOMIC:
11774 case RID_AUTO_TYPE:
11775 case RID_INT_N_0:
11776 case RID_INT_N_1:
11777 case RID_INT_N_2:
11778 case RID_INT_N_3:
11779 c_parser_consume_token (parser);
11780 return value;
11781 default:
11782 return NULL_TREE;
11786 /* Parse an objc-selector-arg.
11788 objc-selector-arg:
11789 objc-selector
11790 objc-keywordname-list
11792 objc-keywordname-list:
11793 objc-keywordname
11794 objc-keywordname-list objc-keywordname
11796 objc-keywordname:
11797 objc-selector :
11801 static tree
11802 c_parser_objc_selector_arg (c_parser *parser)
11804 tree sel = c_parser_objc_selector (parser);
11805 tree list = NULL_TREE;
11806 if (sel
11807 && c_parser_next_token_is_not (parser, CPP_COLON)
11808 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11809 return sel;
11810 while (true)
11812 if (c_parser_next_token_is (parser, CPP_SCOPE))
11814 c_parser_consume_token (parser);
11815 list = chainon (list, build_tree_list (sel, NULL_TREE));
11816 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11818 else
11820 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11821 return list;
11822 list = chainon (list, build_tree_list (sel, NULL_TREE));
11824 sel = c_parser_objc_selector (parser);
11825 if (!sel
11826 && c_parser_next_token_is_not (parser, CPP_COLON)
11827 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11828 break;
11830 return list;
11833 /* Parse an objc-receiver.
11835 objc-receiver:
11836 expression
11837 class-name
11838 type-name
11841 static tree
11842 c_parser_objc_receiver (c_parser *parser)
11844 location_t loc = c_parser_peek_token (parser)->location;
11846 if (c_parser_peek_token (parser)->type == CPP_NAME
11847 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11848 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11850 tree id = c_parser_peek_token (parser)->value;
11851 c_parser_consume_token (parser);
11852 return objc_get_class_reference (id);
11854 struct c_expr ce = c_parser_expression (parser);
11855 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11856 return c_fully_fold (ce.value, false, NULL);
11859 /* Parse objc-message-args.
11861 objc-message-args:
11862 objc-selector
11863 objc-keywordarg-list
11865 objc-keywordarg-list:
11866 objc-keywordarg
11867 objc-keywordarg-list objc-keywordarg
11869 objc-keywordarg:
11870 objc-selector : objc-keywordexpr
11871 : objc-keywordexpr
11874 static tree
11875 c_parser_objc_message_args (c_parser *parser)
11877 tree sel = c_parser_objc_selector (parser);
11878 tree list = NULL_TREE;
11879 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11880 return sel;
11881 while (true)
11883 tree keywordexpr;
11884 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11885 return error_mark_node;
11886 keywordexpr = c_parser_objc_keywordexpr (parser);
11887 list = chainon (list, build_tree_list (sel, keywordexpr));
11888 sel = c_parser_objc_selector (parser);
11889 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11890 break;
11892 return list;
11895 /* Parse an objc-keywordexpr.
11897 objc-keywordexpr:
11898 nonempty-expr-list
11901 static tree
11902 c_parser_objc_keywordexpr (c_parser *parser)
11904 tree ret;
11905 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11906 NULL, NULL, NULL, NULL);
11907 if (vec_safe_length (expr_list) == 1)
11909 /* Just return the expression, remove a level of
11910 indirection. */
11911 ret = (*expr_list)[0];
11913 else
11915 /* We have a comma expression, we will collapse later. */
11916 ret = build_tree_list_vec (expr_list);
11918 release_tree_vector (expr_list);
11919 return ret;
11922 /* A check, needed in several places, that ObjC interface, implementation or
11923 method definitions are not prefixed by incorrect items. */
11924 static bool
11925 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11926 struct c_declspecs *specs)
11928 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11929 || specs->typespec_kind != ctsk_none)
11931 c_parser_error (parser,
11932 "no type or storage class may be specified here,");
11933 c_parser_skip_to_end_of_block_or_statement (parser);
11934 return true;
11936 return false;
11939 /* Parse an Objective-C @property declaration. The syntax is:
11941 objc-property-declaration:
11942 '@property' objc-property-attributes[opt] struct-declaration ;
11944 objc-property-attributes:
11945 '(' objc-property-attribute-list ')'
11947 objc-property-attribute-list:
11948 objc-property-attribute
11949 objc-property-attribute-list, objc-property-attribute
11951 objc-property-attribute
11952 'getter' = identifier
11953 'setter' = identifier
11954 'readonly'
11955 'readwrite'
11956 'assign'
11957 'retain'
11958 'copy'
11959 'nonatomic'
11961 For example:
11962 @property NSString *name;
11963 @property (readonly) id object;
11964 @property (retain, nonatomic, getter=getTheName) id name;
11965 @property int a, b, c;
11967 PS: This function is identical to cp_parser_objc_at_propery_declaration
11968 for C++. Keep them in sync. */
11969 static void
11970 c_parser_objc_at_property_declaration (c_parser *parser)
11972 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
11973 location_t loc = c_parser_peek_token (parser)->location;
11974 c_parser_consume_token (parser); /* Eat '@property'. */
11976 /* Parse the optional attribute list.
11978 A list of parsed, but not verified, attributes. */
11979 vec<property_attribute_info *> prop_attr_list = vNULL;
11981 bool syntax_error = false;
11982 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11984 matching_parens parens;
11986 location_t attr_start = c_parser_peek_token (parser)->location;
11987 /* Eat the '(' */
11988 parens.consume_open (parser);
11990 /* Property attribute keywords are valid now. */
11991 parser->objc_property_attr_context = true;
11993 /* Allow @property (), with a warning. */
11994 location_t attr_end = c_parser_peek_token (parser)->location;
11996 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11998 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
11999 warning_at (attr_comb, OPT_Wattributes,
12000 "empty property attribute list");
12002 else
12003 while (true)
12005 c_token *token = c_parser_peek_token (parser);
12006 attr_start = token->location;
12007 attr_end = get_finish (token->location);
12008 location_t attr_comb = make_location (attr_start, attr_start,
12009 attr_end);
12011 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12013 warning_at (attr_comb, OPT_Wattributes,
12014 "missing property attribute");
12015 if (token->type == CPP_CLOSE_PAREN)
12016 break;
12017 c_parser_consume_token (parser);
12018 continue;
12021 tree attr_name = NULL_TREE;
12022 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12023 bool add_at = false;
12024 if (token->type == CPP_KEYWORD)
12026 keyword = token->keyword;
12027 if (OBJC_IS_AT_KEYWORD (keyword))
12029 /* For '@' keywords the token value has the keyword,
12030 prepend the '@' for diagnostics. */
12031 attr_name = token->value;
12032 add_at = true;
12034 else
12035 attr_name = ridpointers[(int)keyword];
12037 else if (token->type == CPP_NAME)
12038 attr_name = token->value;
12039 c_parser_consume_token (parser);
12041 enum objc_property_attribute_kind prop_kind
12042 = objc_prop_attr_kind_for_rid (keyword);
12043 property_attribute_info *prop
12044 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12045 prop_attr_list.safe_push (prop);
12047 tree meth_name;
12048 switch (prop->prop_kind)
12050 default: break;
12051 case OBJC_PROPERTY_ATTR_UNKNOWN:
12052 if (attr_name)
12053 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12054 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12055 else
12056 error_at (attr_comb, "unknown property attribute");
12057 prop->parse_error = syntax_error = true;
12058 break;
12060 case OBJC_PROPERTY_ATTR_GETTER:
12061 case OBJC_PROPERTY_ATTR_SETTER:
12062 if (c_parser_next_token_is_not (parser, CPP_EQ))
12064 attr_comb = make_location (attr_end, attr_start, attr_end);
12065 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12066 attr_name);
12067 prop->parse_error = syntax_error = true;
12068 break;
12070 token = c_parser_peek_token (parser);
12071 attr_end = token->location;
12072 c_parser_consume_token (parser); /* eat the = */
12073 if (c_parser_next_token_is_not (parser, CPP_NAME))
12075 attr_comb = make_location (attr_end, attr_start, attr_end);
12076 error_at (attr_comb, "expected %qE selector name",
12077 attr_name);
12078 prop->parse_error = syntax_error = true;
12079 break;
12081 /* Get the end of the method name, and consume the name. */
12082 token = c_parser_peek_token (parser);
12083 attr_end = get_finish (token->location);
12084 meth_name = token->value;
12085 c_parser_consume_token (parser);
12086 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12088 if (c_parser_next_token_is_not (parser, CPP_COLON))
12090 attr_comb = make_location (attr_end, attr_start,
12091 attr_end);
12092 error_at (attr_comb, "setter method names must"
12093 " terminate with %<:%>");
12094 prop->parse_error = syntax_error = true;
12096 else
12098 attr_end = get_finish (c_parser_peek_token
12099 (parser)->location);
12100 c_parser_consume_token (parser);
12102 attr_comb = make_location (attr_start, attr_start,
12103 attr_end);
12105 else
12106 attr_comb = make_location (attr_start, attr_start,
12107 attr_end);
12108 prop->ident = meth_name;
12109 /* Updated location including all that was successfully
12110 parsed. */
12111 prop->prop_loc = attr_comb;
12112 break;
12115 /* If we see a comma here, then keep going - even if we already
12116 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12117 this makes a more useful output and avoid spurious warnings about
12118 missing attributes that are, in fact, specified after the one with
12119 the syntax error. */
12120 if (c_parser_next_token_is (parser, CPP_COMMA))
12121 c_parser_consume_token (parser);
12122 else
12123 break;
12125 parser->objc_property_attr_context = false;
12127 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12128 /* We don't really want to chew the whole of the file looking for a
12129 matching closing parenthesis, so we will try to read the decl and
12130 let the error handling for that close out the statement. */
12132 else
12133 syntax_error = false, parens.skip_until_found_close (parser);
12136 /* 'properties' is the list of properties that we read. Usually a
12137 single one, but maybe more (eg, in "@property int a, b, c;" there
12138 are three). */
12139 tree properties = c_parser_struct_declaration (parser);
12141 if (properties == error_mark_node)
12142 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12143 else
12145 if (properties == NULL_TREE)
12146 c_parser_error (parser, "expected identifier");
12147 else
12149 /* Comma-separated properties are chained together in reverse order;
12150 add them one by one. */
12151 properties = nreverse (properties);
12152 for (; properties; properties = TREE_CHAIN (properties))
12153 objc_add_property_declaration (loc, copy_node (properties),
12154 prop_attr_list);
12156 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12159 while (!prop_attr_list.is_empty())
12160 delete prop_attr_list.pop ();
12161 prop_attr_list.release ();
12162 parser->error = false;
12165 /* Parse an Objective-C @synthesize declaration. The syntax is:
12167 objc-synthesize-declaration:
12168 @synthesize objc-synthesize-identifier-list ;
12170 objc-synthesize-identifier-list:
12171 objc-synthesize-identifier
12172 objc-synthesize-identifier-list, objc-synthesize-identifier
12174 objc-synthesize-identifier
12175 identifier
12176 identifier = identifier
12178 For example:
12179 @synthesize MyProperty;
12180 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12182 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12183 for C++. Keep them in sync.
12185 static void
12186 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12188 tree list = NULL_TREE;
12189 location_t loc;
12190 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12191 loc = c_parser_peek_token (parser)->location;
12193 c_parser_consume_token (parser);
12194 while (true)
12196 tree property, ivar;
12197 if (c_parser_next_token_is_not (parser, CPP_NAME))
12199 c_parser_error (parser, "expected identifier");
12200 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12201 /* Once we find the semicolon, we can resume normal parsing.
12202 We have to reset parser->error manually because
12203 c_parser_skip_until_found() won't reset it for us if the
12204 next token is precisely a semicolon. */
12205 parser->error = false;
12206 return;
12208 property = c_parser_peek_token (parser)->value;
12209 c_parser_consume_token (parser);
12210 if (c_parser_next_token_is (parser, CPP_EQ))
12212 c_parser_consume_token (parser);
12213 if (c_parser_next_token_is_not (parser, CPP_NAME))
12215 c_parser_error (parser, "expected identifier");
12216 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12217 parser->error = false;
12218 return;
12220 ivar = c_parser_peek_token (parser)->value;
12221 c_parser_consume_token (parser);
12223 else
12224 ivar = NULL_TREE;
12225 list = chainon (list, build_tree_list (ivar, property));
12226 if (c_parser_next_token_is (parser, CPP_COMMA))
12227 c_parser_consume_token (parser);
12228 else
12229 break;
12231 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12232 objc_add_synthesize_declaration (loc, list);
12235 /* Parse an Objective-C @dynamic declaration. The syntax is:
12237 objc-dynamic-declaration:
12238 @dynamic identifier-list ;
12240 For example:
12241 @dynamic MyProperty;
12242 @dynamic MyProperty, AnotherProperty;
12244 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12245 for C++. Keep them in sync.
12247 static void
12248 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12250 tree list = NULL_TREE;
12251 location_t loc;
12252 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12253 loc = c_parser_peek_token (parser)->location;
12255 c_parser_consume_token (parser);
12256 while (true)
12258 tree property;
12259 if (c_parser_next_token_is_not (parser, CPP_NAME))
12261 c_parser_error (parser, "expected identifier");
12262 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12263 parser->error = false;
12264 return;
12266 property = c_parser_peek_token (parser)->value;
12267 list = chainon (list, build_tree_list (NULL_TREE, property));
12268 c_parser_consume_token (parser);
12269 if (c_parser_next_token_is (parser, CPP_COMMA))
12270 c_parser_consume_token (parser);
12271 else
12272 break;
12274 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12275 objc_add_dynamic_declaration (loc, list);
12279 /* Parse a pragma GCC ivdep. */
12281 static bool
12282 c_parse_pragma_ivdep (c_parser *parser)
12284 c_parser_consume_pragma (parser);
12285 c_parser_skip_to_pragma_eol (parser);
12286 return true;
12289 /* Parse a pragma GCC unroll. */
12291 static unsigned short
12292 c_parser_pragma_unroll (c_parser *parser)
12294 unsigned short unroll;
12295 c_parser_consume_pragma (parser);
12296 location_t location = c_parser_peek_token (parser)->location;
12297 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12298 mark_exp_read (expr);
12299 expr = c_fully_fold (expr, false, NULL);
12300 HOST_WIDE_INT lunroll = 0;
12301 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12302 || TREE_CODE (expr) != INTEGER_CST
12303 || (lunroll = tree_to_shwi (expr)) < 0
12304 || lunroll >= USHRT_MAX)
12306 error_at (location, "%<#pragma GCC unroll%> requires an"
12307 " assignment-expression that evaluates to a non-negative"
12308 " integral constant less than %u", USHRT_MAX);
12309 unroll = 0;
12311 else
12313 unroll = (unsigned short)lunroll;
12314 if (unroll == 0)
12315 unroll = 1;
12318 c_parser_skip_to_pragma_eol (parser);
12319 return unroll;
12322 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12323 should be considered, statements. ALLOW_STMT is true if we're within
12324 the context of a function and such pragmas are to be allowed. Returns
12325 true if we actually parsed such a pragma. */
12327 static bool
12328 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12330 unsigned int id;
12331 const char *construct = NULL;
12333 id = c_parser_peek_token (parser)->pragma_kind;
12334 gcc_assert (id != PRAGMA_NONE);
12336 switch (id)
12338 case PRAGMA_OACC_DECLARE:
12339 c_parser_oacc_declare (parser);
12340 return false;
12342 case PRAGMA_OACC_ENTER_DATA:
12343 if (context != pragma_compound)
12345 construct = "acc enter data";
12346 in_compound:
12347 if (context == pragma_stmt)
12349 error_at (c_parser_peek_token (parser)->location,
12350 "%<#pragma %s%> may only be used in compound "
12351 "statements", construct);
12352 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12353 return true;
12355 goto bad_stmt;
12357 c_parser_oacc_enter_exit_data (parser, true);
12358 return false;
12360 case PRAGMA_OACC_EXIT_DATA:
12361 if (context != pragma_compound)
12363 construct = "acc exit data";
12364 goto in_compound;
12366 c_parser_oacc_enter_exit_data (parser, false);
12367 return false;
12369 case PRAGMA_OACC_ROUTINE:
12370 if (context != pragma_external)
12372 error_at (c_parser_peek_token (parser)->location,
12373 "%<#pragma acc routine%> must be at file scope");
12374 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12375 return false;
12377 c_parser_oacc_routine (parser, context);
12378 return false;
12380 case PRAGMA_OACC_UPDATE:
12381 if (context != pragma_compound)
12383 construct = "acc update";
12384 goto in_compound;
12386 c_parser_oacc_update (parser);
12387 return false;
12389 case PRAGMA_OMP_BARRIER:
12390 if (context != pragma_compound)
12392 construct = "omp barrier";
12393 goto in_compound;
12395 c_parser_omp_barrier (parser);
12396 return false;
12398 case PRAGMA_OMP_DEPOBJ:
12399 if (context != pragma_compound)
12401 construct = "omp depobj";
12402 goto in_compound;
12404 c_parser_omp_depobj (parser);
12405 return false;
12407 case PRAGMA_OMP_FLUSH:
12408 if (context != pragma_compound)
12410 construct = "omp flush";
12411 goto in_compound;
12413 c_parser_omp_flush (parser);
12414 return false;
12416 case PRAGMA_OMP_TASKWAIT:
12417 if (context != pragma_compound)
12419 construct = "omp taskwait";
12420 goto in_compound;
12422 c_parser_omp_taskwait (parser);
12423 return false;
12425 case PRAGMA_OMP_TASKYIELD:
12426 if (context != pragma_compound)
12428 construct = "omp taskyield";
12429 goto in_compound;
12431 c_parser_omp_taskyield (parser);
12432 return false;
12434 case PRAGMA_OMP_CANCEL:
12435 if (context != pragma_compound)
12437 construct = "omp cancel";
12438 goto in_compound;
12440 c_parser_omp_cancel (parser);
12441 return false;
12443 case PRAGMA_OMP_CANCELLATION_POINT:
12444 return c_parser_omp_cancellation_point (parser, context);
12446 case PRAGMA_OMP_THREADPRIVATE:
12447 c_parser_omp_threadprivate (parser);
12448 return false;
12450 case PRAGMA_OMP_TARGET:
12451 return c_parser_omp_target (parser, context, if_p);
12453 case PRAGMA_OMP_END_DECLARE_TARGET:
12454 c_parser_omp_end_declare_target (parser);
12455 return false;
12457 case PRAGMA_OMP_SCAN:
12458 error_at (c_parser_peek_token (parser)->location,
12459 "%<#pragma omp scan%> may only be used in "
12460 "a loop construct with %<inscan%> %<reduction%> clause");
12461 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12462 return false;
12464 case PRAGMA_OMP_SECTION:
12465 error_at (c_parser_peek_token (parser)->location,
12466 "%<#pragma omp section%> may only be used in "
12467 "%<#pragma omp sections%> construct");
12468 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12469 return false;
12471 case PRAGMA_OMP_DECLARE:
12472 return c_parser_omp_declare (parser, context);
12474 case PRAGMA_OMP_REQUIRES:
12475 if (context != pragma_external)
12477 error_at (c_parser_peek_token (parser)->location,
12478 "%<#pragma omp requires%> may only be used at file scope");
12479 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12480 return false;
12482 c_parser_omp_requires (parser);
12483 return false;
12485 case PRAGMA_OMP_NOTHING:
12486 c_parser_omp_nothing (parser);
12487 return false;
12489 case PRAGMA_OMP_ERROR:
12490 return c_parser_omp_error (parser, context);
12492 case PRAGMA_OMP_ORDERED:
12493 return c_parser_omp_ordered (parser, context, if_p);
12495 case PRAGMA_IVDEP:
12497 const bool ivdep = c_parse_pragma_ivdep (parser);
12498 unsigned short unroll;
12499 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12500 unroll = c_parser_pragma_unroll (parser);
12501 else
12502 unroll = 0;
12503 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12504 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12505 && !c_parser_next_token_is_keyword (parser, RID_DO))
12507 c_parser_error (parser, "for, while or do statement expected");
12508 return false;
12510 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12511 c_parser_for_statement (parser, ivdep, unroll, if_p);
12512 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12513 c_parser_while_statement (parser, ivdep, unroll, if_p);
12514 else
12515 c_parser_do_statement (parser, ivdep, unroll);
12517 return true;
12519 case PRAGMA_UNROLL:
12521 unsigned short unroll = c_parser_pragma_unroll (parser);
12522 bool ivdep;
12523 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12524 ivdep = c_parse_pragma_ivdep (parser);
12525 else
12526 ivdep = false;
12527 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12528 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12529 && !c_parser_next_token_is_keyword (parser, RID_DO))
12531 c_parser_error (parser, "for, while or do statement expected");
12532 return false;
12534 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12535 c_parser_for_statement (parser, ivdep, unroll, if_p);
12536 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12537 c_parser_while_statement (parser, ivdep, unroll, if_p);
12538 else
12539 c_parser_do_statement (parser, ivdep, unroll);
12541 return true;
12543 case PRAGMA_GCC_PCH_PREPROCESS:
12544 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12545 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12546 return false;
12548 case PRAGMA_OACC_WAIT:
12549 if (context != pragma_compound)
12551 construct = "acc wait";
12552 goto in_compound;
12554 /* FALL THROUGH. */
12556 default:
12557 if (id < PRAGMA_FIRST_EXTERNAL)
12559 if (context != pragma_stmt && context != pragma_compound)
12561 bad_stmt:
12562 c_parser_error (parser, "expected declaration specifiers");
12563 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12564 return false;
12566 c_parser_omp_construct (parser, if_p);
12567 return true;
12569 break;
12572 c_parser_consume_pragma (parser);
12573 c_invoke_pragma_handler (id);
12575 /* Skip to EOL, but suppress any error message. Those will have been
12576 generated by the handler routine through calling error, as opposed
12577 to calling c_parser_error. */
12578 parser->error = true;
12579 c_parser_skip_to_pragma_eol (parser);
12581 return false;
12584 /* The interface the pragma parsers have to the lexer. */
12586 enum cpp_ttype
12587 pragma_lex (tree *value, location_t *loc)
12589 c_token *tok = c_parser_peek_token (the_parser);
12590 enum cpp_ttype ret = tok->type;
12592 *value = tok->value;
12593 if (loc)
12594 *loc = tok->location;
12596 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12597 ret = CPP_EOF;
12598 else if (ret == CPP_STRING)
12599 *value = c_parser_string_literal (the_parser, false, false).value;
12600 else
12602 if (ret == CPP_KEYWORD)
12603 ret = CPP_NAME;
12604 c_parser_consume_token (the_parser);
12607 return ret;
12610 static void
12611 c_parser_pragma_pch_preprocess (c_parser *parser)
12613 tree name = NULL;
12615 parser->lex_joined_string = true;
12616 c_parser_consume_pragma (parser);
12617 if (c_parser_next_token_is (parser, CPP_STRING))
12619 name = c_parser_peek_token (parser)->value;
12620 c_parser_consume_token (parser);
12622 else
12623 c_parser_error (parser, "expected string literal");
12624 c_parser_skip_to_pragma_eol (parser);
12625 parser->lex_joined_string = false;
12627 if (name)
12628 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12631 /* OpenACC and OpenMP parsing routines. */
12633 /* Returns name of the next clause.
12634 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12635 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12636 returned and the token is consumed. */
12638 static pragma_omp_clause
12639 c_parser_omp_clause_name (c_parser *parser)
12641 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12643 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12644 result = PRAGMA_OACC_CLAUSE_AUTO;
12645 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12646 result = PRAGMA_OMP_CLAUSE_IF;
12647 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12648 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12649 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12650 result = PRAGMA_OMP_CLAUSE_FOR;
12651 else if (c_parser_next_token_is (parser, CPP_NAME))
12653 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12655 switch (p[0])
12657 case 'a':
12658 if (!strcmp ("affinity", p))
12659 result = PRAGMA_OMP_CLAUSE_AFFINITY;
12660 else if (!strcmp ("aligned", p))
12661 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12662 else if (!strcmp ("allocate", p))
12663 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12664 else if (!strcmp ("async", p))
12665 result = PRAGMA_OACC_CLAUSE_ASYNC;
12666 else if (!strcmp ("attach", p))
12667 result = PRAGMA_OACC_CLAUSE_ATTACH;
12668 break;
12669 case 'b':
12670 if (!strcmp ("bind", p))
12671 result = PRAGMA_OMP_CLAUSE_BIND;
12672 break;
12673 case 'c':
12674 if (!strcmp ("collapse", p))
12675 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12676 else if (!strcmp ("copy", p))
12677 result = PRAGMA_OACC_CLAUSE_COPY;
12678 else if (!strcmp ("copyin", p))
12679 result = PRAGMA_OMP_CLAUSE_COPYIN;
12680 else if (!strcmp ("copyout", p))
12681 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12682 else if (!strcmp ("copyprivate", p))
12683 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12684 else if (!strcmp ("create", p))
12685 result = PRAGMA_OACC_CLAUSE_CREATE;
12686 break;
12687 case 'd':
12688 if (!strcmp ("defaultmap", p))
12689 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12690 else if (!strcmp ("delete", p))
12691 result = PRAGMA_OACC_CLAUSE_DELETE;
12692 else if (!strcmp ("depend", p))
12693 result = PRAGMA_OMP_CLAUSE_DEPEND;
12694 else if (!strcmp ("detach", p))
12695 result = PRAGMA_OACC_CLAUSE_DETACH;
12696 else if (!strcmp ("device", p))
12697 result = PRAGMA_OMP_CLAUSE_DEVICE;
12698 else if (!strcmp ("deviceptr", p))
12699 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12700 else if (!strcmp ("device_resident", p))
12701 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12702 else if (!strcmp ("device_type", p))
12703 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12704 else if (!strcmp ("dist_schedule", p))
12705 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12706 break;
12707 case 'f':
12708 if (!strcmp ("filter", p))
12709 result = PRAGMA_OMP_CLAUSE_FILTER;
12710 else if (!strcmp ("final", p))
12711 result = PRAGMA_OMP_CLAUSE_FINAL;
12712 else if (!strcmp ("finalize", p))
12713 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12714 else if (!strcmp ("firstprivate", p))
12715 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12716 else if (!strcmp ("from", p))
12717 result = PRAGMA_OMP_CLAUSE_FROM;
12718 break;
12719 case 'g':
12720 if (!strcmp ("gang", p))
12721 result = PRAGMA_OACC_CLAUSE_GANG;
12722 else if (!strcmp ("grainsize", p))
12723 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12724 break;
12725 case 'h':
12726 if (!strcmp ("hint", p))
12727 result = PRAGMA_OMP_CLAUSE_HINT;
12728 else if (!strcmp ("host", p))
12729 result = PRAGMA_OACC_CLAUSE_HOST;
12730 break;
12731 case 'i':
12732 if (!strcmp ("if_present", p))
12733 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12734 else if (!strcmp ("in_reduction", p))
12735 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12736 else if (!strcmp ("inbranch", p))
12737 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12738 else if (!strcmp ("independent", p))
12739 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12740 else if (!strcmp ("is_device_ptr", p))
12741 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12742 break;
12743 case 'l':
12744 if (!strcmp ("lastprivate", p))
12745 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12746 else if (!strcmp ("linear", p))
12747 result = PRAGMA_OMP_CLAUSE_LINEAR;
12748 else if (!strcmp ("link", p))
12749 result = PRAGMA_OMP_CLAUSE_LINK;
12750 break;
12751 case 'm':
12752 if (!strcmp ("map", p))
12753 result = PRAGMA_OMP_CLAUSE_MAP;
12754 else if (!strcmp ("mergeable", p))
12755 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12756 break;
12757 case 'n':
12758 if (!strcmp ("no_create", p))
12759 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12760 else if (!strcmp ("nogroup", p))
12761 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12762 else if (!strcmp ("nohost", p))
12763 result = PRAGMA_OACC_CLAUSE_NOHOST;
12764 else if (!strcmp ("nontemporal", p))
12765 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12766 else if (!strcmp ("notinbranch", p))
12767 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12768 else if (!strcmp ("nowait", p))
12769 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12770 else if (!strcmp ("num_gangs", p))
12771 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12772 else if (!strcmp ("num_tasks", p))
12773 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12774 else if (!strcmp ("num_teams", p))
12775 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12776 else if (!strcmp ("num_threads", p))
12777 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12778 else if (!strcmp ("num_workers", p))
12779 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12780 break;
12781 case 'o':
12782 if (!strcmp ("ordered", p))
12783 result = PRAGMA_OMP_CLAUSE_ORDERED;
12784 else if (!strcmp ("order", p))
12785 result = PRAGMA_OMP_CLAUSE_ORDER;
12786 break;
12787 case 'p':
12788 if (!strcmp ("parallel", p))
12789 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12790 else if (!strcmp ("present", p))
12791 result = PRAGMA_OACC_CLAUSE_PRESENT;
12792 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12793 clauses. */
12794 else if (!strcmp ("present_or_copy", p)
12795 || !strcmp ("pcopy", p))
12796 result = PRAGMA_OACC_CLAUSE_COPY;
12797 else if (!strcmp ("present_or_copyin", p)
12798 || !strcmp ("pcopyin", p))
12799 result = PRAGMA_OACC_CLAUSE_COPYIN;
12800 else if (!strcmp ("present_or_copyout", p)
12801 || !strcmp ("pcopyout", p))
12802 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12803 else if (!strcmp ("present_or_create", p)
12804 || !strcmp ("pcreate", p))
12805 result = PRAGMA_OACC_CLAUSE_CREATE;
12806 else if (!strcmp ("priority", p))
12807 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12808 else if (!strcmp ("private", p))
12809 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12810 else if (!strcmp ("proc_bind", p))
12811 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12812 break;
12813 case 'r':
12814 if (!strcmp ("reduction", p))
12815 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12816 break;
12817 case 's':
12818 if (!strcmp ("safelen", p))
12819 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12820 else if (!strcmp ("schedule", p))
12821 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12822 else if (!strcmp ("sections", p))
12823 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12824 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12825 result = PRAGMA_OACC_CLAUSE_HOST;
12826 else if (!strcmp ("seq", p))
12827 result = PRAGMA_OACC_CLAUSE_SEQ;
12828 else if (!strcmp ("shared", p))
12829 result = PRAGMA_OMP_CLAUSE_SHARED;
12830 else if (!strcmp ("simd", p))
12831 result = PRAGMA_OMP_CLAUSE_SIMD;
12832 else if (!strcmp ("simdlen", p))
12833 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12834 break;
12835 case 't':
12836 if (!strcmp ("task_reduction", p))
12837 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12838 else if (!strcmp ("taskgroup", p))
12839 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12840 else if (!strcmp ("thread_limit", p))
12841 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12842 else if (!strcmp ("threads", p))
12843 result = PRAGMA_OMP_CLAUSE_THREADS;
12844 else if (!strcmp ("tile", p))
12845 result = PRAGMA_OACC_CLAUSE_TILE;
12846 else if (!strcmp ("to", p))
12847 result = PRAGMA_OMP_CLAUSE_TO;
12848 break;
12849 case 'u':
12850 if (!strcmp ("uniform", p))
12851 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12852 else if (!strcmp ("untied", p))
12853 result = PRAGMA_OMP_CLAUSE_UNTIED;
12854 else if (!strcmp ("use_device", p))
12855 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12856 else if (!strcmp ("use_device_addr", p))
12857 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12858 else if (!strcmp ("use_device_ptr", p))
12859 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12860 break;
12861 case 'v':
12862 if (!strcmp ("vector", p))
12863 result = PRAGMA_OACC_CLAUSE_VECTOR;
12864 else if (!strcmp ("vector_length", p))
12865 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12866 break;
12867 case 'w':
12868 if (!strcmp ("wait", p))
12869 result = PRAGMA_OACC_CLAUSE_WAIT;
12870 else if (!strcmp ("worker", p))
12871 result = PRAGMA_OACC_CLAUSE_WORKER;
12872 break;
12876 if (result != PRAGMA_OMP_CLAUSE_NONE)
12877 c_parser_consume_token (parser);
12879 return result;
12882 /* Validate that a clause of the given type does not already exist. */
12884 static void
12885 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12886 const char *name)
12888 if (tree c = omp_find_clause (clauses, code))
12889 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12892 /* OpenACC 2.0
12893 Parse wait clause or wait directive parameters. */
12895 static tree
12896 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12898 vec<tree, va_gc> *args;
12899 tree t, args_tree;
12901 matching_parens parens;
12902 if (!parens.require_open (parser))
12903 return list;
12905 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12906 args_tree = build_tree_list_vec (args);
12908 for (t = args_tree; t; t = TREE_CHAIN (t))
12910 tree targ = TREE_VALUE (t);
12912 if (targ != error_mark_node)
12914 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12916 c_parser_error (parser, "expression must be integral");
12917 targ = error_mark_node;
12919 else
12921 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12923 OMP_CLAUSE_DECL (c) = targ;
12924 OMP_CLAUSE_CHAIN (c) = list;
12925 list = c;
12930 release_tree_vector (args);
12931 parens.require_close (parser);
12932 return list;
12935 /* OpenACC 2.0, OpenMP 2.5:
12936 variable-list:
12937 identifier
12938 variable-list , identifier
12940 If KIND is nonzero, create the appropriate node and install the
12941 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12942 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12944 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12945 return the list created.
12947 The optional ALLOW_DEREF argument is true if list items can use the deref
12948 (->) operator. */
12950 static tree
12951 c_parser_omp_variable_list (c_parser *parser,
12952 location_t clause_loc,
12953 enum omp_clause_code kind, tree list,
12954 bool allow_deref = false)
12956 auto_vec<c_token> tokens;
12957 unsigned int tokens_avail = 0;
12958 bool first = true;
12960 while (1)
12962 bool array_section_p = false;
12963 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
12965 if (c_parser_next_token_is_not (parser, CPP_NAME)
12966 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
12968 struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
12969 if (expr.value != error_mark_node)
12971 tree u = build_omp_clause (clause_loc, kind);
12972 OMP_CLAUSE_DECL (u) = expr.value;
12973 OMP_CLAUSE_CHAIN (u) = list;
12974 list = u;
12977 if (c_parser_next_token_is_not (parser, CPP_COMMA))
12978 break;
12980 c_parser_consume_token (parser);
12981 first = false;
12982 continue;
12985 tokens.truncate (0);
12986 unsigned int nesting_depth = 0;
12987 while (1)
12989 c_token *token = c_parser_peek_token (parser);
12990 switch (token->type)
12992 case CPP_EOF:
12993 case CPP_PRAGMA_EOL:
12994 break;
12995 case CPP_OPEN_BRACE:
12996 case CPP_OPEN_PAREN:
12997 case CPP_OPEN_SQUARE:
12998 ++nesting_depth;
12999 goto add;
13000 case CPP_CLOSE_BRACE:
13001 case CPP_CLOSE_PAREN:
13002 case CPP_CLOSE_SQUARE:
13003 if (nesting_depth-- == 0)
13004 break;
13005 goto add;
13006 case CPP_COMMA:
13007 if (nesting_depth == 0)
13008 break;
13009 goto add;
13010 default:
13011 add:
13012 tokens.safe_push (*token);
13013 c_parser_consume_token (parser);
13014 continue;
13016 break;
13019 /* Make sure nothing tries to read past the end of the tokens. */
13020 c_token eof_token;
13021 memset (&eof_token, 0, sizeof (eof_token));
13022 eof_token.type = CPP_EOF;
13023 tokens.safe_push (eof_token);
13024 tokens.safe_push (eof_token);
13026 tokens_avail = parser->tokens_avail;
13027 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13028 parser->tokens = tokens.address ();
13029 parser->tokens_avail = tokens.length ();
13032 tree t = NULL_TREE;
13034 if (c_parser_next_token_is (parser, CPP_NAME)
13035 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13037 t = lookup_name (c_parser_peek_token (parser)->value);
13039 if (t == NULL_TREE)
13041 undeclared_variable (c_parser_peek_token (parser)->location,
13042 c_parser_peek_token (parser)->value);
13043 t = error_mark_node;
13046 c_parser_consume_token (parser);
13048 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13049 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13050 || (c_parser_peek_token (parser)->keyword
13051 == RID_PRETTY_FUNCTION_NAME)
13052 || (c_parser_peek_token (parser)->keyword
13053 == RID_C99_FUNCTION_NAME)))
13054 t = c_parser_predefined_identifier (parser).value;
13055 else
13057 if (first)
13058 c_parser_error (parser, "expected identifier");
13059 break;
13062 if (t == error_mark_node)
13064 else if (kind != 0)
13066 switch (kind)
13068 case OMP_CLAUSE__CACHE_:
13069 /* The OpenACC cache directive explicitly only allows "array
13070 elements or subarrays". */
13071 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13073 c_parser_error (parser, "expected %<[%>");
13074 t = error_mark_node;
13075 break;
13077 /* FALLTHROUGH */
13078 case OMP_CLAUSE_MAP:
13079 case OMP_CLAUSE_FROM:
13080 case OMP_CLAUSE_TO:
13081 while (c_parser_next_token_is (parser, CPP_DOT)
13082 || (allow_deref
13083 && c_parser_next_token_is (parser, CPP_DEREF)))
13085 location_t op_loc = c_parser_peek_token (parser)->location;
13086 if (c_parser_next_token_is (parser, CPP_DEREF))
13087 t = build_simple_mem_ref (t);
13088 c_parser_consume_token (parser);
13089 if (!c_parser_next_token_is (parser, CPP_NAME))
13091 c_parser_error (parser, "expected identifier");
13092 t = error_mark_node;
13093 break;
13096 c_token *comp_tok = c_parser_peek_token (parser);
13097 tree ident = comp_tok->value;
13098 location_t comp_loc = comp_tok->location;
13099 c_parser_consume_token (parser);
13100 t = build_component_ref (op_loc, t, ident, comp_loc);
13102 /* FALLTHROUGH */
13103 case OMP_CLAUSE_AFFINITY:
13104 case OMP_CLAUSE_DEPEND:
13105 case OMP_CLAUSE_REDUCTION:
13106 case OMP_CLAUSE_IN_REDUCTION:
13107 case OMP_CLAUSE_TASK_REDUCTION:
13108 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13110 tree low_bound = NULL_TREE, length = NULL_TREE;
13112 c_parser_consume_token (parser);
13113 if (!c_parser_next_token_is (parser, CPP_COLON))
13115 location_t expr_loc
13116 = c_parser_peek_token (parser)->location;
13117 c_expr expr = c_parser_expression (parser);
13118 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13119 false, true);
13120 low_bound = expr.value;
13122 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13123 length = integer_one_node;
13124 else
13126 /* Look for `:'. */
13127 if (!c_parser_require (parser, CPP_COLON,
13128 "expected %<:%>"))
13130 t = error_mark_node;
13131 break;
13133 array_section_p = true;
13134 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13136 location_t expr_loc
13137 = c_parser_peek_token (parser)->location;
13138 c_expr expr = c_parser_expression (parser);
13139 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13140 false, true);
13141 length = expr.value;
13144 /* Look for the closing `]'. */
13145 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13146 "expected %<]%>"))
13148 t = error_mark_node;
13149 break;
13152 t = tree_cons (low_bound, length, t);
13154 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13155 && t != error_mark_node
13156 && parser->tokens_avail != 2)
13158 if (array_section_p)
13160 error_at (c_parser_peek_token (parser)->location,
13161 "expected %<)%> or %<,%>");
13162 t = error_mark_node;
13164 else
13166 parser->tokens = tokens.address ();
13167 parser->tokens_avail = tokens.length ();
13169 t = c_parser_expr_no_commas (parser, NULL).value;
13170 if (t != error_mark_node && parser->tokens_avail != 2)
13172 error_at (c_parser_peek_token (parser)->location,
13173 "expected %<)%> or %<,%>");
13174 t = error_mark_node;
13178 break;
13179 default:
13180 break;
13183 if (t != error_mark_node)
13185 tree u = build_omp_clause (clause_loc, kind);
13186 OMP_CLAUSE_DECL (u) = t;
13187 OMP_CLAUSE_CHAIN (u) = list;
13188 list = u;
13191 else
13192 list = tree_cons (t, NULL_TREE, list);
13194 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13196 parser->tokens = &parser->tokens_buf[0];
13197 parser->tokens_avail = tokens_avail;
13199 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13200 break;
13202 c_parser_consume_token (parser);
13203 first = false;
13206 return list;
13209 /* Similarly, but expect leading and trailing parenthesis. This is a very
13210 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13211 argument is true if list items can use the deref (->) operator. */
13213 static tree
13214 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13215 tree list, bool allow_deref = false)
13217 /* The clauses location. */
13218 location_t loc = c_parser_peek_token (parser)->location;
13220 matching_parens parens;
13221 if (parens.require_open (parser))
13223 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13224 parens.skip_until_found_close (parser);
13226 return list;
13229 /* OpenACC 2.0:
13230 copy ( variable-list )
13231 copyin ( variable-list )
13232 copyout ( variable-list )
13233 create ( variable-list )
13234 delete ( variable-list )
13235 present ( variable-list )
13237 OpenACC 2.6:
13238 no_create ( variable-list )
13239 attach ( variable-list )
13240 detach ( variable-list ) */
13242 static tree
13243 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13244 tree list)
13246 enum gomp_map_kind kind;
13247 switch (c_kind)
13249 case PRAGMA_OACC_CLAUSE_ATTACH:
13250 kind = GOMP_MAP_ATTACH;
13251 break;
13252 case PRAGMA_OACC_CLAUSE_COPY:
13253 kind = GOMP_MAP_TOFROM;
13254 break;
13255 case PRAGMA_OACC_CLAUSE_COPYIN:
13256 kind = GOMP_MAP_TO;
13257 break;
13258 case PRAGMA_OACC_CLAUSE_COPYOUT:
13259 kind = GOMP_MAP_FROM;
13260 break;
13261 case PRAGMA_OACC_CLAUSE_CREATE:
13262 kind = GOMP_MAP_ALLOC;
13263 break;
13264 case PRAGMA_OACC_CLAUSE_DELETE:
13265 kind = GOMP_MAP_RELEASE;
13266 break;
13267 case PRAGMA_OACC_CLAUSE_DETACH:
13268 kind = GOMP_MAP_DETACH;
13269 break;
13270 case PRAGMA_OACC_CLAUSE_DEVICE:
13271 kind = GOMP_MAP_FORCE_TO;
13272 break;
13273 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13274 kind = GOMP_MAP_DEVICE_RESIDENT;
13275 break;
13276 case PRAGMA_OACC_CLAUSE_HOST:
13277 kind = GOMP_MAP_FORCE_FROM;
13278 break;
13279 case PRAGMA_OACC_CLAUSE_LINK:
13280 kind = GOMP_MAP_LINK;
13281 break;
13282 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13283 kind = GOMP_MAP_IF_PRESENT;
13284 break;
13285 case PRAGMA_OACC_CLAUSE_PRESENT:
13286 kind = GOMP_MAP_FORCE_PRESENT;
13287 break;
13288 default:
13289 gcc_unreachable ();
13291 tree nl, c;
13292 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13294 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13295 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13297 return nl;
13300 /* OpenACC 2.0:
13301 deviceptr ( variable-list ) */
13303 static tree
13304 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13306 location_t loc = c_parser_peek_token (parser)->location;
13307 tree vars, t;
13309 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13310 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13311 variable-list must only allow for pointer variables. */
13312 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13313 for (t = vars; t && t; t = TREE_CHAIN (t))
13315 tree v = TREE_PURPOSE (t);
13317 /* FIXME diagnostics: Ideally we should keep individual
13318 locations for all the variables in the var list to make the
13319 following errors more precise. Perhaps
13320 c_parser_omp_var_list_parens() should construct a list of
13321 locations to go along with the var list. */
13323 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13324 error_at (loc, "%qD is not a variable", v);
13325 else if (TREE_TYPE (v) == error_mark_node)
13327 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13328 error_at (loc, "%qD is not a pointer variable", v);
13330 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13331 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13332 OMP_CLAUSE_DECL (u) = v;
13333 OMP_CLAUSE_CHAIN (u) = list;
13334 list = u;
13337 return list;
13340 /* OpenACC 2.0, OpenMP 3.0:
13341 collapse ( constant-expression ) */
13343 static tree
13344 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13346 tree c, num = error_mark_node;
13347 HOST_WIDE_INT n;
13348 location_t loc;
13350 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13351 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13353 loc = c_parser_peek_token (parser)->location;
13354 matching_parens parens;
13355 if (parens.require_open (parser))
13357 num = c_parser_expr_no_commas (parser, NULL).value;
13358 parens.skip_until_found_close (parser);
13360 if (num == error_mark_node)
13361 return list;
13362 mark_exp_read (num);
13363 num = c_fully_fold (num, false, NULL);
13364 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13365 || !tree_fits_shwi_p (num)
13366 || (n = tree_to_shwi (num)) <= 0
13367 || (int) n != n)
13369 error_at (loc,
13370 "collapse argument needs positive constant integer expression");
13371 return list;
13373 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13374 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13375 OMP_CLAUSE_CHAIN (c) = list;
13376 return c;
13379 /* OpenMP 2.5:
13380 copyin ( variable-list ) */
13382 static tree
13383 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13385 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13388 /* OpenMP 2.5:
13389 copyprivate ( variable-list ) */
13391 static tree
13392 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13394 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13397 /* OpenMP 2.5:
13398 default ( none | shared )
13400 OpenACC:
13401 default ( none | present ) */
13403 static tree
13404 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13406 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13407 location_t loc = c_parser_peek_token (parser)->location;
13408 tree c;
13410 matching_parens parens;
13411 if (!parens.require_open (parser))
13412 return list;
13413 if (c_parser_next_token_is (parser, CPP_NAME))
13415 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13417 switch (p[0])
13419 case 'n':
13420 if (strcmp ("none", p) != 0)
13421 goto invalid_kind;
13422 kind = OMP_CLAUSE_DEFAULT_NONE;
13423 break;
13425 case 'p':
13426 if (strcmp ("present", p) != 0 || !is_oacc)
13427 goto invalid_kind;
13428 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13429 break;
13431 case 's':
13432 if (strcmp ("shared", p) != 0 || is_oacc)
13433 goto invalid_kind;
13434 kind = OMP_CLAUSE_DEFAULT_SHARED;
13435 break;
13437 default:
13438 goto invalid_kind;
13441 c_parser_consume_token (parser);
13443 else
13445 invalid_kind:
13446 if (is_oacc)
13447 c_parser_error (parser, "expected %<none%> or %<present%>");
13448 else
13449 c_parser_error (parser, "expected %<none%> or %<shared%>");
13451 parens.skip_until_found_close (parser);
13453 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13454 return list;
13456 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13457 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13458 OMP_CLAUSE_CHAIN (c) = list;
13459 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13461 return c;
13464 /* OpenMP 2.5:
13465 firstprivate ( variable-list ) */
13467 static tree
13468 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13470 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13473 /* OpenMP 3.1:
13474 final ( expression ) */
13476 static tree
13477 c_parser_omp_clause_final (c_parser *parser, tree list)
13479 location_t loc = c_parser_peek_token (parser)->location;
13480 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13482 matching_parens parens;
13483 tree t, c;
13484 if (!parens.require_open (parser))
13485 t = error_mark_node;
13486 else
13488 location_t eloc = c_parser_peek_token (parser)->location;
13489 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13490 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13491 t = c_objc_common_truthvalue_conversion (eloc, t);
13492 t = c_fully_fold (t, false, NULL);
13493 parens.skip_until_found_close (parser);
13496 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13498 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13499 OMP_CLAUSE_FINAL_EXPR (c) = t;
13500 OMP_CLAUSE_CHAIN (c) = list;
13501 list = c;
13503 else
13504 c_parser_error (parser, "expected %<(%>");
13506 return list;
13509 /* OpenACC, OpenMP 2.5:
13510 if ( expression )
13512 OpenMP 4.5:
13513 if ( directive-name-modifier : expression )
13515 directive-name-modifier:
13516 parallel | task | taskloop | target data | target | target update
13517 | target enter data | target exit data
13519 OpenMP 5.0:
13520 directive-name-modifier:
13521 ... | simd | cancel */
13523 static tree
13524 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13526 location_t location = c_parser_peek_token (parser)->location;
13527 enum tree_code if_modifier = ERROR_MARK;
13529 matching_parens parens;
13530 if (!parens.require_open (parser))
13531 return list;
13533 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13535 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13536 int n = 2;
13537 if (strcmp (p, "cancel") == 0)
13538 if_modifier = VOID_CST;
13539 else if (strcmp (p, "parallel") == 0)
13540 if_modifier = OMP_PARALLEL;
13541 else if (strcmp (p, "simd") == 0)
13542 if_modifier = OMP_SIMD;
13543 else if (strcmp (p, "task") == 0)
13544 if_modifier = OMP_TASK;
13545 else if (strcmp (p, "taskloop") == 0)
13546 if_modifier = OMP_TASKLOOP;
13547 else if (strcmp (p, "target") == 0)
13549 if_modifier = OMP_TARGET;
13550 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13552 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13553 if (strcmp ("data", p) == 0)
13554 if_modifier = OMP_TARGET_DATA;
13555 else if (strcmp ("update", p) == 0)
13556 if_modifier = OMP_TARGET_UPDATE;
13557 else if (strcmp ("enter", p) == 0)
13558 if_modifier = OMP_TARGET_ENTER_DATA;
13559 else if (strcmp ("exit", p) == 0)
13560 if_modifier = OMP_TARGET_EXIT_DATA;
13561 if (if_modifier != OMP_TARGET)
13563 n = 3;
13564 c_parser_consume_token (parser);
13566 else
13568 location_t loc = c_parser_peek_2nd_token (parser)->location;
13569 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13570 "or %<exit%>");
13571 if_modifier = ERROR_MARK;
13573 if (if_modifier == OMP_TARGET_ENTER_DATA
13574 || if_modifier == OMP_TARGET_EXIT_DATA)
13576 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13578 p = IDENTIFIER_POINTER
13579 (c_parser_peek_2nd_token (parser)->value);
13580 if (strcmp ("data", p) == 0)
13581 n = 4;
13583 if (n == 4)
13584 c_parser_consume_token (parser);
13585 else
13587 location_t loc
13588 = c_parser_peek_2nd_token (parser)->location;
13589 error_at (loc, "expected %<data%>");
13590 if_modifier = ERROR_MARK;
13595 if (if_modifier != ERROR_MARK)
13597 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13599 c_parser_consume_token (parser);
13600 c_parser_consume_token (parser);
13602 else
13604 if (n > 2)
13606 location_t loc = c_parser_peek_2nd_token (parser)->location;
13607 error_at (loc, "expected %<:%>");
13609 if_modifier = ERROR_MARK;
13614 location_t loc = c_parser_peek_token (parser)->location;
13615 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13616 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13617 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13618 t = c_fully_fold (t, false, NULL);
13619 parens.skip_until_found_close (parser);
13621 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13622 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13624 if (if_modifier != ERROR_MARK
13625 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13627 const char *p = NULL;
13628 switch (if_modifier)
13630 case VOID_CST: p = "cancel"; break;
13631 case OMP_PARALLEL: p = "parallel"; break;
13632 case OMP_SIMD: p = "simd"; break;
13633 case OMP_TASK: p = "task"; break;
13634 case OMP_TASKLOOP: p = "taskloop"; break;
13635 case OMP_TARGET_DATA: p = "target data"; break;
13636 case OMP_TARGET: p = "target"; break;
13637 case OMP_TARGET_UPDATE: p = "target update"; break;
13638 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13639 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13640 default: gcc_unreachable ();
13642 error_at (location, "too many %<if%> clauses with %qs modifier",
13644 return list;
13646 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13648 if (!is_omp)
13649 error_at (location, "too many %<if%> clauses");
13650 else
13651 error_at (location, "too many %<if%> clauses without modifier");
13652 return list;
13654 else if (if_modifier == ERROR_MARK
13655 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13657 error_at (location, "if any %<if%> clause has modifier, then all "
13658 "%<if%> clauses have to use modifier");
13659 return list;
13663 c = build_omp_clause (location, OMP_CLAUSE_IF);
13664 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13665 OMP_CLAUSE_IF_EXPR (c) = t;
13666 OMP_CLAUSE_CHAIN (c) = list;
13667 return c;
13670 /* OpenMP 2.5:
13671 lastprivate ( variable-list )
13673 OpenMP 5.0:
13674 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13676 static tree
13677 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13679 /* The clauses location. */
13680 location_t loc = c_parser_peek_token (parser)->location;
13682 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13684 bool conditional = false;
13685 if (c_parser_next_token_is (parser, CPP_NAME)
13686 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13688 const char *p
13689 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13690 if (strcmp (p, "conditional") == 0)
13692 conditional = true;
13693 c_parser_consume_token (parser);
13694 c_parser_consume_token (parser);
13697 tree nlist = c_parser_omp_variable_list (parser, loc,
13698 OMP_CLAUSE_LASTPRIVATE, list);
13699 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13700 if (conditional)
13701 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13702 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13703 return nlist;
13705 return list;
13708 /* OpenMP 3.1:
13709 mergeable */
13711 static tree
13712 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13714 tree c;
13716 /* FIXME: Should we allow duplicates? */
13717 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13719 c = build_omp_clause (c_parser_peek_token (parser)->location,
13720 OMP_CLAUSE_MERGEABLE);
13721 OMP_CLAUSE_CHAIN (c) = list;
13723 return c;
13726 /* OpenMP 2.5:
13727 nowait */
13729 static tree
13730 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13732 tree c;
13733 location_t loc = c_parser_peek_token (parser)->location;
13735 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13737 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13738 OMP_CLAUSE_CHAIN (c) = list;
13739 return c;
13742 /* OpenMP 2.5:
13743 num_threads ( expression ) */
13745 static tree
13746 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13748 location_t num_threads_loc = c_parser_peek_token (parser)->location;
13749 matching_parens parens;
13750 if (parens.require_open (parser))
13752 location_t expr_loc = c_parser_peek_token (parser)->location;
13753 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13754 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13755 tree c, t = expr.value;
13756 t = c_fully_fold (t, false, NULL);
13758 parens.skip_until_found_close (parser);
13760 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13762 c_parser_error (parser, "expected integer expression");
13763 return list;
13766 /* Attempt to statically determine when the number isn't positive. */
13767 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13768 build_int_cst (TREE_TYPE (t), 0));
13769 protected_set_expr_location (c, expr_loc);
13770 if (c == boolean_true_node)
13772 warning_at (expr_loc, 0,
13773 "%<num_threads%> value must be positive");
13774 t = integer_one_node;
13777 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13779 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13780 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13781 OMP_CLAUSE_CHAIN (c) = list;
13782 list = c;
13785 return list;
13788 /* OpenMP 4.5:
13789 num_tasks ( expression ) */
13791 static tree
13792 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13794 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13795 matching_parens parens;
13796 if (parens.require_open (parser))
13798 location_t expr_loc = c_parser_peek_token (parser)->location;
13799 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13800 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13801 tree c, t = expr.value;
13802 t = c_fully_fold (t, false, NULL);
13804 parens.skip_until_found_close (parser);
13806 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13808 c_parser_error (parser, "expected integer expression");
13809 return list;
13812 /* Attempt to statically determine when the number isn't positive. */
13813 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13814 build_int_cst (TREE_TYPE (t), 0));
13815 if (CAN_HAVE_LOCATION_P (c))
13816 SET_EXPR_LOCATION (c, expr_loc);
13817 if (c == boolean_true_node)
13819 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13820 t = integer_one_node;
13823 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13825 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13826 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13827 OMP_CLAUSE_CHAIN (c) = list;
13828 list = c;
13831 return list;
13834 /* OpenMP 4.5:
13835 grainsize ( expression ) */
13837 static tree
13838 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13840 location_t grainsize_loc = c_parser_peek_token (parser)->location;
13841 matching_parens parens;
13842 if (parens.require_open (parser))
13844 location_t expr_loc = c_parser_peek_token (parser)->location;
13845 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13846 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13847 tree c, t = expr.value;
13848 t = c_fully_fold (t, false, NULL);
13850 parens.skip_until_found_close (parser);
13852 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13854 c_parser_error (parser, "expected integer expression");
13855 return list;
13858 /* Attempt to statically determine when the number isn't positive. */
13859 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13860 build_int_cst (TREE_TYPE (t), 0));
13861 if (CAN_HAVE_LOCATION_P (c))
13862 SET_EXPR_LOCATION (c, expr_loc);
13863 if (c == boolean_true_node)
13865 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
13866 t = integer_one_node;
13869 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
13871 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
13872 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
13873 OMP_CLAUSE_CHAIN (c) = list;
13874 list = c;
13877 return list;
13880 /* OpenMP 4.5:
13881 priority ( expression ) */
13883 static tree
13884 c_parser_omp_clause_priority (c_parser *parser, tree list)
13886 location_t priority_loc = c_parser_peek_token (parser)->location;
13887 matching_parens parens;
13888 if (parens.require_open (parser))
13890 location_t expr_loc = c_parser_peek_token (parser)->location;
13891 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13892 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13893 tree c, t = expr.value;
13894 t = c_fully_fold (t, false, NULL);
13896 parens.skip_until_found_close (parser);
13898 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13900 c_parser_error (parser, "expected integer expression");
13901 return list;
13904 /* Attempt to statically determine when the number isn't
13905 non-negative. */
13906 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
13907 build_int_cst (TREE_TYPE (t), 0));
13908 if (CAN_HAVE_LOCATION_P (c))
13909 SET_EXPR_LOCATION (c, expr_loc);
13910 if (c == boolean_true_node)
13912 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
13913 t = integer_one_node;
13916 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
13918 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
13919 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
13920 OMP_CLAUSE_CHAIN (c) = list;
13921 list = c;
13924 return list;
13927 /* OpenMP 4.5:
13928 hint ( expression ) */
13930 static tree
13931 c_parser_omp_clause_hint (c_parser *parser, tree list)
13933 location_t hint_loc = c_parser_peek_token (parser)->location;
13934 matching_parens parens;
13935 if (parens.require_open (parser))
13937 location_t expr_loc = c_parser_peek_token (parser)->location;
13938 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13939 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13940 tree c, t = expr.value;
13941 t = c_fully_fold (t, false, NULL);
13942 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
13943 || TREE_CODE (t) != INTEGER_CST
13944 || tree_int_cst_sgn (t) == -1)
13946 c_parser_error (parser, "expected constant integer expression "
13947 "with valid sync-hint value");
13948 return list;
13950 parens.skip_until_found_close (parser);
13951 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
13953 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
13954 OMP_CLAUSE_HINT_EXPR (c) = t;
13955 OMP_CLAUSE_CHAIN (c) = list;
13956 list = c;
13959 return list;
13962 /* OpenMP 5.1:
13963 filter ( integer-expression ) */
13965 static tree
13966 c_parser_omp_clause_filter (c_parser *parser, tree list)
13968 location_t hint_loc = c_parser_peek_token (parser)->location;
13969 matching_parens parens;
13970 if (parens.require_open (parser))
13972 location_t expr_loc = c_parser_peek_token (parser)->location;
13973 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13974 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13975 tree c, t = expr.value;
13976 t = c_fully_fold (t, false, NULL);
13977 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13979 c_parser_error (parser, "expected integer expression");
13980 return list;
13982 parens.skip_until_found_close (parser);
13983 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
13985 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
13986 OMP_CLAUSE_FILTER_EXPR (c) = t;
13987 OMP_CLAUSE_CHAIN (c) = list;
13988 list = c;
13991 return list;
13994 /* OpenMP 4.5:
13995 defaultmap ( tofrom : scalar )
13997 OpenMP 5.0:
13998 defaultmap ( implicit-behavior [ : variable-category ] ) */
14000 static tree
14001 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14003 location_t loc = c_parser_peek_token (parser)->location;
14004 tree c;
14005 const char *p;
14006 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14007 enum omp_clause_defaultmap_kind category
14008 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14010 matching_parens parens;
14011 if (!parens.require_open (parser))
14012 return list;
14013 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14014 p = "default";
14015 else if (!c_parser_next_token_is (parser, CPP_NAME))
14017 invalid_behavior:
14018 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14019 "%<tofrom%>, %<firstprivate%>, %<none%> "
14020 "or %<default%>");
14021 goto out_err;
14023 else
14024 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14026 switch (p[0])
14028 case 'a':
14029 if (strcmp ("alloc", p) == 0)
14030 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14031 else
14032 goto invalid_behavior;
14033 break;
14035 case 'd':
14036 if (strcmp ("default", p) == 0)
14037 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14038 else
14039 goto invalid_behavior;
14040 break;
14042 case 'f':
14043 if (strcmp ("firstprivate", p) == 0)
14044 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14045 else if (strcmp ("from", p) == 0)
14046 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14047 else
14048 goto invalid_behavior;
14049 break;
14051 case 'n':
14052 if (strcmp ("none", p) == 0)
14053 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14054 else
14055 goto invalid_behavior;
14056 break;
14058 case 't':
14059 if (strcmp ("tofrom", p) == 0)
14060 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14061 else if (strcmp ("to", p) == 0)
14062 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14063 else
14064 goto invalid_behavior;
14065 break;
14067 default:
14068 goto invalid_behavior;
14070 c_parser_consume_token (parser);
14072 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14074 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14075 goto out_err;
14076 if (!c_parser_next_token_is (parser, CPP_NAME))
14078 invalid_category:
14079 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14080 "%<pointer%>");
14081 goto out_err;
14083 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14084 switch (p[0])
14086 case 'a':
14087 if (strcmp ("aggregate", p) == 0)
14088 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14089 else
14090 goto invalid_category;
14091 break;
14093 case 'p':
14094 if (strcmp ("pointer", p) == 0)
14095 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14096 else
14097 goto invalid_category;
14098 break;
14100 case 's':
14101 if (strcmp ("scalar", p) == 0)
14102 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14103 else
14104 goto invalid_category;
14105 break;
14107 default:
14108 goto invalid_category;
14111 c_parser_consume_token (parser);
14113 parens.skip_until_found_close (parser);
14115 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14116 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14117 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14118 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14119 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14120 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14122 enum omp_clause_defaultmap_kind cat = category;
14123 location_t loc = OMP_CLAUSE_LOCATION (c);
14124 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14125 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14126 p = NULL;
14127 switch (cat)
14129 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14130 p = NULL;
14131 break;
14132 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14133 p = "aggregate";
14134 break;
14135 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14136 p = "pointer";
14137 break;
14138 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14139 p = "scalar";
14140 break;
14141 default:
14142 gcc_unreachable ();
14144 if (p)
14145 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14147 else
14148 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14149 "category");
14150 break;
14153 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14154 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14155 OMP_CLAUSE_CHAIN (c) = list;
14156 return c;
14158 out_err:
14159 parens.skip_until_found_close (parser);
14160 return list;
14163 /* OpenACC 2.0:
14164 use_device ( variable-list )
14166 OpenMP 4.5:
14167 use_device_ptr ( variable-list ) */
14169 static tree
14170 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14172 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14173 list);
14176 /* OpenMP 5.0:
14177 use_device_addr ( variable-list ) */
14179 static tree
14180 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14182 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14183 list);
14186 /* OpenMP 4.5:
14187 is_device_ptr ( variable-list ) */
14189 static tree
14190 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14192 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14195 /* OpenACC:
14196 num_gangs ( expression )
14197 num_workers ( expression )
14198 vector_length ( expression ) */
14200 static tree
14201 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14202 tree list)
14204 location_t loc = c_parser_peek_token (parser)->location;
14206 matching_parens parens;
14207 if (!parens.require_open (parser))
14208 return list;
14210 location_t expr_loc = c_parser_peek_token (parser)->location;
14211 c_expr expr = c_parser_expression (parser);
14212 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14213 tree c, t = expr.value;
14214 t = c_fully_fold (t, false, NULL);
14216 parens.skip_until_found_close (parser);
14218 if (t == error_mark_node)
14219 return list;
14220 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14222 error_at (expr_loc, "%qs expression must be integral",
14223 omp_clause_code_name[code]);
14224 return list;
14227 /* Attempt to statically determine when the number isn't positive. */
14228 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14229 build_int_cst (TREE_TYPE (t), 0));
14230 protected_set_expr_location (c, expr_loc);
14231 if (c == boolean_true_node)
14233 warning_at (expr_loc, 0,
14234 "%qs value must be positive",
14235 omp_clause_code_name[code]);
14236 t = integer_one_node;
14239 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14241 c = build_omp_clause (loc, code);
14242 OMP_CLAUSE_OPERAND (c, 0) = t;
14243 OMP_CLAUSE_CHAIN (c) = list;
14244 return c;
14247 /* OpenACC:
14249 gang [( gang-arg-list )]
14250 worker [( [num:] int-expr )]
14251 vector [( [length:] int-expr )]
14253 where gang-arg is one of:
14255 [num:] int-expr
14256 static: size-expr
14258 and size-expr may be:
14261 int-expr
14264 static tree
14265 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14266 omp_clause_code kind,
14267 const char *str, tree list)
14269 const char *id = "num";
14270 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14272 if (kind == OMP_CLAUSE_VECTOR)
14273 id = "length";
14275 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14277 c_parser_consume_token (parser);
14281 c_token *next = c_parser_peek_token (parser);
14282 int idx = 0;
14284 /* Gang static argument. */
14285 if (kind == OMP_CLAUSE_GANG
14286 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14288 c_parser_consume_token (parser);
14290 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14291 goto cleanup_error;
14293 idx = 1;
14294 if (ops[idx] != NULL_TREE)
14296 c_parser_error (parser, "too many %<static%> arguments");
14297 goto cleanup_error;
14300 /* Check for the '*' argument. */
14301 if (c_parser_next_token_is (parser, CPP_MULT)
14302 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14303 || c_parser_peek_2nd_token (parser)->type
14304 == CPP_CLOSE_PAREN))
14306 c_parser_consume_token (parser);
14307 ops[idx] = integer_minus_one_node;
14309 if (c_parser_next_token_is (parser, CPP_COMMA))
14311 c_parser_consume_token (parser);
14312 continue;
14314 else
14315 break;
14318 /* Worker num: argument and vector length: arguments. */
14319 else if (c_parser_next_token_is (parser, CPP_NAME)
14320 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14321 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14323 c_parser_consume_token (parser); /* id */
14324 c_parser_consume_token (parser); /* ':' */
14327 /* Now collect the actual argument. */
14328 if (ops[idx] != NULL_TREE)
14330 c_parser_error (parser, "unexpected argument");
14331 goto cleanup_error;
14334 location_t expr_loc = c_parser_peek_token (parser)->location;
14335 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14336 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14337 tree expr = cexpr.value;
14338 if (expr == error_mark_node)
14339 goto cleanup_error;
14341 expr = c_fully_fold (expr, false, NULL);
14343 /* Attempt to statically determine when the number isn't a
14344 positive integer. */
14346 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14348 c_parser_error (parser, "expected integer expression");
14349 return list;
14352 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14353 build_int_cst (TREE_TYPE (expr), 0));
14354 if (c == boolean_true_node)
14356 warning_at (loc, 0,
14357 "%qs value must be positive", str);
14358 expr = integer_one_node;
14361 ops[idx] = expr;
14363 if (kind == OMP_CLAUSE_GANG
14364 && c_parser_next_token_is (parser, CPP_COMMA))
14366 c_parser_consume_token (parser);
14367 continue;
14369 break;
14371 while (1);
14373 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14374 goto cleanup_error;
14377 check_no_duplicate_clause (list, kind, str);
14379 c = build_omp_clause (loc, kind);
14381 if (ops[1])
14382 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14384 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14385 OMP_CLAUSE_CHAIN (c) = list;
14387 return c;
14389 cleanup_error:
14390 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14391 return list;
14394 /* OpenACC 2.5:
14395 auto
14396 finalize
14397 independent
14398 nohost
14399 seq */
14401 static tree
14402 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14403 tree list)
14405 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14407 tree c = build_omp_clause (loc, code);
14408 OMP_CLAUSE_CHAIN (c) = list;
14410 return c;
14413 /* OpenACC:
14414 async [( int-expr )] */
14416 static tree
14417 c_parser_oacc_clause_async (c_parser *parser, tree list)
14419 tree c, t;
14420 location_t loc = c_parser_peek_token (parser)->location;
14422 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14424 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14426 c_parser_consume_token (parser);
14428 t = c_parser_expr_no_commas (parser, NULL).value;
14429 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14430 c_parser_error (parser, "expected integer expression");
14431 else if (t == error_mark_node
14432 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14433 return list;
14435 else
14436 t = c_fully_fold (t, false, NULL);
14438 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14440 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14441 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14442 OMP_CLAUSE_CHAIN (c) = list;
14443 list = c;
14445 return list;
14448 /* OpenACC 2.0:
14449 tile ( size-expr-list ) */
14451 static tree
14452 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14454 tree c, expr = error_mark_node;
14455 location_t loc;
14456 tree tile = NULL_TREE;
14458 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14459 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14461 loc = c_parser_peek_token (parser)->location;
14462 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14463 return list;
14467 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14468 return list;
14470 if (c_parser_next_token_is (parser, CPP_MULT)
14471 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14472 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14474 c_parser_consume_token (parser);
14475 expr = integer_zero_node;
14477 else
14479 location_t expr_loc = c_parser_peek_token (parser)->location;
14480 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14481 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14482 expr = cexpr.value;
14484 if (expr == error_mark_node)
14486 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14487 "expected %<)%>");
14488 return list;
14491 expr = c_fully_fold (expr, false, NULL);
14493 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14494 || !tree_fits_shwi_p (expr)
14495 || tree_to_shwi (expr) <= 0)
14497 error_at (expr_loc, "%<tile%> argument needs positive"
14498 " integral constant");
14499 expr = integer_zero_node;
14503 tile = tree_cons (NULL_TREE, expr, tile);
14505 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14507 /* Consume the trailing ')'. */
14508 c_parser_consume_token (parser);
14510 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14511 tile = nreverse (tile);
14512 OMP_CLAUSE_TILE_LIST (c) = tile;
14513 OMP_CLAUSE_CHAIN (c) = list;
14514 return c;
14517 /* OpenACC:
14518 wait [( int-expr-list )] */
14520 static tree
14521 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14523 location_t clause_loc = c_parser_peek_token (parser)->location;
14525 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14526 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14527 else
14529 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14531 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14532 OMP_CLAUSE_CHAIN (c) = list;
14533 list = c;
14536 return list;
14540 /* OpenMP 5.0:
14541 order ( concurrent ) */
14543 static tree
14544 c_parser_omp_clause_order (c_parser *parser, tree list)
14546 location_t loc = c_parser_peek_token (parser)->location;
14547 tree c;
14548 const char *p;
14550 matching_parens parens;
14551 if (!parens.require_open (parser))
14552 return list;
14553 if (!c_parser_next_token_is (parser, CPP_NAME))
14555 c_parser_error (parser, "expected %<concurrent%>");
14556 goto out_err;
14558 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14559 if (strcmp (p, "concurrent") != 0)
14561 c_parser_error (parser, "expected %<concurrent%>");
14562 goto out_err;
14564 c_parser_consume_token (parser);
14565 parens.skip_until_found_close (parser);
14566 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14567 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14568 OMP_CLAUSE_CHAIN (c) = list;
14569 return c;
14571 out_err:
14572 parens.skip_until_found_close (parser);
14573 return list;
14577 /* OpenMP 5.0:
14578 bind ( teams | parallel | thread ) */
14580 static tree
14581 c_parser_omp_clause_bind (c_parser *parser, tree list)
14583 location_t loc = c_parser_peek_token (parser)->location;
14584 tree c;
14585 const char *p;
14586 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14588 matching_parens parens;
14589 if (!parens.require_open (parser))
14590 return list;
14591 if (!c_parser_next_token_is (parser, CPP_NAME))
14593 invalid:
14594 c_parser_error (parser,
14595 "expected %<teams%>, %<parallel%> or %<thread%>");
14596 parens.skip_until_found_close (parser);
14597 return list;
14599 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14600 if (strcmp (p, "teams") == 0)
14601 kind = OMP_CLAUSE_BIND_TEAMS;
14602 else if (strcmp (p, "parallel") == 0)
14603 kind = OMP_CLAUSE_BIND_PARALLEL;
14604 else if (strcmp (p, "thread") != 0)
14605 goto invalid;
14606 c_parser_consume_token (parser);
14607 parens.skip_until_found_close (parser);
14608 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14609 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14610 OMP_CLAUSE_BIND_KIND (c) = kind;
14611 OMP_CLAUSE_CHAIN (c) = list;
14612 return c;
14616 /* OpenMP 2.5:
14617 ordered
14619 OpenMP 4.5:
14620 ordered ( constant-expression ) */
14622 static tree
14623 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14625 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14627 tree c, num = NULL_TREE;
14628 HOST_WIDE_INT n;
14629 location_t loc = c_parser_peek_token (parser)->location;
14630 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14632 matching_parens parens;
14633 parens.consume_open (parser);
14634 num = c_parser_expr_no_commas (parser, NULL).value;
14635 parens.skip_until_found_close (parser);
14637 if (num == error_mark_node)
14638 return list;
14639 if (num)
14641 mark_exp_read (num);
14642 num = c_fully_fold (num, false, NULL);
14643 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14644 || !tree_fits_shwi_p (num)
14645 || (n = tree_to_shwi (num)) <= 0
14646 || (int) n != n)
14648 error_at (loc, "ordered argument needs positive "
14649 "constant integer expression");
14650 return list;
14653 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14654 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14655 OMP_CLAUSE_CHAIN (c) = list;
14656 return c;
14659 /* OpenMP 2.5:
14660 private ( variable-list ) */
14662 static tree
14663 c_parser_omp_clause_private (c_parser *parser, tree list)
14665 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14668 /* OpenMP 2.5:
14669 reduction ( reduction-operator : variable-list )
14671 reduction-operator:
14672 One of: + * - & ^ | && ||
14674 OpenMP 3.1:
14676 reduction-operator:
14677 One of: + * - & ^ | && || max min
14679 OpenMP 4.0:
14681 reduction-operator:
14682 One of: + * - & ^ | && ||
14683 identifier
14685 OpenMP 5.0:
14686 reduction ( reduction-modifier, reduction-operator : variable-list )
14687 in_reduction ( reduction-operator : variable-list )
14688 task_reduction ( reduction-operator : variable-list ) */
14690 static tree
14691 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14692 bool is_omp, tree list)
14694 location_t clause_loc = c_parser_peek_token (parser)->location;
14695 matching_parens parens;
14696 if (parens.require_open (parser))
14698 bool task = false;
14699 bool inscan = false;
14700 enum tree_code code = ERROR_MARK;
14701 tree reduc_id = NULL_TREE;
14703 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14705 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14706 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14708 c_parser_consume_token (parser);
14709 c_parser_consume_token (parser);
14711 else if (c_parser_next_token_is (parser, CPP_NAME)
14712 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14714 const char *p
14715 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14716 if (strcmp (p, "task") == 0)
14717 task = true;
14718 else if (strcmp (p, "inscan") == 0)
14719 inscan = true;
14720 if (task || inscan)
14722 c_parser_consume_token (parser);
14723 c_parser_consume_token (parser);
14728 switch (c_parser_peek_token (parser)->type)
14730 case CPP_PLUS:
14731 code = PLUS_EXPR;
14732 break;
14733 case CPP_MULT:
14734 code = MULT_EXPR;
14735 break;
14736 case CPP_MINUS:
14737 code = MINUS_EXPR;
14738 break;
14739 case CPP_AND:
14740 code = BIT_AND_EXPR;
14741 break;
14742 case CPP_XOR:
14743 code = BIT_XOR_EXPR;
14744 break;
14745 case CPP_OR:
14746 code = BIT_IOR_EXPR;
14747 break;
14748 case CPP_AND_AND:
14749 code = TRUTH_ANDIF_EXPR;
14750 break;
14751 case CPP_OR_OR:
14752 code = TRUTH_ORIF_EXPR;
14753 break;
14754 case CPP_NAME:
14756 const char *p
14757 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14758 if (strcmp (p, "min") == 0)
14760 code = MIN_EXPR;
14761 break;
14763 if (strcmp (p, "max") == 0)
14765 code = MAX_EXPR;
14766 break;
14768 reduc_id = c_parser_peek_token (parser)->value;
14769 break;
14771 default:
14772 c_parser_error (parser,
14773 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14774 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14775 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14776 return list;
14778 c_parser_consume_token (parser);
14779 reduc_id = c_omp_reduction_id (code, reduc_id);
14780 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14782 tree nl, c;
14784 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
14785 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14787 tree d = OMP_CLAUSE_DECL (c), type;
14788 if (TREE_CODE (d) != TREE_LIST)
14789 type = TREE_TYPE (d);
14790 else
14792 int cnt = 0;
14793 tree t;
14794 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
14795 cnt++;
14796 type = TREE_TYPE (t);
14797 while (cnt > 0)
14799 if (TREE_CODE (type) != POINTER_TYPE
14800 && TREE_CODE (type) != ARRAY_TYPE)
14801 break;
14802 type = TREE_TYPE (type);
14803 cnt--;
14806 while (TREE_CODE (type) == ARRAY_TYPE)
14807 type = TREE_TYPE (type);
14808 OMP_CLAUSE_REDUCTION_CODE (c) = code;
14809 if (task)
14810 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
14811 else if (inscan)
14812 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
14813 if (code == ERROR_MARK
14814 || !(INTEGRAL_TYPE_P (type)
14815 || TREE_CODE (type) == REAL_TYPE
14816 || TREE_CODE (type) == COMPLEX_TYPE))
14817 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
14818 = c_omp_reduction_lookup (reduc_id,
14819 TYPE_MAIN_VARIANT (type));
14822 list = nl;
14824 parens.skip_until_found_close (parser);
14826 return list;
14829 /* OpenMP 2.5:
14830 schedule ( schedule-kind )
14831 schedule ( schedule-kind , expression )
14833 schedule-kind:
14834 static | dynamic | guided | runtime | auto
14836 OpenMP 4.5:
14837 schedule ( schedule-modifier : schedule-kind )
14838 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14840 schedule-modifier:
14841 simd
14842 monotonic
14843 nonmonotonic */
14845 static tree
14846 c_parser_omp_clause_schedule (c_parser *parser, tree list)
14848 tree c, t;
14849 location_t loc = c_parser_peek_token (parser)->location;
14850 int modifiers = 0, nmodifiers = 0;
14852 matching_parens parens;
14853 if (!parens.require_open (parser))
14854 return list;
14856 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
14858 location_t comma = UNKNOWN_LOCATION;
14859 while (c_parser_next_token_is (parser, CPP_NAME))
14861 tree kind = c_parser_peek_token (parser)->value;
14862 const char *p = IDENTIFIER_POINTER (kind);
14863 if (strcmp ("simd", p) == 0)
14864 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
14865 else if (strcmp ("monotonic", p) == 0)
14866 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
14867 else if (strcmp ("nonmonotonic", p) == 0)
14868 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
14869 else
14870 break;
14871 comma = UNKNOWN_LOCATION;
14872 c_parser_consume_token (parser);
14873 if (nmodifiers++ == 0
14874 && c_parser_next_token_is (parser, CPP_COMMA))
14876 comma = c_parser_peek_token (parser)->location;
14877 c_parser_consume_token (parser);
14879 else
14881 c_parser_require (parser, CPP_COLON, "expected %<:%>");
14882 break;
14885 if (comma != UNKNOWN_LOCATION)
14886 error_at (comma, "expected %<:%>");
14888 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
14889 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14890 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14891 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14893 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14894 "specified");
14895 modifiers = 0;
14898 if (c_parser_next_token_is (parser, CPP_NAME))
14900 tree kind = c_parser_peek_token (parser)->value;
14901 const char *p = IDENTIFIER_POINTER (kind);
14903 switch (p[0])
14905 case 'd':
14906 if (strcmp ("dynamic", p) != 0)
14907 goto invalid_kind;
14908 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
14909 break;
14911 case 'g':
14912 if (strcmp ("guided", p) != 0)
14913 goto invalid_kind;
14914 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
14915 break;
14917 case 'r':
14918 if (strcmp ("runtime", p) != 0)
14919 goto invalid_kind;
14920 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
14921 break;
14923 default:
14924 goto invalid_kind;
14927 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
14928 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
14929 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14930 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
14931 else
14932 goto invalid_kind;
14934 c_parser_consume_token (parser);
14935 if (c_parser_next_token_is (parser, CPP_COMMA))
14937 location_t here;
14938 c_parser_consume_token (parser);
14940 here = c_parser_peek_token (parser)->location;
14941 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14942 expr = convert_lvalue_to_rvalue (here, expr, false, true);
14943 t = expr.value;
14944 t = c_fully_fold (t, false, NULL);
14946 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
14947 error_at (here, "schedule %<runtime%> does not take "
14948 "a %<chunk_size%> parameter");
14949 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
14950 error_at (here,
14951 "schedule %<auto%> does not take "
14952 "a %<chunk_size%> parameter");
14953 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
14955 /* Attempt to statically determine when the number isn't
14956 positive. */
14957 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
14958 build_int_cst (TREE_TYPE (t), 0));
14959 protected_set_expr_location (s, loc);
14960 if (s == boolean_true_node)
14962 warning_at (loc, 0,
14963 "chunk size value must be positive");
14964 t = integer_one_node;
14966 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
14968 else
14969 c_parser_error (parser, "expected integer expression");
14971 parens.skip_until_found_close (parser);
14973 else
14974 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14975 "expected %<,%> or %<)%>");
14977 OMP_CLAUSE_SCHEDULE_KIND (c)
14978 = (enum omp_clause_schedule_kind)
14979 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
14981 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
14982 OMP_CLAUSE_CHAIN (c) = list;
14983 return c;
14985 invalid_kind:
14986 c_parser_error (parser, "invalid schedule kind");
14987 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14988 return list;
14991 /* OpenMP 2.5:
14992 shared ( variable-list ) */
14994 static tree
14995 c_parser_omp_clause_shared (c_parser *parser, tree list)
14997 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15000 /* OpenMP 3.0:
15001 untied */
15003 static tree
15004 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15006 tree c;
15008 /* FIXME: Should we allow duplicates? */
15009 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15011 c = build_omp_clause (c_parser_peek_token (parser)->location,
15012 OMP_CLAUSE_UNTIED);
15013 OMP_CLAUSE_CHAIN (c) = list;
15015 return c;
15018 /* OpenMP 4.0:
15019 inbranch
15020 notinbranch */
15022 static tree
15023 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15024 enum omp_clause_code code, tree list)
15026 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15028 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15029 OMP_CLAUSE_CHAIN (c) = list;
15031 return c;
15034 /* OpenMP 4.0:
15035 parallel
15037 sections
15038 taskgroup */
15040 static tree
15041 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15042 enum omp_clause_code code, tree list)
15044 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15045 OMP_CLAUSE_CHAIN (c) = list;
15047 return c;
15050 /* OpenMP 4.5:
15051 nogroup */
15053 static tree
15054 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15056 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15057 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15058 OMP_CLAUSE_NOGROUP);
15059 OMP_CLAUSE_CHAIN (c) = list;
15060 return c;
15063 /* OpenMP 4.5:
15064 simd
15065 threads */
15067 static tree
15068 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15069 enum omp_clause_code code, tree list)
15071 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15072 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15073 OMP_CLAUSE_CHAIN (c) = list;
15074 return c;
15077 /* OpenMP 4.0:
15078 num_teams ( expression ) */
15080 static tree
15081 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15083 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15084 matching_parens parens;
15085 if (parens.require_open (parser))
15087 location_t expr_loc = c_parser_peek_token (parser)->location;
15088 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15089 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15090 tree c, t = expr.value;
15091 t = c_fully_fold (t, false, NULL);
15093 parens.skip_until_found_close (parser);
15095 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15097 c_parser_error (parser, "expected integer expression");
15098 return list;
15101 /* Attempt to statically determine when the number isn't positive. */
15102 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15103 build_int_cst (TREE_TYPE (t), 0));
15104 protected_set_expr_location (c, expr_loc);
15105 if (c == boolean_true_node)
15107 warning_at (expr_loc, 0, "%<num_teams%> value must be positive");
15108 t = integer_one_node;
15111 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15113 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15114 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
15115 OMP_CLAUSE_CHAIN (c) = list;
15116 list = c;
15119 return list;
15122 /* OpenMP 4.0:
15123 thread_limit ( expression ) */
15125 static tree
15126 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15128 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15129 matching_parens parens;
15130 if (parens.require_open (parser))
15132 location_t expr_loc = c_parser_peek_token (parser)->location;
15133 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15134 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15135 tree c, t = expr.value;
15136 t = c_fully_fold (t, false, NULL);
15138 parens.skip_until_found_close (parser);
15140 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15142 c_parser_error (parser, "expected integer expression");
15143 return list;
15146 /* Attempt to statically determine when the number isn't positive. */
15147 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15148 build_int_cst (TREE_TYPE (t), 0));
15149 protected_set_expr_location (c, expr_loc);
15150 if (c == boolean_true_node)
15152 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15153 t = integer_one_node;
15156 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15157 "thread_limit");
15159 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15160 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15161 OMP_CLAUSE_CHAIN (c) = list;
15162 list = c;
15165 return list;
15168 /* OpenMP 4.0:
15169 aligned ( variable-list )
15170 aligned ( variable-list : constant-expression ) */
15172 static tree
15173 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15175 location_t clause_loc = c_parser_peek_token (parser)->location;
15176 tree nl, c;
15178 matching_parens parens;
15179 if (!parens.require_open (parser))
15180 return list;
15182 nl = c_parser_omp_variable_list (parser, clause_loc,
15183 OMP_CLAUSE_ALIGNED, list);
15185 if (c_parser_next_token_is (parser, CPP_COLON))
15187 c_parser_consume_token (parser);
15188 location_t expr_loc = c_parser_peek_token (parser)->location;
15189 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15190 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15191 tree alignment = expr.value;
15192 alignment = c_fully_fold (alignment, false, NULL);
15193 if (TREE_CODE (alignment) != INTEGER_CST
15194 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15195 || tree_int_cst_sgn (alignment) != 1)
15197 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15198 "be positive constant integer expression");
15199 alignment = NULL_TREE;
15202 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15203 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15206 parens.skip_until_found_close (parser);
15207 return nl;
15210 /* OpenMP 5.0:
15211 allocate ( variable-list )
15212 allocate ( expression : variable-list ) */
15214 static tree
15215 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15217 location_t clause_loc = c_parser_peek_token (parser)->location;
15218 tree nl, c;
15219 tree allocator = NULL_TREE;
15221 matching_parens parens;
15222 if (!parens.require_open (parser))
15223 return list;
15225 if ((c_parser_next_token_is_not (parser, CPP_NAME)
15226 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15227 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15228 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15230 location_t expr_loc = c_parser_peek_token (parser)->location;
15231 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15232 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15233 allocator = expr.value;
15234 allocator = c_fully_fold (allocator, false, NULL);
15235 tree orig_type
15236 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
15237 orig_type = TYPE_MAIN_VARIANT (orig_type);
15238 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15239 || TREE_CODE (orig_type) != ENUMERAL_TYPE
15240 || TYPE_NAME (orig_type) != get_identifier ("omp_allocator_handle_t"))
15242 error_at (clause_loc, "%<allocate%> clause allocator expression "
15243 "has type %qT rather than "
15244 "%<omp_allocator_handle_t%>",
15245 TREE_TYPE (allocator));
15246 allocator = NULL_TREE;
15248 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15250 parens.skip_until_found_close (parser);
15251 return list;
15255 nl = c_parser_omp_variable_list (parser, clause_loc,
15256 OMP_CLAUSE_ALLOCATE, list);
15258 if (allocator)
15259 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15260 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15262 parens.skip_until_found_close (parser);
15263 return nl;
15266 /* OpenMP 4.0:
15267 linear ( variable-list )
15268 linear ( variable-list : expression )
15270 OpenMP 4.5:
15271 linear ( modifier ( variable-list ) )
15272 linear ( modifier ( variable-list ) : expression ) */
15274 static tree
15275 c_parser_omp_clause_linear (c_parser *parser, tree list)
15277 location_t clause_loc = c_parser_peek_token (parser)->location;
15278 tree nl, c, step;
15279 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15281 matching_parens parens;
15282 if (!parens.require_open (parser))
15283 return list;
15285 if (c_parser_next_token_is (parser, CPP_NAME))
15287 c_token *tok = c_parser_peek_token (parser);
15288 const char *p = IDENTIFIER_POINTER (tok->value);
15289 if (strcmp ("val", p) == 0)
15290 kind = OMP_CLAUSE_LINEAR_VAL;
15291 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15292 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15293 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15295 c_parser_consume_token (parser);
15296 c_parser_consume_token (parser);
15300 nl = c_parser_omp_variable_list (parser, clause_loc,
15301 OMP_CLAUSE_LINEAR, list);
15303 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15304 parens.skip_until_found_close (parser);
15306 if (c_parser_next_token_is (parser, CPP_COLON))
15308 c_parser_consume_token (parser);
15309 location_t expr_loc = c_parser_peek_token (parser)->location;
15310 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15311 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15312 step = expr.value;
15313 step = c_fully_fold (step, false, NULL);
15314 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15316 error_at (clause_loc, "%<linear%> clause step expression must "
15317 "be integral");
15318 step = integer_one_node;
15322 else
15323 step = integer_one_node;
15325 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15327 OMP_CLAUSE_LINEAR_STEP (c) = step;
15328 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15331 parens.skip_until_found_close (parser);
15332 return nl;
15335 /* OpenMP 5.0:
15336 nontemporal ( variable-list ) */
15338 static tree
15339 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15341 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15344 /* OpenMP 4.0:
15345 safelen ( constant-expression ) */
15347 static tree
15348 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15350 location_t clause_loc = c_parser_peek_token (parser)->location;
15351 tree c, t;
15353 matching_parens parens;
15354 if (!parens.require_open (parser))
15355 return list;
15357 location_t expr_loc = c_parser_peek_token (parser)->location;
15358 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15359 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15360 t = expr.value;
15361 t = c_fully_fold (t, false, NULL);
15362 if (TREE_CODE (t) != INTEGER_CST
15363 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15364 || tree_int_cst_sgn (t) != 1)
15366 error_at (clause_loc, "%<safelen%> clause expression must "
15367 "be positive constant integer expression");
15368 t = NULL_TREE;
15371 parens.skip_until_found_close (parser);
15372 if (t == NULL_TREE || t == error_mark_node)
15373 return list;
15375 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15377 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15378 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15379 OMP_CLAUSE_CHAIN (c) = list;
15380 return c;
15383 /* OpenMP 4.0:
15384 simdlen ( constant-expression ) */
15386 static tree
15387 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15389 location_t clause_loc = c_parser_peek_token (parser)->location;
15390 tree c, t;
15392 matching_parens parens;
15393 if (!parens.require_open (parser))
15394 return list;
15396 location_t expr_loc = c_parser_peek_token (parser)->location;
15397 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15398 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15399 t = expr.value;
15400 t = c_fully_fold (t, false, NULL);
15401 if (TREE_CODE (t) != INTEGER_CST
15402 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15403 || tree_int_cst_sgn (t) != 1)
15405 error_at (clause_loc, "%<simdlen%> clause expression must "
15406 "be positive constant integer expression");
15407 t = NULL_TREE;
15410 parens.skip_until_found_close (parser);
15411 if (t == NULL_TREE || t == error_mark_node)
15412 return list;
15414 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15416 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15417 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15418 OMP_CLAUSE_CHAIN (c) = list;
15419 return c;
15422 /* OpenMP 4.5:
15423 vec:
15424 identifier [+/- integer]
15425 vec , identifier [+/- integer]
15428 static tree
15429 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15430 tree list)
15432 tree vec = NULL;
15433 if (c_parser_next_token_is_not (parser, CPP_NAME)
15434 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15436 c_parser_error (parser, "expected identifier");
15437 return list;
15440 while (c_parser_next_token_is (parser, CPP_NAME)
15441 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15443 tree t = lookup_name (c_parser_peek_token (parser)->value);
15444 tree addend = NULL;
15446 if (t == NULL_TREE)
15448 undeclared_variable (c_parser_peek_token (parser)->location,
15449 c_parser_peek_token (parser)->value);
15450 t = error_mark_node;
15453 c_parser_consume_token (parser);
15455 bool neg = false;
15456 if (c_parser_next_token_is (parser, CPP_MINUS))
15457 neg = true;
15458 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15460 addend = integer_zero_node;
15461 neg = false;
15462 goto add_to_vector;
15464 c_parser_consume_token (parser);
15466 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15468 c_parser_error (parser, "expected integer");
15469 return list;
15472 addend = c_parser_peek_token (parser)->value;
15473 if (TREE_CODE (addend) != INTEGER_CST)
15475 c_parser_error (parser, "expected integer");
15476 return list;
15478 c_parser_consume_token (parser);
15480 add_to_vector:
15481 if (t != error_mark_node)
15483 vec = tree_cons (addend, t, vec);
15484 if (neg)
15485 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15488 if (c_parser_next_token_is_not (parser, CPP_COMMA)
15489 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
15490 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
15491 break;
15493 c_parser_consume_token (parser);
15496 if (vec == NULL_TREE)
15497 return list;
15499 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15500 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15501 OMP_CLAUSE_DECL (u) = nreverse (vec);
15502 OMP_CLAUSE_CHAIN (u) = list;
15503 return u;
15506 /* OpenMP 5.0:
15507 iterators ( iterators-definition )
15509 iterators-definition:
15510 iterator-specifier
15511 iterator-specifier , iterators-definition
15513 iterator-specifier:
15514 identifier = range-specification
15515 iterator-type identifier = range-specification
15517 range-specification:
15518 begin : end
15519 begin : end : step */
15521 static tree
15522 c_parser_omp_iterators (c_parser *parser)
15524 tree ret = NULL_TREE, *last = &ret;
15525 c_parser_consume_token (parser);
15527 push_scope ();
15529 matching_parens parens;
15530 if (!parens.require_open (parser))
15531 return error_mark_node;
15535 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
15536 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
15538 struct c_type_name *type = c_parser_type_name (parser);
15539 if (type != NULL)
15540 iter_type = groktypename (type, &type_expr, NULL);
15542 if (iter_type == NULL_TREE)
15543 iter_type = integer_type_node;
15545 location_t loc = c_parser_peek_token (parser)->location;
15546 if (!c_parser_next_token_is (parser, CPP_NAME))
15548 c_parser_error (parser, "expected identifier");
15549 break;
15552 tree id = c_parser_peek_token (parser)->value;
15553 c_parser_consume_token (parser);
15555 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15556 break;
15558 location_t eloc = c_parser_peek_token (parser)->location;
15559 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15560 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15561 tree begin = expr.value;
15563 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15564 break;
15566 eloc = c_parser_peek_token (parser)->location;
15567 expr = c_parser_expr_no_commas (parser, NULL);
15568 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15569 tree end = expr.value;
15571 tree step = integer_one_node;
15572 if (c_parser_next_token_is (parser, CPP_COLON))
15574 c_parser_consume_token (parser);
15575 eloc = c_parser_peek_token (parser)->location;
15576 expr = c_parser_expr_no_commas (parser, NULL);
15577 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15578 step = expr.value;
15581 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
15582 DECL_ARTIFICIAL (iter_var) = 1;
15583 DECL_CONTEXT (iter_var) = current_function_decl;
15584 pushdecl (iter_var);
15586 *last = make_tree_vec (6);
15587 TREE_VEC_ELT (*last, 0) = iter_var;
15588 TREE_VEC_ELT (*last, 1) = begin;
15589 TREE_VEC_ELT (*last, 2) = end;
15590 TREE_VEC_ELT (*last, 3) = step;
15591 last = &TREE_CHAIN (*last);
15593 if (c_parser_next_token_is (parser, CPP_COMMA))
15595 c_parser_consume_token (parser);
15596 continue;
15598 break;
15600 while (1);
15602 parens.skip_until_found_close (parser);
15603 return ret ? ret : error_mark_node;
15606 /* OpenMP 5.0:
15607 affinity ( [aff-modifier :] variable-list )
15608 aff-modifier:
15609 iterator ( iterators-definition ) */
15611 static tree
15612 c_parser_omp_clause_affinity (c_parser *parser, tree list)
15614 location_t clause_loc = c_parser_peek_token (parser)->location;
15615 tree nl, iterators = NULL_TREE;
15617 matching_parens parens;
15618 if (!parens.require_open (parser))
15619 return list;
15621 if (c_parser_next_token_is (parser, CPP_NAME))
15623 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15624 bool parse_iter = ((strcmp ("iterator", p) == 0)
15625 && (c_parser_peek_2nd_token (parser)->type
15626 == CPP_OPEN_PAREN));
15627 if (parse_iter)
15629 unsigned n = 3;
15630 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
15631 && (c_parser_peek_nth_token_raw (parser, n)->type
15632 == CPP_CLOSE_PAREN)
15633 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15634 == CPP_COLON));
15636 if (parse_iter)
15638 iterators = c_parser_omp_iterators (parser);
15639 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15641 if (iterators)
15642 pop_scope ();
15643 parens.skip_until_found_close (parser);
15644 return list;
15648 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
15649 list);
15650 if (iterators)
15652 tree block = pop_scope ();
15653 if (iterators != error_mark_node)
15655 TREE_VEC_ELT (iterators, 5) = block;
15656 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15657 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
15658 OMP_CLAUSE_DECL (c));
15662 parens.skip_until_found_close (parser);
15663 return nl;
15667 /* OpenMP 4.0:
15668 depend ( depend-kind: variable-list )
15670 depend-kind:
15671 in | out | inout
15673 OpenMP 4.5:
15674 depend ( source )
15676 depend ( sink : vec )
15678 OpenMP 5.0:
15679 depend ( depend-modifier , depend-kind: variable-list )
15681 depend-kind:
15682 in | out | inout | mutexinoutset | depobj
15684 depend-modifier:
15685 iterator ( iterators-definition ) */
15687 static tree
15688 c_parser_omp_clause_depend (c_parser *parser, tree list)
15690 location_t clause_loc = c_parser_peek_token (parser)->location;
15691 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
15692 tree nl, c, iterators = NULL_TREE;
15694 matching_parens parens;
15695 if (!parens.require_open (parser))
15696 return list;
15700 if (c_parser_next_token_is_not (parser, CPP_NAME))
15701 goto invalid_kind;
15703 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15704 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
15706 iterators = c_parser_omp_iterators (parser);
15707 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
15708 continue;
15710 if (strcmp ("in", p) == 0)
15711 kind = OMP_CLAUSE_DEPEND_IN;
15712 else if (strcmp ("inout", p) == 0)
15713 kind = OMP_CLAUSE_DEPEND_INOUT;
15714 else if (strcmp ("mutexinoutset", p) == 0)
15715 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
15716 else if (strcmp ("out", p) == 0)
15717 kind = OMP_CLAUSE_DEPEND_OUT;
15718 else if (strcmp ("depobj", p) == 0)
15719 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
15720 else if (strcmp ("sink", p) == 0)
15721 kind = OMP_CLAUSE_DEPEND_SINK;
15722 else if (strcmp ("source", p) == 0)
15723 kind = OMP_CLAUSE_DEPEND_SOURCE;
15724 else
15725 goto invalid_kind;
15726 break;
15728 while (1);
15730 c_parser_consume_token (parser);
15732 if (iterators
15733 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
15735 pop_scope ();
15736 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
15737 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
15738 iterators = NULL_TREE;
15741 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
15743 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15744 OMP_CLAUSE_DEPEND_KIND (c) = kind;
15745 OMP_CLAUSE_DECL (c) = NULL_TREE;
15746 OMP_CLAUSE_CHAIN (c) = list;
15747 parens.skip_until_found_close (parser);
15748 return c;
15751 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15752 goto resync_fail;
15754 if (kind == OMP_CLAUSE_DEPEND_SINK)
15755 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
15756 else
15758 nl = c_parser_omp_variable_list (parser, clause_loc,
15759 OMP_CLAUSE_DEPEND, list);
15761 if (iterators)
15763 tree block = pop_scope ();
15764 if (iterators == error_mark_node)
15765 iterators = NULL_TREE;
15766 else
15767 TREE_VEC_ELT (iterators, 5) = block;
15770 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15772 OMP_CLAUSE_DEPEND_KIND (c) = kind;
15773 if (iterators)
15774 OMP_CLAUSE_DECL (c)
15775 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
15779 parens.skip_until_found_close (parser);
15780 return nl;
15782 invalid_kind:
15783 c_parser_error (parser, "invalid depend kind");
15784 resync_fail:
15785 parens.skip_until_found_close (parser);
15786 if (iterators)
15787 pop_scope ();
15788 return list;
15791 /* OpenMP 4.0:
15792 map ( map-kind: variable-list )
15793 map ( variable-list )
15795 map-kind:
15796 alloc | to | from | tofrom
15798 OpenMP 4.5:
15799 map-kind:
15800 alloc | to | from | tofrom | release | delete
15802 map ( always [,] map-kind: variable-list )
15804 OpenMP 5.0:
15805 map ( [map-type-modifier[,] ...] map-kind: variable-list )
15807 map-type-modifier:
15808 always | close */
15810 static tree
15811 c_parser_omp_clause_map (c_parser *parser, tree list)
15813 location_t clause_loc = c_parser_peek_token (parser)->location;
15814 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
15815 tree nl, c;
15817 matching_parens parens;
15818 if (!parens.require_open (parser))
15819 return list;
15821 int pos = 1;
15822 int map_kind_pos = 0;
15823 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
15825 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
15827 map_kind_pos = pos;
15828 break;
15831 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
15832 pos++;
15833 pos++;
15836 int always_modifier = 0;
15837 int close_modifier = 0;
15838 for (int pos = 1; pos < map_kind_pos; ++pos)
15840 c_token *tok = c_parser_peek_token (parser);
15842 if (tok->type == CPP_COMMA)
15844 c_parser_consume_token (parser);
15845 continue;
15848 const char *p = IDENTIFIER_POINTER (tok->value);
15849 if (strcmp ("always", p) == 0)
15851 if (always_modifier)
15853 c_parser_error (parser, "too many %<always%> modifiers");
15854 parens.skip_until_found_close (parser);
15855 return list;
15857 always_modifier++;
15859 else if (strcmp ("close", p) == 0)
15861 if (close_modifier)
15863 c_parser_error (parser, "too many %<close%> modifiers");
15864 parens.skip_until_found_close (parser);
15865 return list;
15867 close_modifier++;
15869 else
15871 c_parser_error (parser, "%<#pragma omp target%> with "
15872 "modifier other than %<always%> or %<close%>"
15873 "on %<map%> clause");
15874 parens.skip_until_found_close (parser);
15875 return list;
15878 c_parser_consume_token (parser);
15881 if (c_parser_next_token_is (parser, CPP_NAME)
15882 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15884 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15885 if (strcmp ("alloc", p) == 0)
15886 kind = GOMP_MAP_ALLOC;
15887 else if (strcmp ("to", p) == 0)
15888 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
15889 else if (strcmp ("from", p) == 0)
15890 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
15891 else if (strcmp ("tofrom", p) == 0)
15892 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
15893 else if (strcmp ("release", p) == 0)
15894 kind = GOMP_MAP_RELEASE;
15895 else if (strcmp ("delete", p) == 0)
15896 kind = GOMP_MAP_DELETE;
15897 else
15899 c_parser_error (parser, "invalid map kind");
15900 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15901 "expected %<)%>");
15902 return list;
15904 c_parser_consume_token (parser);
15905 c_parser_consume_token (parser);
15908 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
15910 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15911 OMP_CLAUSE_SET_MAP_KIND (c, kind);
15913 parens.skip_until_found_close (parser);
15914 return nl;
15917 /* OpenMP 4.0:
15918 device ( expression ) */
15920 static tree
15921 c_parser_omp_clause_device (c_parser *parser, tree list)
15923 location_t clause_loc = c_parser_peek_token (parser)->location;
15924 matching_parens parens;
15925 if (parens.require_open (parser))
15927 location_t expr_loc = c_parser_peek_token (parser)->location;
15928 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15929 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15930 tree c, t = expr.value;
15931 t = c_fully_fold (t, false, NULL);
15933 parens.skip_until_found_close (parser);
15935 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15937 c_parser_error (parser, "expected integer expression");
15938 return list;
15941 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
15943 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
15944 OMP_CLAUSE_DEVICE_ID (c) = t;
15945 OMP_CLAUSE_CHAIN (c) = list;
15946 list = c;
15949 return list;
15952 /* OpenMP 4.0:
15953 dist_schedule ( static )
15954 dist_schedule ( static , expression ) */
15956 static tree
15957 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
15959 tree c, t = NULL_TREE;
15960 location_t loc = c_parser_peek_token (parser)->location;
15962 matching_parens parens;
15963 if (!parens.require_open (parser))
15964 return list;
15966 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
15968 c_parser_error (parser, "invalid dist_schedule kind");
15969 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15970 "expected %<)%>");
15971 return list;
15974 c_parser_consume_token (parser);
15975 if (c_parser_next_token_is (parser, CPP_COMMA))
15977 c_parser_consume_token (parser);
15979 location_t expr_loc = c_parser_peek_token (parser)->location;
15980 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15981 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15982 t = expr.value;
15983 t = c_fully_fold (t, false, NULL);
15984 parens.skip_until_found_close (parser);
15986 else
15987 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15988 "expected %<,%> or %<)%>");
15990 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15991 "dist_schedule"); */
15992 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
15993 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
15994 if (t == error_mark_node)
15995 return list;
15997 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
15998 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
15999 OMP_CLAUSE_CHAIN (c) = list;
16000 return c;
16003 /* OpenMP 4.0:
16004 proc_bind ( proc-bind-kind )
16006 proc-bind-kind:
16007 primary | master | close | spread
16008 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16010 static tree
16011 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16013 location_t clause_loc = c_parser_peek_token (parser)->location;
16014 enum omp_clause_proc_bind_kind kind;
16015 tree c;
16017 matching_parens parens;
16018 if (!parens.require_open (parser))
16019 return list;
16021 if (c_parser_next_token_is (parser, CPP_NAME))
16023 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16024 if (strcmp ("primary", p) == 0)
16025 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16026 else if (strcmp ("master", p) == 0)
16027 kind = OMP_CLAUSE_PROC_BIND_MASTER;
16028 else if (strcmp ("close", p) == 0)
16029 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16030 else if (strcmp ("spread", p) == 0)
16031 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16032 else
16033 goto invalid_kind;
16035 else
16036 goto invalid_kind;
16038 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16039 c_parser_consume_token (parser);
16040 parens.skip_until_found_close (parser);
16041 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16042 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16043 OMP_CLAUSE_CHAIN (c) = list;
16044 return c;
16046 invalid_kind:
16047 c_parser_error (parser, "invalid proc_bind kind");
16048 parens.skip_until_found_close (parser);
16049 return list;
16052 /* OpenMP 5.0:
16053 device_type ( host | nohost | any ) */
16055 static tree
16056 c_parser_omp_clause_device_type (c_parser *parser, tree list)
16058 location_t clause_loc = c_parser_peek_token (parser)->location;
16059 enum omp_clause_device_type_kind kind;
16060 tree c;
16062 matching_parens parens;
16063 if (!parens.require_open (parser))
16064 return list;
16066 if (c_parser_next_token_is (parser, CPP_NAME))
16068 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16069 if (strcmp ("host", p) == 0)
16070 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
16071 else if (strcmp ("nohost", p) == 0)
16072 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
16073 else if (strcmp ("any", p) == 0)
16074 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
16075 else
16076 goto invalid_kind;
16078 else
16079 goto invalid_kind;
16081 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16082 "device_type"); */
16083 c_parser_consume_token (parser);
16084 parens.skip_until_found_close (parser);
16085 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
16086 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
16087 OMP_CLAUSE_CHAIN (c) = list;
16088 return c;
16090 invalid_kind:
16091 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
16092 parens.skip_until_found_close (parser);
16093 return list;
16096 /* OpenMP 4.0:
16097 to ( variable-list ) */
16099 static tree
16100 c_parser_omp_clause_to (c_parser *parser, tree list)
16102 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list);
16105 /* OpenMP 4.0:
16106 from ( variable-list ) */
16108 static tree
16109 c_parser_omp_clause_from (c_parser *parser, tree list)
16111 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list);
16114 /* OpenMP 4.0:
16115 uniform ( variable-list ) */
16117 static tree
16118 c_parser_omp_clause_uniform (c_parser *parser, tree list)
16120 /* The clauses location. */
16121 location_t loc = c_parser_peek_token (parser)->location;
16123 matching_parens parens;
16124 if (parens.require_open (parser))
16126 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
16127 list);
16128 parens.skip_until_found_close (parser);
16130 return list;
16133 /* OpenMP 5.0:
16134 detach ( event-handle ) */
16136 static tree
16137 c_parser_omp_clause_detach (c_parser *parser, tree list)
16139 matching_parens parens;
16140 location_t clause_loc = c_parser_peek_token (parser)->location;
16142 if (!parens.require_open (parser))
16143 return list;
16145 if (c_parser_next_token_is_not (parser, CPP_NAME)
16146 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16148 c_parser_error (parser, "expected identifier");
16149 parens.skip_until_found_close (parser);
16150 return list;
16153 tree t = lookup_name (c_parser_peek_token (parser)->value);
16154 if (t == NULL_TREE)
16156 undeclared_variable (c_parser_peek_token (parser)->location,
16157 c_parser_peek_token (parser)->value);
16158 parens.skip_until_found_close (parser);
16159 return list;
16161 c_parser_consume_token (parser);
16163 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16164 if (!INTEGRAL_TYPE_P (type)
16165 || TREE_CODE (type) != ENUMERAL_TYPE
16166 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16168 error_at (clause_loc, "%<detach%> clause event handle "
16169 "has type %qT rather than "
16170 "%<omp_event_handle_t%>",
16171 type);
16172 parens.skip_until_found_close (parser);
16173 return list;
16176 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16177 OMP_CLAUSE_DECL (u) = t;
16178 OMP_CLAUSE_CHAIN (u) = list;
16179 parens.skip_until_found_close (parser);
16180 return u;
16183 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16184 is a bitmask in MASK. Return the list of clauses found. */
16186 static tree
16187 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16188 const char *where, bool finish_p = true)
16190 tree clauses = NULL;
16191 bool first = true;
16193 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16195 location_t here;
16196 pragma_omp_clause c_kind;
16197 const char *c_name;
16198 tree prev = clauses;
16200 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16201 c_parser_consume_token (parser);
16203 here = c_parser_peek_token (parser)->location;
16204 c_kind = c_parser_omp_clause_name (parser);
16206 switch (c_kind)
16208 case PRAGMA_OACC_CLAUSE_ASYNC:
16209 clauses = c_parser_oacc_clause_async (parser, clauses);
16210 c_name = "async";
16211 break;
16212 case PRAGMA_OACC_CLAUSE_AUTO:
16213 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16214 clauses);
16215 c_name = "auto";
16216 break;
16217 case PRAGMA_OACC_CLAUSE_ATTACH:
16218 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16219 c_name = "attach";
16220 break;
16221 case PRAGMA_OACC_CLAUSE_COLLAPSE:
16222 clauses = c_parser_omp_clause_collapse (parser, clauses);
16223 c_name = "collapse";
16224 break;
16225 case PRAGMA_OACC_CLAUSE_COPY:
16226 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16227 c_name = "copy";
16228 break;
16229 case PRAGMA_OACC_CLAUSE_COPYIN:
16230 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16231 c_name = "copyin";
16232 break;
16233 case PRAGMA_OACC_CLAUSE_COPYOUT:
16234 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16235 c_name = "copyout";
16236 break;
16237 case PRAGMA_OACC_CLAUSE_CREATE:
16238 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16239 c_name = "create";
16240 break;
16241 case PRAGMA_OACC_CLAUSE_DELETE:
16242 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16243 c_name = "delete";
16244 break;
16245 case PRAGMA_OMP_CLAUSE_DEFAULT:
16246 clauses = c_parser_omp_clause_default (parser, clauses, true);
16247 c_name = "default";
16248 break;
16249 case PRAGMA_OACC_CLAUSE_DETACH:
16250 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16251 c_name = "detach";
16252 break;
16253 case PRAGMA_OACC_CLAUSE_DEVICE:
16254 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16255 c_name = "device";
16256 break;
16257 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16258 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16259 c_name = "deviceptr";
16260 break;
16261 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16262 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16263 c_name = "device_resident";
16264 break;
16265 case PRAGMA_OACC_CLAUSE_FINALIZE:
16266 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16267 clauses);
16268 c_name = "finalize";
16269 break;
16270 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16271 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16272 c_name = "firstprivate";
16273 break;
16274 case PRAGMA_OACC_CLAUSE_GANG:
16275 c_name = "gang";
16276 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16277 c_name, clauses);
16278 break;
16279 case PRAGMA_OACC_CLAUSE_HOST:
16280 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16281 c_name = "host";
16282 break;
16283 case PRAGMA_OACC_CLAUSE_IF:
16284 clauses = c_parser_omp_clause_if (parser, clauses, false);
16285 c_name = "if";
16286 break;
16287 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16288 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16289 clauses);
16290 c_name = "if_present";
16291 break;
16292 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16293 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16294 clauses);
16295 c_name = "independent";
16296 break;
16297 case PRAGMA_OACC_CLAUSE_LINK:
16298 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16299 c_name = "link";
16300 break;
16301 case PRAGMA_OACC_CLAUSE_NO_CREATE:
16302 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16303 c_name = "no_create";
16304 break;
16305 case PRAGMA_OACC_CLAUSE_NOHOST:
16306 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
16307 clauses);
16308 c_name = "nohost";
16309 break;
16310 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16311 clauses = c_parser_oacc_single_int_clause (parser,
16312 OMP_CLAUSE_NUM_GANGS,
16313 clauses);
16314 c_name = "num_gangs";
16315 break;
16316 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16317 clauses = c_parser_oacc_single_int_clause (parser,
16318 OMP_CLAUSE_NUM_WORKERS,
16319 clauses);
16320 c_name = "num_workers";
16321 break;
16322 case PRAGMA_OACC_CLAUSE_PRESENT:
16323 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16324 c_name = "present";
16325 break;
16326 case PRAGMA_OACC_CLAUSE_PRIVATE:
16327 clauses = c_parser_omp_clause_private (parser, clauses);
16328 c_name = "private";
16329 break;
16330 case PRAGMA_OACC_CLAUSE_REDUCTION:
16331 clauses
16332 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16333 false, clauses);
16334 c_name = "reduction";
16335 break;
16336 case PRAGMA_OACC_CLAUSE_SEQ:
16337 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16338 clauses);
16339 c_name = "seq";
16340 break;
16341 case PRAGMA_OACC_CLAUSE_TILE:
16342 clauses = c_parser_oacc_clause_tile (parser, clauses);
16343 c_name = "tile";
16344 break;
16345 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16346 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16347 c_name = "use_device";
16348 break;
16349 case PRAGMA_OACC_CLAUSE_VECTOR:
16350 c_name = "vector";
16351 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16352 c_name, clauses);
16353 break;
16354 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16355 clauses = c_parser_oacc_single_int_clause (parser,
16356 OMP_CLAUSE_VECTOR_LENGTH,
16357 clauses);
16358 c_name = "vector_length";
16359 break;
16360 case PRAGMA_OACC_CLAUSE_WAIT:
16361 clauses = c_parser_oacc_clause_wait (parser, clauses);
16362 c_name = "wait";
16363 break;
16364 case PRAGMA_OACC_CLAUSE_WORKER:
16365 c_name = "worker";
16366 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16367 c_name, clauses);
16368 break;
16369 default:
16370 c_parser_error (parser, "expected %<#pragma acc%> clause");
16371 goto saw_error;
16374 first = false;
16376 if (((mask >> c_kind) & 1) == 0)
16378 /* Remove the invalid clause(s) from the list to avoid
16379 confusing the rest of the compiler. */
16380 clauses = prev;
16381 error_at (here, "%qs is not valid for %qs", c_name, where);
16385 saw_error:
16386 c_parser_skip_to_pragma_eol (parser);
16388 if (finish_p)
16389 return c_finish_omp_clauses (clauses, C_ORT_ACC);
16391 return clauses;
16394 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16395 is a bitmask in MASK. Return the list of clauses found.
16396 FINISH_P set if c_finish_omp_clauses should be called.
16397 NESTED non-zero if clauses should be terminated by closing paren instead
16398 of end of pragma. If it is 2, additionally commas are required in between
16399 the clauses. */
16401 static tree
16402 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16403 const char *where, bool finish_p = true,
16404 int nested = 0)
16406 tree clauses = NULL;
16407 bool first = true;
16409 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16411 location_t here;
16412 pragma_omp_clause c_kind;
16413 const char *c_name;
16414 tree prev = clauses;
16416 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16417 break;
16419 if (!first)
16421 if (c_parser_next_token_is (parser, CPP_COMMA))
16422 c_parser_consume_token (parser);
16423 else if (nested == 2)
16424 error_at (c_parser_peek_token (parser)->location,
16425 "clauses in %<simd%> trait should be separated "
16426 "by %<,%>");
16429 here = c_parser_peek_token (parser)->location;
16430 c_kind = c_parser_omp_clause_name (parser);
16432 switch (c_kind)
16434 case PRAGMA_OMP_CLAUSE_BIND:
16435 clauses = c_parser_omp_clause_bind (parser, clauses);
16436 c_name = "bind";
16437 break;
16438 case PRAGMA_OMP_CLAUSE_COLLAPSE:
16439 clauses = c_parser_omp_clause_collapse (parser, clauses);
16440 c_name = "collapse";
16441 break;
16442 case PRAGMA_OMP_CLAUSE_COPYIN:
16443 clauses = c_parser_omp_clause_copyin (parser, clauses);
16444 c_name = "copyin";
16445 break;
16446 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16447 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16448 c_name = "copyprivate";
16449 break;
16450 case PRAGMA_OMP_CLAUSE_DEFAULT:
16451 clauses = c_parser_omp_clause_default (parser, clauses, false);
16452 c_name = "default";
16453 break;
16454 case PRAGMA_OMP_CLAUSE_DETACH:
16455 clauses = c_parser_omp_clause_detach (parser, clauses);
16456 c_name = "detach";
16457 break;
16458 case PRAGMA_OMP_CLAUSE_FILTER:
16459 clauses = c_parser_omp_clause_filter (parser, clauses);
16460 c_name = "filter";
16461 break;
16462 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
16463 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16464 c_name = "firstprivate";
16465 break;
16466 case PRAGMA_OMP_CLAUSE_FINAL:
16467 clauses = c_parser_omp_clause_final (parser, clauses);
16468 c_name = "final";
16469 break;
16470 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
16471 clauses = c_parser_omp_clause_grainsize (parser, clauses);
16472 c_name = "grainsize";
16473 break;
16474 case PRAGMA_OMP_CLAUSE_HINT:
16475 clauses = c_parser_omp_clause_hint (parser, clauses);
16476 c_name = "hint";
16477 break;
16478 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
16479 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
16480 c_name = "defaultmap";
16481 break;
16482 case PRAGMA_OMP_CLAUSE_IF:
16483 clauses = c_parser_omp_clause_if (parser, clauses, true);
16484 c_name = "if";
16485 break;
16486 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
16487 clauses
16488 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
16489 true, clauses);
16490 c_name = "in_reduction";
16491 break;
16492 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
16493 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
16494 c_name = "lastprivate";
16495 break;
16496 case PRAGMA_OMP_CLAUSE_MERGEABLE:
16497 clauses = c_parser_omp_clause_mergeable (parser, clauses);
16498 c_name = "mergeable";
16499 break;
16500 case PRAGMA_OMP_CLAUSE_NOWAIT:
16501 clauses = c_parser_omp_clause_nowait (parser, clauses);
16502 c_name = "nowait";
16503 break;
16504 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
16505 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
16506 c_name = "num_tasks";
16507 break;
16508 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
16509 clauses = c_parser_omp_clause_num_threads (parser, clauses);
16510 c_name = "num_threads";
16511 break;
16512 case PRAGMA_OMP_CLAUSE_ORDER:
16513 clauses = c_parser_omp_clause_order (parser, clauses);
16514 c_name = "order";
16515 break;
16516 case PRAGMA_OMP_CLAUSE_ORDERED:
16517 clauses = c_parser_omp_clause_ordered (parser, clauses);
16518 c_name = "ordered";
16519 break;
16520 case PRAGMA_OMP_CLAUSE_PRIORITY:
16521 clauses = c_parser_omp_clause_priority (parser, clauses);
16522 c_name = "priority";
16523 break;
16524 case PRAGMA_OMP_CLAUSE_PRIVATE:
16525 clauses = c_parser_omp_clause_private (parser, clauses);
16526 c_name = "private";
16527 break;
16528 case PRAGMA_OMP_CLAUSE_REDUCTION:
16529 clauses
16530 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16531 true, clauses);
16532 c_name = "reduction";
16533 break;
16534 case PRAGMA_OMP_CLAUSE_SCHEDULE:
16535 clauses = c_parser_omp_clause_schedule (parser, clauses);
16536 c_name = "schedule";
16537 break;
16538 case PRAGMA_OMP_CLAUSE_SHARED:
16539 clauses = c_parser_omp_clause_shared (parser, clauses);
16540 c_name = "shared";
16541 break;
16542 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
16543 clauses
16544 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
16545 true, clauses);
16546 c_name = "task_reduction";
16547 break;
16548 case PRAGMA_OMP_CLAUSE_UNTIED:
16549 clauses = c_parser_omp_clause_untied (parser, clauses);
16550 c_name = "untied";
16551 break;
16552 case PRAGMA_OMP_CLAUSE_INBRANCH:
16553 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
16554 clauses);
16555 c_name = "inbranch";
16556 break;
16557 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
16558 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
16559 c_name = "nontemporal";
16560 break;
16561 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
16562 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
16563 clauses);
16564 c_name = "notinbranch";
16565 break;
16566 case PRAGMA_OMP_CLAUSE_PARALLEL:
16567 clauses
16568 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
16569 clauses);
16570 c_name = "parallel";
16571 if (!first)
16573 clause_not_first:
16574 error_at (here, "%qs must be the first clause of %qs",
16575 c_name, where);
16576 clauses = prev;
16578 break;
16579 case PRAGMA_OMP_CLAUSE_FOR:
16580 clauses
16581 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
16582 clauses);
16583 c_name = "for";
16584 if (!first)
16585 goto clause_not_first;
16586 break;
16587 case PRAGMA_OMP_CLAUSE_SECTIONS:
16588 clauses
16589 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
16590 clauses);
16591 c_name = "sections";
16592 if (!first)
16593 goto clause_not_first;
16594 break;
16595 case PRAGMA_OMP_CLAUSE_TASKGROUP:
16596 clauses
16597 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
16598 clauses);
16599 c_name = "taskgroup";
16600 if (!first)
16601 goto clause_not_first;
16602 break;
16603 case PRAGMA_OMP_CLAUSE_LINK:
16604 clauses
16605 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
16606 c_name = "link";
16607 break;
16608 case PRAGMA_OMP_CLAUSE_TO:
16609 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
16610 clauses
16611 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
16612 clauses);
16613 else
16614 clauses = c_parser_omp_clause_to (parser, clauses);
16615 c_name = "to";
16616 break;
16617 case PRAGMA_OMP_CLAUSE_FROM:
16618 clauses = c_parser_omp_clause_from (parser, clauses);
16619 c_name = "from";
16620 break;
16621 case PRAGMA_OMP_CLAUSE_UNIFORM:
16622 clauses = c_parser_omp_clause_uniform (parser, clauses);
16623 c_name = "uniform";
16624 break;
16625 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
16626 clauses = c_parser_omp_clause_num_teams (parser, clauses);
16627 c_name = "num_teams";
16628 break;
16629 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
16630 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
16631 c_name = "thread_limit";
16632 break;
16633 case PRAGMA_OMP_CLAUSE_ALIGNED:
16634 clauses = c_parser_omp_clause_aligned (parser, clauses);
16635 c_name = "aligned";
16636 break;
16637 case PRAGMA_OMP_CLAUSE_ALLOCATE:
16638 clauses = c_parser_omp_clause_allocate (parser, clauses);
16639 c_name = "allocate";
16640 break;
16641 case PRAGMA_OMP_CLAUSE_LINEAR:
16642 clauses = c_parser_omp_clause_linear (parser, clauses);
16643 c_name = "linear";
16644 break;
16645 case PRAGMA_OMP_CLAUSE_AFFINITY:
16646 clauses = c_parser_omp_clause_affinity (parser, clauses);
16647 c_name = "affinity";
16648 break;
16649 case PRAGMA_OMP_CLAUSE_DEPEND:
16650 clauses = c_parser_omp_clause_depend (parser, clauses);
16651 c_name = "depend";
16652 break;
16653 case PRAGMA_OMP_CLAUSE_MAP:
16654 clauses = c_parser_omp_clause_map (parser, clauses);
16655 c_name = "map";
16656 break;
16657 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
16658 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16659 c_name = "use_device_ptr";
16660 break;
16661 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
16662 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
16663 c_name = "use_device_addr";
16664 break;
16665 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
16666 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
16667 c_name = "is_device_ptr";
16668 break;
16669 case PRAGMA_OMP_CLAUSE_DEVICE:
16670 clauses = c_parser_omp_clause_device (parser, clauses);
16671 c_name = "device";
16672 break;
16673 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
16674 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
16675 c_name = "dist_schedule";
16676 break;
16677 case PRAGMA_OMP_CLAUSE_PROC_BIND:
16678 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
16679 c_name = "proc_bind";
16680 break;
16681 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
16682 clauses = c_parser_omp_clause_device_type (parser, clauses);
16683 c_name = "device_type";
16684 break;
16685 case PRAGMA_OMP_CLAUSE_SAFELEN:
16686 clauses = c_parser_omp_clause_safelen (parser, clauses);
16687 c_name = "safelen";
16688 break;
16689 case PRAGMA_OMP_CLAUSE_SIMDLEN:
16690 clauses = c_parser_omp_clause_simdlen (parser, clauses);
16691 c_name = "simdlen";
16692 break;
16693 case PRAGMA_OMP_CLAUSE_NOGROUP:
16694 clauses = c_parser_omp_clause_nogroup (parser, clauses);
16695 c_name = "nogroup";
16696 break;
16697 case PRAGMA_OMP_CLAUSE_THREADS:
16698 clauses
16699 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
16700 clauses);
16701 c_name = "threads";
16702 break;
16703 case PRAGMA_OMP_CLAUSE_SIMD:
16704 clauses
16705 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
16706 clauses);
16707 c_name = "simd";
16708 break;
16709 default:
16710 c_parser_error (parser, "expected %<#pragma omp%> clause");
16711 goto saw_error;
16714 first = false;
16716 if (((mask >> c_kind) & 1) == 0)
16718 /* Remove the invalid clause(s) from the list to avoid
16719 confusing the rest of the compiler. */
16720 clauses = prev;
16721 error_at (here, "%qs is not valid for %qs", c_name, where);
16725 saw_error:
16726 if (!nested)
16727 c_parser_skip_to_pragma_eol (parser);
16729 if (finish_p)
16731 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
16732 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
16733 return c_finish_omp_clauses (clauses, C_ORT_OMP);
16736 return clauses;
16739 /* OpenACC 2.0, OpenMP 2.5:
16740 structured-block:
16741 statement
16743 In practice, we're also interested in adding the statement to an
16744 outer node. So it is convenient if we work around the fact that
16745 c_parser_statement calls add_stmt. */
16747 static tree
16748 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
16750 tree stmt = push_stmt_list ();
16751 c_parser_statement (parser, if_p);
16752 return pop_stmt_list (stmt);
16755 /* OpenACC 2.0:
16756 # pragma acc cache (variable-list) new-line
16758 LOC is the location of the #pragma token.
16761 static tree
16762 c_parser_oacc_cache (location_t loc, c_parser *parser)
16764 tree stmt, clauses;
16766 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
16767 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16769 c_parser_skip_to_pragma_eol (parser);
16771 stmt = make_node (OACC_CACHE);
16772 TREE_TYPE (stmt) = void_type_node;
16773 OACC_CACHE_CLAUSES (stmt) = clauses;
16774 SET_EXPR_LOCATION (stmt, loc);
16775 add_stmt (stmt);
16777 return stmt;
16780 /* OpenACC 2.0:
16781 # pragma acc data oacc-data-clause[optseq] new-line
16782 structured-block
16784 LOC is the location of the #pragma token.
16787 #define OACC_DATA_CLAUSE_MASK \
16788 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16791 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16795 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16796 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16798 static tree
16799 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
16801 tree stmt, clauses, block;
16803 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
16804 "#pragma acc data");
16806 block = c_begin_omp_parallel ();
16807 add_stmt (c_parser_omp_structured_block (parser, if_p));
16809 stmt = c_finish_oacc_data (loc, clauses, block);
16811 return stmt;
16814 /* OpenACC 2.0:
16815 # pragma acc declare oacc-data-clause[optseq] new-line
16818 #define OACC_DECLARE_CLAUSE_MASK \
16819 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16820 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
16825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
16826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16828 static void
16829 c_parser_oacc_declare (c_parser *parser)
16831 location_t pragma_loc = c_parser_peek_token (parser)->location;
16832 tree clauses, stmt, t, decl;
16834 bool error = false;
16836 c_parser_consume_pragma (parser);
16838 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
16839 "#pragma acc declare");
16840 if (!clauses)
16842 error_at (pragma_loc,
16843 "no valid clauses specified in %<#pragma acc declare%>");
16844 return;
16847 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
16849 location_t loc = OMP_CLAUSE_LOCATION (t);
16850 decl = OMP_CLAUSE_DECL (t);
16851 if (!DECL_P (decl))
16853 error_at (loc, "array section in %<#pragma acc declare%>");
16854 error = true;
16855 continue;
16858 switch (OMP_CLAUSE_MAP_KIND (t))
16860 case GOMP_MAP_FIRSTPRIVATE_POINTER:
16861 case GOMP_MAP_ALLOC:
16862 case GOMP_MAP_TO:
16863 case GOMP_MAP_FORCE_DEVICEPTR:
16864 case GOMP_MAP_DEVICE_RESIDENT:
16865 break;
16867 case GOMP_MAP_LINK:
16868 if (!global_bindings_p ()
16869 && (TREE_STATIC (decl)
16870 || !DECL_EXTERNAL (decl)))
16872 error_at (loc,
16873 "%qD must be a global variable in "
16874 "%<#pragma acc declare link%>",
16875 decl);
16876 error = true;
16877 continue;
16879 break;
16881 default:
16882 if (global_bindings_p ())
16884 error_at (loc, "invalid OpenACC clause at file scope");
16885 error = true;
16886 continue;
16888 if (DECL_EXTERNAL (decl))
16890 error_at (loc,
16891 "invalid use of %<extern%> variable %qD "
16892 "in %<#pragma acc declare%>", decl);
16893 error = true;
16894 continue;
16896 else if (TREE_PUBLIC (decl))
16898 error_at (loc,
16899 "invalid use of %<global%> variable %qD "
16900 "in %<#pragma acc declare%>", decl);
16901 error = true;
16902 continue;
16904 break;
16907 if (!c_check_in_current_scope (decl))
16909 error_at (loc,
16910 "%qD must be a variable declared in the same scope as "
16911 "%<#pragma acc declare%>", decl);
16912 error = true;
16913 continue;
16916 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
16917 || lookup_attribute ("omp declare target link",
16918 DECL_ATTRIBUTES (decl)))
16920 error_at (loc, "variable %qD used more than once with "
16921 "%<#pragma acc declare%>", decl);
16922 error = true;
16923 continue;
16926 if (!error)
16928 tree id;
16930 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
16931 id = get_identifier ("omp declare target link");
16932 else
16933 id = get_identifier ("omp declare target");
16935 DECL_ATTRIBUTES (decl)
16936 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
16938 if (global_bindings_p ())
16940 symtab_node *node = symtab_node::get (decl);
16941 if (node != NULL)
16943 node->offloadable = 1;
16944 if (ENABLE_OFFLOADING)
16946 g->have_offload = true;
16947 if (is_a <varpool_node *> (node))
16948 vec_safe_push (offload_vars, decl);
16955 if (error || global_bindings_p ())
16956 return;
16958 stmt = make_node (OACC_DECLARE);
16959 TREE_TYPE (stmt) = void_type_node;
16960 OACC_DECLARE_CLAUSES (stmt) = clauses;
16961 SET_EXPR_LOCATION (stmt, pragma_loc);
16963 add_stmt (stmt);
16965 return;
16968 /* OpenACC 2.0:
16969 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16973 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16976 LOC is the location of the #pragma token.
16979 #define OACC_ENTER_DATA_CLAUSE_MASK \
16980 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16987 #define OACC_EXIT_DATA_CLAUSE_MASK \
16988 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
16992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
16993 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
16994 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16996 static void
16997 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
16999 location_t loc = c_parser_peek_token (parser)->location;
17000 tree clauses, stmt;
17001 const char *p = "";
17003 c_parser_consume_pragma (parser);
17005 if (c_parser_next_token_is (parser, CPP_NAME))
17007 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17008 c_parser_consume_token (parser);
17011 if (strcmp (p, "data") != 0)
17013 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17014 enter ? "enter" : "exit");
17015 parser->error = true;
17016 c_parser_skip_to_pragma_eol (parser);
17017 return;
17020 if (enter)
17021 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17022 "#pragma acc enter data");
17023 else
17024 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17025 "#pragma acc exit data");
17027 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17029 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17030 enter ? "enter" : "exit");
17031 return;
17034 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
17035 TREE_TYPE (stmt) = void_type_node;
17036 OMP_STANDALONE_CLAUSES (stmt) = clauses;
17037 SET_EXPR_LOCATION (stmt, loc);
17038 add_stmt (stmt);
17042 /* OpenACC 2.0:
17043 # pragma acc host_data oacc-data-clause[optseq] new-line
17044 structured-block
17047 #define OACC_HOST_DATA_CLAUSE_MASK \
17048 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17052 static tree
17053 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
17055 tree stmt, clauses, block;
17057 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
17058 "#pragma acc host_data");
17060 block = c_begin_omp_parallel ();
17061 add_stmt (c_parser_omp_structured_block (parser, if_p));
17062 stmt = c_finish_oacc_host_data (loc, clauses, block);
17063 return stmt;
17067 /* OpenACC 2.0:
17069 # pragma acc loop oacc-loop-clause[optseq] new-line
17070 structured-block
17072 LOC is the location of the #pragma token.
17075 #define OACC_LOOP_CLAUSE_MASK \
17076 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17079 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17080 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17081 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17082 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17083 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17086 static tree
17087 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
17088 omp_clause_mask mask, tree *cclauses, bool *if_p)
17090 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
17092 strcat (p_name, " loop");
17093 mask |= OACC_LOOP_CLAUSE_MASK;
17095 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
17096 cclauses == NULL);
17097 if (cclauses)
17099 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
17100 if (*cclauses)
17101 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
17102 if (clauses)
17103 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17106 tree block = c_begin_compound_stmt (true);
17107 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
17108 if_p);
17109 block = c_end_compound_stmt (loc, block, true);
17110 add_stmt (block);
17112 return stmt;
17115 /* OpenACC 2.0:
17116 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17117 structured-block
17121 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17122 structured-block
17124 OpenACC 2.6:
17126 # pragma acc serial oacc-serial-clause[optseq] new-line
17127 structured-block
17129 LOC is the location of the #pragma token.
17132 #define OACC_KERNELS_CLAUSE_MASK \
17133 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17137 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17138 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17139 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17140 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17141 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17142 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17143 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17144 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17145 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17146 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17147 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17149 #define OACC_PARALLEL_CLAUSE_MASK \
17150 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17162 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17163 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17164 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17165 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17166 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17167 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17169 #define OACC_SERIAL_CLAUSE_MASK \
17170 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17171 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17172 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17173 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17174 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17175 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17177 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17180 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17181 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17182 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17183 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17184 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17186 static tree
17187 c_parser_oacc_compute (location_t loc, c_parser *parser,
17188 enum pragma_kind p_kind, char *p_name, bool *if_p)
17190 omp_clause_mask mask;
17191 enum tree_code code;
17192 switch (p_kind)
17194 case PRAGMA_OACC_KERNELS:
17195 strcat (p_name, " kernels");
17196 mask = OACC_KERNELS_CLAUSE_MASK;
17197 code = OACC_KERNELS;
17198 break;
17199 case PRAGMA_OACC_PARALLEL:
17200 strcat (p_name, " parallel");
17201 mask = OACC_PARALLEL_CLAUSE_MASK;
17202 code = OACC_PARALLEL;
17203 break;
17204 case PRAGMA_OACC_SERIAL:
17205 strcat (p_name, " serial");
17206 mask = OACC_SERIAL_CLAUSE_MASK;
17207 code = OACC_SERIAL;
17208 break;
17209 default:
17210 gcc_unreachable ();
17213 if (c_parser_next_token_is (parser, CPP_NAME))
17215 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17216 if (strcmp (p, "loop") == 0)
17218 c_parser_consume_token (parser);
17219 tree block = c_begin_omp_parallel ();
17220 tree clauses;
17221 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17222 return c_finish_omp_construct (loc, code, block, clauses);
17226 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17228 tree block = c_begin_omp_parallel ();
17229 add_stmt (c_parser_omp_structured_block (parser, if_p));
17231 return c_finish_omp_construct (loc, code, block, clauses);
17234 /* OpenACC 2.0:
17235 # pragma acc routine oacc-routine-clause[optseq] new-line
17236 function-definition
17238 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17241 #define OACC_ROUTINE_CLAUSE_MASK \
17242 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17248 /* Parse an OpenACC routine directive. For named directives, we apply
17249 immediately to the named function. For unnamed ones we then parse
17250 a declaration or definition, which must be for a function. */
17252 static void
17253 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17255 gcc_checking_assert (context == pragma_external);
17257 oacc_routine_data data;
17258 data.error_seen = false;
17259 data.fndecl_seen = false;
17260 data.loc = c_parser_peek_token (parser)->location;
17262 c_parser_consume_pragma (parser);
17264 /* Look for optional '( name )'. */
17265 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17267 c_parser_consume_token (parser); /* '(' */
17269 tree decl = NULL_TREE;
17270 c_token *name_token = c_parser_peek_token (parser);
17271 location_t name_loc = name_token->location;
17272 if (name_token->type == CPP_NAME
17273 && (name_token->id_kind == C_ID_ID
17274 || name_token->id_kind == C_ID_TYPENAME))
17276 decl = lookup_name (name_token->value);
17277 if (!decl)
17278 error_at (name_loc,
17279 "%qE has not been declared", name_token->value);
17280 c_parser_consume_token (parser);
17282 else
17283 c_parser_error (parser, "expected function name");
17285 if (!decl
17286 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17288 c_parser_skip_to_pragma_eol (parser, false);
17289 return;
17292 data.clauses
17293 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17294 "#pragma acc routine");
17295 /* The clauses are in reverse order; fix that to make later diagnostic
17296 emission easier. */
17297 data.clauses = nreverse (data.clauses);
17299 if (TREE_CODE (decl) != FUNCTION_DECL)
17301 error_at (name_loc, "%qD does not refer to a function", decl);
17302 return;
17305 c_finish_oacc_routine (&data, decl, false);
17307 else /* No optional '( name )'. */
17309 data.clauses
17310 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17311 "#pragma acc routine");
17312 /* The clauses are in reverse order; fix that to make later diagnostic
17313 emission easier. */
17314 data.clauses = nreverse (data.clauses);
17316 /* Emit a helpful diagnostic if there's another pragma following this
17317 one. Also don't allow a static assertion declaration, as in the
17318 following we'll just parse a *single* "declaration or function
17319 definition", and the static assertion counts an one. */
17320 if (c_parser_next_token_is (parser, CPP_PRAGMA)
17321 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17323 error_at (data.loc,
17324 "%<#pragma acc routine%> not immediately followed by"
17325 " function declaration or definition");
17326 /* ..., and then just keep going. */
17327 return;
17330 /* We only have to consider the pragma_external case here. */
17331 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17332 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17334 int ext = disable_extension_diagnostics ();
17336 c_parser_consume_token (parser);
17337 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17338 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17339 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17340 NULL, NULL, false, NULL, &data);
17341 restore_extension_diagnostics (ext);
17343 else
17344 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17345 NULL, NULL, false, NULL, &data);
17349 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17350 IS_DEFN is true if we're applying it to the definition. */
17352 static void
17353 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17354 bool is_defn)
17356 /* Keep going if we're in error reporting mode. */
17357 if (data->error_seen
17358 || fndecl == error_mark_node)
17359 return;
17361 if (data->fndecl_seen)
17363 error_at (data->loc,
17364 "%<#pragma acc routine%> not immediately followed by"
17365 " a single function declaration or definition");
17366 data->error_seen = true;
17367 return;
17369 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17371 error_at (data->loc,
17372 "%<#pragma acc routine%> not immediately followed by"
17373 " function declaration or definition");
17374 data->error_seen = true;
17375 return;
17378 int compatible
17379 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17380 "#pragma acc routine");
17381 if (compatible < 0)
17383 data->error_seen = true;
17384 return;
17386 if (compatible > 0)
17389 else
17391 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17393 error_at (data->loc,
17394 TREE_USED (fndecl)
17395 ? G_("%<#pragma acc routine%> must be applied before use")
17396 : G_("%<#pragma acc routine%> must be applied before"
17397 " definition"));
17398 data->error_seen = true;
17399 return;
17402 /* Set the routine's level of parallelism. */
17403 tree dims = oacc_build_routine_dims (data->clauses);
17404 oacc_replace_fn_attrib (fndecl, dims);
17406 /* Add an "omp declare target" attribute. */
17407 DECL_ATTRIBUTES (fndecl)
17408 = tree_cons (get_identifier ("omp declare target"),
17409 data->clauses, DECL_ATTRIBUTES (fndecl));
17412 /* Remember that we've used this "#pragma acc routine". */
17413 data->fndecl_seen = true;
17416 /* OpenACC 2.0:
17417 # pragma acc update oacc-update-clause[optseq] new-line
17420 #define OACC_UPDATE_CLAUSE_MASK \
17421 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17423 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17424 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17425 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17426 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17428 static void
17429 c_parser_oacc_update (c_parser *parser)
17431 location_t loc = c_parser_peek_token (parser)->location;
17433 c_parser_consume_pragma (parser);
17435 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17436 "#pragma acc update");
17437 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17439 error_at (loc,
17440 "%<#pragma acc update%> must contain at least one "
17441 "%<device%> or %<host%> or %<self%> clause");
17442 return;
17445 if (parser->error)
17446 return;
17448 tree stmt = make_node (OACC_UPDATE);
17449 TREE_TYPE (stmt) = void_type_node;
17450 OACC_UPDATE_CLAUSES (stmt) = clauses;
17451 SET_EXPR_LOCATION (stmt, loc);
17452 add_stmt (stmt);
17455 /* OpenACC 2.0:
17456 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17458 LOC is the location of the #pragma token.
17461 #define OACC_WAIT_CLAUSE_MASK \
17462 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17464 static tree
17465 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
17467 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
17469 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17470 list = c_parser_oacc_wait_list (parser, loc, list);
17472 strcpy (p_name, " wait");
17473 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
17474 stmt = c_finish_oacc_wait (loc, list, clauses);
17475 add_stmt (stmt);
17477 return stmt;
17480 /* OpenMP 5.0:
17481 # pragma omp allocate (list) [allocator(allocator)] */
17483 static void
17484 c_parser_omp_allocate (location_t loc, c_parser *parser)
17486 tree allocator = NULL_TREE;
17487 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
17488 if (c_parser_next_token_is (parser, CPP_NAME))
17490 matching_parens parens;
17491 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17492 c_parser_consume_token (parser);
17493 if (strcmp ("allocator", p) != 0)
17494 error_at (c_parser_peek_token (parser)->location,
17495 "expected %<allocator%>");
17496 else if (parens.require_open (parser))
17498 location_t expr_loc = c_parser_peek_token (parser)->location;
17499 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17500 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17501 allocator = expr.value;
17502 allocator = c_fully_fold (allocator, false, NULL);
17503 tree orig_type
17504 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
17505 orig_type = TYPE_MAIN_VARIANT (orig_type);
17506 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
17507 || TREE_CODE (orig_type) != ENUMERAL_TYPE
17508 || TYPE_NAME (orig_type)
17509 != get_identifier ("omp_allocator_handle_t"))
17511 error_at (expr_loc, "%<allocator%> clause allocator expression "
17512 "has type %qT rather than "
17513 "%<omp_allocator_handle_t%>",
17514 TREE_TYPE (allocator));
17515 allocator = NULL_TREE;
17517 parens.skip_until_found_close (parser);
17520 c_parser_skip_to_pragma_eol (parser);
17522 if (allocator)
17523 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
17524 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
17526 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
17529 /* OpenMP 2.5:
17530 # pragma omp atomic new-line
17531 expression-stmt
17533 expression-stmt:
17534 x binop= expr | x++ | ++x | x-- | --x
17535 binop:
17536 +, *, -, /, &, ^, |, <<, >>
17538 where x is an lvalue expression with scalar type.
17540 OpenMP 3.1:
17541 # pragma omp atomic new-line
17542 update-stmt
17544 # pragma omp atomic read new-line
17545 read-stmt
17547 # pragma omp atomic write new-line
17548 write-stmt
17550 # pragma omp atomic update new-line
17551 update-stmt
17553 # pragma omp atomic capture new-line
17554 capture-stmt
17556 # pragma omp atomic capture new-line
17557 capture-block
17559 read-stmt:
17560 v = x
17561 write-stmt:
17562 x = expr
17563 update-stmt:
17564 expression-stmt | x = x binop expr
17565 capture-stmt:
17566 v = expression-stmt
17567 capture-block:
17568 { v = x; update-stmt; } | { update-stmt; v = x; }
17570 OpenMP 4.0:
17571 update-stmt:
17572 expression-stmt | x = x binop expr | x = expr binop x
17573 capture-stmt:
17574 v = update-stmt
17575 capture-block:
17576 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17578 where x and v are lvalue expressions with scalar type.
17580 LOC is the location of the #pragma token. */
17582 static void
17583 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
17585 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
17586 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
17587 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
17588 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
17589 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
17590 struct c_expr expr;
17591 location_t eloc;
17592 bool structured_block = false;
17593 bool swapped = false;
17594 bool non_lvalue_p;
17595 bool first = true;
17596 tree clauses = NULL_TREE;
17598 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17600 if (!first
17601 && c_parser_next_token_is (parser, CPP_COMMA)
17602 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
17603 c_parser_consume_token (parser);
17605 first = false;
17607 if (c_parser_next_token_is (parser, CPP_NAME))
17609 const char *p
17610 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17611 location_t cloc = c_parser_peek_token (parser)->location;
17612 enum tree_code new_code = ERROR_MARK;
17613 enum omp_memory_order new_memory_order
17614 = OMP_MEMORY_ORDER_UNSPECIFIED;
17616 if (!strcmp (p, "read"))
17617 new_code = OMP_ATOMIC_READ;
17618 else if (!strcmp (p, "write"))
17619 new_code = NOP_EXPR;
17620 else if (!strcmp (p, "update"))
17621 new_code = OMP_ATOMIC;
17622 else if (!strcmp (p, "capture"))
17623 new_code = OMP_ATOMIC_CAPTURE_NEW;
17624 else if (openacc)
17626 p = NULL;
17627 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
17628 "or %<capture%> clause");
17630 else if (!strcmp (p, "seq_cst"))
17631 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17632 else if (!strcmp (p, "acq_rel"))
17633 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17634 else if (!strcmp (p, "release"))
17635 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
17636 else if (!strcmp (p, "acquire"))
17637 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17638 else if (!strcmp (p, "relaxed"))
17639 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
17640 else if (!strcmp (p, "hint"))
17642 c_parser_consume_token (parser);
17643 clauses = c_parser_omp_clause_hint (parser, clauses);
17644 continue;
17646 else
17648 p = NULL;
17649 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
17650 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17651 "%<release%>, %<relaxed%> or %<hint%> clause");
17653 if (p)
17655 if (new_code != ERROR_MARK)
17657 /* OpenACC permits 'update capture'. */
17658 if (openacc
17659 && code == OMP_ATOMIC
17660 && new_code == OMP_ATOMIC_CAPTURE_NEW)
17661 code = new_code;
17662 else if (code != ERROR_MARK)
17663 error_at (cloc, "too many atomic clauses");
17664 else
17665 code = new_code;
17667 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17669 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17670 error_at (cloc, "too many memory order clauses");
17671 else
17672 memory_order = new_memory_order;
17674 c_parser_consume_token (parser);
17675 continue;
17678 break;
17680 c_parser_skip_to_pragma_eol (parser);
17682 if (code == ERROR_MARK)
17683 code = OMP_ATOMIC;
17684 if (openacc)
17685 memory_order = OMP_MEMORY_ORDER_RELAXED;
17686 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
17688 omp_requires_mask
17689 = (enum omp_requires) (omp_requires_mask
17690 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
17691 switch ((enum omp_memory_order)
17692 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
17694 case OMP_MEMORY_ORDER_UNSPECIFIED:
17695 case OMP_MEMORY_ORDER_RELAXED:
17696 memory_order = OMP_MEMORY_ORDER_RELAXED;
17697 break;
17698 case OMP_MEMORY_ORDER_SEQ_CST:
17699 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17700 break;
17701 case OMP_MEMORY_ORDER_ACQ_REL:
17702 switch (code)
17704 case OMP_ATOMIC_READ:
17705 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17706 break;
17707 case NOP_EXPR: /* atomic write */
17708 case OMP_ATOMIC:
17709 memory_order = OMP_MEMORY_ORDER_RELEASE;
17710 break;
17711 default:
17712 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17713 break;
17715 break;
17716 default:
17717 gcc_unreachable ();
17720 else
17721 switch (code)
17723 case OMP_ATOMIC_READ:
17724 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17725 || memory_order == OMP_MEMORY_ORDER_RELEASE)
17727 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
17728 "%<acq_rel%> or %<release%> clauses");
17729 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17731 break;
17732 case NOP_EXPR: /* atomic write */
17733 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17734 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17736 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
17737 "%<acq_rel%> or %<acquire%> clauses");
17738 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17740 break;
17741 case OMP_ATOMIC:
17742 /* case OMP_ATOMIC_CAPTURE_NEW: - or update to OpenMP 5.1 */
17743 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17744 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17746 error_at (loc, "%<#pragma omp atomic update%> incompatible with "
17747 "%<acq_rel%> or %<acquire%> clauses");
17748 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17750 break;
17751 default:
17752 break;
17755 switch (code)
17757 case OMP_ATOMIC_READ:
17758 case NOP_EXPR: /* atomic write */
17759 v = c_parser_cast_expression (parser, NULL).value;
17760 non_lvalue_p = !lvalue_p (v);
17761 v = c_fully_fold (v, false, NULL, true);
17762 if (v == error_mark_node)
17763 goto saw_error;
17764 if (non_lvalue_p)
17765 v = non_lvalue (v);
17766 loc = c_parser_peek_token (parser)->location;
17767 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17768 goto saw_error;
17769 if (code == NOP_EXPR)
17771 lhs = c_parser_expression (parser).value;
17772 lhs = c_fully_fold (lhs, false, NULL);
17773 if (lhs == error_mark_node)
17774 goto saw_error;
17776 else
17778 lhs = c_parser_cast_expression (parser, NULL).value;
17779 non_lvalue_p = !lvalue_p (lhs);
17780 lhs = c_fully_fold (lhs, false, NULL, true);
17781 if (lhs == error_mark_node)
17782 goto saw_error;
17783 if (non_lvalue_p)
17784 lhs = non_lvalue (lhs);
17786 if (code == NOP_EXPR)
17788 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17789 opcode. */
17790 code = OMP_ATOMIC;
17791 rhs = lhs;
17792 lhs = v;
17793 v = NULL_TREE;
17795 goto done;
17796 case OMP_ATOMIC_CAPTURE_NEW:
17797 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
17799 c_parser_consume_token (parser);
17800 structured_block = true;
17802 else
17804 v = c_parser_cast_expression (parser, NULL).value;
17805 non_lvalue_p = !lvalue_p (v);
17806 v = c_fully_fold (v, false, NULL, true);
17807 if (v == error_mark_node)
17808 goto saw_error;
17809 if (non_lvalue_p)
17810 v = non_lvalue (v);
17811 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17812 goto saw_error;
17814 break;
17815 default:
17816 break;
17819 /* For structured_block case we don't know yet whether
17820 old or new x should be captured. */
17821 restart:
17822 eloc = c_parser_peek_token (parser)->location;
17823 expr = c_parser_cast_expression (parser, NULL);
17824 lhs = expr.value;
17825 expr = default_function_array_conversion (eloc, expr);
17826 unfolded_lhs = expr.value;
17827 lhs = c_fully_fold (lhs, false, NULL, true);
17828 orig_lhs = lhs;
17829 switch (TREE_CODE (lhs))
17831 case ERROR_MARK:
17832 saw_error:
17833 c_parser_skip_to_end_of_block_or_statement (parser);
17834 if (structured_block)
17836 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17837 c_parser_consume_token (parser);
17838 else if (code == OMP_ATOMIC_CAPTURE_NEW)
17840 c_parser_skip_to_end_of_block_or_statement (parser);
17841 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17842 c_parser_consume_token (parser);
17845 return;
17847 case POSTINCREMENT_EXPR:
17848 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17849 code = OMP_ATOMIC_CAPTURE_OLD;
17850 /* FALLTHROUGH */
17851 case PREINCREMENT_EXPR:
17852 lhs = TREE_OPERAND (lhs, 0);
17853 unfolded_lhs = NULL_TREE;
17854 opcode = PLUS_EXPR;
17855 rhs = integer_one_node;
17856 break;
17858 case POSTDECREMENT_EXPR:
17859 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17860 code = OMP_ATOMIC_CAPTURE_OLD;
17861 /* FALLTHROUGH */
17862 case PREDECREMENT_EXPR:
17863 lhs = TREE_OPERAND (lhs, 0);
17864 unfolded_lhs = NULL_TREE;
17865 opcode = MINUS_EXPR;
17866 rhs = integer_one_node;
17867 break;
17869 case COMPOUND_EXPR:
17870 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
17871 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
17872 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
17873 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
17874 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17875 (TREE_OPERAND (lhs, 1), 0), 0)))
17876 == BOOLEAN_TYPE)
17877 /* Undo effects of boolean_increment for post {in,de}crement. */
17878 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
17879 /* FALLTHRU */
17880 case MODIFY_EXPR:
17881 if (TREE_CODE (lhs) == MODIFY_EXPR
17882 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
17884 /* Undo effects of boolean_increment. */
17885 if (integer_onep (TREE_OPERAND (lhs, 1)))
17887 /* This is pre or post increment. */
17888 rhs = TREE_OPERAND (lhs, 1);
17889 lhs = TREE_OPERAND (lhs, 0);
17890 unfolded_lhs = NULL_TREE;
17891 opcode = NOP_EXPR;
17892 if (code == OMP_ATOMIC_CAPTURE_NEW
17893 && !structured_block
17894 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17895 code = OMP_ATOMIC_CAPTURE_OLD;
17896 break;
17898 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
17899 && TREE_OPERAND (lhs, 0)
17900 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
17902 /* This is pre or post decrement. */
17903 rhs = TREE_OPERAND (lhs, 1);
17904 lhs = TREE_OPERAND (lhs, 0);
17905 unfolded_lhs = NULL_TREE;
17906 opcode = NOP_EXPR;
17907 if (code == OMP_ATOMIC_CAPTURE_NEW
17908 && !structured_block
17909 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17910 code = OMP_ATOMIC_CAPTURE_OLD;
17911 break;
17914 /* FALLTHRU */
17915 default:
17916 if (!lvalue_p (unfolded_lhs))
17917 lhs = non_lvalue (lhs);
17918 switch (c_parser_peek_token (parser)->type)
17920 case CPP_MULT_EQ:
17921 opcode = MULT_EXPR;
17922 break;
17923 case CPP_DIV_EQ:
17924 opcode = TRUNC_DIV_EXPR;
17925 break;
17926 case CPP_PLUS_EQ:
17927 opcode = PLUS_EXPR;
17928 break;
17929 case CPP_MINUS_EQ:
17930 opcode = MINUS_EXPR;
17931 break;
17932 case CPP_LSHIFT_EQ:
17933 opcode = LSHIFT_EXPR;
17934 break;
17935 case CPP_RSHIFT_EQ:
17936 opcode = RSHIFT_EXPR;
17937 break;
17938 case CPP_AND_EQ:
17939 opcode = BIT_AND_EXPR;
17940 break;
17941 case CPP_OR_EQ:
17942 opcode = BIT_IOR_EXPR;
17943 break;
17944 case CPP_XOR_EQ:
17945 opcode = BIT_XOR_EXPR;
17946 break;
17947 case CPP_EQ:
17948 c_parser_consume_token (parser);
17949 eloc = c_parser_peek_token (parser)->location;
17950 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
17951 rhs1 = expr.value;
17952 switch (TREE_CODE (rhs1))
17954 case MULT_EXPR:
17955 case TRUNC_DIV_EXPR:
17956 case RDIV_EXPR:
17957 case PLUS_EXPR:
17958 case MINUS_EXPR:
17959 case LSHIFT_EXPR:
17960 case RSHIFT_EXPR:
17961 case BIT_AND_EXPR:
17962 case BIT_IOR_EXPR:
17963 case BIT_XOR_EXPR:
17964 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
17966 opcode = TREE_CODE (rhs1);
17967 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17968 true);
17969 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17970 true);
17971 goto stmt_done;
17973 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
17975 opcode = TREE_CODE (rhs1);
17976 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17977 true);
17978 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17979 true);
17980 swapped = !commutative_tree_code (opcode);
17981 goto stmt_done;
17983 break;
17984 case ERROR_MARK:
17985 goto saw_error;
17986 default:
17987 break;
17989 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
17991 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17993 code = OMP_ATOMIC_CAPTURE_OLD;
17994 v = lhs;
17995 lhs = NULL_TREE;
17996 expr = default_function_array_read_conversion (eloc, expr);
17997 unfolded_lhs1 = expr.value;
17998 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
17999 rhs1 = NULL_TREE;
18000 c_parser_consume_token (parser);
18001 goto restart;
18003 if (structured_block)
18005 opcode = NOP_EXPR;
18006 expr = default_function_array_read_conversion (eloc, expr);
18007 rhs = c_fully_fold (expr.value, false, NULL, true);
18008 rhs1 = NULL_TREE;
18009 goto stmt_done;
18012 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
18013 goto saw_error;
18014 default:
18015 c_parser_error (parser,
18016 "invalid operator for %<#pragma omp atomic%>");
18017 goto saw_error;
18020 /* Arrange to pass the location of the assignment operator to
18021 c_finish_omp_atomic. */
18022 loc = c_parser_peek_token (parser)->location;
18023 c_parser_consume_token (parser);
18024 eloc = c_parser_peek_token (parser)->location;
18025 expr = c_parser_expression (parser);
18026 expr = default_function_array_read_conversion (eloc, expr);
18027 rhs = expr.value;
18028 rhs = c_fully_fold (rhs, false, NULL, true);
18029 break;
18031 stmt_done:
18032 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18034 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18035 goto saw_error;
18036 v = c_parser_cast_expression (parser, NULL).value;
18037 non_lvalue_p = !lvalue_p (v);
18038 v = c_fully_fold (v, false, NULL, true);
18039 if (v == error_mark_node)
18040 goto saw_error;
18041 if (non_lvalue_p)
18042 v = non_lvalue (v);
18043 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18044 goto saw_error;
18045 eloc = c_parser_peek_token (parser)->location;
18046 expr = c_parser_cast_expression (parser, NULL);
18047 lhs1 = expr.value;
18048 expr = default_function_array_read_conversion (eloc, expr);
18049 unfolded_lhs1 = expr.value;
18050 lhs1 = c_fully_fold (lhs1, false, NULL, true);
18051 if (lhs1 == error_mark_node)
18052 goto saw_error;
18053 if (!lvalue_p (unfolded_lhs1))
18054 lhs1 = non_lvalue (lhs1);
18056 if (structured_block)
18058 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18059 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
18061 done:
18062 if (unfolded_lhs && unfolded_lhs1
18063 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
18065 error ("%<#pragma omp atomic capture%> uses two different "
18066 "expressions for memory");
18067 stmt = error_mark_node;
18069 else
18070 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1,
18071 swapped, memory_order);
18072 if (stmt != error_mark_node)
18073 add_stmt (stmt);
18075 if (!structured_block)
18076 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18080 /* OpenMP 2.5:
18081 # pragma omp barrier new-line
18084 static void
18085 c_parser_omp_barrier (c_parser *parser)
18087 location_t loc = c_parser_peek_token (parser)->location;
18088 c_parser_consume_pragma (parser);
18089 c_parser_skip_to_pragma_eol (parser);
18091 c_finish_omp_barrier (loc);
18094 /* OpenMP 2.5:
18095 # pragma omp critical [(name)] new-line
18096 structured-block
18098 OpenMP 4.5:
18099 # pragma omp critical [(name) [hint(expression)]] new-line
18101 LOC is the location of the #pragma itself. */
18103 #define OMP_CRITICAL_CLAUSE_MASK \
18104 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
18106 static tree
18107 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
18109 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
18111 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
18113 c_parser_consume_token (parser);
18114 if (c_parser_next_token_is (parser, CPP_NAME))
18116 name = c_parser_peek_token (parser)->value;
18117 c_parser_consume_token (parser);
18118 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
18120 else
18121 c_parser_error (parser, "expected identifier");
18123 if (c_parser_next_token_is (parser, CPP_COMMA)
18124 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18125 c_parser_consume_token (parser);
18127 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
18128 "#pragma omp critical");
18129 stmt = c_parser_omp_structured_block (parser, if_p);
18130 return c_finish_omp_critical (loc, stmt, name, clauses);
18133 /* OpenMP 5.0:
18134 # pragma omp depobj ( depobj ) depobj-clause new-line
18136 depobj-clause:
18137 depend (dependence-type : locator)
18138 destroy
18139 update (dependence-type)
18141 dependence-type:
18144 inout
18145 mutexinout */
18147 static void
18148 c_parser_omp_depobj (c_parser *parser)
18150 location_t loc = c_parser_peek_token (parser)->location;
18151 c_parser_consume_pragma (parser);
18152 matching_parens parens;
18153 if (!parens.require_open (parser))
18155 c_parser_skip_to_pragma_eol (parser);
18156 return;
18159 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
18160 if (depobj != error_mark_node)
18162 if (!lvalue_p (depobj))
18164 error_at (EXPR_LOC_OR_LOC (depobj, loc),
18165 "%<depobj%> expression is not lvalue expression");
18166 depobj = error_mark_node;
18168 else
18170 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
18171 depobj, false);
18172 if (addr == error_mark_node)
18173 depobj = error_mark_node;
18174 else
18175 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
18176 addr, RO_UNARY_STAR);
18180 parens.skip_until_found_close (parser);
18181 tree clause = NULL_TREE;
18182 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
18183 location_t c_loc = c_parser_peek_token (parser)->location;
18184 if (c_parser_next_token_is (parser, CPP_NAME))
18186 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18188 c_parser_consume_token (parser);
18189 if (!strcmp ("depend", p))
18191 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
18192 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
18193 if (!clause)
18194 clause = error_mark_node;
18196 else if (!strcmp ("destroy", p))
18197 kind = OMP_CLAUSE_DEPEND_LAST;
18198 else if (!strcmp ("update", p))
18200 matching_parens c_parens;
18201 if (c_parens.require_open (parser))
18203 location_t c2_loc = c_parser_peek_token (parser)->location;
18204 if (c_parser_next_token_is (parser, CPP_NAME))
18206 const char *p2
18207 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18209 c_parser_consume_token (parser);
18210 if (!strcmp ("in", p2))
18211 kind = OMP_CLAUSE_DEPEND_IN;
18212 else if (!strcmp ("out", p2))
18213 kind = OMP_CLAUSE_DEPEND_OUT;
18214 else if (!strcmp ("inout", p2))
18215 kind = OMP_CLAUSE_DEPEND_INOUT;
18216 else if (!strcmp ("mutexinoutset", p2))
18217 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
18219 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
18221 clause = error_mark_node;
18222 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
18223 "%<mutexinoutset%>");
18225 c_parens.skip_until_found_close (parser);
18227 else
18228 clause = error_mark_node;
18231 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
18233 clause = error_mark_node;
18234 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
18236 c_parser_skip_to_pragma_eol (parser);
18238 c_finish_omp_depobj (loc, depobj, kind, clause);
18242 /* OpenMP 2.5:
18243 # pragma omp flush flush-vars[opt] new-line
18245 flush-vars:
18246 ( variable-list )
18248 OpenMP 5.0:
18249 # pragma omp flush memory-order-clause new-line */
18251 static void
18252 c_parser_omp_flush (c_parser *parser)
18254 location_t loc = c_parser_peek_token (parser)->location;
18255 c_parser_consume_pragma (parser);
18256 enum memmodel mo = MEMMODEL_LAST;
18257 if (c_parser_next_token_is (parser, CPP_NAME))
18259 const char *p
18260 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18262 if (!strcmp (p, "acq_rel"))
18263 mo = MEMMODEL_ACQ_REL;
18264 else if (!strcmp (p, "release"))
18265 mo = MEMMODEL_RELEASE;
18266 else if (!strcmp (p, "acquire"))
18267 mo = MEMMODEL_ACQUIRE;
18268 else
18269 error_at (c_parser_peek_token (parser)->location,
18270 "expected %<acq_rel%>, %<release%> or %<acquire%>");
18271 c_parser_consume_token (parser);
18273 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
18275 if (mo != MEMMODEL_LAST)
18276 error_at (c_parser_peek_token (parser)->location,
18277 "%<flush%> list specified together with memory order "
18278 "clause");
18279 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
18281 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18282 c_parser_error (parser, "expected %<(%> or end of line");
18283 c_parser_skip_to_pragma_eol (parser);
18285 c_finish_omp_flush (loc, mo);
18288 /* OpenMP 5.0:
18290 scan-loop-body:
18291 { structured-block scan-directive structured-block } */
18293 static void
18294 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
18296 tree substmt;
18297 location_t loc;
18298 tree clauses = NULL_TREE;
18300 loc = c_parser_peek_token (parser)->location;
18301 if (!open_brace_parsed
18302 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18304 /* Avoid skipping until the end of the block. */
18305 parser->error = false;
18306 return;
18309 substmt = c_parser_omp_structured_block (parser, NULL);
18310 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
18311 SET_EXPR_LOCATION (substmt, loc);
18312 add_stmt (substmt);
18314 loc = c_parser_peek_token (parser)->location;
18315 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
18317 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
18319 c_parser_consume_pragma (parser);
18321 if (c_parser_next_token_is (parser, CPP_NAME))
18323 const char *p
18324 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18325 if (strcmp (p, "inclusive") == 0)
18326 clause = OMP_CLAUSE_INCLUSIVE;
18327 else if (strcmp (p, "exclusive") == 0)
18328 clause = OMP_CLAUSE_EXCLUSIVE;
18330 if (clause != OMP_CLAUSE_ERROR)
18332 c_parser_consume_token (parser);
18333 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
18335 else
18336 c_parser_error (parser, "expected %<inclusive%> or "
18337 "%<exclusive%> clause");
18338 c_parser_skip_to_pragma_eol (parser);
18340 else
18341 error ("expected %<#pragma omp scan%>");
18343 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
18344 substmt = c_parser_omp_structured_block (parser, NULL);
18345 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
18346 SET_EXPR_LOCATION (substmt, loc);
18347 add_stmt (substmt);
18349 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
18350 "expected %<}%>");
18353 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
18354 The real trick here is to determine the loop control variable early
18355 so that we can push a new decl if necessary to make it private.
18356 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
18357 respectively. */
18359 static tree
18360 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
18361 tree clauses, tree *cclauses, bool *if_p)
18363 tree decl, cond, incr, body, init, stmt, cl;
18364 unsigned char save_in_statement;
18365 tree declv, condv, incrv, initv, ret = NULL_TREE;
18366 tree pre_body = NULL_TREE, this_pre_body;
18367 tree ordered_cl = NULL_TREE;
18368 bool fail = false, open_brace_parsed = false;
18369 int i, collapse = 1, ordered = 0, count, nbraces = 0;
18370 location_t for_loc;
18371 bool tiling = false;
18372 bool inscan = false;
18373 vec<tree, va_gc> *for_block = make_tree_vector ();
18375 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
18376 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
18377 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
18378 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
18380 tiling = true;
18381 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
18383 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
18384 && OMP_CLAUSE_ORDERED_EXPR (cl))
18386 ordered_cl = cl;
18387 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
18389 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
18390 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
18391 && (code == OMP_SIMD || code == OMP_FOR))
18392 inscan = true;
18394 if (ordered && ordered < collapse)
18396 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
18397 "%<ordered%> clause parameter is less than %<collapse%>");
18398 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
18399 = build_int_cst (NULL_TREE, collapse);
18400 ordered = collapse;
18402 if (ordered)
18404 for (tree *pc = &clauses; *pc; )
18405 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
18407 error_at (OMP_CLAUSE_LOCATION (*pc),
18408 "%<linear%> clause may not be specified together "
18409 "with %<ordered%> clause with a parameter");
18410 *pc = OMP_CLAUSE_CHAIN (*pc);
18412 else
18413 pc = &OMP_CLAUSE_CHAIN (*pc);
18416 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
18417 count = ordered ? ordered : collapse;
18419 declv = make_tree_vec (count);
18420 initv = make_tree_vec (count);
18421 condv = make_tree_vec (count);
18422 incrv = make_tree_vec (count);
18424 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
18426 c_parser_error (parser, "for statement expected");
18427 return NULL;
18429 for_loc = c_parser_peek_token (parser)->location;
18430 c_parser_consume_token (parser);
18432 /* Forbid break/continue in the loop initializer, condition, and
18433 increment expressions. */
18434 save_in_statement = in_statement;
18435 in_statement = IN_OMP_BLOCK;
18437 for (i = 0; i < count; i++)
18439 int bracecount = 0;
18441 matching_parens parens;
18442 if (!parens.require_open (parser))
18443 goto pop_scopes;
18445 /* Parse the initialization declaration or expression. */
18446 if (c_parser_next_tokens_start_declaration (parser))
18448 if (i > 0)
18449 vec_safe_push (for_block, c_begin_compound_stmt (true));
18450 this_pre_body = push_stmt_list ();
18451 c_in_omp_for = true;
18452 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
18453 c_in_omp_for = false;
18454 if (this_pre_body)
18456 this_pre_body = pop_stmt_list (this_pre_body);
18457 if (pre_body)
18459 tree t = pre_body;
18460 pre_body = push_stmt_list ();
18461 add_stmt (t);
18462 add_stmt (this_pre_body);
18463 pre_body = pop_stmt_list (pre_body);
18465 else
18466 pre_body = this_pre_body;
18468 decl = check_for_loop_decls (for_loc, flag_isoc99);
18469 if (decl == NULL)
18470 goto error_init;
18471 if (DECL_INITIAL (decl) == error_mark_node)
18472 decl = error_mark_node;
18473 init = decl;
18475 else if (c_parser_next_token_is (parser, CPP_NAME)
18476 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
18478 struct c_expr decl_exp;
18479 struct c_expr init_exp;
18480 location_t init_loc;
18482 decl_exp = c_parser_postfix_expression (parser);
18483 decl = decl_exp.value;
18485 c_parser_require (parser, CPP_EQ, "expected %<=%>");
18487 init_loc = c_parser_peek_token (parser)->location;
18488 init_exp = c_parser_expr_no_commas (parser, NULL);
18489 init_exp = default_function_array_read_conversion (init_loc,
18490 init_exp);
18491 c_in_omp_for = true;
18492 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
18493 NOP_EXPR, init_loc, init_exp.value,
18494 init_exp.original_type);
18495 c_in_omp_for = false;
18496 init = c_process_expr_stmt (init_loc, init);
18498 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18500 else
18502 error_init:
18503 c_parser_error (parser,
18504 "expected iteration declaration or initialization");
18505 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18506 "expected %<)%>");
18507 fail = true;
18508 goto parse_next;
18511 /* Parse the loop condition. */
18512 cond = NULL_TREE;
18513 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
18515 location_t cond_loc = c_parser_peek_token (parser)->location;
18516 c_in_omp_for = true;
18517 struct c_expr cond_expr
18518 = c_parser_binary_expression (parser, NULL, NULL_TREE);
18519 c_in_omp_for = false;
18521 cond = cond_expr.value;
18522 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
18523 switch (cond_expr.original_code)
18525 case GT_EXPR:
18526 case GE_EXPR:
18527 case LT_EXPR:
18528 case LE_EXPR:
18529 break;
18530 case NE_EXPR:
18531 if (code != OACC_LOOP)
18532 break;
18533 /* FALLTHRU. */
18534 default:
18535 /* Can't be cond = error_mark_node, because we want to preserve
18536 the location until c_finish_omp_for. */
18537 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
18538 break;
18540 protected_set_expr_location (cond, cond_loc);
18542 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18544 /* Parse the increment expression. */
18545 incr = NULL_TREE;
18546 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
18548 location_t incr_loc = c_parser_peek_token (parser)->location;
18550 incr = c_process_expr_stmt (incr_loc,
18551 c_parser_expression (parser).value);
18553 parens.skip_until_found_close (parser);
18555 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
18556 fail = true;
18557 else
18559 TREE_VEC_ELT (declv, i) = decl;
18560 TREE_VEC_ELT (initv, i) = init;
18561 TREE_VEC_ELT (condv, i) = cond;
18562 TREE_VEC_ELT (incrv, i) = incr;
18565 parse_next:
18566 if (i == count - 1)
18567 break;
18569 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18570 in between the collapsed for loops to be still considered perfectly
18571 nested. Hopefully the final version clarifies this.
18572 For now handle (multiple) {'s and empty statements. */
18575 if (c_parser_next_token_is_keyword (parser, RID_FOR))
18577 c_parser_consume_token (parser);
18578 break;
18580 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18582 c_parser_consume_token (parser);
18583 bracecount++;
18585 else if (bracecount
18586 && c_parser_next_token_is (parser, CPP_SEMICOLON))
18587 c_parser_consume_token (parser);
18588 else
18590 c_parser_error (parser, "not enough perfectly nested loops");
18591 if (bracecount)
18593 open_brace_parsed = true;
18594 bracecount--;
18596 fail = true;
18597 count = 0;
18598 break;
18601 while (1);
18603 nbraces += bracecount;
18606 if (nbraces)
18607 if_p = NULL;
18609 in_statement = IN_OMP_FOR;
18610 body = push_stmt_list ();
18612 if (inscan)
18613 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
18614 else if (open_brace_parsed)
18616 location_t here = c_parser_peek_token (parser)->location;
18617 stmt = c_begin_compound_stmt (true);
18618 c_parser_compound_statement_nostart (parser);
18619 add_stmt (c_end_compound_stmt (here, stmt, true));
18621 else
18622 add_stmt (c_parser_c99_block_statement (parser, if_p));
18624 body = pop_stmt_list (body);
18625 in_statement = save_in_statement;
18627 while (nbraces)
18629 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18631 c_parser_consume_token (parser);
18632 nbraces--;
18634 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
18635 c_parser_consume_token (parser);
18636 else
18638 c_parser_error (parser, "collapsed loops not perfectly nested");
18639 while (nbraces)
18641 location_t here = c_parser_peek_token (parser)->location;
18642 stmt = c_begin_compound_stmt (true);
18643 add_stmt (body);
18644 c_parser_compound_statement_nostart (parser);
18645 body = c_end_compound_stmt (here, stmt, true);
18646 nbraces--;
18648 goto pop_scopes;
18652 /* Only bother calling c_finish_omp_for if we haven't already generated
18653 an error from the initialization parsing. */
18654 if (!fail)
18656 c_in_omp_for = true;
18657 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
18658 incrv, body, pre_body, true);
18659 c_in_omp_for = false;
18661 /* Check for iterators appearing in lb, b or incr expressions. */
18662 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
18663 stmt = NULL_TREE;
18665 if (stmt)
18667 add_stmt (stmt);
18669 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
18671 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
18672 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
18673 tree decl = TREE_OPERAND (init, 0);
18674 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
18675 gcc_assert (COMPARISON_CLASS_P (cond));
18676 gcc_assert (TREE_OPERAND (cond, 0) == decl);
18678 tree op0 = TREE_OPERAND (init, 1);
18679 if (!OMP_FOR_NON_RECTANGULAR (stmt)
18680 || TREE_CODE (op0) != TREE_VEC)
18681 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
18682 else
18684 TREE_VEC_ELT (op0, 1)
18685 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
18686 TREE_VEC_ELT (op0, 2)
18687 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
18690 tree op1 = TREE_OPERAND (cond, 1);
18691 if (!OMP_FOR_NON_RECTANGULAR (stmt)
18692 || TREE_CODE (op1) != TREE_VEC)
18693 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
18694 else
18696 TREE_VEC_ELT (op1, 1)
18697 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
18698 TREE_VEC_ELT (op1, 2)
18699 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
18703 if (cclauses != NULL
18704 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
18706 tree *c;
18707 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
18708 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
18709 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
18710 c = &OMP_CLAUSE_CHAIN (*c);
18711 else
18713 for (i = 0; i < count; i++)
18714 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
18715 break;
18716 if (i == count)
18717 c = &OMP_CLAUSE_CHAIN (*c);
18718 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
18720 error_at (loc,
18721 "iteration variable %qD should not be firstprivate",
18722 OMP_CLAUSE_DECL (*c));
18723 *c = OMP_CLAUSE_CHAIN (*c);
18725 else
18727 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
18728 tree l = *c;
18729 *c = OMP_CLAUSE_CHAIN (*c);
18730 if (code == OMP_SIMD)
18732 OMP_CLAUSE_CHAIN (l)
18733 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18734 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
18736 else
18738 OMP_CLAUSE_CHAIN (l) = clauses;
18739 clauses = l;
18744 OMP_FOR_CLAUSES (stmt) = clauses;
18746 ret = stmt;
18748 pop_scopes:
18749 while (!for_block->is_empty ())
18751 /* FIXME diagnostics: LOC below should be the actual location of
18752 this particular for block. We need to build a list of
18753 locations to go along with FOR_BLOCK. */
18754 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
18755 add_stmt (stmt);
18757 release_tree_vector (for_block);
18758 return ret;
18761 /* Helper function for OpenMP parsing, split clauses and call
18762 finish_omp_clauses on each of the set of clauses afterwards. */
18764 static void
18765 omp_split_clauses (location_t loc, enum tree_code code,
18766 omp_clause_mask mask, tree clauses, tree *cclauses)
18768 int i;
18769 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
18770 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
18771 if (cclauses[i])
18772 cclauses[i] = c_finish_omp_clauses (cclauses[i],
18773 i == C_OMP_CLAUSE_SPLIT_TARGET
18774 ? C_ORT_OMP_TARGET : C_ORT_OMP);
18777 /* OpenMP 5.0:
18778 #pragma omp loop loop-clause[optseq] new-line
18779 for-loop
18781 LOC is the location of the #pragma token.
18784 #define OMP_LOOP_CLAUSE_MASK \
18785 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18786 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18787 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
18790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18792 static tree
18793 c_parser_omp_loop (location_t loc, c_parser *parser,
18794 char *p_name, omp_clause_mask mask, tree *cclauses,
18795 bool *if_p)
18797 tree block, clauses, ret;
18799 strcat (p_name, " loop");
18800 mask |= OMP_LOOP_CLAUSE_MASK;
18802 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18803 if (cclauses)
18805 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
18806 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
18809 block = c_begin_compound_stmt (true);
18810 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
18811 block = c_end_compound_stmt (loc, block, true);
18812 add_stmt (block);
18814 return ret;
18817 /* OpenMP 4.0:
18818 #pragma omp simd simd-clause[optseq] new-line
18819 for-loop
18821 LOC is the location of the #pragma token.
18824 #define OMP_SIMD_CLAUSE_MASK \
18825 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
18826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
18827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
18829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18830 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18831 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
18835 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18837 static tree
18838 c_parser_omp_simd (location_t loc, c_parser *parser,
18839 char *p_name, omp_clause_mask mask, tree *cclauses,
18840 bool *if_p)
18842 tree block, clauses, ret;
18844 strcat (p_name, " simd");
18845 mask |= OMP_SIMD_CLAUSE_MASK;
18847 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18848 if (cclauses)
18850 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
18851 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
18852 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
18853 OMP_CLAUSE_ORDERED);
18854 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
18856 error_at (OMP_CLAUSE_LOCATION (c),
18857 "%<ordered%> clause with parameter may not be specified "
18858 "on %qs construct", p_name);
18859 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
18863 block = c_begin_compound_stmt (true);
18864 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
18865 block = c_end_compound_stmt (loc, block, true);
18866 add_stmt (block);
18868 return ret;
18871 /* OpenMP 2.5:
18872 #pragma omp for for-clause[optseq] new-line
18873 for-loop
18875 OpenMP 4.0:
18876 #pragma omp for simd for-simd-clause[optseq] new-line
18877 for-loop
18879 LOC is the location of the #pragma token.
18882 #define OMP_FOR_CLAUSE_MASK \
18883 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
18889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
18890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
18893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18895 static tree
18896 c_parser_omp_for (location_t loc, c_parser *parser,
18897 char *p_name, omp_clause_mask mask, tree *cclauses,
18898 bool *if_p)
18900 tree block, clauses, ret;
18902 strcat (p_name, " for");
18903 mask |= OMP_FOR_CLAUSE_MASK;
18904 /* parallel for{, simd} disallows nowait clause, but for
18905 target {teams distribute ,}parallel for{, simd} it should be accepted. */
18906 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
18907 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18908 /* Composite distribute parallel for{, simd} disallows ordered clause. */
18909 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18910 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
18912 if (c_parser_next_token_is (parser, CPP_NAME))
18914 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18916 if (strcmp (p, "simd") == 0)
18918 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18919 if (cclauses == NULL)
18920 cclauses = cclauses_buf;
18922 c_parser_consume_token (parser);
18923 if (!flag_openmp) /* flag_openmp_simd */
18924 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
18925 if_p);
18926 block = c_begin_compound_stmt (true);
18927 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
18928 block = c_end_compound_stmt (loc, block, true);
18929 if (ret == NULL_TREE)
18930 return ret;
18931 ret = make_node (OMP_FOR);
18932 TREE_TYPE (ret) = void_type_node;
18933 OMP_FOR_BODY (ret) = block;
18934 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18935 SET_EXPR_LOCATION (ret, loc);
18936 add_stmt (ret);
18937 return ret;
18940 if (!flag_openmp) /* flag_openmp_simd */
18942 c_parser_skip_to_pragma_eol (parser, false);
18943 return NULL_TREE;
18946 /* Composite distribute parallel for disallows linear clause. */
18947 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18948 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
18950 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18951 if (cclauses)
18953 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
18954 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18957 block = c_begin_compound_stmt (true);
18958 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
18959 block = c_end_compound_stmt (loc, block, true);
18960 add_stmt (block);
18962 return ret;
18965 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
18966 omp_clause_mask, tree *, bool *);
18968 /* OpenMP 2.5:
18969 # pragma omp master new-line
18970 structured-block
18972 LOC is the location of the #pragma token.
18975 static tree
18976 c_parser_omp_master (location_t loc, c_parser *parser,
18977 char *p_name, omp_clause_mask mask, tree *cclauses,
18978 bool *if_p)
18980 tree block, clauses, ret;
18982 strcat (p_name, " master");
18984 if (c_parser_next_token_is (parser, CPP_NAME))
18986 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18988 if (strcmp (p, "taskloop") == 0)
18990 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18991 if (cclauses == NULL)
18992 cclauses = cclauses_buf;
18994 c_parser_consume_token (parser);
18995 if (!flag_openmp) /* flag_openmp_simd */
18996 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18997 if_p);
18998 block = c_begin_compound_stmt (true);
18999 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19000 if_p);
19001 block = c_end_compound_stmt (loc, block, true);
19002 if (ret == NULL_TREE)
19003 return ret;
19004 ret = c_finish_omp_master (loc, block);
19005 OMP_MASTER_COMBINED (ret) = 1;
19006 return ret;
19009 if (!flag_openmp) /* flag_openmp_simd */
19011 c_parser_skip_to_pragma_eol (parser, false);
19012 return NULL_TREE;
19015 if (cclauses)
19017 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
19018 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
19020 else
19021 c_parser_skip_to_pragma_eol (parser);
19023 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
19024 if_p));
19027 /* OpenMP 5.1:
19028 # pragma omp masked masked-clauses new-line
19029 structured-block
19031 LOC is the location of the #pragma token.
19034 #define OMP_MASKED_CLAUSE_MASK \
19035 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
19037 static tree
19038 c_parser_omp_masked (location_t loc, c_parser *parser,
19039 char *p_name, omp_clause_mask mask, tree *cclauses,
19040 bool *if_p)
19042 tree block, clauses, ret;
19044 strcat (p_name, " masked");
19045 mask |= OMP_MASKED_CLAUSE_MASK;
19047 if (c_parser_next_token_is (parser, CPP_NAME))
19049 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19051 if (strcmp (p, "taskloop") == 0)
19053 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19054 if (cclauses == NULL)
19055 cclauses = cclauses_buf;
19057 c_parser_consume_token (parser);
19058 if (!flag_openmp) /* flag_openmp_simd */
19059 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19060 if_p);
19061 block = c_begin_compound_stmt (true);
19062 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19063 if_p);
19064 block = c_end_compound_stmt (loc, block, true);
19065 if (ret == NULL_TREE)
19066 return ret;
19067 ret = c_finish_omp_masked (loc, block,
19068 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
19069 OMP_MASKED_COMBINED (ret) = 1;
19070 return ret;
19073 if (!flag_openmp) /* flag_openmp_simd */
19075 c_parser_skip_to_pragma_eol (parser, false);
19076 return NULL_TREE;
19079 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19080 if (cclauses)
19082 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
19083 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
19086 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
19087 if_p),
19088 clauses);
19091 /* OpenMP 2.5:
19092 # pragma omp ordered new-line
19093 structured-block
19095 OpenMP 4.5:
19096 # pragma omp ordered ordered-clauses new-line
19097 structured-block
19099 # pragma omp ordered depend-clauses new-line */
19101 #define OMP_ORDERED_CLAUSE_MASK \
19102 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
19103 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
19105 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
19106 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19108 static bool
19109 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
19110 bool *if_p)
19112 location_t loc = c_parser_peek_token (parser)->location;
19113 c_parser_consume_pragma (parser);
19115 if (context != pragma_stmt && context != pragma_compound)
19117 c_parser_error (parser, "expected declaration specifiers");
19118 c_parser_skip_to_pragma_eol (parser, false);
19119 return false;
19122 if (c_parser_next_token_is (parser, CPP_NAME))
19124 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19126 if (!strcmp ("depend", p))
19128 if (!flag_openmp) /* flag_openmp_simd */
19130 c_parser_skip_to_pragma_eol (parser, false);
19131 return false;
19133 if (context == pragma_stmt)
19135 error_at (loc,
19136 "%<#pragma omp ordered%> with %<depend%> clause may "
19137 "only be used in compound statements");
19138 c_parser_skip_to_pragma_eol (parser, false);
19139 return true;
19142 tree clauses
19143 = c_parser_omp_all_clauses (parser,
19144 OMP_ORDERED_DEPEND_CLAUSE_MASK,
19145 "#pragma omp ordered");
19146 c_finish_omp_ordered (loc, clauses, NULL_TREE);
19147 return false;
19151 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
19152 "#pragma omp ordered");
19154 if (!flag_openmp /* flag_openmp_simd */
19155 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
19156 return false;
19158 c_finish_omp_ordered (loc, clauses,
19159 c_parser_omp_structured_block (parser, if_p));
19160 return true;
19163 /* OpenMP 2.5:
19165 section-scope:
19166 { section-sequence }
19168 section-sequence:
19169 section-directive[opt] structured-block
19170 section-sequence section-directive structured-block
19172 SECTIONS_LOC is the location of the #pragma omp sections. */
19174 static tree
19175 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
19177 tree stmt, substmt;
19178 bool error_suppress = false;
19179 location_t loc;
19181 loc = c_parser_peek_token (parser)->location;
19182 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19184 /* Avoid skipping until the end of the block. */
19185 parser->error = false;
19186 return NULL_TREE;
19189 stmt = push_stmt_list ();
19191 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
19193 substmt = c_parser_omp_structured_block (parser, NULL);
19194 substmt = build1 (OMP_SECTION, void_type_node, substmt);
19195 SET_EXPR_LOCATION (substmt, loc);
19196 add_stmt (substmt);
19199 while (1)
19201 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19202 break;
19203 if (c_parser_next_token_is (parser, CPP_EOF))
19204 break;
19206 loc = c_parser_peek_token (parser)->location;
19207 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
19209 c_parser_consume_pragma (parser);
19210 c_parser_skip_to_pragma_eol (parser);
19211 error_suppress = false;
19213 else if (!error_suppress)
19215 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
19216 error_suppress = true;
19219 substmt = c_parser_omp_structured_block (parser, NULL);
19220 substmt = build1 (OMP_SECTION, void_type_node, substmt);
19221 SET_EXPR_LOCATION (substmt, loc);
19222 add_stmt (substmt);
19224 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19225 "expected %<#pragma omp section%> or %<}%>");
19227 substmt = pop_stmt_list (stmt);
19229 stmt = make_node (OMP_SECTIONS);
19230 SET_EXPR_LOCATION (stmt, sections_loc);
19231 TREE_TYPE (stmt) = void_type_node;
19232 OMP_SECTIONS_BODY (stmt) = substmt;
19234 return add_stmt (stmt);
19237 /* OpenMP 2.5:
19238 # pragma omp sections sections-clause[optseq] newline
19239 sections-scope
19241 LOC is the location of the #pragma token.
19244 #define OMP_SECTIONS_CLAUSE_MASK \
19245 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19250 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19252 static tree
19253 c_parser_omp_sections (location_t loc, c_parser *parser,
19254 char *p_name, omp_clause_mask mask, tree *cclauses)
19256 tree block, clauses, ret;
19258 strcat (p_name, " sections");
19259 mask |= OMP_SECTIONS_CLAUSE_MASK;
19260 if (cclauses)
19261 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
19263 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19264 if (cclauses)
19266 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
19267 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
19270 block = c_begin_compound_stmt (true);
19271 ret = c_parser_omp_sections_scope (loc, parser);
19272 if (ret)
19273 OMP_SECTIONS_CLAUSES (ret) = clauses;
19274 block = c_end_compound_stmt (loc, block, true);
19275 add_stmt (block);
19277 return ret;
19280 /* OpenMP 2.5:
19281 # pragma omp parallel parallel-clause[optseq] new-line
19282 structured-block
19283 # pragma omp parallel for parallel-for-clause[optseq] new-line
19284 structured-block
19285 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
19286 structured-block
19288 OpenMP 4.0:
19289 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
19290 structured-block
19292 LOC is the location of the #pragma token.
19295 #define OMP_PARALLEL_CLAUSE_MASK \
19296 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19297 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19298 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19299 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
19300 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19301 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
19302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
19304 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19305 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
19307 static tree
19308 c_parser_omp_parallel (location_t loc, c_parser *parser,
19309 char *p_name, omp_clause_mask mask, tree *cclauses,
19310 bool *if_p)
19312 tree stmt, clauses, block;
19314 strcat (p_name, " parallel");
19315 mask |= OMP_PARALLEL_CLAUSE_MASK;
19316 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
19317 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
19318 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
19319 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
19321 if (c_parser_next_token_is_keyword (parser, RID_FOR))
19323 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19324 if (cclauses == NULL)
19325 cclauses = cclauses_buf;
19327 c_parser_consume_token (parser);
19328 if (!flag_openmp) /* flag_openmp_simd */
19329 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
19330 block = c_begin_omp_parallel ();
19331 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
19332 stmt
19333 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19334 block);
19335 if (ret == NULL_TREE)
19336 return ret;
19337 OMP_PARALLEL_COMBINED (stmt) = 1;
19338 return stmt;
19340 /* When combined with distribute, parallel has to be followed by for.
19341 #pragma omp target parallel is allowed though. */
19342 else if (cclauses
19343 && (mask & (OMP_CLAUSE_MASK_1
19344 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19346 error_at (loc, "expected %<for%> after %qs", p_name);
19347 c_parser_skip_to_pragma_eol (parser);
19348 return NULL_TREE;
19350 else if (c_parser_next_token_is (parser, CPP_NAME))
19352 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19353 if (cclauses == NULL && strcmp (p, "masked") == 0)
19355 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19356 cclauses = cclauses_buf;
19358 c_parser_consume_token (parser);
19359 if (!flag_openmp) /* flag_openmp_simd */
19360 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
19361 if_p);
19362 block = c_begin_omp_parallel ();
19363 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
19364 if_p);
19365 stmt = c_finish_omp_parallel (loc,
19366 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19367 block);
19368 if (ret == NULL)
19369 return ret;
19370 /* masked does have just filter clause, but during gimplification
19371 isn't represented by a gimplification omp context, so for
19372 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
19373 so that
19374 #pragma omp parallel masked
19375 #pragma omp taskloop simd lastprivate (x)
19376 isn't confused with
19377 #pragma omp parallel masked taskloop simd lastprivate (x) */
19378 if (OMP_MASKED_COMBINED (ret))
19379 OMP_PARALLEL_COMBINED (stmt) = 1;
19380 return stmt;
19382 else if (cclauses == NULL && strcmp (p, "master") == 0)
19384 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19385 cclauses = cclauses_buf;
19387 c_parser_consume_token (parser);
19388 if (!flag_openmp) /* flag_openmp_simd */
19389 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
19390 if_p);
19391 block = c_begin_omp_parallel ();
19392 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
19393 if_p);
19394 stmt = c_finish_omp_parallel (loc,
19395 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19396 block);
19397 if (ret == NULL)
19398 return ret;
19399 /* master doesn't have any clauses and during gimplification
19400 isn't represented by a gimplification omp context, so for
19401 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
19402 so that
19403 #pragma omp parallel master
19404 #pragma omp taskloop simd lastprivate (x)
19405 isn't confused with
19406 #pragma omp parallel master taskloop simd lastprivate (x) */
19407 if (OMP_MASTER_COMBINED (ret))
19408 OMP_PARALLEL_COMBINED (stmt) = 1;
19409 return stmt;
19411 else if (strcmp (p, "loop") == 0)
19413 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19414 if (cclauses == NULL)
19415 cclauses = cclauses_buf;
19417 c_parser_consume_token (parser);
19418 if (!flag_openmp) /* flag_openmp_simd */
19419 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19420 if_p);
19421 block = c_begin_omp_parallel ();
19422 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19423 if_p);
19424 stmt
19425 = c_finish_omp_parallel (loc,
19426 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19427 block);
19428 if (ret == NULL_TREE)
19429 return ret;
19430 OMP_PARALLEL_COMBINED (stmt) = 1;
19431 return stmt;
19433 else if (!flag_openmp) /* flag_openmp_simd */
19435 c_parser_skip_to_pragma_eol (parser, false);
19436 return NULL_TREE;
19438 else if (cclauses == NULL && strcmp (p, "sections") == 0)
19440 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19441 cclauses = cclauses_buf;
19443 c_parser_consume_token (parser);
19444 block = c_begin_omp_parallel ();
19445 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
19446 stmt = c_finish_omp_parallel (loc,
19447 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19448 block);
19449 OMP_PARALLEL_COMBINED (stmt) = 1;
19450 return stmt;
19453 else if (!flag_openmp) /* flag_openmp_simd */
19455 c_parser_skip_to_pragma_eol (parser, false);
19456 return NULL_TREE;
19459 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19460 if (cclauses)
19462 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
19463 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
19466 block = c_begin_omp_parallel ();
19467 c_parser_statement (parser, if_p);
19468 stmt = c_finish_omp_parallel (loc, clauses, block);
19470 return stmt;
19473 /* OpenMP 2.5:
19474 # pragma omp single single-clause[optseq] new-line
19475 structured-block
19477 LOC is the location of the #pragma.
19480 #define OMP_SINGLE_CLAUSE_MASK \
19481 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
19484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19487 static tree
19488 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
19490 tree stmt = make_node (OMP_SINGLE);
19491 SET_EXPR_LOCATION (stmt, loc);
19492 TREE_TYPE (stmt) = void_type_node;
19494 OMP_SINGLE_CLAUSES (stmt)
19495 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
19496 "#pragma omp single");
19497 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
19499 return add_stmt (stmt);
19502 /* OpenMP 5.1:
19503 # pragma omp scope scope-clause[optseq] new-line
19504 structured-block
19506 LOC is the location of the #pragma.
19509 #define OMP_SCOPE_CLAUSE_MASK \
19510 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19514 static tree
19515 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
19517 tree stmt = make_node (OMP_SCOPE);
19518 SET_EXPR_LOCATION (stmt, loc);
19519 TREE_TYPE (stmt) = void_type_node;
19521 OMP_SCOPE_CLAUSES (stmt)
19522 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
19523 "#pragma omp scope");
19524 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
19526 return add_stmt (stmt);
19529 /* OpenMP 3.0:
19530 # pragma omp task task-clause[optseq] new-line
19532 LOC is the location of the #pragma.
19535 #define OMP_TASK_CLAUSE_MASK \
19536 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
19538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
19539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
19543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
19544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
19546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
19548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
19549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
19551 static tree
19552 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
19554 tree clauses, block;
19556 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
19557 "#pragma omp task");
19559 block = c_begin_omp_task ();
19560 c_parser_statement (parser, if_p);
19561 return c_finish_omp_task (loc, clauses, block);
19564 /* OpenMP 3.0:
19565 # pragma omp taskwait new-line
19567 OpenMP 5.0:
19568 # pragma omp taskwait taskwait-clause[optseq] new-line
19571 #define OMP_TASKWAIT_CLAUSE_MASK \
19572 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19574 static void
19575 c_parser_omp_taskwait (c_parser *parser)
19577 location_t loc = c_parser_peek_token (parser)->location;
19578 c_parser_consume_pragma (parser);
19580 tree clauses
19581 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
19582 "#pragma omp taskwait");
19584 if (clauses)
19586 tree stmt = make_node (OMP_TASK);
19587 TREE_TYPE (stmt) = void_node;
19588 OMP_TASK_CLAUSES (stmt) = clauses;
19589 OMP_TASK_BODY (stmt) = NULL_TREE;
19590 SET_EXPR_LOCATION (stmt, loc);
19591 add_stmt (stmt);
19593 else
19594 c_finish_omp_taskwait (loc);
19597 /* OpenMP 3.1:
19598 # pragma omp taskyield new-line
19601 static void
19602 c_parser_omp_taskyield (c_parser *parser)
19604 location_t loc = c_parser_peek_token (parser)->location;
19605 c_parser_consume_pragma (parser);
19606 c_parser_skip_to_pragma_eol (parser);
19608 c_finish_omp_taskyield (loc);
19611 /* OpenMP 4.0:
19612 # pragma omp taskgroup new-line
19614 OpenMP 5.0:
19615 # pragma omp taskgroup taskgroup-clause[optseq] new-line
19618 #define OMP_TASKGROUP_CLAUSE_MASK \
19619 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19620 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19622 static tree
19623 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
19625 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
19626 "#pragma omp taskgroup");
19628 tree body = c_parser_omp_structured_block (parser, if_p);
19629 return c_finish_omp_taskgroup (loc, body, clauses);
19632 /* OpenMP 4.0:
19633 # pragma omp cancel cancel-clause[optseq] new-line
19635 LOC is the location of the #pragma.
19638 #define OMP_CANCEL_CLAUSE_MASK \
19639 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
19643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
19645 static void
19646 c_parser_omp_cancel (c_parser *parser)
19648 location_t loc = c_parser_peek_token (parser)->location;
19650 c_parser_consume_pragma (parser);
19651 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
19652 "#pragma omp cancel");
19654 c_finish_omp_cancel (loc, clauses);
19657 /* OpenMP 4.0:
19658 # pragma omp cancellation point cancelpt-clause[optseq] new-line
19660 LOC is the location of the #pragma.
19663 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
19664 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19665 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19666 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
19669 static bool
19670 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
19672 location_t loc = c_parser_peek_token (parser)->location;
19673 tree clauses;
19674 bool point_seen = false;
19676 c_parser_consume_pragma (parser);
19677 if (c_parser_next_token_is (parser, CPP_NAME))
19679 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19680 if (strcmp (p, "point") == 0)
19682 c_parser_consume_token (parser);
19683 point_seen = true;
19686 if (!point_seen)
19688 c_parser_error (parser, "expected %<point%>");
19689 c_parser_skip_to_pragma_eol (parser);
19690 return false;
19693 if (context != pragma_compound)
19695 if (context == pragma_stmt)
19696 error_at (loc,
19697 "%<#pragma %s%> may only be used in compound statements",
19698 "omp cancellation point");
19699 else
19700 c_parser_error (parser, "expected declaration specifiers");
19701 c_parser_skip_to_pragma_eol (parser, false);
19702 return true;
19705 clauses
19706 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
19707 "#pragma omp cancellation point");
19709 c_finish_omp_cancellation_point (loc, clauses);
19710 return true;
19713 /* OpenMP 4.0:
19714 #pragma omp distribute distribute-clause[optseq] new-line
19715 for-loop */
19717 #define OMP_DISTRIBUTE_CLAUSE_MASK \
19718 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
19725 static tree
19726 c_parser_omp_distribute (location_t loc, c_parser *parser,
19727 char *p_name, omp_clause_mask mask, tree *cclauses,
19728 bool *if_p)
19730 tree clauses, block, ret;
19732 strcat (p_name, " distribute");
19733 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
19735 if (c_parser_next_token_is (parser, CPP_NAME))
19737 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19738 bool simd = false;
19739 bool parallel = false;
19741 if (strcmp (p, "simd") == 0)
19742 simd = true;
19743 else
19744 parallel = strcmp (p, "parallel") == 0;
19745 if (parallel || simd)
19747 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19748 if (cclauses == NULL)
19749 cclauses = cclauses_buf;
19750 c_parser_consume_token (parser);
19751 if (!flag_openmp) /* flag_openmp_simd */
19753 if (simd)
19754 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19755 if_p);
19756 else
19757 return c_parser_omp_parallel (loc, parser, p_name, mask,
19758 cclauses, if_p);
19760 block = c_begin_compound_stmt (true);
19761 if (simd)
19762 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19763 if_p);
19764 else
19765 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
19766 if_p);
19767 block = c_end_compound_stmt (loc, block, true);
19768 if (ret == NULL)
19769 return ret;
19770 ret = make_node (OMP_DISTRIBUTE);
19771 TREE_TYPE (ret) = void_type_node;
19772 OMP_FOR_BODY (ret) = block;
19773 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19774 SET_EXPR_LOCATION (ret, loc);
19775 add_stmt (ret);
19776 return ret;
19779 if (!flag_openmp) /* flag_openmp_simd */
19781 c_parser_skip_to_pragma_eol (parser, false);
19782 return NULL_TREE;
19785 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19786 if (cclauses)
19788 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
19789 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19792 block = c_begin_compound_stmt (true);
19793 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
19794 if_p);
19795 block = c_end_compound_stmt (loc, block, true);
19796 add_stmt (block);
19798 return ret;
19801 /* OpenMP 4.0:
19802 # pragma omp teams teams-clause[optseq] new-line
19803 structured-block */
19805 #define OMP_TEAMS_CLAUSE_MASK \
19806 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
19811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
19812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
19815 static tree
19816 c_parser_omp_teams (location_t loc, c_parser *parser,
19817 char *p_name, omp_clause_mask mask, tree *cclauses,
19818 bool *if_p)
19820 tree clauses, block, ret;
19822 strcat (p_name, " teams");
19823 mask |= OMP_TEAMS_CLAUSE_MASK;
19825 if (c_parser_next_token_is (parser, CPP_NAME))
19827 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19828 if (strcmp (p, "distribute") == 0)
19830 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19831 if (cclauses == NULL)
19832 cclauses = cclauses_buf;
19834 c_parser_consume_token (parser);
19835 if (!flag_openmp) /* flag_openmp_simd */
19836 return c_parser_omp_distribute (loc, parser, p_name, mask,
19837 cclauses, if_p);
19838 block = c_begin_omp_parallel ();
19839 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
19840 if_p);
19841 block = c_end_compound_stmt (loc, block, true);
19842 if (ret == NULL)
19843 return ret;
19844 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19845 ret = make_node (OMP_TEAMS);
19846 TREE_TYPE (ret) = void_type_node;
19847 OMP_TEAMS_CLAUSES (ret) = clauses;
19848 OMP_TEAMS_BODY (ret) = block;
19849 OMP_TEAMS_COMBINED (ret) = 1;
19850 SET_EXPR_LOCATION (ret, loc);
19851 return add_stmt (ret);
19853 else if (strcmp (p, "loop") == 0)
19855 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19856 if (cclauses == NULL)
19857 cclauses = cclauses_buf;
19859 c_parser_consume_token (parser);
19860 if (!flag_openmp) /* flag_openmp_simd */
19861 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19862 if_p);
19863 block = c_begin_omp_parallel ();
19864 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
19865 block = c_end_compound_stmt (loc, block, true);
19866 if (ret == NULL)
19867 return ret;
19868 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19869 ret = make_node (OMP_TEAMS);
19870 TREE_TYPE (ret) = void_type_node;
19871 OMP_TEAMS_CLAUSES (ret) = clauses;
19872 OMP_TEAMS_BODY (ret) = block;
19873 OMP_TEAMS_COMBINED (ret) = 1;
19874 SET_EXPR_LOCATION (ret, loc);
19875 return add_stmt (ret);
19878 if (!flag_openmp) /* flag_openmp_simd */
19880 c_parser_skip_to_pragma_eol (parser, false);
19881 return NULL_TREE;
19884 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19885 if (cclauses)
19887 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
19888 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19891 tree stmt = make_node (OMP_TEAMS);
19892 TREE_TYPE (stmt) = void_type_node;
19893 OMP_TEAMS_CLAUSES (stmt) = clauses;
19894 block = c_begin_omp_parallel ();
19895 add_stmt (c_parser_omp_structured_block (parser, if_p));
19896 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19897 SET_EXPR_LOCATION (stmt, loc);
19899 return add_stmt (stmt);
19902 /* OpenMP 4.0:
19903 # pragma omp target data target-data-clause[optseq] new-line
19904 structured-block */
19906 #define OMP_TARGET_DATA_CLAUSE_MASK \
19907 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19908 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
19913 static tree
19914 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
19916 tree clauses
19917 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
19918 "#pragma omp target data");
19919 c_omp_adjust_map_clauses (clauses, false);
19920 int map_seen = 0;
19921 for (tree *pc = &clauses; *pc;)
19923 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19924 switch (OMP_CLAUSE_MAP_KIND (*pc))
19926 case GOMP_MAP_TO:
19927 case GOMP_MAP_ALWAYS_TO:
19928 case GOMP_MAP_FROM:
19929 case GOMP_MAP_ALWAYS_FROM:
19930 case GOMP_MAP_TOFROM:
19931 case GOMP_MAP_ALWAYS_TOFROM:
19932 case GOMP_MAP_ALLOC:
19933 map_seen = 3;
19934 break;
19935 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19936 case GOMP_MAP_ALWAYS_POINTER:
19937 case GOMP_MAP_ATTACH_DETACH:
19938 break;
19939 default:
19940 map_seen |= 1;
19941 error_at (OMP_CLAUSE_LOCATION (*pc),
19942 "%<#pragma omp target data%> with map-type other "
19943 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19944 "on %<map%> clause");
19945 *pc = OMP_CLAUSE_CHAIN (*pc);
19946 continue;
19948 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
19949 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
19950 map_seen = 3;
19951 pc = &OMP_CLAUSE_CHAIN (*pc);
19954 if (map_seen != 3)
19956 if (map_seen == 0)
19957 error_at (loc,
19958 "%<#pragma omp target data%> must contain at least "
19959 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19960 "clause");
19961 return NULL_TREE;
19964 tree stmt = make_node (OMP_TARGET_DATA);
19965 TREE_TYPE (stmt) = void_type_node;
19966 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
19967 keep_next_level ();
19968 tree block = c_begin_compound_stmt (true);
19969 add_stmt (c_parser_omp_structured_block (parser, if_p));
19970 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19972 SET_EXPR_LOCATION (stmt, loc);
19973 return add_stmt (stmt);
19976 /* OpenMP 4.0:
19977 # pragma omp target update target-update-clause[optseq] new-line */
19979 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
19980 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
19981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19987 static bool
19988 c_parser_omp_target_update (location_t loc, c_parser *parser,
19989 enum pragma_context context)
19991 if (context == pragma_stmt)
19993 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19994 "omp target update");
19995 c_parser_skip_to_pragma_eol (parser, false);
19996 return true;
19999 tree clauses
20000 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
20001 "#pragma omp target update");
20002 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
20003 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
20005 error_at (loc,
20006 "%<#pragma omp target update%> must contain at least one "
20007 "%<from%> or %<to%> clauses");
20008 return false;
20011 tree stmt = make_node (OMP_TARGET_UPDATE);
20012 TREE_TYPE (stmt) = void_type_node;
20013 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
20014 SET_EXPR_LOCATION (stmt, loc);
20015 add_stmt (stmt);
20016 return false;
20019 /* OpenMP 4.5:
20020 # pragma omp target enter data target-data-clause[optseq] new-line */
20022 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
20023 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20024 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20025 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20026 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20027 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20029 static bool
20030 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
20031 enum pragma_context context)
20033 bool data_seen = false;
20034 if (c_parser_next_token_is (parser, CPP_NAME))
20036 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20037 if (strcmp (p, "data") == 0)
20039 c_parser_consume_token (parser);
20040 data_seen = true;
20043 if (!data_seen)
20045 c_parser_error (parser, "expected %<data%>");
20046 c_parser_skip_to_pragma_eol (parser);
20047 return false;
20050 if (context == pragma_stmt)
20052 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
20053 "omp target enter data");
20054 c_parser_skip_to_pragma_eol (parser, false);
20055 return true;
20058 tree clauses
20059 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
20060 "#pragma omp target enter data");
20061 c_omp_adjust_map_clauses (clauses, false);
20062 int map_seen = 0;
20063 for (tree *pc = &clauses; *pc;)
20065 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20066 switch (OMP_CLAUSE_MAP_KIND (*pc))
20068 case GOMP_MAP_TO:
20069 case GOMP_MAP_ALWAYS_TO:
20070 case GOMP_MAP_ALLOC:
20071 map_seen = 3;
20072 break;
20073 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20074 case GOMP_MAP_ALWAYS_POINTER:
20075 case GOMP_MAP_ATTACH_DETACH:
20076 break;
20077 default:
20078 map_seen |= 1;
20079 error_at (OMP_CLAUSE_LOCATION (*pc),
20080 "%<#pragma omp target enter data%> with map-type other "
20081 "than %<to%> or %<alloc%> on %<map%> clause");
20082 *pc = OMP_CLAUSE_CHAIN (*pc);
20083 continue;
20085 pc = &OMP_CLAUSE_CHAIN (*pc);
20088 if (map_seen != 3)
20090 if (map_seen == 0)
20091 error_at (loc,
20092 "%<#pragma omp target enter data%> must contain at least "
20093 "one %<map%> clause");
20094 return true;
20097 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
20098 TREE_TYPE (stmt) = void_type_node;
20099 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
20100 SET_EXPR_LOCATION (stmt, loc);
20101 add_stmt (stmt);
20102 return true;
20105 /* OpenMP 4.5:
20106 # pragma omp target exit data target-data-clause[optseq] new-line */
20108 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
20109 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20110 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20111 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20112 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20113 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20115 static bool
20116 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
20117 enum pragma_context context)
20119 bool data_seen = false;
20120 if (c_parser_next_token_is (parser, CPP_NAME))
20122 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20123 if (strcmp (p, "data") == 0)
20125 c_parser_consume_token (parser);
20126 data_seen = true;
20129 if (!data_seen)
20131 c_parser_error (parser, "expected %<data%>");
20132 c_parser_skip_to_pragma_eol (parser);
20133 return false;
20136 if (context == pragma_stmt)
20138 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
20139 "omp target exit data");
20140 c_parser_skip_to_pragma_eol (parser, false);
20141 return true;
20144 tree clauses
20145 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
20146 "#pragma omp target exit data");
20147 c_omp_adjust_map_clauses (clauses, false);
20148 int map_seen = 0;
20149 for (tree *pc = &clauses; *pc;)
20151 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20152 switch (OMP_CLAUSE_MAP_KIND (*pc))
20154 case GOMP_MAP_FROM:
20155 case GOMP_MAP_ALWAYS_FROM:
20156 case GOMP_MAP_RELEASE:
20157 case GOMP_MAP_DELETE:
20158 map_seen = 3;
20159 break;
20160 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20161 case GOMP_MAP_ALWAYS_POINTER:
20162 case GOMP_MAP_ATTACH_DETACH:
20163 break;
20164 default:
20165 map_seen |= 1;
20166 error_at (OMP_CLAUSE_LOCATION (*pc),
20167 "%<#pragma omp target exit data%> with map-type other "
20168 "than %<from%>, %<release%> or %<delete%> on %<map%>"
20169 " clause");
20170 *pc = OMP_CLAUSE_CHAIN (*pc);
20171 continue;
20173 pc = &OMP_CLAUSE_CHAIN (*pc);
20176 if (map_seen != 3)
20178 if (map_seen == 0)
20179 error_at (loc,
20180 "%<#pragma omp target exit data%> must contain at least one "
20181 "%<map%> clause");
20182 return true;
20185 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
20186 TREE_TYPE (stmt) = void_type_node;
20187 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
20188 SET_EXPR_LOCATION (stmt, loc);
20189 add_stmt (stmt);
20190 return true;
20193 /* OpenMP 4.0:
20194 # pragma omp target target-clause[optseq] new-line
20195 structured-block */
20197 #define OMP_TARGET_CLAUSE_MASK \
20198 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20199 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20201 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20202 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
20203 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20204 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20205 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20206 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
20207 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
20210 static bool
20211 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
20213 location_t loc = c_parser_peek_token (parser)->location;
20214 c_parser_consume_pragma (parser);
20215 tree *pc = NULL, stmt, block;
20217 if (context != pragma_stmt && context != pragma_compound)
20219 c_parser_error (parser, "expected declaration specifiers");
20220 c_parser_skip_to_pragma_eol (parser);
20221 return false;
20224 if (flag_openmp)
20225 omp_requires_mask
20226 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
20228 if (c_parser_next_token_is (parser, CPP_NAME))
20230 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20231 enum tree_code ccode = ERROR_MARK;
20233 if (strcmp (p, "teams") == 0)
20234 ccode = OMP_TEAMS;
20235 else if (strcmp (p, "parallel") == 0)
20236 ccode = OMP_PARALLEL;
20237 else if (strcmp (p, "simd") == 0)
20238 ccode = OMP_SIMD;
20239 if (ccode != ERROR_MARK)
20241 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
20242 char p_name[sizeof ("#pragma omp target teams distribute "
20243 "parallel for simd")];
20245 c_parser_consume_token (parser);
20246 strcpy (p_name, "#pragma omp target");
20247 if (!flag_openmp) /* flag_openmp_simd */
20249 tree stmt;
20250 switch (ccode)
20252 case OMP_TEAMS:
20253 stmt = c_parser_omp_teams (loc, parser, p_name,
20254 OMP_TARGET_CLAUSE_MASK,
20255 cclauses, if_p);
20256 break;
20257 case OMP_PARALLEL:
20258 stmt = c_parser_omp_parallel (loc, parser, p_name,
20259 OMP_TARGET_CLAUSE_MASK,
20260 cclauses, if_p);
20261 break;
20262 case OMP_SIMD:
20263 stmt = c_parser_omp_simd (loc, parser, p_name,
20264 OMP_TARGET_CLAUSE_MASK,
20265 cclauses, if_p);
20266 break;
20267 default:
20268 gcc_unreachable ();
20270 return stmt != NULL_TREE;
20272 keep_next_level ();
20273 tree block = c_begin_compound_stmt (true), ret;
20274 switch (ccode)
20276 case OMP_TEAMS:
20277 ret = c_parser_omp_teams (loc, parser, p_name,
20278 OMP_TARGET_CLAUSE_MASK, cclauses,
20279 if_p);
20280 break;
20281 case OMP_PARALLEL:
20282 ret = c_parser_omp_parallel (loc, parser, p_name,
20283 OMP_TARGET_CLAUSE_MASK, cclauses,
20284 if_p);
20285 break;
20286 case OMP_SIMD:
20287 ret = c_parser_omp_simd (loc, parser, p_name,
20288 OMP_TARGET_CLAUSE_MASK, cclauses,
20289 if_p);
20290 break;
20291 default:
20292 gcc_unreachable ();
20294 block = c_end_compound_stmt (loc, block, true);
20295 if (ret == NULL_TREE)
20296 return false;
20297 if (ccode == OMP_TEAMS)
20299 /* For combined target teams, ensure the num_teams and
20300 thread_limit clause expressions are evaluated on the host,
20301 before entering the target construct. */
20302 tree c;
20303 for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20304 c; c = OMP_CLAUSE_CHAIN (c))
20305 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
20306 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
20307 && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
20309 tree expr = OMP_CLAUSE_OPERAND (c, 0);
20310 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
20311 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
20312 expr, NULL_TREE, NULL_TREE);
20313 add_stmt (expr);
20314 OMP_CLAUSE_OPERAND (c, 0) = expr;
20315 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
20316 OMP_CLAUSE_FIRSTPRIVATE);
20317 OMP_CLAUSE_DECL (tc) = tmp;
20318 OMP_CLAUSE_CHAIN (tc)
20319 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
20320 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
20323 tree stmt = make_node (OMP_TARGET);
20324 TREE_TYPE (stmt) = void_type_node;
20325 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
20326 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
20327 OMP_TARGET_BODY (stmt) = block;
20328 OMP_TARGET_COMBINED (stmt) = 1;
20329 SET_EXPR_LOCATION (stmt, loc);
20330 add_stmt (stmt);
20331 pc = &OMP_TARGET_CLAUSES (stmt);
20332 goto check_clauses;
20334 else if (!flag_openmp) /* flag_openmp_simd */
20336 c_parser_skip_to_pragma_eol (parser, false);
20337 return false;
20339 else if (strcmp (p, "data") == 0)
20341 c_parser_consume_token (parser);
20342 c_parser_omp_target_data (loc, parser, if_p);
20343 return true;
20345 else if (strcmp (p, "enter") == 0)
20347 c_parser_consume_token (parser);
20348 return c_parser_omp_target_enter_data (loc, parser, context);
20350 else if (strcmp (p, "exit") == 0)
20352 c_parser_consume_token (parser);
20353 return c_parser_omp_target_exit_data (loc, parser, context);
20355 else if (strcmp (p, "update") == 0)
20357 c_parser_consume_token (parser);
20358 return c_parser_omp_target_update (loc, parser, context);
20361 if (!flag_openmp) /* flag_openmp_simd */
20363 c_parser_skip_to_pragma_eol (parser, false);
20364 return false;
20367 stmt = make_node (OMP_TARGET);
20368 TREE_TYPE (stmt) = void_type_node;
20370 OMP_TARGET_CLAUSES (stmt)
20371 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
20372 "#pragma omp target", false);
20373 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
20374 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
20376 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
20377 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
20378 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
20379 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
20380 OMP_CLAUSE_CHAIN (c) = nc;
20382 OMP_TARGET_CLAUSES (stmt)
20383 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
20384 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
20386 pc = &OMP_TARGET_CLAUSES (stmt);
20387 keep_next_level ();
20388 block = c_begin_compound_stmt (true);
20389 add_stmt (c_parser_omp_structured_block (parser, if_p));
20390 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20392 SET_EXPR_LOCATION (stmt, loc);
20393 add_stmt (stmt);
20395 check_clauses:
20396 while (*pc)
20398 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20399 switch (OMP_CLAUSE_MAP_KIND (*pc))
20401 case GOMP_MAP_TO:
20402 case GOMP_MAP_ALWAYS_TO:
20403 case GOMP_MAP_FROM:
20404 case GOMP_MAP_ALWAYS_FROM:
20405 case GOMP_MAP_TOFROM:
20406 case GOMP_MAP_ALWAYS_TOFROM:
20407 case GOMP_MAP_ALLOC:
20408 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20409 case GOMP_MAP_ALWAYS_POINTER:
20410 case GOMP_MAP_ATTACH_DETACH:
20411 break;
20412 default:
20413 error_at (OMP_CLAUSE_LOCATION (*pc),
20414 "%<#pragma omp target%> with map-type other "
20415 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20416 "on %<map%> clause");
20417 *pc = OMP_CLAUSE_CHAIN (*pc);
20418 continue;
20420 pc = &OMP_CLAUSE_CHAIN (*pc);
20422 cfun->has_omp_target = true;
20423 return true;
20426 /* OpenMP 4.0:
20427 # pragma omp declare simd declare-simd-clauses[optseq] new-line
20429 OpenMP 5.0:
20430 # pragma omp declare variant (identifier) match(context-selector) new-line
20433 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
20434 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
20435 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20436 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
20437 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
20438 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
20439 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
20441 static void
20442 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
20444 c_token *token = c_parser_peek_token (parser);
20445 gcc_assert (token->type == CPP_NAME);
20446 tree kind = token->value;
20447 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
20448 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
20450 auto_vec<c_token> clauses;
20451 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20453 c_token *token = c_parser_peek_token (parser);
20454 if (token->type == CPP_EOF)
20456 c_parser_skip_to_pragma_eol (parser);
20457 return;
20459 clauses.safe_push (*token);
20460 c_parser_consume_token (parser);
20462 clauses.safe_push (*c_parser_peek_token (parser));
20463 c_parser_skip_to_pragma_eol (parser);
20465 while (c_parser_next_token_is (parser, CPP_PRAGMA))
20467 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
20468 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
20469 || c_parser_peek_2nd_token (parser)->value != kind)
20471 error ("%<#pragma omp declare %s%> must be followed by "
20472 "function declaration or definition or another "
20473 "%<#pragma omp declare %s%>",
20474 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
20475 return;
20477 c_parser_consume_pragma (parser);
20478 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20480 c_token *token = c_parser_peek_token (parser);
20481 if (token->type == CPP_EOF)
20483 c_parser_skip_to_pragma_eol (parser);
20484 return;
20486 clauses.safe_push (*token);
20487 c_parser_consume_token (parser);
20489 clauses.safe_push (*c_parser_peek_token (parser));
20490 c_parser_skip_to_pragma_eol (parser);
20493 /* Make sure nothing tries to read past the end of the tokens. */
20494 c_token eof_token;
20495 memset (&eof_token, 0, sizeof (eof_token));
20496 eof_token.type = CPP_EOF;
20497 clauses.safe_push (eof_token);
20498 clauses.safe_push (eof_token);
20500 switch (context)
20502 case pragma_external:
20503 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20504 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20506 int ext = disable_extension_diagnostics ();
20508 c_parser_consume_token (parser);
20509 while (c_parser_next_token_is (parser, CPP_KEYWORD)
20510 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20511 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20512 NULL, &clauses);
20513 restore_extension_diagnostics (ext);
20515 else
20516 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20517 NULL, &clauses);
20518 break;
20519 case pragma_struct:
20520 case pragma_param:
20521 case pragma_stmt:
20522 error ("%<#pragma omp declare %s%> must be followed by "
20523 "function declaration or definition",
20524 IDENTIFIER_POINTER (kind));
20525 break;
20526 case pragma_compound:
20527 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20528 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20530 int ext = disable_extension_diagnostics ();
20532 c_parser_consume_token (parser);
20533 while (c_parser_next_token_is (parser, CPP_KEYWORD)
20534 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20535 if (c_parser_next_tokens_start_declaration (parser))
20537 c_parser_declaration_or_fndef (parser, true, true, true, true,
20538 true, NULL, &clauses);
20539 restore_extension_diagnostics (ext);
20540 break;
20542 restore_extension_diagnostics (ext);
20544 else if (c_parser_next_tokens_start_declaration (parser))
20546 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
20547 NULL, &clauses);
20548 break;
20550 error ("%<#pragma omp declare %s%> must be followed by "
20551 "function declaration or definition",
20552 IDENTIFIER_POINTER (kind));
20553 break;
20554 default:
20555 gcc_unreachable ();
20559 static const char *const omp_construct_selectors[] = {
20560 "simd", "target", "teams", "parallel", "for", NULL };
20561 static const char *const omp_device_selectors[] = {
20562 "kind", "isa", "arch", NULL };
20563 static const char *const omp_implementation_selectors[] = {
20564 "vendor", "extension", "atomic_default_mem_order", "unified_address",
20565 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
20566 static const char *const omp_user_selectors[] = {
20567 "condition", NULL };
20569 /* OpenMP 5.0:
20571 trait-selector:
20572 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
20574 trait-score:
20575 score(score-expression) */
20577 static tree
20578 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
20580 tree ret = NULL_TREE;
20583 tree selector;
20584 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20585 || c_parser_next_token_is (parser, CPP_NAME))
20586 selector = c_parser_peek_token (parser)->value;
20587 else
20589 c_parser_error (parser, "expected trait selector name");
20590 return error_mark_node;
20593 tree properties = NULL_TREE;
20594 const char *const *selectors = NULL;
20595 bool allow_score = true;
20596 bool allow_user = false;
20597 int property_limit = 0;
20598 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
20599 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
20600 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
20601 switch (IDENTIFIER_POINTER (set)[0])
20603 case 'c': /* construct */
20604 selectors = omp_construct_selectors;
20605 allow_score = false;
20606 property_limit = 1;
20607 property_kind = CTX_PROPERTY_SIMD;
20608 break;
20609 case 'd': /* device */
20610 selectors = omp_device_selectors;
20611 allow_score = false;
20612 allow_user = true;
20613 property_limit = 3;
20614 property_kind = CTX_PROPERTY_NAME_LIST;
20615 break;
20616 case 'i': /* implementation */
20617 selectors = omp_implementation_selectors;
20618 allow_user = true;
20619 property_limit = 3;
20620 property_kind = CTX_PROPERTY_NAME_LIST;
20621 break;
20622 case 'u': /* user */
20623 selectors = omp_user_selectors;
20624 property_limit = 1;
20625 property_kind = CTX_PROPERTY_EXPR;
20626 break;
20627 default:
20628 gcc_unreachable ();
20630 for (int i = 0; ; i++)
20632 if (selectors[i] == NULL)
20634 if (allow_user)
20636 property_kind = CTX_PROPERTY_USER;
20637 break;
20639 else
20641 error_at (c_parser_peek_token (parser)->location,
20642 "selector %qs not allowed for context selector "
20643 "set %qs", IDENTIFIER_POINTER (selector),
20644 IDENTIFIER_POINTER (set));
20645 c_parser_consume_token (parser);
20646 return error_mark_node;
20649 if (i == property_limit)
20650 property_kind = CTX_PROPERTY_NONE;
20651 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
20652 break;
20654 if (property_kind == CTX_PROPERTY_NAME_LIST
20655 && IDENTIFIER_POINTER (set)[0] == 'i'
20656 && strcmp (IDENTIFIER_POINTER (selector),
20657 "atomic_default_mem_order") == 0)
20658 property_kind = CTX_PROPERTY_ID;
20660 c_parser_consume_token (parser);
20662 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20664 if (property_kind == CTX_PROPERTY_NONE)
20666 error_at (c_parser_peek_token (parser)->location,
20667 "selector %qs does not accept any properties",
20668 IDENTIFIER_POINTER (selector));
20669 return error_mark_node;
20672 matching_parens parens;
20673 parens.require_open (parser);
20675 c_token *token = c_parser_peek_token (parser);
20676 if (allow_score
20677 && c_parser_next_token_is (parser, CPP_NAME)
20678 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
20679 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
20681 c_parser_consume_token (parser);
20683 matching_parens parens2;
20684 parens2.require_open (parser);
20685 tree score = c_parser_expr_no_commas (parser, NULL).value;
20686 parens2.skip_until_found_close (parser);
20687 c_parser_require (parser, CPP_COLON, "expected %<:%>");
20688 if (score != error_mark_node)
20690 mark_exp_read (score);
20691 score = c_fully_fold (score, false, NULL);
20692 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
20693 || TREE_CODE (score) != INTEGER_CST)
20694 error_at (token->location, "score argument must be "
20695 "constant integer expression");
20696 else if (tree_int_cst_sgn (score) < 0)
20697 error_at (token->location, "score argument must be "
20698 "non-negative");
20699 else
20700 properties = tree_cons (get_identifier (" score"),
20701 score, properties);
20703 token = c_parser_peek_token (parser);
20706 switch (property_kind)
20708 tree t;
20709 case CTX_PROPERTY_USER:
20712 t = c_parser_expr_no_commas (parser, NULL).value;
20713 if (TREE_CODE (t) == STRING_CST)
20714 properties = tree_cons (NULL_TREE, t, properties);
20715 else if (t != error_mark_node)
20717 mark_exp_read (t);
20718 t = c_fully_fold (t, false, NULL);
20719 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20720 || !tree_fits_shwi_p (t))
20721 error_at (token->location, "property must be "
20722 "constant integer expression or string "
20723 "literal");
20724 else
20725 properties = tree_cons (NULL_TREE, t, properties);
20727 else
20728 return error_mark_node;
20730 if (c_parser_next_token_is (parser, CPP_COMMA))
20731 c_parser_consume_token (parser);
20732 else
20733 break;
20735 while (1);
20736 break;
20737 case CTX_PROPERTY_ID:
20738 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20739 || c_parser_next_token_is (parser, CPP_NAME))
20741 tree prop = c_parser_peek_token (parser)->value;
20742 c_parser_consume_token (parser);
20743 properties = tree_cons (prop, NULL_TREE, properties);
20745 else
20747 c_parser_error (parser, "expected identifier");
20748 return error_mark_node;
20750 break;
20751 case CTX_PROPERTY_NAME_LIST:
20754 tree prop = NULL_TREE, value = NULL_TREE;
20755 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20756 || c_parser_next_token_is (parser, CPP_NAME))
20758 prop = c_parser_peek_token (parser)->value;
20759 c_parser_consume_token (parser);
20761 else if (c_parser_next_token_is (parser, CPP_STRING))
20762 value = c_parser_string_literal (parser, false,
20763 false).value;
20764 else
20766 c_parser_error (parser, "expected identifier or "
20767 "string literal");
20768 return error_mark_node;
20771 properties = tree_cons (prop, value, properties);
20773 if (c_parser_next_token_is (parser, CPP_COMMA))
20774 c_parser_consume_token (parser);
20775 else
20776 break;
20778 while (1);
20779 break;
20780 case CTX_PROPERTY_EXPR:
20781 t = c_parser_expr_no_commas (parser, NULL).value;
20782 if (t != error_mark_node)
20784 mark_exp_read (t);
20785 t = c_fully_fold (t, false, NULL);
20786 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20787 || !tree_fits_shwi_p (t))
20788 error_at (token->location, "property must be "
20789 "constant integer expression");
20790 else
20791 properties = tree_cons (NULL_TREE, t, properties);
20793 else
20794 return error_mark_node;
20795 break;
20796 case CTX_PROPERTY_SIMD:
20797 if (parms == NULL_TREE)
20799 error_at (token->location, "properties for %<simd%> "
20800 "selector may not be specified in "
20801 "%<metadirective%>");
20802 return error_mark_node;
20804 tree c;
20805 c = c_parser_omp_all_clauses (parser,
20806 OMP_DECLARE_SIMD_CLAUSE_MASK,
20807 "simd", true, 2);
20808 c = c_omp_declare_simd_clauses_to_numbers (parms
20809 == error_mark_node
20810 ? NULL_TREE : parms,
20812 properties = c;
20813 break;
20814 default:
20815 gcc_unreachable ();
20818 parens.skip_until_found_close (parser);
20819 properties = nreverse (properties);
20821 else if (property_kind == CTX_PROPERTY_NAME_LIST
20822 || property_kind == CTX_PROPERTY_ID
20823 || property_kind == CTX_PROPERTY_EXPR)
20825 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
20826 return error_mark_node;
20829 ret = tree_cons (selector, properties, ret);
20831 if (c_parser_next_token_is (parser, CPP_COMMA))
20832 c_parser_consume_token (parser);
20833 else
20834 break;
20836 while (1);
20838 return nreverse (ret);
20841 /* OpenMP 5.0:
20843 trait-set-selector[,trait-set-selector[,...]]
20845 trait-set-selector:
20846 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20848 trait-set-selector-name:
20849 constructor
20850 device
20851 implementation
20852 user */
20854 static tree
20855 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
20857 tree ret = NULL_TREE;
20860 const char *setp = "";
20861 if (c_parser_next_token_is (parser, CPP_NAME))
20862 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20863 switch (setp[0])
20865 case 'c':
20866 if (strcmp (setp, "construct") == 0)
20867 setp = NULL;
20868 break;
20869 case 'd':
20870 if (strcmp (setp, "device") == 0)
20871 setp = NULL;
20872 break;
20873 case 'i':
20874 if (strcmp (setp, "implementation") == 0)
20875 setp = NULL;
20876 break;
20877 case 'u':
20878 if (strcmp (setp, "user") == 0)
20879 setp = NULL;
20880 break;
20881 default:
20882 break;
20884 if (setp)
20886 c_parser_error (parser, "expected %<construct%>, %<device%>, "
20887 "%<implementation%> or %<user%>");
20888 return error_mark_node;
20891 tree set = c_parser_peek_token (parser)->value;
20892 c_parser_consume_token (parser);
20894 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
20895 return error_mark_node;
20897 matching_braces braces;
20898 if (!braces.require_open (parser))
20899 return error_mark_node;
20901 tree selectors = c_parser_omp_context_selector (parser, set, parms);
20902 if (selectors == error_mark_node)
20903 ret = error_mark_node;
20904 else if (ret != error_mark_node)
20905 ret = tree_cons (set, selectors, ret);
20907 braces.skip_until_found_close (parser);
20909 if (c_parser_next_token_is (parser, CPP_COMMA))
20910 c_parser_consume_token (parser);
20911 else
20912 break;
20914 while (1);
20916 if (ret == error_mark_node)
20917 return ret;
20918 return nreverse (ret);
20921 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20922 that into "omp declare variant base" attribute. */
20924 static void
20925 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
20927 matching_parens parens;
20928 if (!parens.require_open (parser))
20930 fail:
20931 c_parser_skip_to_pragma_eol (parser, false);
20932 return;
20935 if (c_parser_next_token_is_not (parser, CPP_NAME)
20936 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20938 c_parser_error (parser, "expected identifier");
20939 goto fail;
20942 c_token *token = c_parser_peek_token (parser);
20943 tree variant = lookup_name (token->value);
20945 if (variant == NULL_TREE)
20947 undeclared_variable (token->location, token->value);
20948 variant = error_mark_node;
20951 c_parser_consume_token (parser);
20953 parens.require_close (parser);
20955 const char *clause = "";
20956 location_t match_loc = c_parser_peek_token (parser)->location;
20957 if (c_parser_next_token_is (parser, CPP_NAME))
20958 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20959 if (strcmp (clause, "match"))
20961 c_parser_error (parser, "expected %<match%>");
20962 goto fail;
20965 c_parser_consume_token (parser);
20967 if (!parens.require_open (parser))
20968 goto fail;
20970 if (parms == NULL_TREE)
20971 parms = error_mark_node;
20973 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
20974 if (ctx == error_mark_node)
20975 goto fail;
20976 ctx = c_omp_check_context_selector (match_loc, ctx);
20977 if (ctx != error_mark_node && variant != error_mark_node)
20979 if (TREE_CODE (variant) != FUNCTION_DECL)
20981 error_at (token->location, "variant %qD is not a function", variant);
20982 variant = error_mark_node;
20984 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
20985 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
20987 error_at (token->location, "variant %qD and base %qD have "
20988 "incompatible types", variant, fndecl);
20989 variant = error_mark_node;
20991 else if (fndecl_built_in_p (variant)
20992 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20993 "__builtin_", strlen ("__builtin_")) == 0
20994 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20995 "__sync_", strlen ("__sync_")) == 0
20996 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20997 "__atomic_", strlen ("__atomic_")) == 0))
20999 error_at (token->location, "variant %qD is a built-in", variant);
21000 variant = error_mark_node;
21002 if (variant != error_mark_node)
21004 C_DECL_USED (variant) = 1;
21005 tree construct = omp_get_context_selector (ctx, "construct", NULL);
21006 c_omp_mark_declare_variant (match_loc, variant, construct);
21007 if (omp_context_selector_matches (ctx))
21009 tree attr
21010 = tree_cons (get_identifier ("omp declare variant base"),
21011 build_tree_list (variant, ctx),
21012 DECL_ATTRIBUTES (fndecl));
21013 DECL_ATTRIBUTES (fndecl) = attr;
21018 parens.require_close (parser);
21019 c_parser_skip_to_pragma_eol (parser);
21022 /* Finalize #pragma omp declare simd or #pragma omp declare variant
21023 clauses after FNDECL has been parsed, and put that into "omp declare simd"
21024 or "omp declare variant base" attribute. */
21026 static void
21027 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
21028 vec<c_token> *pclauses)
21030 vec<c_token> &clauses = *pclauses;
21032 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
21033 indicates error has been reported and CPP_PRAGMA that
21034 c_finish_omp_declare_simd has already processed the tokens. */
21035 if (clauses.exists () && clauses[0].type == CPP_EOF)
21036 return;
21037 const char *kind = "simd";
21038 if (clauses.exists ()
21039 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
21040 kind = IDENTIFIER_POINTER (clauses[0].value);
21041 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
21042 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
21044 error ("%<#pragma omp declare %s%> not immediately followed by "
21045 "a function declaration or definition", kind);
21046 clauses[0].type = CPP_EOF;
21047 return;
21049 if (clauses.exists () && clauses[0].type != CPP_NAME)
21051 error_at (DECL_SOURCE_LOCATION (fndecl),
21052 "%<#pragma omp declare %s%> not immediately followed by "
21053 "a single function declaration or definition", kind);
21054 clauses[0].type = CPP_EOF;
21055 return;
21058 if (parms == NULL_TREE)
21059 parms = DECL_ARGUMENTS (fndecl);
21061 unsigned int tokens_avail = parser->tokens_avail;
21062 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
21064 parser->tokens = clauses.address ();
21065 parser->tokens_avail = clauses.length ();
21067 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
21068 while (parser->tokens_avail > 3)
21070 c_token *token = c_parser_peek_token (parser);
21071 gcc_assert (token->type == CPP_NAME
21072 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
21073 c_parser_consume_token (parser);
21074 parser->in_pragma = true;
21076 if (strcmp (kind, "simd") == 0)
21078 tree c;
21079 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
21080 "#pragma omp declare simd");
21081 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
21082 if (c != NULL_TREE)
21083 c = tree_cons (NULL_TREE, c, NULL_TREE);
21084 c = build_tree_list (get_identifier ("omp declare simd"), c);
21085 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
21086 DECL_ATTRIBUTES (fndecl) = c;
21088 else
21090 gcc_assert (strcmp (kind, "variant") == 0);
21091 c_finish_omp_declare_variant (parser, fndecl, parms);
21095 parser->tokens = &parser->tokens_buf[0];
21096 parser->tokens_avail = tokens_avail;
21097 if (clauses.exists ())
21098 clauses[0].type = CPP_PRAGMA;
21102 /* OpenMP 4.0:
21103 # pragma omp declare target new-line
21104 declarations and definitions
21105 # pragma omp end declare target new-line
21107 OpenMP 4.5:
21108 # pragma omp declare target ( extended-list ) new-line
21110 # pragma omp declare target declare-target-clauses[seq] new-line */
21112 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
21113 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21114 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
21115 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
21117 static void
21118 c_parser_omp_declare_target (c_parser *parser)
21120 tree clauses = NULL_TREE;
21121 int device_type = 0;
21122 bool only_device_type = true;
21123 if (c_parser_next_token_is (parser, CPP_NAME))
21124 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
21125 "#pragma omp declare target");
21126 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21128 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
21129 clauses);
21130 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
21131 c_parser_skip_to_pragma_eol (parser);
21133 else
21135 c_parser_skip_to_pragma_eol (parser);
21136 current_omp_declare_target_attribute++;
21137 return;
21139 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
21140 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
21141 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
21142 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
21144 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
21145 continue;
21146 tree t = OMP_CLAUSE_DECL (c), id;
21147 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
21148 tree at2 = lookup_attribute ("omp declare target link",
21149 DECL_ATTRIBUTES (t));
21150 only_device_type = false;
21151 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
21153 id = get_identifier ("omp declare target link");
21154 std::swap (at1, at2);
21156 else
21157 id = get_identifier ("omp declare target");
21158 if (at2)
21160 error_at (OMP_CLAUSE_LOCATION (c),
21161 "%qD specified both in declare target %<link%> and %<to%>"
21162 " clauses", t);
21163 continue;
21165 if (!at1)
21167 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
21168 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
21169 continue;
21171 symtab_node *node = symtab_node::get (t);
21172 if (node != NULL)
21174 node->offloadable = 1;
21175 if (ENABLE_OFFLOADING)
21177 g->have_offload = true;
21178 if (is_a <varpool_node *> (node))
21179 vec_safe_push (offload_vars, t);
21183 if (TREE_CODE (t) != FUNCTION_DECL)
21184 continue;
21185 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
21187 tree at3 = lookup_attribute ("omp declare target host",
21188 DECL_ATTRIBUTES (t));
21189 if (at3 == NULL_TREE)
21191 id = get_identifier ("omp declare target host");
21192 DECL_ATTRIBUTES (t)
21193 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
21196 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
21198 tree at3 = lookup_attribute ("omp declare target nohost",
21199 DECL_ATTRIBUTES (t));
21200 if (at3 == NULL_TREE)
21202 id = get_identifier ("omp declare target nohost");
21203 DECL_ATTRIBUTES (t)
21204 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
21208 if (device_type && only_device_type)
21209 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
21210 "directive with only %<device_type%> clauses ignored");
21213 static void
21214 c_parser_omp_end_declare_target (c_parser *parser)
21216 location_t loc = c_parser_peek_token (parser)->location;
21217 c_parser_consume_pragma (parser);
21218 if (c_parser_next_token_is (parser, CPP_NAME)
21219 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
21220 "declare") == 0)
21222 c_parser_consume_token (parser);
21223 if (c_parser_next_token_is (parser, CPP_NAME)
21224 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
21225 "target") == 0)
21226 c_parser_consume_token (parser);
21227 else
21229 c_parser_error (parser, "expected %<target%>");
21230 c_parser_skip_to_pragma_eol (parser);
21231 return;
21234 else
21236 c_parser_error (parser, "expected %<declare%>");
21237 c_parser_skip_to_pragma_eol (parser);
21238 return;
21240 c_parser_skip_to_pragma_eol (parser);
21241 if (!current_omp_declare_target_attribute)
21242 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
21243 "%<#pragma omp declare target%>");
21244 else
21245 current_omp_declare_target_attribute--;
21249 /* OpenMP 4.0
21250 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21251 initializer-clause[opt] new-line
21253 initializer-clause:
21254 initializer (omp_priv = initializer)
21255 initializer (function-name (argument-list)) */
21257 static void
21258 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
21260 unsigned int tokens_avail = 0, i;
21261 vec<tree> types = vNULL;
21262 vec<c_token> clauses = vNULL;
21263 enum tree_code reduc_code = ERROR_MARK;
21264 tree reduc_id = NULL_TREE;
21265 tree type;
21266 location_t rloc = c_parser_peek_token (parser)->location;
21268 if (context == pragma_struct || context == pragma_param)
21270 error ("%<#pragma omp declare reduction%> not at file or block scope");
21271 goto fail;
21274 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
21275 goto fail;
21277 switch (c_parser_peek_token (parser)->type)
21279 case CPP_PLUS:
21280 reduc_code = PLUS_EXPR;
21281 break;
21282 case CPP_MULT:
21283 reduc_code = MULT_EXPR;
21284 break;
21285 case CPP_MINUS:
21286 reduc_code = MINUS_EXPR;
21287 break;
21288 case CPP_AND:
21289 reduc_code = BIT_AND_EXPR;
21290 break;
21291 case CPP_XOR:
21292 reduc_code = BIT_XOR_EXPR;
21293 break;
21294 case CPP_OR:
21295 reduc_code = BIT_IOR_EXPR;
21296 break;
21297 case CPP_AND_AND:
21298 reduc_code = TRUTH_ANDIF_EXPR;
21299 break;
21300 case CPP_OR_OR:
21301 reduc_code = TRUTH_ORIF_EXPR;
21302 break;
21303 case CPP_NAME:
21304 const char *p;
21305 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21306 if (strcmp (p, "min") == 0)
21308 reduc_code = MIN_EXPR;
21309 break;
21311 if (strcmp (p, "max") == 0)
21313 reduc_code = MAX_EXPR;
21314 break;
21316 reduc_id = c_parser_peek_token (parser)->value;
21317 break;
21318 default:
21319 c_parser_error (parser,
21320 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
21321 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
21322 goto fail;
21325 tree orig_reduc_id, reduc_decl;
21326 orig_reduc_id = reduc_id;
21327 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
21328 reduc_decl = c_omp_reduction_decl (reduc_id);
21329 c_parser_consume_token (parser);
21331 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
21332 goto fail;
21334 while (true)
21336 location_t loc = c_parser_peek_token (parser)->location;
21337 struct c_type_name *ctype = c_parser_type_name (parser);
21338 if (ctype != NULL)
21340 type = groktypename (ctype, NULL, NULL);
21341 if (type == error_mark_node)
21343 else if ((INTEGRAL_TYPE_P (type)
21344 || TREE_CODE (type) == REAL_TYPE
21345 || TREE_CODE (type) == COMPLEX_TYPE)
21346 && orig_reduc_id == NULL_TREE)
21347 error_at (loc, "predeclared arithmetic type in "
21348 "%<#pragma omp declare reduction%>");
21349 else if (TREE_CODE (type) == FUNCTION_TYPE
21350 || TREE_CODE (type) == ARRAY_TYPE)
21351 error_at (loc, "function or array type in "
21352 "%<#pragma omp declare reduction%>");
21353 else if (TYPE_ATOMIC (type))
21354 error_at (loc, "%<_Atomic%> qualified type in "
21355 "%<#pragma omp declare reduction%>");
21356 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
21357 error_at (loc, "const, volatile or restrict qualified type in "
21358 "%<#pragma omp declare reduction%>");
21359 else
21361 tree t;
21362 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
21363 if (comptypes (TREE_PURPOSE (t), type))
21365 error_at (loc, "redeclaration of %qs "
21366 "%<#pragma omp declare reduction%> for "
21367 "type %qT",
21368 IDENTIFIER_POINTER (reduc_id)
21369 + sizeof ("omp declare reduction ") - 1,
21370 type);
21371 location_t ploc
21372 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
21373 0));
21374 error_at (ploc, "previous %<#pragma omp declare "
21375 "reduction%>");
21376 break;
21378 if (t == NULL_TREE)
21379 types.safe_push (type);
21381 if (c_parser_next_token_is (parser, CPP_COMMA))
21382 c_parser_consume_token (parser);
21383 else
21384 break;
21386 else
21387 break;
21390 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
21391 || types.is_empty ())
21393 fail:
21394 clauses.release ();
21395 types.release ();
21396 while (true)
21398 c_token *token = c_parser_peek_token (parser);
21399 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
21400 break;
21401 c_parser_consume_token (parser);
21403 c_parser_skip_to_pragma_eol (parser);
21404 return;
21407 if (types.length () > 1)
21409 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21411 c_token *token = c_parser_peek_token (parser);
21412 if (token->type == CPP_EOF)
21413 goto fail;
21414 clauses.safe_push (*token);
21415 c_parser_consume_token (parser);
21417 clauses.safe_push (*c_parser_peek_token (parser));
21418 c_parser_skip_to_pragma_eol (parser);
21420 /* Make sure nothing tries to read past the end of the tokens. */
21421 c_token eof_token;
21422 memset (&eof_token, 0, sizeof (eof_token));
21423 eof_token.type = CPP_EOF;
21424 clauses.safe_push (eof_token);
21425 clauses.safe_push (eof_token);
21428 int errs = errorcount;
21429 FOR_EACH_VEC_ELT (types, i, type)
21431 tokens_avail = parser->tokens_avail;
21432 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
21433 if (!clauses.is_empty ())
21435 parser->tokens = clauses.address ();
21436 parser->tokens_avail = clauses.length ();
21437 parser->in_pragma = true;
21440 bool nested = current_function_decl != NULL_TREE;
21441 if (nested)
21442 c_push_function_context ();
21443 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
21444 reduc_id, default_function_type);
21445 current_function_decl = fndecl;
21446 allocate_struct_function (fndecl, true);
21447 push_scope ();
21448 tree stmt = push_stmt_list ();
21449 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
21450 warn about these. */
21451 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
21452 get_identifier ("omp_out"), type);
21453 DECL_ARTIFICIAL (omp_out) = 1;
21454 DECL_CONTEXT (omp_out) = fndecl;
21455 pushdecl (omp_out);
21456 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
21457 get_identifier ("omp_in"), type);
21458 DECL_ARTIFICIAL (omp_in) = 1;
21459 DECL_CONTEXT (omp_in) = fndecl;
21460 pushdecl (omp_in);
21461 struct c_expr combiner = c_parser_expression (parser);
21462 struct c_expr initializer;
21463 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
21464 bool bad = false;
21465 initializer.set_error ();
21466 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
21467 bad = true;
21468 else if (c_parser_next_token_is (parser, CPP_NAME)
21469 && strcmp (IDENTIFIER_POINTER
21470 (c_parser_peek_token (parser)->value),
21471 "initializer") == 0)
21473 c_parser_consume_token (parser);
21474 pop_scope ();
21475 push_scope ();
21476 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
21477 get_identifier ("omp_priv"), type);
21478 DECL_ARTIFICIAL (omp_priv) = 1;
21479 DECL_INITIAL (omp_priv) = error_mark_node;
21480 DECL_CONTEXT (omp_priv) = fndecl;
21481 pushdecl (omp_priv);
21482 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
21483 get_identifier ("omp_orig"), type);
21484 DECL_ARTIFICIAL (omp_orig) = 1;
21485 DECL_CONTEXT (omp_orig) = fndecl;
21486 pushdecl (omp_orig);
21487 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
21488 bad = true;
21489 else if (!c_parser_next_token_is (parser, CPP_NAME))
21491 c_parser_error (parser, "expected %<omp_priv%> or "
21492 "function-name");
21493 bad = true;
21495 else if (strcmp (IDENTIFIER_POINTER
21496 (c_parser_peek_token (parser)->value),
21497 "omp_priv") != 0)
21499 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
21500 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
21502 c_parser_error (parser, "expected function-name %<(%>");
21503 bad = true;
21505 else
21506 initializer = c_parser_postfix_expression (parser);
21507 if (initializer.value
21508 && TREE_CODE (initializer.value) == CALL_EXPR)
21510 int j;
21511 tree c = initializer.value;
21512 for (j = 0; j < call_expr_nargs (c); j++)
21514 tree a = CALL_EXPR_ARG (c, j);
21515 STRIP_NOPS (a);
21516 if (TREE_CODE (a) == ADDR_EXPR
21517 && TREE_OPERAND (a, 0) == omp_priv)
21518 break;
21520 if (j == call_expr_nargs (c))
21521 error ("one of the initializer call arguments should be "
21522 "%<&omp_priv%>");
21525 else
21527 c_parser_consume_token (parser);
21528 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21529 bad = true;
21530 else
21532 tree st = push_stmt_list ();
21533 location_t loc = c_parser_peek_token (parser)->location;
21534 rich_location richloc (line_table, loc);
21535 start_init (omp_priv, NULL_TREE, 0, &richloc);
21536 struct c_expr init = c_parser_initializer (parser);
21537 finish_init ();
21538 finish_decl (omp_priv, loc, init.value,
21539 init.original_type, NULL_TREE);
21540 pop_stmt_list (st);
21543 if (!bad
21544 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
21545 bad = true;
21548 if (!bad)
21550 c_parser_skip_to_pragma_eol (parser);
21552 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
21553 DECL_INITIAL (reduc_decl));
21554 DECL_INITIAL (reduc_decl) = t;
21555 DECL_SOURCE_LOCATION (omp_out) = rloc;
21556 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
21557 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
21558 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
21559 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
21560 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
21561 if (omp_priv)
21563 DECL_SOURCE_LOCATION (omp_priv) = rloc;
21564 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
21565 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
21566 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
21567 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
21568 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
21569 walk_tree (&DECL_INITIAL (omp_priv),
21570 c_check_omp_declare_reduction_r,
21571 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
21575 pop_stmt_list (stmt);
21576 pop_scope ();
21577 if (cfun->language != NULL)
21579 ggc_free (cfun->language);
21580 cfun->language = NULL;
21582 set_cfun (NULL);
21583 current_function_decl = NULL_TREE;
21584 if (nested)
21585 c_pop_function_context ();
21587 if (!clauses.is_empty ())
21589 parser->tokens = &parser->tokens_buf[0];
21590 parser->tokens_avail = tokens_avail;
21592 if (bad)
21593 goto fail;
21594 if (errs != errorcount)
21595 break;
21598 clauses.release ();
21599 types.release ();
21603 /* OpenMP 4.0
21604 #pragma omp declare simd declare-simd-clauses[optseq] new-line
21605 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21606 initializer-clause[opt] new-line
21607 #pragma omp declare target new-line
21609 OpenMP 5.0
21610 #pragma omp declare variant (identifier) match (context-selector) */
21612 static bool
21613 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
21615 c_parser_consume_pragma (parser);
21616 if (c_parser_next_token_is (parser, CPP_NAME))
21618 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21619 if (strcmp (p, "simd") == 0)
21621 /* c_parser_consume_token (parser); done in
21622 c_parser_omp_declare_simd. */
21623 c_parser_omp_declare_simd (parser, context);
21624 return true;
21626 if (strcmp (p, "reduction") == 0)
21628 c_parser_consume_token (parser);
21629 c_parser_omp_declare_reduction (parser, context);
21630 return false;
21632 if (!flag_openmp) /* flag_openmp_simd */
21634 c_parser_skip_to_pragma_eol (parser, false);
21635 return false;
21637 if (strcmp (p, "target") == 0)
21639 c_parser_consume_token (parser);
21640 c_parser_omp_declare_target (parser);
21641 return false;
21643 if (strcmp (p, "variant") == 0)
21645 /* c_parser_consume_token (parser); done in
21646 c_parser_omp_declare_simd. */
21647 c_parser_omp_declare_simd (parser, context);
21648 return true;
21652 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
21653 "%<target%> or %<variant%>");
21654 c_parser_skip_to_pragma_eol (parser);
21655 return false;
21658 /* OpenMP 5.0
21659 #pragma omp requires clauses[optseq] new-line */
21661 static void
21662 c_parser_omp_requires (c_parser *parser)
21664 bool first = true;
21665 enum omp_requires new_req = (enum omp_requires) 0;
21667 c_parser_consume_pragma (parser);
21669 location_t loc = c_parser_peek_token (parser)->location;
21670 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21672 if (!first
21673 && c_parser_next_token_is (parser, CPP_COMMA)
21674 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
21675 c_parser_consume_token (parser);
21677 first = false;
21679 if (c_parser_next_token_is (parser, CPP_NAME))
21681 const char *p
21682 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21683 location_t cloc = c_parser_peek_token (parser)->location;
21684 enum omp_requires this_req = (enum omp_requires) 0;
21686 if (!strcmp (p, "unified_address"))
21687 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
21688 else if (!strcmp (p, "unified_shared_memory"))
21689 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
21690 else if (!strcmp (p, "dynamic_allocators"))
21691 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
21692 else if (!strcmp (p, "reverse_offload"))
21693 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
21694 else if (!strcmp (p, "atomic_default_mem_order"))
21696 c_parser_consume_token (parser);
21698 matching_parens parens;
21699 if (parens.require_open (parser))
21701 if (c_parser_next_token_is (parser, CPP_NAME))
21703 tree v = c_parser_peek_token (parser)->value;
21704 p = IDENTIFIER_POINTER (v);
21706 if (!strcmp (p, "seq_cst"))
21707 this_req
21708 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
21709 else if (!strcmp (p, "relaxed"))
21710 this_req
21711 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
21712 else if (!strcmp (p, "acq_rel"))
21713 this_req
21714 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
21716 if (this_req == 0)
21718 error_at (c_parser_peek_token (parser)->location,
21719 "expected %<seq_cst%>, %<relaxed%> or "
21720 "%<acq_rel%>");
21721 switch (c_parser_peek_token (parser)->type)
21723 case CPP_EOF:
21724 case CPP_PRAGMA_EOL:
21725 case CPP_CLOSE_PAREN:
21726 break;
21727 default:
21728 if (c_parser_peek_2nd_token (parser)->type
21729 == CPP_CLOSE_PAREN)
21730 c_parser_consume_token (parser);
21731 break;
21734 else
21735 c_parser_consume_token (parser);
21737 parens.skip_until_found_close (parser);
21738 if (this_req == 0)
21740 c_parser_skip_to_pragma_eol (parser, false);
21741 return;
21744 p = NULL;
21746 else
21748 error_at (cloc, "expected %<unified_address%>, "
21749 "%<unified_shared_memory%>, "
21750 "%<dynamic_allocators%>, "
21751 "%<reverse_offload%> "
21752 "or %<atomic_default_mem_order%> clause");
21753 c_parser_skip_to_pragma_eol (parser, false);
21754 return;
21756 if (p)
21757 sorry_at (cloc, "%qs clause on %<requires%> directive not "
21758 "supported yet", p);
21759 if (p)
21760 c_parser_consume_token (parser);
21761 if (this_req)
21763 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21765 if ((this_req & new_req) != 0)
21766 error_at (cloc, "too many %qs clauses", p);
21767 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
21768 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
21769 error_at (cloc, "%qs clause used lexically after first "
21770 "target construct or offloading API", p);
21772 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21774 error_at (cloc, "too many %qs clauses",
21775 "atomic_default_mem_order");
21776 this_req = (enum omp_requires) 0;
21778 else if ((omp_requires_mask
21779 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21781 error_at (cloc, "more than one %<atomic_default_mem_order%>"
21782 " clause in a single compilation unit");
21783 this_req
21784 = (enum omp_requires)
21785 (omp_requires_mask
21786 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
21788 else if ((omp_requires_mask
21789 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
21790 error_at (cloc, "%<atomic_default_mem_order%> clause used "
21791 "lexically after first %<atomic%> construct "
21792 "without memory order clause");
21793 new_req = (enum omp_requires) (new_req | this_req);
21794 omp_requires_mask
21795 = (enum omp_requires) (omp_requires_mask | this_req);
21796 continue;
21799 break;
21801 c_parser_skip_to_pragma_eol (parser);
21803 if (new_req == 0)
21804 error_at (loc, "%<pragma omp requires%> requires at least one clause");
21807 /* Helper function for c_parser_omp_taskloop.
21808 Disallow zero sized or potentially zero sized task reductions. */
21810 static tree
21811 c_finish_taskloop_clauses (tree clauses)
21813 tree *pc = &clauses;
21814 for (tree c = clauses; c; c = *pc)
21816 bool remove = false;
21817 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
21819 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
21820 if (integer_zerop (TYPE_SIZE_UNIT (type)))
21822 error_at (OMP_CLAUSE_LOCATION (c),
21823 "zero sized type %qT in %<reduction%> clause", type);
21824 remove = true;
21826 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
21828 error_at (OMP_CLAUSE_LOCATION (c),
21829 "variable sized type %qT in %<reduction%> clause",
21830 type);
21831 remove = true;
21834 if (remove)
21835 *pc = OMP_CLAUSE_CHAIN (c);
21836 else
21837 pc = &OMP_CLAUSE_CHAIN (c);
21839 return clauses;
21842 /* OpenMP 4.5:
21843 #pragma omp taskloop taskloop-clause[optseq] new-line
21844 for-loop
21846 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21847 for-loop */
21849 #define OMP_TASKLOOP_CLAUSE_MASK \
21850 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21851 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21852 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21853 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21854 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
21856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
21857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21858 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21860 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
21863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21864 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21865 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21866 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
21868 static tree
21869 c_parser_omp_taskloop (location_t loc, c_parser *parser,
21870 char *p_name, omp_clause_mask mask, tree *cclauses,
21871 bool *if_p)
21873 tree clauses, block, ret;
21875 strcat (p_name, " taskloop");
21876 mask |= OMP_TASKLOOP_CLAUSE_MASK;
21877 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21878 clause. */
21879 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
21880 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
21882 if (c_parser_next_token_is (parser, CPP_NAME))
21884 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21886 if (strcmp (p, "simd") == 0)
21888 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21889 if (cclauses == NULL)
21890 cclauses = cclauses_buf;
21891 c_parser_consume_token (parser);
21892 if (!flag_openmp) /* flag_openmp_simd */
21893 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21894 if_p);
21895 block = c_begin_compound_stmt (true);
21896 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
21897 block = c_end_compound_stmt (loc, block, true);
21898 if (ret == NULL)
21899 return ret;
21900 ret = make_node (OMP_TASKLOOP);
21901 TREE_TYPE (ret) = void_type_node;
21902 OMP_FOR_BODY (ret) = block;
21903 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21904 OMP_FOR_CLAUSES (ret)
21905 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
21906 SET_EXPR_LOCATION (ret, loc);
21907 add_stmt (ret);
21908 return ret;
21911 if (!flag_openmp) /* flag_openmp_simd */
21913 c_parser_skip_to_pragma_eol (parser, false);
21914 return NULL_TREE;
21917 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21918 if (cclauses)
21920 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
21921 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21924 clauses = c_finish_taskloop_clauses (clauses);
21925 block = c_begin_compound_stmt (true);
21926 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
21927 block = c_end_compound_stmt (loc, block, true);
21928 add_stmt (block);
21930 return ret;
21933 /* OpenMP 5.1
21934 #pragma omp nothing new-line */
21936 static void
21937 c_parser_omp_nothing (c_parser *parser)
21939 c_parser_consume_pragma (parser);
21940 c_parser_skip_to_pragma_eol (parser);
21943 /* OpenMP 5.1
21944 #pragma omp error clauses[optseq] new-line */
21946 static bool
21947 c_parser_omp_error (c_parser *parser, enum pragma_context context)
21949 int at_compilation = -1;
21950 int severity_fatal = -1;
21951 tree message = NULL_TREE;
21952 bool first = true;
21953 bool bad = false;
21954 location_t loc = c_parser_peek_token (parser)->location;
21956 c_parser_consume_pragma (parser);
21958 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21960 if (!first
21961 && c_parser_next_token_is (parser, CPP_COMMA)
21962 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
21963 c_parser_consume_token (parser);
21965 first = false;
21967 if (!c_parser_next_token_is (parser, CPP_NAME))
21968 break;
21970 const char *p
21971 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21972 location_t cloc = c_parser_peek_token (parser)->location;
21973 static const char *args[] = {
21974 "execution", "compilation", "warning", "fatal"
21976 int *v = NULL;
21977 int idx = 0, n = -1;
21978 tree m = NULL_TREE;
21980 if (!strcmp (p, "at"))
21981 v = &at_compilation;
21982 else if (!strcmp (p, "severity"))
21984 v = &severity_fatal;
21985 idx += 2;
21987 else if (strcmp (p, "message"))
21989 error_at (cloc,
21990 "expected %<at%>, %<severity%> or %<message%> clause");
21991 c_parser_skip_to_pragma_eol (parser, false);
21992 return false;
21995 c_parser_consume_token (parser);
21997 matching_parens parens;
21998 if (parens.require_open (parser))
22000 if (v == NULL)
22002 location_t expr_loc = c_parser_peek_token (parser)->location;
22003 c_expr expr = c_parser_expr_no_commas (parser, NULL);
22004 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
22005 m = convert (const_string_type_node, expr.value);
22006 m = c_fully_fold (m, false, NULL);
22008 else
22010 if (c_parser_next_token_is (parser, CPP_NAME))
22012 tree val = c_parser_peek_token (parser)->value;
22013 const char *q = IDENTIFIER_POINTER (val);
22015 if (!strcmp (q, args[idx]))
22016 n = 0;
22017 else if (!strcmp (q, args[idx + 1]))
22018 n = 1;
22020 if (n == -1)
22022 error_at (c_parser_peek_token (parser)->location,
22023 "expected %qs or %qs", args[idx], args[idx + 1]);
22024 bad = true;
22025 switch (c_parser_peek_token (parser)->type)
22027 case CPP_EOF:
22028 case CPP_PRAGMA_EOL:
22029 case CPP_CLOSE_PAREN:
22030 break;
22031 default:
22032 if (c_parser_peek_2nd_token (parser)->type
22033 == CPP_CLOSE_PAREN)
22034 c_parser_consume_token (parser);
22035 break;
22038 else
22039 c_parser_consume_token (parser);
22042 parens.skip_until_found_close (parser);
22044 if (v == NULL)
22046 if (message)
22048 error_at (cloc, "too many %qs clauses", p);
22049 bad = true;
22051 else
22052 message = m;
22054 else if (n != -1)
22056 if (*v != -1)
22058 error_at (cloc, "too many %qs clauses", p);
22059 bad = true;
22061 else
22062 *v = n;
22065 else
22066 bad = true;
22068 c_parser_skip_to_pragma_eol (parser);
22069 if (bad)
22070 return true;
22072 if (at_compilation == -1)
22073 at_compilation = 1;
22074 if (severity_fatal == -1)
22075 severity_fatal = 1;
22076 if (!at_compilation)
22078 if (context != pragma_compound)
22080 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
22081 "may only be used in compound statements");
22082 return true;
22084 tree fndecl
22085 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
22086 : BUILT_IN_GOMP_WARNING);
22087 if (!message)
22088 message = build_zero_cst (const_string_type_node);
22089 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
22090 build_all_ones_cst (size_type_node));
22091 add_stmt (stmt);
22092 return true;
22094 const char *msg = NULL;
22095 if (message)
22097 msg = c_getstr (message);
22098 if (msg == NULL)
22099 msg = _("<message unknown at compile time>");
22101 if (msg)
22102 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
22103 "%<pragma omp error%> encountered: %s", msg);
22104 else
22105 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
22106 "%<pragma omp error%> encountered");
22107 return false;
22110 /* Main entry point to parsing most OpenMP pragmas. */
22112 static void
22113 c_parser_omp_construct (c_parser *parser, bool *if_p)
22115 enum pragma_kind p_kind;
22116 location_t loc;
22117 tree stmt;
22118 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
22119 omp_clause_mask mask (0);
22121 loc = c_parser_peek_token (parser)->location;
22122 p_kind = c_parser_peek_token (parser)->pragma_kind;
22123 c_parser_consume_pragma (parser);
22125 switch (p_kind)
22127 case PRAGMA_OACC_ATOMIC:
22128 c_parser_omp_atomic (loc, parser, true);
22129 return;
22130 case PRAGMA_OACC_CACHE:
22131 strcpy (p_name, "#pragma acc");
22132 stmt = c_parser_oacc_cache (loc, parser);
22133 break;
22134 case PRAGMA_OACC_DATA:
22135 stmt = c_parser_oacc_data (loc, parser, if_p);
22136 break;
22137 case PRAGMA_OACC_HOST_DATA:
22138 stmt = c_parser_oacc_host_data (loc, parser, if_p);
22139 break;
22140 case PRAGMA_OACC_KERNELS:
22141 case PRAGMA_OACC_PARALLEL:
22142 case PRAGMA_OACC_SERIAL:
22143 strcpy (p_name, "#pragma acc");
22144 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
22145 break;
22146 case PRAGMA_OACC_LOOP:
22147 strcpy (p_name, "#pragma acc");
22148 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
22149 break;
22150 case PRAGMA_OACC_WAIT:
22151 strcpy (p_name, "#pragma wait");
22152 stmt = c_parser_oacc_wait (loc, parser, p_name);
22153 break;
22154 case PRAGMA_OMP_ALLOCATE:
22155 c_parser_omp_allocate (loc, parser);
22156 return;
22157 case PRAGMA_OMP_ATOMIC:
22158 c_parser_omp_atomic (loc, parser, false);
22159 return;
22160 case PRAGMA_OMP_CRITICAL:
22161 stmt = c_parser_omp_critical (loc, parser, if_p);
22162 break;
22163 case PRAGMA_OMP_DISTRIBUTE:
22164 strcpy (p_name, "#pragma omp");
22165 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
22166 break;
22167 case PRAGMA_OMP_FOR:
22168 strcpy (p_name, "#pragma omp");
22169 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
22170 break;
22171 case PRAGMA_OMP_LOOP:
22172 strcpy (p_name, "#pragma omp");
22173 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
22174 break;
22175 case PRAGMA_OMP_MASKED:
22176 strcpy (p_name, "#pragma omp");
22177 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
22178 break;
22179 case PRAGMA_OMP_MASTER:
22180 strcpy (p_name, "#pragma omp");
22181 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
22182 break;
22183 case PRAGMA_OMP_PARALLEL:
22184 strcpy (p_name, "#pragma omp");
22185 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
22186 break;
22187 case PRAGMA_OMP_SCOPE:
22188 stmt = c_parser_omp_scope (loc, parser, if_p);
22189 break;
22190 case PRAGMA_OMP_SECTIONS:
22191 strcpy (p_name, "#pragma omp");
22192 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
22193 break;
22194 case PRAGMA_OMP_SIMD:
22195 strcpy (p_name, "#pragma omp");
22196 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
22197 break;
22198 case PRAGMA_OMP_SINGLE:
22199 stmt = c_parser_omp_single (loc, parser, if_p);
22200 break;
22201 case PRAGMA_OMP_TASK:
22202 stmt = c_parser_omp_task (loc, parser, if_p);
22203 break;
22204 case PRAGMA_OMP_TASKGROUP:
22205 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
22206 break;
22207 case PRAGMA_OMP_TASKLOOP:
22208 strcpy (p_name, "#pragma omp");
22209 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
22210 break;
22211 case PRAGMA_OMP_TEAMS:
22212 strcpy (p_name, "#pragma omp");
22213 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
22214 break;
22215 default:
22216 gcc_unreachable ();
22219 if (stmt && stmt != error_mark_node)
22220 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
22224 /* OpenMP 2.5:
22225 # pragma omp threadprivate (variable-list) */
22227 static void
22228 c_parser_omp_threadprivate (c_parser *parser)
22230 tree vars, t;
22231 location_t loc;
22233 c_parser_consume_pragma (parser);
22234 loc = c_parser_peek_token (parser)->location;
22235 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
22237 /* Mark every variable in VARS to be assigned thread local storage. */
22238 for (t = vars; t; t = TREE_CHAIN (t))
22240 tree v = TREE_PURPOSE (t);
22242 /* FIXME diagnostics: Ideally we should keep individual
22243 locations for all the variables in the var list to make the
22244 following errors more precise. Perhaps
22245 c_parser_omp_var_list_parens() should construct a list of
22246 locations to go along with the var list. */
22248 /* If V had already been marked threadprivate, it doesn't matter
22249 whether it had been used prior to this point. */
22250 if (!VAR_P (v))
22251 error_at (loc, "%qD is not a variable", v);
22252 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
22253 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
22254 else if (! is_global_var (v))
22255 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
22256 else if (TREE_TYPE (v) == error_mark_node)
22258 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
22259 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
22260 else
22262 if (! DECL_THREAD_LOCAL_P (v))
22264 set_decl_tls_model (v, decl_default_tls_model (v));
22265 /* If rtl has been already set for this var, call
22266 make_decl_rtl once again, so that encode_section_info
22267 has a chance to look at the new decl flags. */
22268 if (DECL_RTL_SET_P (v))
22269 make_decl_rtl (v);
22271 C_DECL_THREADPRIVATE_P (v) = 1;
22275 c_parser_skip_to_pragma_eol (parser);
22278 /* Parse a transaction attribute (GCC Extension).
22280 transaction-attribute:
22281 gnu-attributes
22282 attribute-specifier
22285 static tree
22286 c_parser_transaction_attributes (c_parser *parser)
22288 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
22289 return c_parser_gnu_attributes (parser);
22291 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
22292 return NULL_TREE;
22293 return c_parser_std_attribute_specifier (parser, true);
22296 /* Parse a __transaction_atomic or __transaction_relaxed statement
22297 (GCC Extension).
22299 transaction-statement:
22300 __transaction_atomic transaction-attribute[opt] compound-statement
22301 __transaction_relaxed compound-statement
22303 Note that the only valid attribute is: "outer".
22306 static tree
22307 c_parser_transaction (c_parser *parser, enum rid keyword)
22309 unsigned int old_in = parser->in_transaction;
22310 unsigned int this_in = 1, new_in;
22311 location_t loc = c_parser_peek_token (parser)->location;
22312 tree stmt, attrs;
22314 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
22315 || keyword == RID_TRANSACTION_RELAXED)
22316 && c_parser_next_token_is_keyword (parser, keyword));
22317 c_parser_consume_token (parser);
22319 if (keyword == RID_TRANSACTION_RELAXED)
22320 this_in |= TM_STMT_ATTR_RELAXED;
22321 else
22323 attrs = c_parser_transaction_attributes (parser);
22324 if (attrs)
22325 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
22328 /* Keep track if we're in the lexical scope of an outer transaction. */
22329 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
22331 parser->in_transaction = new_in;
22332 stmt = c_parser_compound_statement (parser);
22333 parser->in_transaction = old_in;
22335 if (flag_tm)
22336 stmt = c_finish_transaction (loc, stmt, this_in);
22337 else
22338 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
22339 "%<__transaction_atomic%> without transactional memory support enabled"
22340 : "%<__transaction_relaxed %> "
22341 "without transactional memory support enabled"));
22343 return stmt;
22346 /* Parse a __transaction_atomic or __transaction_relaxed expression
22347 (GCC Extension).
22349 transaction-expression:
22350 __transaction_atomic ( expression )
22351 __transaction_relaxed ( expression )
22354 static struct c_expr
22355 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
22357 struct c_expr ret;
22358 unsigned int old_in = parser->in_transaction;
22359 unsigned int this_in = 1;
22360 location_t loc = c_parser_peek_token (parser)->location;
22361 tree attrs;
22363 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
22364 || keyword == RID_TRANSACTION_RELAXED)
22365 && c_parser_next_token_is_keyword (parser, keyword));
22366 c_parser_consume_token (parser);
22368 if (keyword == RID_TRANSACTION_RELAXED)
22369 this_in |= TM_STMT_ATTR_RELAXED;
22370 else
22372 attrs = c_parser_transaction_attributes (parser);
22373 if (attrs)
22374 this_in |= parse_tm_stmt_attr (attrs, 0);
22377 parser->in_transaction = this_in;
22378 matching_parens parens;
22379 if (parens.require_open (parser))
22381 tree expr = c_parser_expression (parser).value;
22382 ret.original_type = TREE_TYPE (expr);
22383 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
22384 if (this_in & TM_STMT_ATTR_RELAXED)
22385 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
22386 SET_EXPR_LOCATION (ret.value, loc);
22387 ret.original_code = TRANSACTION_EXPR;
22388 if (!parens.require_close (parser))
22390 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
22391 goto error;
22394 else
22396 error:
22397 ret.set_error ();
22398 ret.original_code = ERROR_MARK;
22399 ret.original_type = NULL;
22401 parser->in_transaction = old_in;
22403 if (!flag_tm)
22404 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
22405 "%<__transaction_atomic%> without transactional memory support enabled"
22406 : "%<__transaction_relaxed %> "
22407 "without transactional memory support enabled"));
22409 set_c_expr_source_range (&ret, loc, loc);
22411 return ret;
22414 /* Parse a __transaction_cancel statement (GCC Extension).
22416 transaction-cancel-statement:
22417 __transaction_cancel transaction-attribute[opt] ;
22419 Note that the only valid attribute is "outer".
22422 static tree
22423 c_parser_transaction_cancel (c_parser *parser)
22425 location_t loc = c_parser_peek_token (parser)->location;
22426 tree attrs;
22427 bool is_outer = false;
22429 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
22430 c_parser_consume_token (parser);
22432 attrs = c_parser_transaction_attributes (parser);
22433 if (attrs)
22434 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
22436 if (!flag_tm)
22438 error_at (loc, "%<__transaction_cancel%> without "
22439 "transactional memory support enabled");
22440 goto ret_error;
22442 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
22444 error_at (loc, "%<__transaction_cancel%> within a "
22445 "%<__transaction_relaxed%>");
22446 goto ret_error;
22448 else if (is_outer)
22450 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
22451 && !is_tm_may_cancel_outer (current_function_decl))
22453 error_at (loc, "outer %<__transaction_cancel%> not "
22454 "within outer %<__transaction_atomic%> or "
22455 "a %<transaction_may_cancel_outer%> function");
22456 goto ret_error;
22459 else if (parser->in_transaction == 0)
22461 error_at (loc, "%<__transaction_cancel%> not within "
22462 "%<__transaction_atomic%>");
22463 goto ret_error;
22466 return add_stmt (build_tm_abort_call (loc, is_outer));
22468 ret_error:
22469 return build1 (NOP_EXPR, void_type_node, error_mark_node);
22472 /* Parse a single source file. */
22474 void
22475 c_parse_file (void)
22477 /* Use local storage to begin. If the first token is a pragma, parse it.
22478 If it is #pragma GCC pch_preprocess, then this will load a PCH file
22479 which will cause garbage collection. */
22480 c_parser tparser;
22482 memset (&tparser, 0, sizeof tparser);
22483 tparser.translate_strings_p = true;
22484 tparser.tokens = &tparser.tokens_buf[0];
22485 the_parser = &tparser;
22487 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
22488 c_parser_pragma_pch_preprocess (&tparser);
22489 else
22490 c_common_no_more_pch ();
22492 the_parser = ggc_alloc<c_parser> ();
22493 *the_parser = tparser;
22494 if (tparser.tokens == &tparser.tokens_buf[0])
22495 the_parser->tokens = &the_parser->tokens_buf[0];
22497 /* Initialize EH, if we've been told to do so. */
22498 if (flag_exceptions)
22499 using_eh_for_cleanups ();
22501 c_parser_translation_unit (the_parser);
22502 the_parser = NULL;
22505 /* Parse the body of a function declaration marked with "__RTL".
22507 The RTL parser works on the level of characters read from a
22508 FILE *, whereas c_parser works at the level of tokens.
22509 Square this circle by consuming all of the tokens up to and
22510 including the closing brace, recording the start/end of the RTL
22511 fragment, and reopening the file and re-reading the relevant
22512 lines within the RTL parser.
22514 This requires the opening and closing braces of the C function
22515 to be on separate lines from the RTL they wrap.
22517 Take ownership of START_WITH_PASS, if non-NULL. */
22519 location_t
22520 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
22522 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
22524 free (start_with_pass);
22525 return c_parser_peek_token (parser)->location;
22528 location_t start_loc = c_parser_peek_token (parser)->location;
22530 /* Consume all tokens, up to the closing brace, handling
22531 matching pairs of braces in the rtl dump. */
22532 int num_open_braces = 1;
22533 while (1)
22535 switch (c_parser_peek_token (parser)->type)
22537 case CPP_OPEN_BRACE:
22538 num_open_braces++;
22539 break;
22540 case CPP_CLOSE_BRACE:
22541 if (--num_open_braces == 0)
22542 goto found_closing_brace;
22543 break;
22544 case CPP_EOF:
22545 error_at (start_loc, "no closing brace");
22546 free (start_with_pass);
22547 return c_parser_peek_token (parser)->location;
22548 default:
22549 break;
22551 c_parser_consume_token (parser);
22554 found_closing_brace:
22555 /* At the closing brace; record its location. */
22556 location_t end_loc = c_parser_peek_token (parser)->location;
22558 /* Consume the closing brace. */
22559 c_parser_consume_token (parser);
22561 /* Invoke the RTL parser. */
22562 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
22564 free (start_with_pass);
22565 return end_loc;
22568 /* Run the backend on the cfun created above, transferring ownership of
22569 START_WITH_PASS. */
22570 run_rtl_passes (start_with_pass);
22571 return end_loc;
22574 #include "gt-c-c-parser.h"