1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2022 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
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
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/>. */
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
29 Add testcases covering every input symbol in every state in old and
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. */
39 #define INCLUDE_MEMORY
41 #include "coretypes.h"
46 #include "stringpool.h"
49 #include "stor-layout.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
54 #include "c-family/c-objc.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
63 #include "gcc-rich-location.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.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;
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;
91 set_source_range (expr->value, start, finish);
95 set_c_expr_source_range (c_expr *expr,
96 source_range src_range)
98 expr->src_range = src_range;
100 set_source_range (expr->value, src_range);
104 /* Initialization routine for this file. */
109 /* The only initialization required is of the reserved word
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);
124 mask |= D_ASM | D_EXT;
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)
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;
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. */
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;
171 id = get_identifier ("omp_all_memory");
172 C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
173 C_IS_RESERVED_WORD (id) = 1;
174 ridpointers [RID_OMP_ALL_MEMORY] = id;
178 /* A parser structure recording information about the state and
179 context of parsing. Includes lexer information with up to two
180 tokens of look-ahead; more are not needed for C. */
181 struct GTY(()) c_parser {
182 /* The look-ahead tokens. */
183 c_token * GTY((skip)) tokens;
184 /* Buffer for look-ahead tokens. */
185 c_token tokens_buf[4];
186 /* How many look-ahead tokens are available (0 - 4, or
187 more if parsing from pre-lexed tokens). */
188 unsigned int tokens_avail;
189 /* Raw look-ahead tokens, used only for checking in Objective-C
190 whether '[[' starts attributes. */
191 vec<c_token, va_gc> *raw_tokens;
192 /* The number of raw look-ahead tokens that have since been fully
194 unsigned int raw_tokens_used;
195 /* True if a syntax error is being recovered from; false otherwise.
196 c_parser_error sets this flag. It should clear this flag when
197 enough tokens have been consumed to recover from the error. */
198 BOOL_BITFIELD error : 1;
199 /* True if we're processing a pragma, and shouldn't automatically
200 consume CPP_PRAGMA_EOL. */
201 BOOL_BITFIELD in_pragma : 1;
202 /* True if we're parsing the outermost block of an if statement. */
203 BOOL_BITFIELD in_if_block : 1;
204 /* True if we want to lex a translated, joined string (for an
205 initial #pragma pch_preprocess). Otherwise the parser is
206 responsible for concatenating strings and translating to the
207 execution character set as needed. */
208 BOOL_BITFIELD lex_joined_string : 1;
209 /* True if, when the parser is concatenating string literals, it
210 should translate them to the execution character set (false
211 inside attributes). */
212 BOOL_BITFIELD translate_strings_p : 1;
214 /* Objective-C specific parser/lexer information. */
216 /* True if we are in a context where the Objective-C "PQ" keywords
217 are considered keywords. */
218 BOOL_BITFIELD objc_pq_context : 1;
219 /* True if we are parsing a (potential) Objective-C foreach
220 statement. This is set to true after we parsed 'for (' and while
221 we wait for 'in' or ';' to decide if it's a standard C for loop or an
222 Objective-C foreach loop. */
223 BOOL_BITFIELD objc_could_be_foreach_context : 1;
224 /* The following flag is needed to contextualize Objective-C lexical
225 analysis. In some cases (e.g., 'int NSObject;'), it is
226 undesirable to bind an identifier to an Objective-C class, even
227 if a class with that name exists. */
228 BOOL_BITFIELD objc_need_raw_identifier : 1;
229 /* Nonzero if we're processing a __transaction statement. The value
230 is 1 | TM_STMT_ATTR_*. */
231 unsigned int in_transaction : 4;
232 /* True if we are in a context where the Objective-C "Property attribute"
233 keywords are valid. */
234 BOOL_BITFIELD objc_property_attr_context : 1;
236 /* Whether we have just seen/constructed a string-literal. Set when
237 returning a string-literal from c_parser_string_literal. Reset
238 in consume_token. Useful when we get a parse error and see an
239 unknown token, which could have been a string-literal constant
241 BOOL_BITFIELD seen_string_literal : 1;
243 /* Location of the last consumed token. */
244 location_t last_token_location;
247 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
250 c_parser_tokens_buf (c_parser *parser, unsigned n)
252 return &parser->tokens_buf[n];
255 /* Return the error state of PARSER. */
258 c_parser_error (c_parser *parser)
260 return parser->error;
263 /* Set the error state of PARSER to ERR. */
266 c_parser_set_error (c_parser *parser, bool err)
272 /* The actual parser and external interface. ??? Does this need to be
273 garbage-collected? */
275 static GTY (()) c_parser *the_parser;
277 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
278 context-sensitive postprocessing of the token is not done. */
281 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
283 timevar_push (TV_LEX);
285 if (raw || vec_safe_length (parser->raw_tokens) == 0)
287 token->type = c_lex_with_flags (&token->value, &token->location,
289 (parser->lex_joined_string
290 ? 0 : C_LEX_STRING_NO_JOIN));
291 token->id_kind = C_ID_NONE;
292 token->keyword = RID_MAX;
293 token->pragma_kind = PRAGMA_NONE;
297 /* Use a token previously lexed as a raw look-ahead token, and
298 complete the processing on it. */
299 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
300 ++parser->raw_tokens_used;
301 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
303 vec_free (parser->raw_tokens);
304 parser->raw_tokens_used = 0;
317 bool objc_force_identifier = parser->objc_need_raw_identifier;
318 if (c_dialect_objc ())
319 parser->objc_need_raw_identifier = false;
321 if (C_IS_RESERVED_WORD (token->value))
323 enum rid rid_code = C_RID_CODE (token->value);
325 if (rid_code == RID_CXX_COMPAT_WARN)
327 warning_at (token->location,
329 "identifier %qE conflicts with C++ keyword",
332 else if (rid_code >= RID_FIRST_ADDR_SPACE
333 && rid_code <= RID_LAST_ADDR_SPACE)
336 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
337 targetm.addr_space.diagnose_usage (as, token->location);
338 token->id_kind = C_ID_ADDRSPACE;
339 token->keyword = rid_code;
342 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
344 /* We found an Objective-C "pq" keyword (in, out,
345 inout, bycopy, byref, oneway). They need special
346 care because the interpretation depends on the
348 if (parser->objc_pq_context)
350 token->type = CPP_KEYWORD;
351 token->keyword = rid_code;
354 else if (parser->objc_could_be_foreach_context
355 && rid_code == RID_IN)
357 /* We are in Objective-C, inside a (potential)
358 foreach context (which means after having
359 parsed 'for (', but before having parsed ';'),
360 and we found 'in'. We consider it the keyword
361 which terminates the declaration at the
362 beginning of a foreach-statement. Note that
363 this means you can't use 'in' for anything else
364 in that context; in particular, in Objective-C
365 you can't use 'in' as the name of the running
366 variable in a C for loop. We could potentially
367 try to add code here to disambiguate, but it
368 seems a reasonable limitation. */
369 token->type = CPP_KEYWORD;
370 token->keyword = rid_code;
373 /* Else, "pq" keywords outside of the "pq" context are
374 not keywords, and we fall through to the code for
377 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
379 /* We found an Objective-C "property attribute"
380 keyword (getter, setter, readonly, etc). These are
381 only valid in the property context. */
382 if (parser->objc_property_attr_context)
384 token->type = CPP_KEYWORD;
385 token->keyword = rid_code;
388 /* Else they are not special keywords.
391 else if (c_dialect_objc ()
392 && (OBJC_IS_AT_KEYWORD (rid_code)
393 || OBJC_IS_CXX_KEYWORD (rid_code)))
395 /* We found one of the Objective-C "@" keywords (defs,
396 selector, synchronized, etc) or one of the
397 Objective-C "cxx" keywords (class, private,
398 protected, public, try, catch, throw) without a
399 preceding '@' sign. Do nothing and fall through to
400 the code for normal tokens (in C++ we would still
401 consider the CXX ones keywords, but not in C). */
406 token->type = CPP_KEYWORD;
407 token->keyword = rid_code;
412 decl = lookup_name (token->value);
415 if (TREE_CODE (decl) == TYPE_DECL)
417 token->id_kind = C_ID_TYPENAME;
421 else if (c_dialect_objc ())
423 tree objc_interface_decl = objc_is_class_name (token->value);
424 /* Objective-C class names are in the same namespace as
425 variables and typedefs, and hence are shadowed by local
427 if (objc_interface_decl
428 && (!objc_force_identifier || global_bindings_p ()))
430 token->value = objc_interface_decl;
431 token->id_kind = C_ID_CLASSNAME;
435 token->id_kind = C_ID_ID;
439 /* This only happens in Objective-C; it must be a keyword. */
440 token->type = CPP_KEYWORD;
441 switch (C_RID_CODE (token->value))
443 /* Replace 'class' with '@class', 'private' with '@private',
444 etc. This prevents confusion with the C++ keyword
445 'class', and makes the tokens consistent with other
446 Objective-C 'AT' keywords. For example '@class' is
447 reported as RID_AT_CLASS which is consistent with
448 '@synchronized', which is reported as
451 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
452 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
453 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
454 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
455 case RID_THROW: token->keyword = RID_AT_THROW; break;
456 case RID_TRY: token->keyword = RID_AT_TRY; break;
457 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
458 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
459 default: token->keyword = C_RID_CODE (token->value);
464 case CPP_CLOSE_PAREN:
466 /* These tokens may affect the interpretation of any identifiers
467 following, if doing Objective-C. */
468 if (c_dialect_objc ())
469 parser->objc_need_raw_identifier = false;
472 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
473 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
480 timevar_pop (TV_LEX);
483 /* Return a pointer to the next token from PARSER, reading it in if
487 c_parser_peek_token (c_parser *parser)
489 if (parser->tokens_avail == 0)
491 c_lex_one_token (parser, &parser->tokens[0]);
492 parser->tokens_avail = 1;
494 return &parser->tokens[0];
497 /* Return a pointer to the next-but-one token from PARSER, reading it
498 in if necessary. The next token is already read in. */
501 c_parser_peek_2nd_token (c_parser *parser)
503 if (parser->tokens_avail >= 2)
504 return &parser->tokens[1];
505 gcc_assert (parser->tokens_avail == 1);
506 gcc_assert (parser->tokens[0].type != CPP_EOF);
507 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
508 c_lex_one_token (parser, &parser->tokens[1]);
509 parser->tokens_avail = 2;
510 return &parser->tokens[1];
513 /* Return a pointer to the Nth token from PARSER, reading it
514 in if necessary. The N-1th token is already read in. */
517 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
519 /* N is 1-based, not zero-based. */
522 if (parser->tokens_avail >= n)
523 return &parser->tokens[n - 1];
524 gcc_assert (parser->tokens_avail == n - 1);
525 c_lex_one_token (parser, &parser->tokens[n - 1]);
526 parser->tokens_avail = n;
527 return &parser->tokens[n - 1];
530 /* Return a pointer to the Nth token from PARSER, reading it in as a
531 raw look-ahead token if necessary. The N-1th token is already read
532 in. Raw look-ahead tokens remain available for when the non-raw
533 functions above are called. */
536 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
538 /* N is 1-based, not zero-based. */
541 if (parser->tokens_avail >= n)
542 return &parser->tokens[n - 1];
543 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
544 unsigned int raw_avail
545 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
546 gcc_assert (raw_avail >= n - 1);
548 return &(*parser->raw_tokens)[parser->raw_tokens_used
549 + n - 1 - parser->tokens_avail];
550 vec_safe_reserve (parser->raw_tokens, 1);
551 parser->raw_tokens->quick_grow (raw_len + 1);
552 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
553 return &(*parser->raw_tokens)[raw_len];
557 c_keyword_starts_typename (enum rid keyword)
592 if (keyword >= RID_FIRST_INT_N
593 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
594 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
600 /* Return true if TOKEN can start a type name,
603 c_token_starts_typename (c_token *token)
608 switch (token->id_kind)
617 gcc_assert (c_dialect_objc ());
623 return c_keyword_starts_typename (token->keyword);
625 if (c_dialect_objc ())
633 /* Return true if the next token from PARSER can start a type name,
634 false otherwise. LA specifies how to do lookahead in order to
635 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
638 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
640 c_token *token = c_parser_peek_token (parser);
641 if (c_token_starts_typename (token))
644 /* Try a bit harder to detect an unknown typename. */
645 if (la != cla_prefer_id
646 && token->type == CPP_NAME
647 && token->id_kind == C_ID_ID
649 /* Do not try too hard when we could have "object in array". */
650 && !parser->objc_could_be_foreach_context
652 && (la == cla_prefer_type
653 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
654 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
656 /* Only unknown identifiers. */
657 && !lookup_name (token->value))
663 /* Return true if TOKEN is a type qualifier, false otherwise. */
665 c_token_is_qualifier (c_token *token)
670 switch (token->id_kind)
678 switch (token->keyword)
696 /* Return true if the next token from PARSER is a type qualifier,
699 c_parser_next_token_is_qualifier (c_parser *parser)
701 c_token *token = c_parser_peek_token (parser);
702 return c_token_is_qualifier (token);
705 /* Return true if TOKEN can start declaration specifiers (not
706 including standard attributes), false otherwise. */
708 c_token_starts_declspecs (c_token *token)
713 switch (token->id_kind)
722 gcc_assert (c_dialect_objc ());
728 switch (token->keyword)
769 if (token->keyword >= RID_FIRST_INT_N
770 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
771 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
776 if (c_dialect_objc ())
785 /* Return true if TOKEN can start declaration specifiers (not
786 including standard attributes) or a static assertion, false
789 c_token_starts_declaration (c_token *token)
791 if (c_token_starts_declspecs (token)
792 || token->keyword == RID_STATIC_ASSERT)
798 /* Return true if the next token from PARSER can start declaration
799 specifiers (not including standard attributes), false
802 c_parser_next_token_starts_declspecs (c_parser *parser)
804 c_token *token = c_parser_peek_token (parser);
806 /* In Objective-C, a classname normally starts a declspecs unless it
807 is immediately followed by a dot. In that case, it is the
808 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
809 setter/getter on the class. c_token_starts_declspecs() can't
810 differentiate between the two cases because it only checks the
811 current token, so we have a special check here. */
812 if (c_dialect_objc ()
813 && token->type == CPP_NAME
814 && token->id_kind == C_ID_CLASSNAME
815 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
818 return c_token_starts_declspecs (token);
821 /* Return true if the next tokens from PARSER can start declaration
822 specifiers (not including standard attributes) or a static
823 assertion, false otherwise. */
825 c_parser_next_tokens_start_declaration (c_parser *parser)
827 c_token *token = c_parser_peek_token (parser);
830 if (c_dialect_objc ()
831 && token->type == CPP_NAME
832 && token->id_kind == C_ID_CLASSNAME
833 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
836 /* Labels do not start declarations. */
837 if (token->type == CPP_NAME
838 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
841 if (c_token_starts_declaration (token))
844 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
850 /* Consume the next token from PARSER. */
853 c_parser_consume_token (c_parser *parser)
855 gcc_assert (parser->tokens_avail >= 1);
856 gcc_assert (parser->tokens[0].type != CPP_EOF);
857 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
858 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
859 parser->last_token_location = parser->tokens[0].location;
860 if (parser->tokens != &parser->tokens_buf[0])
862 else if (parser->tokens_avail >= 2)
864 parser->tokens[0] = parser->tokens[1];
865 if (parser->tokens_avail >= 3)
867 parser->tokens[1] = parser->tokens[2];
868 if (parser->tokens_avail >= 4)
869 parser->tokens[2] = parser->tokens[3];
872 parser->tokens_avail--;
873 parser->seen_string_literal = false;
876 /* Expect the current token to be a #pragma. Consume it and remember
877 that we've begun parsing a pragma. */
880 c_parser_consume_pragma (c_parser *parser)
882 gcc_assert (!parser->in_pragma);
883 gcc_assert (parser->tokens_avail >= 1);
884 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
885 if (parser->tokens != &parser->tokens_buf[0])
887 else if (parser->tokens_avail >= 2)
889 parser->tokens[0] = parser->tokens[1];
890 if (parser->tokens_avail >= 3)
891 parser->tokens[1] = parser->tokens[2];
893 parser->tokens_avail--;
894 parser->in_pragma = true;
897 /* Update the global input_location from TOKEN. */
899 c_parser_set_source_position_from_token (c_token *token)
901 if (token->type != CPP_EOF)
903 input_location = token->location;
907 /* Helper function for c_parser_error.
908 Having peeked a token of kind TOK1_KIND that might signify
909 a conflict marker, peek successor tokens to determine
910 if we actually do have a conflict marker.
911 Specifically, we consider a run of 7 '<', '=' or '>' characters
912 at the start of a line as a conflict marker.
913 These come through the lexer as three pairs and a single,
914 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
915 If it returns true, *OUT_LOC is written to with the location/range
919 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
922 c_token *token2 = c_parser_peek_2nd_token (parser);
923 if (token2->type != tok1_kind)
925 c_token *token3 = c_parser_peek_nth_token (parser, 3);
926 if (token3->type != tok1_kind)
928 c_token *token4 = c_parser_peek_nth_token (parser, 4);
929 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
932 /* It must be at the start of the line. */
933 location_t start_loc = c_parser_peek_token (parser)->location;
934 if (LOCATION_COLUMN (start_loc) != 1)
937 /* We have a conflict marker. Construct a location of the form:
940 with start == caret, finishing at the end of the marker. */
941 location_t finish_loc = get_finish (token4->location);
942 *out_loc = make_location (start_loc, start_loc, finish_loc);
947 /* Issue a diagnostic of the form
948 FILE:LINE: MESSAGE before TOKEN
949 where TOKEN is the next token in the input stream of PARSER.
950 MESSAGE (specified by the caller) is usually of the form "expected
953 Use RICHLOC as the location of the diagnostic.
955 Do not issue a diagnostic if still recovering from an error.
957 Return true iff an error was actually emitted.
959 ??? This is taken from the C++ parser, but building up messages in
960 this way is not i18n-friendly and some other approach should be
964 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
965 rich_location *richloc)
967 c_token *token = c_parser_peek_token (parser);
970 parser->error = true;
974 /* If this is actually a conflict marker, report it as such. */
975 if (token->type == CPP_LSHIFT
976 || token->type == CPP_RSHIFT
977 || token->type == CPP_EQ_EQ)
980 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
982 error_at (loc, "version control conflict marker in file");
987 /* If we were parsing a string-literal and there is an unknown name
988 token right after, then check to see if that could also have been
989 a literal string by checking the name against a list of known
990 standard string literal constants defined in header files. If
991 there is one, then add that as an hint to the error message. */
992 auto_diagnostic_group d;
994 if (parser->seen_string_literal && token->type == CPP_NAME)
996 tree name = token->value;
997 const char *token_name = IDENTIFIER_POINTER (name);
998 const char *header_hint
999 = get_c_stdlib_header_for_string_macro_name (token_name);
1000 if (header_hint != NULL)
1001 h = name_hint (NULL, new suggest_missing_header (token->location,
1006 c_parse_error (gmsgid,
1007 /* Because c_parse_error does not understand
1008 CPP_KEYWORD, keywords are treated like
1010 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1011 /* ??? The C parser does not save the cpp flags of a
1012 token, we need to pass 0 here and we will not get
1013 the source spelling of some tokens but rather the
1014 canonical spelling. */
1015 token->value, /*flags=*/0, richloc);
1019 /* As c_parser_error_richloc, but issue the message at the
1020 location of PARSER's next token, or at input_location
1021 if the next token is EOF. */
1024 c_parser_error (c_parser *parser, const char *gmsgid)
1026 c_token *token = c_parser_peek_token (parser);
1027 c_parser_set_source_position_from_token (token);
1028 rich_location richloc (line_table, input_location);
1029 return c_parser_error_richloc (parser, gmsgid, &richloc);
1032 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1033 This class is for tracking such a matching pair of symbols.
1034 In particular, it tracks the location of the first token,
1035 so that if the second token is missing, we can highlight the
1036 location of the first token when notifying the user about the
1039 template <typename traits_t>
1043 /* token_pair's ctor. */
1044 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1046 /* If the next token is the opening symbol for this pair, consume it and
1048 Otherwise, issue an error and return false.
1049 In either case, record the location of the opening token. */
1051 bool require_open (c_parser *parser)
1053 c_token *token = c_parser_peek_token (parser);
1055 m_open_loc = token->location;
1057 return c_parser_require (parser, traits_t::open_token_type,
1058 traits_t::open_gmsgid);
1061 /* Consume the next token from PARSER, recording its location as
1062 that of the opening token within the pair. */
1064 void consume_open (c_parser *parser)
1066 c_token *token = c_parser_peek_token (parser);
1067 gcc_assert (token->type == traits_t::open_token_type);
1068 m_open_loc = token->location;
1069 c_parser_consume_token (parser);
1072 /* If the next token is the closing symbol for this pair, consume it
1074 Otherwise, issue an error, highlighting the location of the
1075 corresponding opening token, and return false. */
1077 bool require_close (c_parser *parser) const
1079 return c_parser_require (parser, traits_t::close_token_type,
1080 traits_t::close_gmsgid, m_open_loc);
1083 /* Like token_pair::require_close, except that tokens will be skipped
1084 until the desired token is found. An error message is still produced
1085 if the next token is not as expected. */
1087 void skip_until_found_close (c_parser *parser) const
1089 c_parser_skip_until_found (parser, traits_t::close_token_type,
1090 traits_t::close_gmsgid, m_open_loc);
1094 location_t m_open_loc;
1097 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1099 struct matching_paren_traits
1101 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1102 static const char * const open_gmsgid;
1103 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1104 static const char * const close_gmsgid;
1107 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1108 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1110 /* "matching_parens" is a token_pair<T> class for tracking matching
1111 pairs of parentheses. */
1113 typedef token_pair<matching_paren_traits> matching_parens;
1115 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1117 struct matching_brace_traits
1119 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1120 static const char * const open_gmsgid;
1121 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1122 static const char * const close_gmsgid;
1125 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1126 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1128 /* "matching_braces" is a token_pair<T> class for tracking matching
1131 typedef token_pair<matching_brace_traits> matching_braces;
1133 /* Get a description of the matching symbol to TYPE e.g. "(" for
1137 get_matching_symbol (enum cpp_ttype type)
1143 case CPP_CLOSE_PAREN:
1145 case CPP_CLOSE_BRACE:
1150 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1151 issue the error MSGID. If MSGID is NULL then a message has already
1152 been produced and no message will be produced this time. Returns
1153 true if found, false otherwise.
1155 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1156 within any error as the location of an "opening" token matching
1157 the close token TYPE (e.g. the location of the '(' when TYPE is
1160 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1161 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1162 attempt to generate a fix-it hint for the problem.
1163 Otherwise msgid describes multiple token types (e.g.
1164 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1165 generate a fix-it hint. */
1168 c_parser_require (c_parser *parser,
1169 enum cpp_ttype type,
1171 location_t matching_location,
1172 bool type_is_unique)
1174 if (c_parser_next_token_is (parser, type))
1176 c_parser_consume_token (parser);
1181 location_t next_token_loc = c_parser_peek_token (parser)->location;
1182 gcc_rich_location richloc (next_token_loc);
1184 /* Potentially supply a fix-it hint, suggesting to add the
1185 missing token immediately after the *previous* token.
1186 This may move the primary location within richloc. */
1187 if (!parser->error && type_is_unique)
1188 maybe_suggest_missing_token_insertion (&richloc, type,
1189 parser->last_token_location);
1191 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1192 Attempt to consolidate diagnostics by printing it as a
1193 secondary range within the main diagnostic. */
1194 bool added_matching_location = false;
1195 if (matching_location != UNKNOWN_LOCATION)
1196 added_matching_location
1197 = richloc.add_location_if_nearby (matching_location);
1199 if (c_parser_error_richloc (parser, msgid, &richloc))
1200 /* If we weren't able to consolidate matching_location, then
1201 print it as a secondary diagnostic. */
1202 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1203 inform (matching_location, "to match this %qs",
1204 get_matching_symbol (type));
1210 /* If the next token is the indicated keyword, consume it. Otherwise,
1211 issue the error MSGID. Returns true if found, false otherwise. */
1214 c_parser_require_keyword (c_parser *parser,
1218 if (c_parser_next_token_is_keyword (parser, keyword))
1220 c_parser_consume_token (parser);
1225 c_parser_error (parser, msgid);
1230 /* Like c_parser_require, except that tokens will be skipped until the
1231 desired token is found. An error message is still produced if the
1232 next token is not as expected. If MSGID is NULL then a message has
1233 already been produced and no message will be produced this
1236 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1237 within any error as the location of an "opening" token matching
1238 the close token TYPE (e.g. the location of the '(' when TYPE is
1239 CPP_CLOSE_PAREN). */
1242 c_parser_skip_until_found (c_parser *parser,
1243 enum cpp_ttype type,
1245 location_t matching_location)
1247 unsigned nesting_depth = 0;
1249 if (c_parser_require (parser, type, msgid, matching_location))
1252 /* Skip tokens until the desired token is found. */
1255 /* Peek at the next token. */
1256 c_token *token = c_parser_peek_token (parser);
1257 /* If we've reached the token we want, consume it and stop. */
1258 if (token->type == type && !nesting_depth)
1260 c_parser_consume_token (parser);
1264 /* If we've run out of tokens, stop. */
1265 if (token->type == CPP_EOF)
1267 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1269 if (token->type == CPP_OPEN_BRACE
1270 || token->type == CPP_OPEN_PAREN
1271 || token->type == CPP_OPEN_SQUARE)
1273 else if (token->type == CPP_CLOSE_BRACE
1274 || token->type == CPP_CLOSE_PAREN
1275 || token->type == CPP_CLOSE_SQUARE)
1277 if (nesting_depth-- == 0)
1280 /* Consume this token. */
1281 c_parser_consume_token (parser);
1283 parser->error = false;
1286 /* Skip tokens until the end of a parameter is found, but do not
1287 consume the comma, semicolon or closing delimiter. */
1290 c_parser_skip_to_end_of_parameter (c_parser *parser)
1292 unsigned nesting_depth = 0;
1296 c_token *token = c_parser_peek_token (parser);
1297 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1300 /* If we've run out of tokens, stop. */
1301 if (token->type == CPP_EOF)
1303 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1305 if (token->type == CPP_OPEN_BRACE
1306 || token->type == CPP_OPEN_PAREN
1307 || token->type == CPP_OPEN_SQUARE)
1309 else if (token->type == CPP_CLOSE_BRACE
1310 || token->type == CPP_CLOSE_PAREN
1311 || token->type == CPP_CLOSE_SQUARE)
1313 if (nesting_depth-- == 0)
1316 /* Consume this token. */
1317 c_parser_consume_token (parser);
1319 parser->error = false;
1322 /* Expect to be at the end of the pragma directive and consume an
1323 end of line marker. */
1326 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1328 gcc_assert (parser->in_pragma);
1329 parser->in_pragma = false;
1331 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1332 c_parser_error (parser, "expected end of line");
1334 cpp_ttype token_type;
1337 c_token *token = c_parser_peek_token (parser);
1338 token_type = token->type;
1339 if (token_type == CPP_EOF)
1341 c_parser_consume_token (parser);
1343 while (token_type != CPP_PRAGMA_EOL);
1345 parser->error = false;
1348 /* Skip tokens until we have consumed an entire block, or until we
1349 have consumed a non-nested ';'. */
1352 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1354 unsigned nesting_depth = 0;
1355 bool save_error = parser->error;
1361 /* Peek at the next token. */
1362 token = c_parser_peek_token (parser);
1364 switch (token->type)
1369 case CPP_PRAGMA_EOL:
1370 if (parser->in_pragma)
1375 /* If the next token is a ';', we have reached the
1376 end of the statement. */
1379 /* Consume the ';'. */
1380 c_parser_consume_token (parser);
1385 case CPP_CLOSE_BRACE:
1386 /* If the next token is a non-nested '}', then we have
1387 reached the end of the current block. */
1388 if (nesting_depth == 0 || --nesting_depth == 0)
1390 c_parser_consume_token (parser);
1395 case CPP_OPEN_BRACE:
1396 /* If it the next token is a '{', then we are entering a new
1397 block. Consume the entire block. */
1402 /* If we see a pragma, consume the whole thing at once. We
1403 have some safeguards against consuming pragmas willy-nilly.
1404 Normally, we'd expect to be here with parser->error set,
1405 which disables these safeguards. But it's possible to get
1406 here for secondary error recovery, after parser->error has
1408 c_parser_consume_pragma (parser);
1409 c_parser_skip_to_pragma_eol (parser);
1410 parser->error = save_error;
1417 c_parser_consume_token (parser);
1421 parser->error = false;
1424 /* CPP's options (initialized by c-opts.cc). */
1425 extern cpp_options *cpp_opts;
1427 /* Save the warning flags which are controlled by __extension__. */
1430 disable_extension_diagnostics (void)
1433 | (warn_pointer_arith << 1)
1434 | (warn_traditional << 2)
1436 | (warn_long_long << 4)
1437 | (warn_cxx_compat << 5)
1438 | (warn_overlength_strings << 6)
1439 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1440 play tricks to properly restore it. */
1441 | ((warn_c90_c99_compat == 1) << 7)
1442 | ((warn_c90_c99_compat == -1) << 8)
1443 /* Similarly for warn_c99_c11_compat. */
1444 | ((warn_c99_c11_compat == 1) << 9)
1445 | ((warn_c99_c11_compat == -1) << 10)
1446 /* Similarly for warn_c11_c2x_compat. */
1447 | ((warn_c11_c2x_compat == 1) << 11)
1448 | ((warn_c11_c2x_compat == -1) << 12)
1450 cpp_opts->cpp_pedantic = pedantic = 0;
1451 warn_pointer_arith = 0;
1452 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1454 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1455 warn_cxx_compat = 0;
1456 warn_overlength_strings = 0;
1457 warn_c90_c99_compat = 0;
1458 warn_c99_c11_compat = 0;
1459 warn_c11_c2x_compat = 0;
1463 /* Restore the warning flags which are controlled by __extension__.
1464 FLAGS is the return value from disable_extension_diagnostics. */
1467 restore_extension_diagnostics (int flags)
1469 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1470 warn_pointer_arith = (flags >> 1) & 1;
1471 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1472 flag_iso = (flags >> 3) & 1;
1473 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1474 warn_cxx_compat = (flags >> 5) & 1;
1475 warn_overlength_strings = (flags >> 6) & 1;
1476 /* See above for why is this needed. */
1477 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1478 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1479 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1482 /* Helper data structure for parsing #pragma acc routine. */
1483 struct oacc_routine_data {
1484 bool error_seen; /* Set if error has been reported. */
1485 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1490 /* Used for parsing objc foreach statements. */
1491 static tree objc_foreach_break_label, objc_foreach_continue_label;
1493 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1495 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1496 static void c_parser_external_declaration (c_parser *);
1497 static void c_parser_asm_definition (c_parser *);
1498 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1499 bool, bool, tree * = NULL,
1500 vec<c_token> * = NULL,
1501 bool have_attrs = false,
1503 struct oacc_routine_data * = NULL,
1505 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1506 static void c_parser_static_assert_declaration (c_parser *);
1507 static struct c_typespec c_parser_enum_specifier (c_parser *);
1508 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1509 static tree c_parser_struct_declaration (c_parser *);
1510 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1511 static tree c_parser_alignas_specifier (c_parser *);
1512 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1514 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1516 struct c_declarator *);
1517 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1519 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1521 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1522 static tree c_parser_simple_asm_expr (c_parser *);
1523 static tree c_parser_gnu_attributes (c_parser *);
1524 static struct c_expr c_parser_initializer (c_parser *, tree);
1525 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1527 static void c_parser_initelt (c_parser *, struct obstack *);
1528 static void c_parser_initval (c_parser *, struct c_expr *,
1530 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1531 static location_t c_parser_compound_statement_nostart (c_parser *);
1532 static void c_parser_label (c_parser *, tree);
1533 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1534 static void c_parser_statement_after_labels (c_parser *, bool *,
1535 vec<tree> * = NULL);
1536 static tree c_parser_c99_block_statement (c_parser *, bool *,
1537 location_t * = NULL);
1538 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1539 static void c_parser_switch_statement (c_parser *, bool *);
1540 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1541 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1542 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1543 static tree c_parser_asm_statement (c_parser *);
1544 static tree c_parser_asm_operands (c_parser *);
1545 static tree c_parser_asm_goto_operands (c_parser *);
1546 static tree c_parser_asm_clobbers (c_parser *);
1547 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1549 static struct c_expr c_parser_conditional_expression (c_parser *,
1550 struct c_expr *, tree);
1551 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1553 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1554 static struct c_expr c_parser_unary_expression (c_parser *);
1555 static struct c_expr c_parser_sizeof_expression (c_parser *);
1556 static struct c_expr c_parser_alignof_expression (c_parser *);
1557 static struct c_expr c_parser_postfix_expression (c_parser *);
1558 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1559 struct c_type_name *,
1561 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1564 static tree c_parser_transaction (c_parser *, enum rid);
1565 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1566 static tree c_parser_transaction_cancel (c_parser *);
1567 static struct c_expr c_parser_expression (c_parser *);
1568 static struct c_expr c_parser_expression_conv (c_parser *);
1569 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1570 vec<tree, va_gc> **, location_t *,
1571 tree *, vec<location_t> *,
1572 unsigned int * = NULL);
1573 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1575 static void c_parser_oacc_declare (c_parser *);
1576 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1577 static void c_parser_oacc_update (c_parser *);
1578 static void c_parser_omp_construct (c_parser *, bool *);
1579 static void c_parser_omp_threadprivate (c_parser *);
1580 static void c_parser_omp_barrier (c_parser *);
1581 static void c_parser_omp_depobj (c_parser *);
1582 static void c_parser_omp_flush (c_parser *);
1583 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1584 tree, tree *, bool *);
1585 static void c_parser_omp_taskwait (c_parser *);
1586 static void c_parser_omp_taskyield (c_parser *);
1587 static void c_parser_omp_cancel (c_parser *);
1588 static void c_parser_omp_nothing (c_parser *);
1590 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1591 pragma_stmt, pragma_compound };
1592 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1593 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1594 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1595 static void c_parser_omp_end_declare_target (c_parser *);
1596 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1597 static void c_parser_omp_requires (c_parser *);
1598 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1599 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1600 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1602 /* These Objective-C parser functions are only ever called when
1603 compiling Objective-C. */
1604 static void c_parser_objc_class_definition (c_parser *, tree);
1605 static void c_parser_objc_class_instance_variables (c_parser *);
1606 static void c_parser_objc_class_declaration (c_parser *);
1607 static void c_parser_objc_alias_declaration (c_parser *);
1608 static void c_parser_objc_protocol_definition (c_parser *, tree);
1609 static bool c_parser_objc_method_type (c_parser *);
1610 static void c_parser_objc_method_definition (c_parser *);
1611 static void c_parser_objc_methodprotolist (c_parser *);
1612 static void c_parser_objc_methodproto (c_parser *);
1613 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1614 static tree c_parser_objc_type_name (c_parser *);
1615 static tree c_parser_objc_protocol_refs (c_parser *);
1616 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1617 static void c_parser_objc_synchronized_statement (c_parser *);
1618 static tree c_parser_objc_selector (c_parser *);
1619 static tree c_parser_objc_selector_arg (c_parser *);
1620 static tree c_parser_objc_receiver (c_parser *);
1621 static tree c_parser_objc_message_args (c_parser *);
1622 static tree c_parser_objc_keywordexpr (c_parser *);
1623 static void c_parser_objc_at_property_declaration (c_parser *);
1624 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1625 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1626 static bool c_parser_objc_diagnose_bad_element_prefix
1627 (c_parser *, struct c_declspecs *);
1628 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1630 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1633 external-declarations
1635 external-declarations:
1636 external-declaration
1637 external-declarations external-declaration
1646 c_parser_translation_unit (c_parser *parser)
1648 if (c_parser_next_token_is (parser, CPP_EOF))
1650 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1651 "ISO C forbids an empty translation unit");
1655 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1656 mark_valid_location_for_stdc_pragma (false);
1660 c_parser_external_declaration (parser);
1661 obstack_free (&parser_obstack, obstack_position);
1663 while (c_parser_next_token_is_not (parser, CPP_EOF));
1668 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1669 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1670 error ("storage size of %q+D isn%'t known", decl);
1672 if (current_omp_declare_target_attribute)
1675 error ("%<#pragma omp declare target%> without corresponding "
1676 "%<#pragma omp end declare target%>");
1677 current_omp_declare_target_attribute = 0;
1681 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1683 external-declaration:
1689 external-declaration:
1692 __extension__ external-declaration
1696 external-declaration:
1697 objc-class-definition
1698 objc-class-declaration
1699 objc-alias-declaration
1700 objc-protocol-definition
1701 objc-method-definition
1706 c_parser_external_declaration (c_parser *parser)
1709 switch (c_parser_peek_token (parser)->type)
1712 switch (c_parser_peek_token (parser)->keyword)
1715 ext = disable_extension_diagnostics ();
1716 c_parser_consume_token (parser);
1717 c_parser_external_declaration (parser);
1718 restore_extension_diagnostics (ext);
1721 c_parser_asm_definition (parser);
1723 case RID_AT_INTERFACE:
1724 case RID_AT_IMPLEMENTATION:
1725 gcc_assert (c_dialect_objc ());
1726 c_parser_objc_class_definition (parser, NULL_TREE);
1729 gcc_assert (c_dialect_objc ());
1730 c_parser_objc_class_declaration (parser);
1733 gcc_assert (c_dialect_objc ());
1734 c_parser_objc_alias_declaration (parser);
1736 case RID_AT_PROTOCOL:
1737 gcc_assert (c_dialect_objc ());
1738 c_parser_objc_protocol_definition (parser, NULL_TREE);
1740 case RID_AT_PROPERTY:
1741 gcc_assert (c_dialect_objc ());
1742 c_parser_objc_at_property_declaration (parser);
1744 case RID_AT_SYNTHESIZE:
1745 gcc_assert (c_dialect_objc ());
1746 c_parser_objc_at_synthesize_declaration (parser);
1748 case RID_AT_DYNAMIC:
1749 gcc_assert (c_dialect_objc ());
1750 c_parser_objc_at_dynamic_declaration (parser);
1753 gcc_assert (c_dialect_objc ());
1754 c_parser_consume_token (parser);
1755 objc_finish_implementation ();
1762 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1763 "ISO C does not allow extra %<;%> outside of a function");
1764 c_parser_consume_token (parser);
1767 mark_valid_location_for_stdc_pragma (true);
1768 c_parser_pragma (parser, pragma_external, NULL);
1769 mark_valid_location_for_stdc_pragma (false);
1773 if (c_dialect_objc ())
1775 c_parser_objc_method_definition (parser);
1778 /* Else fall through, and yield a syntax error trying to parse
1779 as a declaration or function definition. */
1783 /* A declaration or a function definition (or, in Objective-C,
1784 an @interface or @protocol with prefix attributes). We can
1785 only tell which after parsing the declaration specifiers, if
1786 any, and the first declarator. */
1787 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1792 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1793 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1795 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1798 add_debug_begin_stmt (location_t loc)
1800 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1801 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1804 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1805 SET_EXPR_LOCATION (stmt, loc);
1809 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1810 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1811 is accepted; otherwise (old-style parameter declarations) only other
1812 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1813 assertion is accepted; otherwise (old-style parameter declarations)
1814 it is not. If NESTED is true, we are inside a function or parsing
1815 old-style parameter declarations; any functions encountered are
1816 nested functions and declaration specifiers are required; otherwise
1817 we are at top level and functions are normal functions and
1818 declaration specifiers may be optional. If EMPTY_OK is true, empty
1819 declarations are OK (subject to all other constraints); otherwise
1820 (old-style parameter declarations) they are diagnosed. If
1821 START_ATTR_OK is true, the declaration specifiers may start with
1822 attributes (GNU or standard); otherwise they may not.
1823 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1824 declaration when parsing an Objective-C foreach statement.
1825 FALLTHRU_ATTR_P is used to signal whether this function parsed
1826 "__attribute__((fallthrough));". ATTRS are any standard attributes
1827 parsed in the caller (in contexts where such attributes had to be
1828 parsed to determine whether what follows is a declaration or a
1829 statement); HAVE_ATTRS says whether there were any such attributes
1833 declaration-specifiers init-declarator-list[opt] ;
1834 static_assert-declaration
1836 function-definition:
1837 declaration-specifiers[opt] declarator declaration-list[opt]
1842 declaration-list declaration
1844 init-declarator-list:
1846 init-declarator-list , init-declarator
1849 declarator simple-asm-expr[opt] gnu-attributes[opt]
1850 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1854 nested-function-definition:
1855 declaration-specifiers declarator declaration-list[opt]
1861 gnu-attributes objc-class-definition
1862 gnu-attributes objc-category-definition
1863 gnu-attributes objc-protocol-definition
1865 The simple-asm-expr and gnu-attributes are GNU extensions.
1867 This function does not handle __extension__; that is handled in its
1868 callers. ??? Following the old parser, __extension__ may start
1869 external declarations, declarations in functions and declarations
1870 at the start of "for" loops, but not old-style parameter
1873 C99 requires declaration specifiers in a function definition; the
1874 absence is diagnosed through the diagnosis of implicit int. In GNU
1875 C we also allow but diagnose declarations without declaration
1876 specifiers, but only at top level (elsewhere they conflict with
1879 In Objective-C, declarations of the looping variable in a foreach
1880 statement are exceptionally terminated by 'in' (for example, 'for
1881 (NSObject *object in array) { ... }').
1886 threadprivate-directive
1890 gimple-function-definition:
1891 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1892 declaration-list[opt] compound-statement
1894 rtl-function-definition:
1895 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1896 declaration-list[opt] compound-statement */
1899 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1900 bool static_assert_ok, bool empty_ok,
1901 bool nested, bool start_attr_ok,
1902 tree *objc_foreach_object_declaration
1904 vec<c_token> *omp_declare_simd_clauses
1906 bool have_attrs /* = false */,
1907 tree attrs /* = NULL_TREE */,
1908 struct oacc_routine_data *oacc_routine_data
1910 bool *fallthru_attr_p /* = NULL */)
1912 struct c_declspecs *specs;
1914 tree all_prefix_attrs;
1915 bool diagnosed_no_specs = false;
1916 location_t here = c_parser_peek_token (parser)->location;
1918 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1920 if (static_assert_ok
1921 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1923 c_parser_static_assert_declaration (parser);
1926 specs = build_null_declspecs ();
1928 /* Handle any standard attributes parsed in the caller. */
1931 declspecs_add_attrs (here, specs, attrs);
1932 specs->non_std_attrs_seen_p = false;
1935 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1936 if (c_parser_peek_token (parser)->type == CPP_NAME
1937 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1938 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1939 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1940 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1942 tree name = c_parser_peek_token (parser)->value;
1944 /* Issue a warning about NAME being an unknown type name, perhaps
1945 with some kind of hint.
1946 If the user forgot a "struct" etc, suggest inserting
1947 it. Otherwise, attempt to look for misspellings. */
1948 gcc_rich_location richloc (here);
1949 if (tag_exists_p (RECORD_TYPE, name))
1951 /* This is not C++ with its implicit typedef. */
1952 richloc.add_fixit_insert_before ("struct ");
1954 "unknown type name %qE;"
1955 " use %<struct%> keyword to refer to the type",
1958 else if (tag_exists_p (UNION_TYPE, name))
1960 richloc.add_fixit_insert_before ("union ");
1962 "unknown type name %qE;"
1963 " use %<union%> keyword to refer to the type",
1966 else if (tag_exists_p (ENUMERAL_TYPE, name))
1968 richloc.add_fixit_insert_before ("enum ");
1970 "unknown type name %qE;"
1971 " use %<enum%> keyword to refer to the type",
1976 auto_diagnostic_group d;
1977 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1979 if (const char *suggestion = hint.suggestion ())
1981 richloc.add_fixit_replace (suggestion);
1983 "unknown type name %qE; did you mean %qs?",
1987 error_at (here, "unknown type name %qE", name);
1990 /* Parse declspecs normally to get a correct pointer type, but avoid
1991 a further "fails to be a type name" error. Refuse nested functions
1992 since it is not how the user likely wants us to recover. */
1993 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1994 c_parser_peek_token (parser)->keyword = RID_VOID;
1995 c_parser_peek_token (parser)->value = error_mark_node;
1999 /* When there are standard attributes at the start of the
2000 declaration (to apply to the entity being declared), an
2001 init-declarator-list or function definition must be present. */
2002 if (c_parser_nth_token_starts_std_attributes (parser, 1))
2005 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2006 true, true, start_attr_ok, true, cla_nonabstract_decl);
2009 c_parser_skip_to_end_of_block_or_statement (parser);
2012 if (nested && !specs->declspecs_seen_p)
2014 c_parser_error (parser, "expected declaration specifiers");
2015 c_parser_skip_to_end_of_block_or_statement (parser);
2019 finish_declspecs (specs);
2020 bool auto_type_p = specs->typespec_word == cts_auto_type;
2021 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2024 error_at (here, "%<__auto_type%> in empty declaration");
2025 else if (specs->typespec_kind == ctsk_none
2026 && attribute_fallthrough_p (specs->attrs))
2028 if (fallthru_attr_p != NULL)
2029 *fallthru_attr_p = true;
2032 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2037 pedwarn (here, OPT_Wattributes,
2038 "%<fallthrough%> attribute at top level");
2040 else if (empty_ok && !(have_attrs
2041 && specs->non_std_attrs_seen_p))
2045 shadow_tag_warned (specs, 1);
2046 pedwarn (here, 0, "empty declaration");
2048 c_parser_consume_token (parser);
2049 if (oacc_routine_data)
2050 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2054 /* Provide better error recovery. Note that a type name here is usually
2055 better diagnosed as a redeclaration. */
2057 && specs->typespec_kind == ctsk_tagdef
2058 && c_parser_next_token_starts_declspecs (parser)
2059 && !c_parser_next_token_is (parser, CPP_NAME))
2061 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2062 parser->error = false;
2063 shadow_tag_warned (specs, 1);
2066 else if (c_dialect_objc () && !auto_type_p)
2068 /* Prefix attributes are an error on method decls. */
2069 switch (c_parser_peek_token (parser)->type)
2073 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2077 warning_at (c_parser_peek_token (parser)->location,
2079 "prefix attributes are ignored for methods");
2080 specs->attrs = NULL_TREE;
2083 c_parser_objc_method_definition (parser);
2085 c_parser_objc_methodproto (parser);
2091 /* This is where we parse 'attributes @interface ...',
2092 'attributes @implementation ...', 'attributes @protocol ...'
2093 (where attributes could be, for example, __attribute__
2096 switch (c_parser_peek_token (parser)->keyword)
2098 case RID_AT_INTERFACE:
2100 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2102 c_parser_objc_class_definition (parser, specs->attrs);
2106 case RID_AT_IMPLEMENTATION:
2108 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2112 warning_at (c_parser_peek_token (parser)->location,
2114 "prefix attributes are ignored for implementations");
2115 specs->attrs = NULL_TREE;
2117 c_parser_objc_class_definition (parser, NULL_TREE);
2121 case RID_AT_PROTOCOL:
2123 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2125 c_parser_objc_protocol_definition (parser, specs->attrs);
2132 case RID_AT_PROPERTY:
2135 c_parser_error (parser, "unexpected attribute");
2136 specs->attrs = NULL;
2143 else if (attribute_fallthrough_p (specs->attrs))
2144 warning_at (here, OPT_Wattributes,
2145 "%<fallthrough%> attribute not followed by %<;%>");
2147 pending_xref_error ();
2148 prefix_attrs = specs->attrs;
2149 all_prefix_attrs = prefix_attrs;
2150 specs->attrs = NULL_TREE;
2153 struct c_declarator *declarator;
2156 tree fnbody = NULL_TREE;
2157 /* Declaring either one or more declarators (in which case we
2158 should diagnose if there were no declaration specifiers) or a
2159 function definition (in which case the diagnostic for
2160 implicit int suffices). */
2161 declarator = c_parser_declarator (parser,
2162 specs->typespec_kind != ctsk_none,
2163 C_DTR_NORMAL, &dummy);
2164 if (declarator == NULL)
2166 if (omp_declare_simd_clauses)
2167 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2168 omp_declare_simd_clauses);
2169 if (oacc_routine_data)
2170 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2171 c_parser_skip_to_end_of_block_or_statement (parser);
2174 if (auto_type_p && declarator->kind != cdk_id)
2177 "%<__auto_type%> requires a plain identifier"
2179 c_parser_skip_to_end_of_block_or_statement (parser);
2182 if (c_parser_next_token_is (parser, CPP_EQ)
2183 || c_parser_next_token_is (parser, CPP_COMMA)
2184 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2185 || c_parser_next_token_is_keyword (parser, RID_ASM)
2186 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2187 || c_parser_next_token_is_keyword (parser, RID_IN))
2189 tree asm_name = NULL_TREE;
2190 tree postfix_attrs = NULL_TREE;
2191 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2193 diagnosed_no_specs = true;
2194 pedwarn (here, 0, "data definition has no type or storage class");
2196 /* Having seen a data definition, there cannot now be a
2197 function definition. */
2199 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2200 asm_name = c_parser_simple_asm_expr (parser);
2201 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2203 postfix_attrs = c_parser_gnu_attributes (parser);
2204 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2206 /* This means there is an attribute specifier after
2207 the declarator in a function definition. Provide
2208 some more information for the user. */
2209 error_at (here, "attributes should be specified before the "
2210 "declarator in a function definition");
2211 c_parser_skip_to_end_of_block_or_statement (parser);
2215 if (c_parser_next_token_is (parser, CPP_EQ))
2219 location_t init_loc;
2220 c_parser_consume_token (parser);
2223 init_loc = c_parser_peek_token (parser)->location;
2224 rich_location richloc (line_table, init_loc);
2225 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2226 /* A parameter is initialized, which is invalid. Don't
2227 attempt to instrument the initializer. */
2228 int flag_sanitize_save = flag_sanitize;
2229 if (nested && !empty_ok)
2231 init = c_parser_expr_no_commas (parser, NULL);
2232 flag_sanitize = flag_sanitize_save;
2233 if (TREE_CODE (init.value) == COMPONENT_REF
2234 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2236 "%<__auto_type%> used with a bit-field"
2238 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2239 tree init_type = TREE_TYPE (init.value);
2240 bool vm_type = variably_modified_type_p (init_type,
2243 init.value = save_expr (init.value);
2245 specs->typespec_kind = ctsk_typeof;
2246 specs->locations[cdw_typedef] = init_loc;
2247 specs->typedef_p = true;
2248 specs->type = init_type;
2251 bool maybe_const = true;
2252 tree type_expr = c_fully_fold (init.value, false,
2254 specs->expr_const_operands &= maybe_const;
2256 specs->expr = build2 (COMPOUND_EXPR,
2257 TREE_TYPE (type_expr),
2258 specs->expr, type_expr);
2260 specs->expr = type_expr;
2262 d = start_decl (declarator, specs, true,
2263 chainon (postfix_attrs, all_prefix_attrs));
2265 d = error_mark_node;
2266 if (omp_declare_simd_clauses)
2267 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2268 omp_declare_simd_clauses);
2272 /* The declaration of the variable is in effect while
2273 its initializer is parsed. */
2274 d = start_decl (declarator, specs, true,
2275 chainon (postfix_attrs, all_prefix_attrs));
2277 d = error_mark_node;
2278 if (omp_declare_simd_clauses)
2279 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2280 omp_declare_simd_clauses);
2281 init_loc = c_parser_peek_token (parser)->location;
2282 rich_location richloc (line_table, init_loc);
2283 start_init (d, asm_name, global_bindings_p (), &richloc);
2284 /* A parameter is initialized, which is invalid. Don't
2285 attempt to instrument the initializer. */
2286 int flag_sanitize_save = flag_sanitize;
2287 if (TREE_CODE (d) == PARM_DECL)
2289 init = c_parser_initializer (parser, d);
2290 flag_sanitize = flag_sanitize_save;
2293 if (oacc_routine_data)
2294 c_finish_oacc_routine (oacc_routine_data, d, false);
2295 if (d != error_mark_node)
2297 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2298 finish_decl (d, init_loc, init.value,
2299 init.original_type, asm_name);
2307 "%<__auto_type%> requires an initialized "
2308 "data declaration");
2309 c_parser_skip_to_end_of_block_or_statement (parser);
2313 location_t lastloc = UNKNOWN_LOCATION;
2314 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2315 tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2316 if (d && TREE_CODE (d) == FUNCTION_DECL)
2318 /* Find the innermost declarator that is neither cdk_id
2320 const struct c_declarator *decl = declarator;
2321 const struct c_declarator *last_non_id_attrs = NULL;
2329 last_non_id_attrs = decl;
2330 decl = decl->declarator;
2334 decl = decl->declarator;
2345 /* If it exists and is cdk_function declaration whose
2346 arguments have not been set yet, use its arguments. */
2347 if (last_non_id_attrs
2348 && last_non_id_attrs->kind == cdk_function)
2350 tree parms = last_non_id_attrs->u.arg_info->parms;
2351 if (DECL_ARGUMENTS (d) == NULL_TREE
2352 && DECL_INITIAL (d) == NULL_TREE)
2353 DECL_ARGUMENTS (d) = parms;
2355 warn_parm_array_mismatch (lastloc, d, parms);
2358 if (omp_declare_simd_clauses)
2360 tree parms = NULL_TREE;
2361 if (d && TREE_CODE (d) == FUNCTION_DECL)
2363 struct c_declarator *ce = declarator;
2365 if (ce->kind == cdk_function)
2367 parms = ce->u.arg_info->parms;
2371 ce = ce->declarator;
2374 temp_store_parm_decls (d, parms);
2375 c_finish_omp_declare_simd (parser, d, parms,
2376 omp_declare_simd_clauses);
2378 temp_pop_parm_decls ();
2380 if (oacc_routine_data)
2381 c_finish_oacc_routine (oacc_routine_data, d, false);
2383 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2384 NULL_TREE, asm_name);
2386 if (c_parser_next_token_is_keyword (parser, RID_IN))
2389 *objc_foreach_object_declaration = d;
2391 *objc_foreach_object_declaration = error_mark_node;
2394 if (c_parser_next_token_is (parser, CPP_COMMA))
2399 "%<__auto_type%> may only be used with"
2400 " a single declarator");
2401 c_parser_skip_to_end_of_block_or_statement (parser);
2404 c_parser_consume_token (parser);
2405 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2406 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2409 all_prefix_attrs = prefix_attrs;
2412 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2414 c_parser_consume_token (parser);
2417 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2419 /* This can only happen in Objective-C: we found the
2420 'in' that terminates the declaration inside an
2421 Objective-C foreach statement. Do not consume the
2422 token, so that the caller can use it to determine
2423 that this indeed is a foreach context. */
2428 c_parser_error (parser, "expected %<,%> or %<;%>");
2429 c_parser_skip_to_end_of_block_or_statement (parser);
2433 else if (auto_type_p)
2436 "%<__auto_type%> requires an initialized data declaration");
2437 c_parser_skip_to_end_of_block_or_statement (parser);
2442 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2443 "%<asm%> or %<__attribute__%>");
2444 c_parser_skip_to_end_of_block_or_statement (parser);
2447 /* Function definition (nested or otherwise). */
2450 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2451 c_push_function_context ();
2453 if (!start_function (specs, declarator, all_prefix_attrs))
2455 /* At this point we've consumed:
2456 declaration-specifiers declarator
2457 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2458 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2460 declaration-specifiers declarator
2461 aren't grokkable as a function definition, so we have
2463 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2464 if (c_parser_next_token_starts_declspecs (parser))
2467 declaration-specifiers declarator decl-specs
2468 then assume we have a missing semicolon, which would
2470 declaration-specifiers declarator decl-specs
2473 <~~~~~~~~~ declaration ~~~~~~~~~~>
2474 Use c_parser_require to get an error with a fix-it hint. */
2475 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2476 parser->error = false;
2480 /* This can appear in many cases looking nothing like a
2481 function definition, so we don't give a more specific
2482 error suggesting there was one. */
2483 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2484 "or %<__attribute__%>");
2487 c_pop_function_context ();
2491 if (DECL_DECLARED_INLINE_P (current_function_decl))
2492 tv = TV_PARSE_INLINE;
2495 auto_timevar at (g_timer, tv);
2497 /* Parse old-style parameter declarations. ??? Attributes are
2498 not allowed to start declaration specifiers here because of a
2499 syntax conflict between a function declaration with attribute
2500 suffix and a function definition with an attribute prefix on
2501 first old-style parameter declaration. Following the old
2502 parser, they are not accepted on subsequent old-style
2503 parameter declarations either. However, there is no
2504 ambiguity after the first declaration, nor indeed on the
2505 first as long as we don't allow postfix attributes after a
2506 declarator with a nonempty identifier list in a definition;
2507 and postfix attributes have never been accepted here in
2508 function definitions either. */
2509 while (c_parser_next_token_is_not (parser, CPP_EOF)
2510 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2511 c_parser_declaration_or_fndef (parser, false, false, false,
2513 store_parm_decls ();
2514 if (omp_declare_simd_clauses)
2515 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2516 omp_declare_simd_clauses);
2517 if (oacc_routine_data)
2518 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2519 location_t startloc = c_parser_peek_token (parser)->location;
2520 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2522 location_t endloc = startloc;
2524 /* If the definition was marked with __RTL, use the RTL parser now,
2525 consuming the function body. */
2526 if (specs->declspec_il == cdil_rtl)
2528 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2530 /* Normally, store_parm_decls sets next_is_function_body,
2531 anticipating a function body. We need a push_scope/pop_scope
2532 pair to flush out this state, or subsequent function parsing
2537 finish_function (endloc);
2540 /* If the definition was marked with __GIMPLE then parse the
2541 function body as GIMPLE. */
2542 else if (specs->declspec_il != cdil_none)
2544 bool saved = in_late_binary_op;
2545 in_late_binary_op = true;
2546 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2548 specs->entry_bb_count);
2549 in_late_binary_op = saved;
2552 fnbody = c_parser_compound_statement (parser, &endloc);
2553 tree fndecl = current_function_decl;
2556 tree decl = current_function_decl;
2557 /* Mark nested functions as needing static-chain initially.
2558 lower_nested_functions will recompute it but the
2559 DECL_STATIC_CHAIN flag is also used before that happens,
2560 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2561 DECL_STATIC_CHAIN (decl) = 1;
2563 finish_function (endloc);
2564 c_pop_function_context ();
2565 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2571 finish_function (endloc);
2573 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2574 if (specs->declspec_il != cdil_none)
2575 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2581 /* Parse an asm-definition (asm() outside a function body). This is a
2589 c_parser_asm_definition (c_parser *parser)
2591 tree asm_str = c_parser_simple_asm_expr (parser);
2593 symtab->finalize_toplevel_asm (asm_str);
2594 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2597 /* Parse a static assertion (C11 6.7.10).
2599 static_assert-declaration:
2600 static_assert-declaration-no-semi ;
2604 c_parser_static_assert_declaration (c_parser *parser)
2606 c_parser_static_assert_declaration_no_semi (parser);
2608 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2609 c_parser_skip_to_end_of_block_or_statement (parser);
2612 /* Parse a static assertion (C11 6.7.10), without the trailing
2615 static_assert-declaration-no-semi:
2616 _Static_assert ( constant-expression , string-literal )
2619 static_assert-declaration-no-semi:
2620 _Static_assert ( constant-expression )
2624 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2626 location_t assert_loc, value_loc;
2628 tree string = NULL_TREE;
2630 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2631 assert_loc = c_parser_peek_token (parser)->location;
2633 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2634 "ISO C99 does not support %<_Static_assert%>");
2636 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2637 "ISO C90 does not support %<_Static_assert%>");
2638 c_parser_consume_token (parser);
2639 matching_parens parens;
2640 if (!parens.require_open (parser))
2642 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2643 value = c_parser_expr_no_commas (parser, NULL).value;
2644 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2645 if (c_parser_next_token_is (parser, CPP_COMMA))
2647 c_parser_consume_token (parser);
2648 switch (c_parser_peek_token (parser)->type)
2654 case CPP_UTF8STRING:
2655 string = c_parser_string_literal (parser, false, true).value;
2658 c_parser_error (parser, "expected string literal");
2662 else if (flag_isoc11)
2663 /* If pedantic for pre-C11, the use of _Static_assert itself will
2664 have been diagnosed, so do not also diagnose the use of this
2665 new C2X feature of _Static_assert. */
2666 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2667 "ISO C11 does not support omitting the string in "
2668 "%<_Static_assert%>");
2669 parens.require_close (parser);
2671 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2673 error_at (value_loc, "expression in static assertion is not an integer");
2676 if (TREE_CODE (value) != INTEGER_CST)
2678 value = c_fully_fold (value, false, NULL);
2679 /* Strip no-op conversions. */
2680 STRIP_TYPE_NOPS (value);
2681 if (TREE_CODE (value) == INTEGER_CST)
2682 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2683 "is not an integer constant expression");
2685 if (TREE_CODE (value) != INTEGER_CST)
2687 error_at (value_loc, "expression in static assertion is not constant");
2690 constant_expression_warning (value);
2691 if (integer_zerop (value))
2694 error_at (assert_loc, "static assertion failed: %E", string);
2696 error_at (assert_loc, "static assertion failed");
2700 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2701 6.7, C11 6.7), adding them to SPECS (which may already include some).
2702 Storage class specifiers are accepted iff SCSPEC_OK; type
2703 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2704 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2705 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2706 addition to the syntax shown, standard attributes are accepted at
2707 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2708 unlike gnu-attributes, they are not accepted in the middle of the
2709 list. (This combines various different syntax productions in the C
2710 standard, and in some cases gnu-attributes and standard attributes
2711 at the start may already have been parsed before this function is
2714 declaration-specifiers:
2715 storage-class-specifier declaration-specifiers[opt]
2716 type-specifier declaration-specifiers[opt]
2717 type-qualifier declaration-specifiers[opt]
2718 function-specifier declaration-specifiers[opt]
2719 alignment-specifier declaration-specifiers[opt]
2721 Function specifiers (inline) are from C99, and are currently
2722 handled as storage class specifiers, as is __thread. Alignment
2723 specifiers are from C11.
2725 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2726 storage-class-specifier:
2734 (_Thread_local is new in C11.)
2736 C99 6.7.4, C11 6.7.4:
2741 (_Noreturn is new in C11.)
2743 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2756 [_Imaginary removed in C99 TC2]
2757 struct-or-union-specifier
2760 atomic-type-specifier
2762 (_Bool and _Complex are new in C99.)
2763 (atomic-type-specifier is new in C11.)
2765 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2771 address-space-qualifier
2774 (restrict is new in C99.)
2775 (_Atomic is new in C11.)
2779 declaration-specifiers:
2780 gnu-attributes declaration-specifiers[opt]
2786 identifier recognized by the target
2788 storage-class-specifier:
2802 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2803 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2805 atomic-type-specifier
2806 _Atomic ( type-name )
2811 class-name objc-protocol-refs[opt]
2812 typedef-name objc-protocol-refs
2817 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2818 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2819 bool alignspec_ok, bool auto_type_ok,
2820 bool start_std_attr_ok, bool end_std_attr_ok,
2821 enum c_lookahead_kind la)
2823 bool attrs_ok = start_attr_ok;
2824 bool seen_type = specs->typespec_kind != ctsk_none;
2827 gcc_assert (la == cla_prefer_id);
2829 if (start_std_attr_ok
2830 && c_parser_nth_token_starts_std_attributes (parser, 1))
2832 gcc_assert (!specs->non_std_attrs_seen_p);
2833 location_t loc = c_parser_peek_token (parser)->location;
2834 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2835 declspecs_add_attrs (loc, specs, attrs);
2836 specs->non_std_attrs_seen_p = false;
2839 while (c_parser_next_token_is (parser, CPP_NAME)
2840 || c_parser_next_token_is (parser, CPP_KEYWORD)
2841 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2843 struct c_typespec t;
2846 location_t loc = c_parser_peek_token (parser)->location;
2848 /* If we cannot accept a type, exit if the next token must start
2849 one. Also, if we already have seen a tagged definition,
2850 a typename would be an error anyway and likely the user
2851 has simply forgotten a semicolon, so we exit. */
2852 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2853 && c_parser_next_tokens_start_typename (parser, la)
2854 && !c_parser_next_token_is_qualifier (parser)
2855 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2858 if (c_parser_next_token_is (parser, CPP_NAME))
2860 c_token *name_token = c_parser_peek_token (parser);
2861 tree value = name_token->value;
2862 c_id_kind kind = name_token->id_kind;
2864 if (kind == C_ID_ADDRSPACE)
2867 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2868 declspecs_add_addrspace (name_token->location, specs, as);
2869 c_parser_consume_token (parser);
2874 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2876 /* If we cannot accept a type, and the next token must start one,
2877 exit. Do the same if we already have seen a tagged definition,
2878 since it would be an error anyway and likely the user has simply
2879 forgotten a semicolon. */
2880 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2883 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2884 a C_ID_CLASSNAME. */
2885 c_parser_consume_token (parser);
2888 if (kind == C_ID_ID)
2890 error_at (loc, "unknown type name %qE", value);
2891 t.kind = ctsk_typedef;
2892 t.spec = error_mark_node;
2894 else if (kind == C_ID_TYPENAME
2895 && (!c_dialect_objc ()
2896 || c_parser_next_token_is_not (parser, CPP_LESS)))
2898 t.kind = ctsk_typedef;
2899 /* For a typedef name, record the meaning, not the name.
2900 In case of 'foo foo, bar;'. */
2901 t.spec = lookup_name (value);
2905 tree proto = NULL_TREE;
2906 gcc_assert (c_dialect_objc ());
2908 if (c_parser_next_token_is (parser, CPP_LESS))
2909 proto = c_parser_objc_protocol_refs (parser);
2910 t.spec = objc_get_protocol_qualified_type (value, proto);
2913 t.expr_const_operands = true;
2914 declspecs_add_type (name_token->location, specs, t);
2917 if (c_parser_next_token_is (parser, CPP_LESS))
2919 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2920 nisse@lysator.liu.se. */
2922 gcc_assert (c_dialect_objc ());
2923 if (!typespec_ok || seen_type)
2925 proto = c_parser_objc_protocol_refs (parser);
2927 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2929 t.expr_const_operands = true;
2930 declspecs_add_type (loc, specs, t);
2933 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2934 switch (c_parser_peek_token (parser)->keyword)
2947 /* TODO: Distinguish between function specifiers (inline, noreturn)
2948 and storage class specifiers, either here or in
2949 declspecs_add_scspec. */
2950 declspecs_add_scspec (loc, specs,
2951 c_parser_peek_token (parser)->value);
2952 c_parser_consume_token (parser);
2984 if (c_dialect_objc ())
2985 parser->objc_need_raw_identifier = true;
2986 t.kind = ctsk_resword;
2987 t.spec = c_parser_peek_token (parser)->value;
2989 t.expr_const_operands = true;
2990 declspecs_add_type (loc, specs, t);
2991 c_parser_consume_token (parser);
2998 t = c_parser_enum_specifier (parser);
2999 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3000 declspecs_add_type (loc, specs, t);
3008 t = c_parser_struct_or_union_specifier (parser);
3009 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3010 declspecs_add_type (loc, specs, t);
3013 /* ??? The old parser rejected typeof after other type
3014 specifiers, but is a syntax error the best way of
3016 if (!typespec_ok || seen_type)
3020 t = c_parser_typeof_specifier (parser);
3021 declspecs_add_type (loc, specs, t);
3024 /* C parser handling of Objective-C constructs needs
3025 checking for correct lvalue-to-rvalue conversions, and
3026 the code in build_modify_expr handling various
3027 Objective-C cases, and that in build_unary_op handling
3028 Objective-C cases for increment / decrement, also needs
3029 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3030 and objc_types_are_equivalent may also need updates. */
3031 if (c_dialect_objc ())
3032 sorry ("%<_Atomic%> in Objective-C");
3034 pedwarn_c99 (loc, OPT_Wpedantic,
3035 "ISO C99 does not support the %<_Atomic%> qualifier");
3037 pedwarn_c99 (loc, OPT_Wpedantic,
3038 "ISO C90 does not support the %<_Atomic%> qualifier");
3041 value = c_parser_peek_token (parser)->value;
3042 c_parser_consume_token (parser);
3043 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3045 /* _Atomic ( type-name ). */
3047 c_parser_consume_token (parser);
3048 struct c_type_name *type = c_parser_type_name (parser);
3049 t.kind = ctsk_typeof;
3050 t.spec = error_mark_node;
3052 t.expr_const_operands = true;
3054 t.spec = groktypename (type, &t.expr,
3055 &t.expr_const_operands);
3056 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3058 if (t.spec != error_mark_node)
3060 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3061 error_at (loc, "%<_Atomic%>-qualified array type");
3062 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3063 error_at (loc, "%<_Atomic%>-qualified function type");
3064 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3065 error_at (loc, "%<_Atomic%> applied to a qualified type");
3067 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3069 declspecs_add_type (loc, specs, t);
3072 declspecs_add_qual (loc, specs, value);
3078 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3079 c_parser_consume_token (parser);
3084 attrs = c_parser_gnu_attributes (parser);
3085 declspecs_add_attrs (loc, specs, attrs);
3090 align = c_parser_alignas_specifier (parser);
3091 declspecs_add_alignas (loc, specs, align);
3095 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3096 c_parser_consume_token (parser);
3097 specs->declspec_il = cdil_gimple;
3098 specs->locations[cdw_gimple] = loc;
3099 c_parser_gimple_or_rtl_pass_list (parser, specs);
3102 c_parser_consume_token (parser);
3103 specs->declspec_il = cdil_rtl;
3104 specs->locations[cdw_rtl] = loc;
3105 c_parser_gimple_or_rtl_pass_list (parser, specs);
3113 && c_parser_nth_token_starts_std_attributes (parser, 1))
3114 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3117 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3120 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3122 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3124 enum gnu-attributes[opt] identifier
3126 The form with trailing comma is new in C99. The forms with
3127 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3128 without commas in the syntax (assignment expressions, not just
3129 conditional expressions); assignment expressions will be diagnosed
3134 enumerator-list , enumerator
3137 enumeration-constant attribute-specifier-sequence[opt]
3138 enumeration-constant attribute-specifier-sequence[opt]
3139 = constant-expression
3144 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3145 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3146 = constant-expression
3150 static struct c_typespec
3151 c_parser_enum_specifier (c_parser *parser)
3153 struct c_typespec ret;
3154 bool have_std_attrs;
3155 tree std_attrs = NULL_TREE;
3157 tree ident = NULL_TREE;
3158 location_t enum_loc;
3159 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3160 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3161 c_parser_consume_token (parser);
3162 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3164 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3165 attrs = c_parser_gnu_attributes (parser);
3166 enum_loc = c_parser_peek_token (parser)->location;
3167 /* Set the location in case we create a decl now. */
3168 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3169 if (c_parser_next_token_is (parser, CPP_NAME))
3171 ident = c_parser_peek_token (parser)->value;
3172 ident_loc = c_parser_peek_token (parser)->location;
3173 enum_loc = ident_loc;
3174 c_parser_consume_token (parser);
3176 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3178 /* Parse an enum definition. */
3179 struct c_enum_contents the_enum;
3182 /* We chain the enumerators in reverse order, then put them in
3183 forward order at the end. */
3185 timevar_push (TV_PARSE_ENUM);
3186 type = start_enum (enum_loc, &the_enum, ident);
3188 c_parser_consume_token (parser);
3196 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3197 location_t decl_loc, value_loc;
3198 if (c_parser_next_token_is_not (parser, CPP_NAME))
3200 /* Give a nicer error for "enum {}". */
3201 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3204 error_at (c_parser_peek_token (parser)->location,
3205 "empty enum is invalid");
3206 parser->error = true;
3209 c_parser_error (parser, "expected identifier");
3210 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3211 values = error_mark_node;
3214 token = c_parser_peek_token (parser);
3215 enum_id = token->value;
3216 /* Set the location in case we create a decl now. */
3217 c_parser_set_source_position_from_token (token);
3218 decl_loc = value_loc = token->location;
3219 c_parser_consume_token (parser);
3220 /* Parse any specified attributes. */
3221 tree std_attrs = NULL_TREE;
3222 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3223 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3224 tree enum_attrs = chainon (std_attrs,
3225 c_parser_gnu_attributes (parser));
3226 if (c_parser_next_token_is (parser, CPP_EQ))
3228 c_parser_consume_token (parser);
3229 value_loc = c_parser_peek_token (parser)->location;
3230 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3233 enum_value = NULL_TREE;
3234 enum_decl = build_enumerator (decl_loc, value_loc,
3235 &the_enum, enum_id, enum_value);
3237 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3238 TREE_CHAIN (enum_decl) = values;
3241 if (c_parser_next_token_is (parser, CPP_COMMA))
3243 comma_loc = c_parser_peek_token (parser)->location;
3245 c_parser_consume_token (parser);
3247 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3250 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3251 "comma at end of enumerator list");
3252 c_parser_consume_token (parser);
3257 c_parser_error (parser, "expected %<,%> or %<}%>");
3258 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3259 values = error_mark_node;
3263 postfix_attrs = c_parser_gnu_attributes (parser);
3264 ret.spec = finish_enum (type, nreverse (values),
3266 chainon (attrs, postfix_attrs)));
3267 ret.kind = ctsk_tagdef;
3268 ret.expr = NULL_TREE;
3269 ret.expr_const_operands = true;
3270 timevar_pop (TV_PARSE_ENUM);
3275 c_parser_error (parser, "expected %<{%>");
3276 ret.spec = error_mark_node;
3277 ret.kind = ctsk_tagref;
3278 ret.expr = NULL_TREE;
3279 ret.expr_const_operands = true;
3282 /* Attributes may only appear when the members are defined or in
3283 certain forward declarations (treat enum forward declarations in
3284 GNU C analogously to struct and union forward declarations in
3286 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3287 c_parser_error (parser, "expected %<;%>");
3288 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3290 /* In ISO C, enumerated types can be referred to only if already
3292 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3295 pedwarn (enum_loc, OPT_Wpedantic,
3296 "ISO C forbids forward references to %<enum%> types");
3301 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3303 struct-or-union-specifier:
3304 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3305 identifier[opt] { struct-contents } gnu-attributes[opt]
3306 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3310 struct-declaration-list
3312 struct-declaration-list:
3313 struct-declaration ;
3314 struct-declaration-list struct-declaration ;
3321 struct-declaration-list struct-declaration
3323 struct-declaration-list:
3324 struct-declaration-list ;
3327 (Note that in the syntax here, unlike that in ISO C, the semicolons
3328 are included here rather than in struct-declaration, in order to
3329 describe the syntax with extra semicolons and missing semicolon at
3334 struct-declaration-list:
3335 @defs ( class-name )
3337 (Note this does not include a trailing semicolon, but can be
3338 followed by further declarations, and gets a pedwarn-if-pedantic
3339 when followed by a semicolon.) */
3341 static struct c_typespec
3342 c_parser_struct_or_union_specifier (c_parser *parser)
3344 struct c_typespec ret;
3345 bool have_std_attrs;
3346 tree std_attrs = NULL_TREE;
3348 tree ident = NULL_TREE;
3349 location_t struct_loc;
3350 location_t ident_loc = UNKNOWN_LOCATION;
3351 enum tree_code code;
3352 switch (c_parser_peek_token (parser)->keyword)
3363 struct_loc = c_parser_peek_token (parser)->location;
3364 c_parser_consume_token (parser);
3365 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3367 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3368 attrs = c_parser_gnu_attributes (parser);
3370 /* Set the location in case we create a decl now. */
3371 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3373 if (c_parser_next_token_is (parser, CPP_NAME))
3375 ident = c_parser_peek_token (parser)->value;
3376 ident_loc = c_parser_peek_token (parser)->location;
3377 struct_loc = ident_loc;
3378 c_parser_consume_token (parser);
3380 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3382 /* Parse a struct or union definition. Start the scope of the
3383 tag before parsing components. */
3384 class c_struct_parse_info *struct_info;
3385 tree type = start_struct (struct_loc, code, ident, &struct_info);
3387 /* We chain the components in reverse order, then put them in
3388 forward order at the end. Each struct-declaration may
3389 declare multiple components (comma-separated), so we must use
3390 chainon to join them, although when parsing each
3391 struct-declaration we can use TREE_CHAIN directly.
3393 The theory behind all this is that there will be more
3394 semicolon separated fields than comma separated fields, and
3395 so we'll be minimizing the number of node traversals required
3398 timevar_push (TV_PARSE_STRUCT);
3399 contents = NULL_TREE;
3400 c_parser_consume_token (parser);
3401 /* Handle the Objective-C @defs construct,
3402 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3403 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3406 gcc_assert (c_dialect_objc ());
3407 c_parser_consume_token (parser);
3408 matching_parens parens;
3409 if (!parens.require_open (parser))
3411 if (c_parser_next_token_is (parser, CPP_NAME)
3412 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3414 name = c_parser_peek_token (parser)->value;
3415 c_parser_consume_token (parser);
3419 c_parser_error (parser, "expected class name");
3420 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3423 parens.skip_until_found_close (parser);
3424 contents = nreverse (objc_get_class_ivars (name));
3427 /* Parse the struct-declarations and semicolons. Problems with
3428 semicolons are diagnosed here; empty structures are diagnosed
3433 /* Parse any stray semicolon. */
3434 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3436 location_t semicolon_loc
3437 = c_parser_peek_token (parser)->location;
3438 gcc_rich_location richloc (semicolon_loc);
3439 richloc.add_fixit_remove ();
3440 pedwarn (&richloc, OPT_Wpedantic,
3441 "extra semicolon in struct or union specified");
3442 c_parser_consume_token (parser);
3445 /* Stop if at the end of the struct or union contents. */
3446 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3448 c_parser_consume_token (parser);
3451 /* Accept #pragmas at struct scope. */
3452 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3454 c_parser_pragma (parser, pragma_struct, NULL);
3457 /* Parse some comma-separated declarations, but not the
3458 trailing semicolon if any. */
3459 decls = c_parser_struct_declaration (parser);
3460 contents = chainon (decls, contents);
3461 /* If no semicolon follows, either we have a parse error or
3462 are at the end of the struct or union and should
3464 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3465 c_parser_consume_token (parser);
3468 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3469 pedwarn (c_parser_peek_token (parser)->location, 0,
3470 "no semicolon at end of struct or union");
3471 else if (parser->error
3472 || !c_parser_next_token_starts_declspecs (parser))
3474 c_parser_error (parser, "expected %<;%>");
3475 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3479 /* If we come here, we have already emitted an error
3480 for an expected `;', identifier or `(', and we also
3481 recovered already. Go on with the next field. */
3484 postfix_attrs = c_parser_gnu_attributes (parser);
3485 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3487 chainon (attrs, postfix_attrs)),
3489 ret.kind = ctsk_tagdef;
3490 ret.expr = NULL_TREE;
3491 ret.expr_const_operands = true;
3492 timevar_pop (TV_PARSE_STRUCT);
3497 c_parser_error (parser, "expected %<{%>");
3498 ret.spec = error_mark_node;
3499 ret.kind = ctsk_tagref;
3500 ret.expr = NULL_TREE;
3501 ret.expr_const_operands = true;
3504 /* Attributes may only appear when the members are defined or in
3505 certain forward declarations. */
3506 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3507 c_parser_error (parser, "expected %<;%>");
3508 /* ??? Existing practice is that GNU attributes are ignored after
3509 the struct or union keyword when not defining the members. */
3510 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3514 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3515 *without* the trailing semicolon.
3518 attribute-specifier-sequence[opt] specifier-qualifier-list
3519 attribute-specifier-sequence[opt] struct-declarator-list
3520 static_assert-declaration-no-semi
3522 specifier-qualifier-list:
3523 type-specifier specifier-qualifier-list[opt]
3524 type-qualifier specifier-qualifier-list[opt]
3525 alignment-specifier specifier-qualifier-list[opt]
3526 gnu-attributes specifier-qualifier-list[opt]
3528 struct-declarator-list:
3530 struct-declarator-list , gnu-attributes[opt] struct-declarator
3533 declarator gnu-attributes[opt]
3534 declarator[opt] : constant-expression gnu-attributes[opt]
3539 __extension__ struct-declaration
3540 specifier-qualifier-list
3542 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3543 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3544 any expression without commas in the syntax (assignment
3545 expressions, not just conditional expressions); assignment
3546 expressions will be diagnosed as non-constant. */
3549 c_parser_struct_declaration (c_parser *parser)
3551 struct c_declspecs *specs;
3553 tree all_prefix_attrs;
3555 location_t decl_loc;
3556 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3560 ext = disable_extension_diagnostics ();
3561 c_parser_consume_token (parser);
3562 decl = c_parser_struct_declaration (parser);
3563 restore_extension_diagnostics (ext);
3566 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3568 c_parser_static_assert_declaration_no_semi (parser);
3571 specs = build_null_declspecs ();
3572 decl_loc = c_parser_peek_token (parser)->location;
3573 /* Strictly by the standard, we shouldn't allow _Alignas here,
3574 but it appears to have been intended to allow it there, so
3575 we're keeping it as it is until WG14 reaches a conclusion
3577 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3578 c_parser_declspecs (parser, specs, false, true, true,
3579 true, false, true, true, cla_nonabstract_decl);
3582 if (!specs->declspecs_seen_p)
3584 c_parser_error (parser, "expected specifier-qualifier-list");
3587 finish_declspecs (specs);
3588 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3589 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3592 if (specs->typespec_kind == ctsk_none)
3594 pedwarn (decl_loc, OPT_Wpedantic,
3595 "ISO C forbids member declarations with no members");
3596 shadow_tag_warned (specs, pedantic);
3601 /* Support for unnamed structs or unions as members of
3602 structs or unions (which is [a] useful and [b] supports
3606 ret = grokfield (c_parser_peek_token (parser)->location,
3607 build_id_declarator (NULL_TREE), specs,
3610 decl_attributes (&ret, attrs, 0);
3615 /* Provide better error recovery. Note that a type name here is valid,
3616 and will be treated as a field name. */
3617 if (specs->typespec_kind == ctsk_tagdef
3618 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3619 && c_parser_next_token_starts_declspecs (parser)
3620 && !c_parser_next_token_is (parser, CPP_NAME))
3622 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3623 parser->error = false;
3627 pending_xref_error ();
3628 prefix_attrs = specs->attrs;
3629 all_prefix_attrs = prefix_attrs;
3630 specs->attrs = NULL_TREE;
3634 /* Declaring one or more declarators or un-named bit-fields. */
3635 struct c_declarator *declarator;
3637 if (c_parser_next_token_is (parser, CPP_COLON))
3638 declarator = build_id_declarator (NULL_TREE);
3640 declarator = c_parser_declarator (parser,
3641 specs->typespec_kind != ctsk_none,
3642 C_DTR_NORMAL, &dummy);
3643 if (declarator == NULL)
3645 c_parser_skip_to_end_of_block_or_statement (parser);
3648 if (c_parser_next_token_is (parser, CPP_COLON)
3649 || c_parser_next_token_is (parser, CPP_COMMA)
3650 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3651 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3652 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3654 tree postfix_attrs = NULL_TREE;
3655 tree width = NULL_TREE;
3657 if (c_parser_next_token_is (parser, CPP_COLON))
3659 c_parser_consume_token (parser);
3660 width = c_parser_expr_no_commas (parser, NULL).value;
3662 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3663 postfix_attrs = c_parser_gnu_attributes (parser);
3664 d = grokfield (c_parser_peek_token (parser)->location,
3665 declarator, specs, width, &all_prefix_attrs);
3666 decl_attributes (&d, chainon (postfix_attrs,
3667 all_prefix_attrs), 0);
3668 DECL_CHAIN (d) = decls;
3670 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3671 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3674 all_prefix_attrs = prefix_attrs;
3675 if (c_parser_next_token_is (parser, CPP_COMMA))
3676 c_parser_consume_token (parser);
3677 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3678 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3680 /* Semicolon consumed in caller. */
3685 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3691 c_parser_error (parser,
3692 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3693 "%<__attribute__%>");
3700 /* Parse a typeof specifier (a GNU extension).
3703 typeof ( expression )
3704 typeof ( type-name )
3707 static struct c_typespec
3708 c_parser_typeof_specifier (c_parser *parser)
3710 struct c_typespec ret;
3711 ret.kind = ctsk_typeof;
3712 ret.spec = error_mark_node;
3713 ret.expr = NULL_TREE;
3714 ret.expr_const_operands = true;
3715 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3716 c_parser_consume_token (parser);
3717 c_inhibit_evaluation_warnings++;
3719 matching_parens parens;
3720 if (!parens.require_open (parser))
3722 c_inhibit_evaluation_warnings--;
3726 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3728 struct c_type_name *type = c_parser_type_name (parser);
3729 c_inhibit_evaluation_warnings--;
3733 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3734 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3740 location_t here = c_parser_peek_token (parser)->location;
3741 struct c_expr expr = c_parser_expression (parser);
3742 c_inhibit_evaluation_warnings--;
3744 if (TREE_CODE (expr.value) == COMPONENT_REF
3745 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3746 error_at (here, "%<typeof%> applied to a bit-field");
3747 mark_exp_read (expr.value);
3748 ret.spec = TREE_TYPE (expr.value);
3749 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3750 /* This is returned with the type so that when the type is
3751 evaluated, this can be evaluated. */
3753 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3754 pop_maybe_used (was_vm);
3756 parens.skip_until_found_close (parser);
3760 /* Parse an alignment-specifier.
3764 alignment-specifier:
3765 _Alignas ( type-name )
3766 _Alignas ( constant-expression )
3770 c_parser_alignas_specifier (c_parser * parser)
3772 tree ret = error_mark_node;
3773 location_t loc = c_parser_peek_token (parser)->location;
3774 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3775 c_parser_consume_token (parser);
3777 pedwarn_c99 (loc, OPT_Wpedantic,
3778 "ISO C99 does not support %<_Alignas%>");
3780 pedwarn_c99 (loc, OPT_Wpedantic,
3781 "ISO C90 does not support %<_Alignas%>");
3782 matching_parens parens;
3783 if (!parens.require_open (parser))
3785 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3787 struct c_type_name *type = c_parser_type_name (parser);
3789 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3793 ret = c_parser_expr_no_commas (parser, NULL).value;
3794 parens.skip_until_found_close (parser);
3798 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3799 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3800 a typedef name may be redeclared; otherwise it may not. KIND
3801 indicates which kind of declarator is wanted. Returns a valid
3802 declarator except in the case of a syntax error in which case NULL is
3803 returned. *SEEN_ID is set to true if an identifier being declared is
3804 seen; this is used to diagnose bad forms of abstract array declarators
3805 and to determine whether an identifier list is syntactically permitted.
3808 pointer[opt] direct-declarator
3812 ( gnu-attributes[opt] declarator )
3813 direct-declarator array-declarator
3814 direct-declarator ( parameter-type-list )
3815 direct-declarator ( identifier-list[opt] )
3818 * type-qualifier-list[opt]
3819 * type-qualifier-list[opt] pointer
3821 type-qualifier-list:
3824 type-qualifier-list type-qualifier
3825 type-qualifier-list gnu-attributes
3828 [ type-qualifier-list[opt] assignment-expression[opt] ]
3829 [ static type-qualifier-list[opt] assignment-expression ]
3830 [ type-qualifier-list static assignment-expression ]
3831 [ type-qualifier-list[opt] * ]
3833 parameter-type-list:
3835 parameter-list , ...
3838 parameter-declaration
3839 parameter-list , parameter-declaration
3841 parameter-declaration:
3842 declaration-specifiers declarator gnu-attributes[opt]
3843 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3847 identifier-list , identifier
3849 abstract-declarator:
3851 pointer[opt] direct-abstract-declarator
3853 direct-abstract-declarator:
3854 ( gnu-attributes[opt] abstract-declarator )
3855 direct-abstract-declarator[opt] array-declarator
3856 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3861 direct-declarator ( parameter-forward-declarations
3862 parameter-type-list[opt] )
3864 direct-abstract-declarator:
3865 direct-abstract-declarator[opt] ( parameter-forward-declarations
3866 parameter-type-list[opt] )
3868 parameter-forward-declarations:
3870 parameter-forward-declarations parameter-list ;
3872 The uses of gnu-attributes shown above are GNU extensions.
3874 Some forms of array declarator are not included in C99 in the
3875 syntax for abstract declarators; these are disallowed elsewhere.
3876 This may be a defect (DR#289).
3878 This function also accepts an omitted abstract declarator as being
3879 an abstract declarator, although not part of the formal syntax. */
3881 struct c_declarator *
3882 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3885 /* Parse any initial pointer part. */
3886 if (c_parser_next_token_is (parser, CPP_MULT))
3888 struct c_declspecs *quals_attrs = build_null_declspecs ();
3889 struct c_declarator *inner;
3890 c_parser_consume_token (parser);
3891 c_parser_declspecs (parser, quals_attrs, false, false, true,
3892 false, false, true, false, cla_prefer_id);
3893 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3897 return make_pointer_declarator (quals_attrs, inner);
3899 /* Now we have a direct declarator, direct abstract declarator or
3900 nothing (which counts as a direct abstract declarator here). */
3901 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3904 /* Parse a direct declarator or direct abstract declarator; arguments
3905 as c_parser_declarator. */
3907 static struct c_declarator *
3908 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3911 /* The direct declarator must start with an identifier (possibly
3912 omitted) or a parenthesized declarator (possibly abstract). In
3913 an ordinary declarator, initial parentheses must start a
3914 parenthesized declarator. In an abstract declarator or parameter
3915 declarator, they could start a parenthesized declarator or a
3916 parameter list. To tell which, the open parenthesis and any
3917 following gnu-attributes must be read. If a declaration
3918 specifier or standard attributes follow, then it is a parameter
3919 list; if the specifier is a typedef name, there might be an
3920 ambiguity about redeclaring it, which is resolved in the
3921 direction of treating it as a typedef name. If a close
3922 parenthesis follows, it is also an empty parameter list, as the
3923 syntax does not permit empty abstract declarators. Otherwise, it
3924 is a parenthesized declarator (in which case the analysis may be
3925 repeated inside it, recursively).
3927 ??? There is an ambiguity in a parameter declaration "int
3928 (__attribute__((foo)) x)", where x is not a typedef name: it
3929 could be an abstract declarator for a function, or declare x with
3930 parentheses. The proper resolution of this ambiguity needs
3931 documenting. At present we follow an accident of the old
3932 parser's implementation, whereby the first parameter must have
3933 some declaration specifiers other than just gnu-attributes. Thus as
3934 a parameter declaration it is treated as a parenthesized
3935 parameter named x, and as an abstract declarator it is
3938 ??? Also following the old parser, gnu-attributes inside an empty
3939 parameter list are ignored, making it a list not yielding a
3940 prototype, rather than giving an error or making it have one
3941 parameter with implicit type int.
3943 ??? Also following the old parser, typedef names may be
3944 redeclared in declarators, but not Objective-C class names. */
3946 if (kind != C_DTR_ABSTRACT
3947 && c_parser_next_token_is (parser, CPP_NAME)
3949 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3950 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3951 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3953 struct c_declarator *inner
3954 = build_id_declarator (c_parser_peek_token (parser)->value);
3956 inner->id_loc = c_parser_peek_token (parser)->location;
3957 c_parser_consume_token (parser);
3958 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3959 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3960 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3963 if (kind != C_DTR_NORMAL
3964 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3965 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3967 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3968 inner->id_loc = c_parser_peek_token (parser)->location;
3969 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3972 /* Either we are at the end of an abstract declarator, or we have
3975 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3978 struct c_declarator *inner;
3979 c_parser_consume_token (parser);
3980 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3982 attrs = c_parser_gnu_attributes (parser);
3983 if (kind != C_DTR_NORMAL
3984 && (c_parser_next_token_starts_declspecs (parser)
3986 && c_parser_nth_token_starts_std_attributes (parser, 1))
3987 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3989 struct c_arg_info *args
3990 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3991 attrs, have_gnu_attrs);
3996 inner = build_id_declarator (NULL_TREE);
3998 && args->types != error_mark_node
3999 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4000 && c_parser_nth_token_starts_std_attributes (parser, 1))
4003 = c_parser_std_attribute_specifier_sequence (parser);
4005 inner = build_attrs_declarator (std_attrs, inner);
4007 inner = build_function_declarator (args, inner);
4008 return c_parser_direct_declarator_inner (parser, *seen_id,
4012 /* A parenthesized declarator. */
4013 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4014 if (inner != NULL && attrs != NULL)
4015 inner = build_attrs_declarator (attrs, inner);
4016 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4018 c_parser_consume_token (parser);
4022 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4026 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4033 if (kind == C_DTR_NORMAL)
4035 c_parser_error (parser, "expected identifier or %<(%>");
4039 return build_id_declarator (NULL_TREE);
4043 /* Parse part of a direct declarator or direct abstract declarator,
4044 given that some (in INNER) has already been parsed; ID_PRESENT is
4045 true if an identifier is present, false for an abstract
4048 static struct c_declarator *
4049 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4050 struct c_declarator *inner)
4052 /* Parse a sequence of array declarators and parameter lists. */
4053 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4054 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4056 location_t brace_loc = c_parser_peek_token (parser)->location;
4057 struct c_declarator *declarator;
4058 struct c_declspecs *quals_attrs = build_null_declspecs ();
4061 struct c_expr dimen;
4062 dimen.value = NULL_TREE;
4063 dimen.original_code = ERROR_MARK;
4064 dimen.original_type = NULL_TREE;
4065 c_parser_consume_token (parser);
4066 c_parser_declspecs (parser, quals_attrs, false, false, true,
4067 false, false, false, false, cla_prefer_id);
4068 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4070 c_parser_consume_token (parser);
4071 if (static_seen && !quals_attrs->declspecs_seen_p)
4072 c_parser_declspecs (parser, quals_attrs, false, false, true,
4073 false, false, false, false, cla_prefer_id);
4074 if (!quals_attrs->declspecs_seen_p)
4076 /* If "static" is present, there must be an array dimension.
4077 Otherwise, there may be a dimension, "*", or no
4082 dimen = c_parser_expr_no_commas (parser, NULL);
4086 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4088 dimen.value = NULL_TREE;
4091 else if (c_parser_next_token_is (parser, CPP_MULT))
4093 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4095 dimen.value = NULL_TREE;
4097 c_parser_consume_token (parser);
4102 dimen = c_parser_expr_no_commas (parser, NULL);
4108 dimen = c_parser_expr_no_commas (parser, NULL);
4111 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4112 c_parser_consume_token (parser);
4115 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4120 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4121 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4122 static_seen, star_seen);
4123 if (declarator == NULL)
4125 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4128 = c_parser_std_attribute_specifier_sequence (parser);
4130 inner = build_attrs_declarator (std_attrs, inner);
4132 inner = set_array_declarator_inner (declarator, inner);
4133 return c_parser_direct_declarator_inner (parser, id_present, inner);
4135 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4138 struct c_arg_info *args;
4139 c_parser_consume_token (parser);
4140 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4142 attrs = c_parser_gnu_attributes (parser);
4143 args = c_parser_parms_declarator (parser, id_present, attrs,
4150 && args->types != error_mark_node
4151 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4152 && c_parser_nth_token_starts_std_attributes (parser, 1))
4155 = c_parser_std_attribute_specifier_sequence (parser);
4157 inner = build_attrs_declarator (std_attrs, inner);
4159 inner = build_function_declarator (args, inner);
4160 return c_parser_direct_declarator_inner (parser, id_present, inner);
4166 /* Parse a parameter list or identifier list, including the closing
4167 parenthesis but not the opening one. ATTRS are the gnu-attributes
4168 at the start of the list. ID_LIST_OK is true if an identifier list
4169 is acceptable; such a list must not have attributes at the start.
4170 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4171 attributes) were present (in which case standard attributes cannot
4174 static struct c_arg_info *
4175 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4176 bool have_gnu_attrs)
4179 declare_parm_level ();
4180 /* If the list starts with an identifier, it is an identifier list.
4181 Otherwise, it is either a prototype list or an empty list. */
4184 && c_parser_next_token_is (parser, CPP_NAME)
4185 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4187 /* Look ahead to detect typos in type names. */
4188 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4189 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4190 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4191 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4192 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4194 tree list = NULL_TREE, *nextp = &list;
4195 while (c_parser_next_token_is (parser, CPP_NAME)
4196 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4198 *nextp = build_tree_list (NULL_TREE,
4199 c_parser_peek_token (parser)->value);
4200 nextp = & TREE_CHAIN (*nextp);
4201 c_parser_consume_token (parser);
4202 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4204 c_parser_consume_token (parser);
4205 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4207 c_parser_error (parser, "expected identifier");
4211 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4213 struct c_arg_info *ret = build_arg_info ();
4215 c_parser_consume_token (parser);
4221 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4229 struct c_arg_info *ret
4230 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4236 /* Parse a parameter list (possibly empty), including the closing
4237 parenthesis but not the opening one. ATTRS are the gnu-attributes
4238 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4239 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4240 which means standard attributes cannot start the list. EXPR is
4241 NULL or an expression that needs to be evaluated for the side
4242 effects of array size expressions in the parameters. */
4244 static struct c_arg_info *
4245 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4246 bool have_gnu_attrs)
4248 bool bad_parm = false;
4250 /* ??? Following the old parser, forward parameter declarations may
4251 use abstract declarators, and if no real parameter declarations
4252 follow the forward declarations then this is not diagnosed. Also
4253 note as above that gnu-attributes are ignored as the only contents of
4254 the parentheses, or as the only contents after forward
4256 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4258 struct c_arg_info *ret = build_arg_info ();
4259 c_parser_consume_token (parser);
4262 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4264 struct c_arg_info *ret = build_arg_info ();
4266 if (flag_allow_parameterless_variadic_functions)
4268 /* F (...) is allowed. */
4269 ret->types = NULL_TREE;
4273 /* Suppress -Wold-style-definition for this case. */
4274 ret->types = error_mark_node;
4275 error_at (c_parser_peek_token (parser)->location,
4276 "ISO C requires a named argument before %<...%>");
4278 c_parser_consume_token (parser);
4279 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4281 c_parser_consume_token (parser);
4286 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4291 /* Nonempty list of parameters, either terminated with semicolon
4292 (forward declarations; recurse) or with close parenthesis (normal
4293 function) or with ", ... )" (variadic function). */
4296 /* Parse a parameter. */
4297 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4300 have_gnu_attrs = false;
4304 push_parm_decl (parm, &expr);
4305 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4308 c_parser_consume_token (parser);
4309 mark_forward_parm_decls ();
4310 bool new_have_gnu_attrs
4311 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4312 new_attrs = c_parser_gnu_attributes (parser);
4313 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4314 new_have_gnu_attrs);
4316 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4318 c_parser_consume_token (parser);
4322 return get_parm_info (false, expr);
4324 if (!c_parser_require (parser, CPP_COMMA,
4325 "expected %<;%>, %<,%> or %<)%>",
4326 UNKNOWN_LOCATION, false))
4328 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4331 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4333 c_parser_consume_token (parser);
4334 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4336 c_parser_consume_token (parser);
4340 return get_parm_info (true, expr);
4344 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4352 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4353 start of the declaration if it is the first parameter;
4354 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4357 static struct c_parm *
4358 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4359 bool have_gnu_attrs)
4361 struct c_declspecs *specs;
4362 struct c_declarator *declarator;
4364 tree postfix_attrs = NULL_TREE;
4367 /* Accept #pragmas between parameter declarations. */
4368 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4369 c_parser_pragma (parser, pragma_param, NULL);
4371 if (!c_parser_next_token_starts_declspecs (parser)
4372 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4374 c_token *token = c_parser_peek_token (parser);
4377 c_parser_set_source_position_from_token (token);
4378 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4380 auto_diagnostic_group d;
4381 name_hint hint = lookup_name_fuzzy (token->value,
4382 FUZZY_LOOKUP_TYPENAME,
4384 if (const char *suggestion = hint.suggestion ())
4386 gcc_rich_location richloc (token->location);
4387 richloc.add_fixit_replace (suggestion);
4389 "unknown type name %qE; did you mean %qs?",
4390 token->value, suggestion);
4393 error_at (token->location, "unknown type name %qE", token->value);
4394 parser->error = true;
4396 /* ??? In some Objective-C cases '...' isn't applicable so there
4397 should be a different message. */
4399 c_parser_error (parser,
4400 "expected declaration specifiers or %<...%>");
4401 c_parser_skip_to_end_of_parameter (parser);
4405 location_t start_loc = c_parser_peek_token (parser)->location;
4407 specs = build_null_declspecs ();
4410 declspecs_add_attrs (input_location, specs, attrs);
4413 c_parser_declspecs (parser, specs, true, true, true, true, false,
4414 !have_gnu_attrs, true, cla_nonabstract_decl);
4415 finish_declspecs (specs);
4416 pending_xref_error ();
4417 prefix_attrs = specs->attrs;
4418 specs->attrs = NULL_TREE;
4419 declarator = c_parser_declarator (parser,
4420 specs->typespec_kind != ctsk_none,
4421 C_DTR_PARM, &dummy);
4422 if (declarator == NULL)
4424 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4427 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4428 postfix_attrs = c_parser_gnu_attributes (parser);
4430 /* Generate a location for the parameter, ranging from the start of the
4431 initial token to the end of the final token.
4433 If we have a identifier, then use it for the caret location, e.g.
4435 extern int callee (int one, int (*two)(int, int), float three);
4436 ~~~~~~^~~~~~~~~~~~~~
4438 otherwise, reuse the start location for the caret location e.g.:
4440 extern int callee (int one, int (*)(int, int), float three);
4443 location_t end_loc = parser->last_token_location;
4445 /* Find any cdk_id declarator; determine if we have an identifier. */
4446 c_declarator *id_declarator = declarator;
4447 while (id_declarator && id_declarator->kind != cdk_id)
4448 id_declarator = id_declarator->declarator;
4449 location_t caret_loc = (id_declarator->u.id.id
4450 ? id_declarator->id_loc
4452 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4454 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4455 declarator, param_loc);
4458 /* Parse a string literal in an asm expression. It should not be
4459 translated, and wide string literals are an error although
4460 permitted by the syntax. This is a GNU extension.
4467 c_parser_asm_string_literal (c_parser *parser)
4470 int save_flag = warn_overlength_strings;
4471 warn_overlength_strings = 0;
4472 str = c_parser_string_literal (parser, false, false).value;
4473 warn_overlength_strings = save_flag;
4477 /* Parse a simple asm expression. This is used in restricted
4478 contexts, where a full expression with inputs and outputs does not
4479 make sense. This is a GNU extension.
4482 asm ( asm-string-literal )
4486 c_parser_simple_asm_expr (c_parser *parser)
4489 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4490 c_parser_consume_token (parser);
4491 matching_parens parens;
4492 if (!parens.require_open (parser))
4494 str = c_parser_asm_string_literal (parser);
4495 if (!parens.require_close (parser))
4497 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4504 c_parser_gnu_attribute_any_word (c_parser *parser)
4506 tree attr_name = NULL_TREE;
4508 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4510 /* ??? See comment above about what keywords are accepted here. */
4512 switch (c_parser_peek_token (parser)->keyword)
4543 case RID_TRANSACTION_ATOMIC:
4544 case RID_TRANSACTION_CANCEL:
4560 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4561 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4563 else if (c_parser_next_token_is (parser, CPP_NAME))
4564 attr_name = c_parser_peek_token (parser)->value;
4569 /* Parse attribute arguments. This is a common form of syntax
4570 covering all currently valid GNU and standard attributes.
4572 gnu-attribute-arguments:
4574 identifier , nonempty-expr-list
4577 where the "identifier" must not be declared as a type. ??? Why not
4578 allow identifiers declared as types to start the arguments? */
4581 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4582 bool require_string, bool allow_empty_args)
4584 vec<tree, va_gc> *expr_list;
4586 /* Parse the attribute contents. If they start with an
4587 identifier which is followed by a comma or close
4588 parenthesis, then the arguments start with that
4589 identifier; otherwise they are an expression list.
4590 In objective-c the identifier may be a classname. */
4591 if (c_parser_next_token_is (parser, CPP_NAME)
4592 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4593 || (c_dialect_objc ()
4594 && c_parser_peek_token (parser)->id_kind
4596 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4597 || (c_parser_peek_2nd_token (parser)->type
4598 == CPP_CLOSE_PAREN))
4599 && (takes_identifier
4600 || (c_dialect_objc ()
4601 && c_parser_peek_token (parser)->id_kind
4602 == C_ID_CLASSNAME)))
4604 tree arg1 = c_parser_peek_token (parser)->value;
4605 c_parser_consume_token (parser);
4606 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4607 attr_args = build_tree_list (NULL_TREE, arg1);
4611 c_parser_consume_token (parser);
4612 expr_list = c_parser_expr_list (parser, false, true,
4613 NULL, NULL, NULL, NULL);
4614 tree_list = build_tree_list_vec (expr_list);
4615 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4616 release_tree_vector (expr_list);
4621 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4623 if (!allow_empty_args)
4624 error_at (c_parser_peek_token (parser)->location,
4625 "parentheses must be omitted if "
4626 "attribute argument list is empty");
4627 attr_args = NULL_TREE;
4629 else if (require_string)
4631 /* The only valid argument for this attribute is a string
4632 literal. Handle this specially here to avoid accepting
4633 string literals with excess parentheses. */
4634 tree string = c_parser_string_literal (parser, false, true).value;
4635 attr_args = build_tree_list (NULL_TREE, string);
4639 expr_list = c_parser_expr_list (parser, false, true,
4640 NULL, NULL, NULL, NULL);
4641 attr_args = build_tree_list_vec (expr_list);
4642 release_tree_vector (expr_list);
4648 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4652 gnu-attributes gnu-attribute
4655 __attribute__ ( ( gnu-attribute-list ) )
4659 gnu-attribute_list , gnu-attrib
4664 any-word ( gnu-attribute-arguments )
4666 where "any-word" may be any identifier (including one declared as a
4667 type), a reserved word storage class specifier, type specifier or
4668 type qualifier. ??? This still leaves out most reserved keywords
4669 (following the old parser), shouldn't we include them?
4670 When EXPECT_COMMA is true, expect the attribute to be preceded
4671 by a comma and fail if it isn't.
4672 When EMPTY_OK is true, allow and consume any number of consecutive
4673 commas with no attributes in between. */
4676 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4677 bool expect_comma = false, bool empty_ok = true)
4679 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4681 && !c_parser_next_token_is (parser, CPP_NAME)
4682 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4685 while (c_parser_next_token_is (parser, CPP_COMMA))
4687 c_parser_consume_token (parser);
4692 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4693 if (attr_name == NULL_TREE)
4696 attr_name = canonicalize_attr_name (attr_name);
4697 c_parser_consume_token (parser);
4700 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4702 if (expect_comma && !comma_first)
4704 /* A comma is missing between the last attribute on the chain
4706 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4708 return error_mark_node;
4710 attr = build_tree_list (attr_name, NULL_TREE);
4711 /* Add this attribute to the list. */
4712 attrs = chainon (attrs, attr);
4715 c_parser_consume_token (parser);
4718 = c_parser_attribute_arguments (parser,
4719 attribute_takes_identifier_p (attr_name),
4722 attr = build_tree_list (attr_name, attr_args);
4723 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4724 c_parser_consume_token (parser);
4727 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4729 return error_mark_node;
4732 if (expect_comma && !comma_first)
4734 /* A comma is missing between the last attribute on the chain
4736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4738 return error_mark_node;
4741 /* Add this attribute to the list. */
4742 attrs = chainon (attrs, attr);
4747 c_parser_gnu_attributes (c_parser *parser)
4749 tree attrs = NULL_TREE;
4750 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4752 bool save_translate_strings_p = parser->translate_strings_p;
4753 parser->translate_strings_p = false;
4754 /* Consume the `__attribute__' keyword. */
4755 c_parser_consume_token (parser);
4756 /* Look for the two `(' tokens. */
4757 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4759 parser->translate_strings_p = save_translate_strings_p;
4762 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4764 parser->translate_strings_p = save_translate_strings_p;
4765 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4768 /* Parse the attribute list. Require a comma between successive
4769 (possibly empty) attributes. */
4770 for (bool expect_comma = false; ; expect_comma = true)
4772 /* Parse a single attribute. */
4773 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4774 if (attr == error_mark_node)
4781 /* Look for the two `)' tokens. */
4782 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4783 c_parser_consume_token (parser);
4786 parser->translate_strings_p = save_translate_strings_p;
4787 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4791 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4792 c_parser_consume_token (parser);
4795 parser->translate_strings_p = save_translate_strings_p;
4796 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4800 parser->translate_strings_p = save_translate_strings_p;
4806 /* Parse an optional balanced token sequence.
4808 balanced-token-sequence:
4810 balanced-token-sequence balanced-token
4813 ( balanced-token-sequence[opt] )
4814 [ balanced-token-sequence[opt] ]
4815 { balanced-token-sequence[opt] }
4816 any token other than ()[]{}
4820 c_parser_balanced_token_sequence (c_parser *parser)
4824 c_token *token = c_parser_peek_token (parser);
4825 switch (token->type)
4827 case CPP_OPEN_BRACE:
4829 matching_braces braces;
4830 braces.consume_open (parser);
4831 c_parser_balanced_token_sequence (parser);
4832 braces.require_close (parser);
4836 case CPP_OPEN_PAREN:
4838 matching_parens parens;
4839 parens.consume_open (parser);
4840 c_parser_balanced_token_sequence (parser);
4841 parens.require_close (parser);
4845 case CPP_OPEN_SQUARE:
4846 c_parser_consume_token (parser);
4847 c_parser_balanced_token_sequence (parser);
4848 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4851 case CPP_CLOSE_BRACE:
4852 case CPP_CLOSE_PAREN:
4853 case CPP_CLOSE_SQUARE:
4858 c_parser_consume_pragma (parser);
4859 c_parser_skip_to_pragma_eol (parser, false);
4863 c_parser_consume_token (parser);
4869 /* Parse standard (C2X) attributes (including GNU attributes in the
4872 attribute-specifier-sequence:
4873 attribute-specifier-sequence[opt] attribute-specifier
4875 attribute-specifier:
4876 [ [ attribute-list ] ]
4880 attribute-list, attribute[opt]
4883 attribute-token attribute-argument-clause[opt]
4887 attribute-prefixed-token
4892 attribute-prefixed-token:
4893 attribute-prefix :: identifier
4898 attribute-argument-clause:
4899 ( balanced-token-sequence[opt] )
4901 Keywords are accepted as identifiers for this purpose.
4905 c_parser_std_attribute (c_parser *parser, bool for_tm)
4907 c_token *token = c_parser_peek_token (parser);
4908 tree ns, name, attribute;
4910 /* Parse the attribute-token. */
4911 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4913 c_parser_error (parser, "expected identifier");
4914 return error_mark_node;
4916 name = canonicalize_attr_name (token->value);
4917 c_parser_consume_token (parser);
4918 if (c_parser_next_token_is (parser, CPP_SCOPE))
4921 c_parser_consume_token (parser);
4922 token = c_parser_peek_token (parser);
4923 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4925 c_parser_error (parser, "expected identifier");
4926 return error_mark_node;
4928 name = canonicalize_attr_name (token->value);
4929 c_parser_consume_token (parser);
4933 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4935 /* Parse the arguments, if any. */
4936 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4937 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4940 location_t open_loc = c_parser_peek_token (parser)->location;
4941 matching_parens parens;
4942 parens.consume_open (parser);
4943 if ((as && as->max_length == 0)
4944 /* Special-case the transactional-memory attribute "outer",
4945 which is specially handled but not registered as an
4946 attribute, to avoid allowing arbitrary balanced token
4947 sequences as arguments. */
4948 || is_attribute_p ("outer", name))
4950 error_at (open_loc, "%qE attribute does not take any arguments", name);
4951 parens.skip_until_found_close (parser);
4952 return error_mark_node;
4954 /* If this is a fake attribute created to handle -Wno-attributes,
4955 we must skip parsing the arguments. */
4956 if (as && !attribute_ignored_p (as))
4958 bool takes_identifier
4960 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4961 && attribute_takes_identifier_p (name));
4964 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4965 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4966 TREE_VALUE (attribute)
4967 = c_parser_attribute_arguments (parser, takes_identifier,
4968 require_string, false);
4971 c_parser_balanced_token_sequence (parser);
4972 parens.require_close (parser);
4975 if (ns == NULL_TREE && !for_tm && !as)
4977 /* An attribute with standard syntax and no namespace specified
4978 is a constraint violation if it is not one of the known
4979 standard attributes. Diagnose it here with a pedwarn and
4980 then discard it to prevent a duplicate warning later. */
4981 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4983 return error_mark_node;
4989 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4991 location_t loc = c_parser_peek_token (parser)->location;
4992 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4994 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4996 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5000 pedwarn_c11 (loc, OPT_Wpedantic,
5001 "ISO C does not support %<[[]]%> attributes before C2X");
5002 tree attributes = NULL_TREE;
5005 c_token *token = c_parser_peek_token (parser);
5006 if (token->type == CPP_CLOSE_SQUARE)
5008 if (token->type == CPP_COMMA)
5010 c_parser_consume_token (parser);
5013 tree attribute = c_parser_std_attribute (parser, for_tm);
5014 if (attribute != error_mark_node)
5016 TREE_CHAIN (attribute) = attributes;
5017 attributes = attribute;
5019 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5022 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5023 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5024 return nreverse (attributes);
5027 /* Look past an optional balanced token sequence of raw look-ahead
5028 tokens starting with the *Nth token. *N is updated to point to the
5029 following token. Return true if such a sequence was found, false
5030 if the tokens parsed were not balanced. */
5033 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5037 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5038 switch (token->type)
5040 case CPP_OPEN_BRACE:
5043 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5045 token = c_parser_peek_nth_token_raw (parser, *n);
5046 if (token->type == CPP_CLOSE_BRACE)
5056 case CPP_OPEN_PAREN:
5059 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5061 token = c_parser_peek_nth_token_raw (parser, *n);
5062 if (token->type == CPP_CLOSE_PAREN)
5072 case CPP_OPEN_SQUARE:
5075 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5077 token = c_parser_peek_nth_token_raw (parser, *n);
5078 if (token->type == CPP_CLOSE_SQUARE)
5088 case CPP_CLOSE_BRACE:
5089 case CPP_CLOSE_PAREN:
5090 case CPP_CLOSE_SQUARE:
5101 /* Return whether standard attributes start with the Nth token. */
5104 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5106 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5107 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5109 /* In C, '[[' must start attributes. In Objective-C, we need to
5110 check whether '[[' is matched by ']]'. */
5111 if (!c_dialect_objc ())
5114 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5116 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5117 if (token->type != CPP_CLOSE_SQUARE)
5119 token = c_parser_peek_nth_token_raw (parser, n + 1);
5120 return token->type == CPP_CLOSE_SQUARE;
5124 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5126 tree attributes = NULL_TREE;
5129 tree attrs = c_parser_std_attribute_specifier (parser, false);
5130 attributes = chainon (attributes, attrs);
5132 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5136 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5137 says whether alignment specifiers are OK (only in cases that might
5138 be the type name of a compound literal).
5141 specifier-qualifier-list abstract-declarator[opt]
5144 struct c_type_name *
5145 c_parser_type_name (c_parser *parser, bool alignas_ok)
5147 struct c_declspecs *specs = build_null_declspecs ();
5148 struct c_declarator *declarator;
5149 struct c_type_name *ret;
5151 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5152 false, true, cla_prefer_type);
5153 if (!specs->declspecs_seen_p)
5155 c_parser_error (parser, "expected specifier-qualifier-list");
5158 if (specs->type != error_mark_node)
5160 pending_xref_error ();
5161 finish_declspecs (specs);
5163 declarator = c_parser_declarator (parser,
5164 specs->typespec_kind != ctsk_none,
5165 C_DTR_ABSTRACT, &dummy);
5166 if (declarator == NULL)
5168 ret = XOBNEW (&parser_obstack, struct c_type_name);
5170 ret->declarator = declarator;
5174 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5177 assignment-expression
5178 { initializer-list }
5179 { initializer-list , }
5182 designation[opt] initializer
5183 initializer-list , designation[opt] initializer
5190 designator-list designator
5197 [ constant-expression ]
5209 [ constant-expression ... constant-expression ]
5211 Any expression without commas is accepted in the syntax for the
5212 constant-expressions, with non-constant expressions rejected later.
5214 DECL is the declaration we're parsing this initializer for.
5216 This function is only used for top-level initializers; for nested
5217 ones, see c_parser_initval. */
5219 static struct c_expr
5220 c_parser_initializer (c_parser *parser, tree decl)
5222 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5223 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5227 location_t loc = c_parser_peek_token (parser)->location;
5228 ret = c_parser_expr_no_commas (parser, NULL);
5229 /* This is handled mostly by gimplify.cc, but we have to deal with
5230 not warning about int x = x; as it is a GCC extension to turn off
5231 this warning but only if warn_init_self is zero. */
5233 && !DECL_EXTERNAL (decl)
5234 && !TREE_STATIC (decl)
5235 && ret.value == decl
5237 suppress_warning (decl, OPT_Winit_self);
5238 if (TREE_CODE (ret.value) != STRING_CST
5239 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5240 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5245 /* The location of the last comma within the current initializer list,
5246 or UNKNOWN_LOCATION if not within one. */
5248 location_t last_init_list_comma;
5250 /* Parse a braced initializer list. TYPE is the type specified for a
5251 compound literal, and NULL_TREE for other initializers and for
5252 nested braced lists. NESTED_P is true for nested braced lists,
5253 false for the list of a compound literal or the list that is the
5254 top-level initializer in a declaration. */
5256 static struct c_expr
5257 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5258 struct obstack *outer_obstack)
5261 struct obstack braced_init_obstack;
5262 location_t brace_loc = c_parser_peek_token (parser)->location;
5263 gcc_obstack_init (&braced_init_obstack);
5264 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5265 matching_braces braces;
5266 braces.consume_open (parser);
5269 finish_implicit_inits (brace_loc, outer_obstack);
5270 push_init_level (brace_loc, 0, &braced_init_obstack);
5273 really_start_incremental_init (type);
5274 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5276 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5280 /* Parse a non-empty initializer list, possibly with a trailing
5284 c_parser_initelt (parser, &braced_init_obstack);
5287 if (c_parser_next_token_is (parser, CPP_COMMA))
5289 last_init_list_comma = c_parser_peek_token (parser)->location;
5290 c_parser_consume_token (parser);
5294 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5298 c_token *next_tok = c_parser_peek_token (parser);
5299 if (next_tok->type != CPP_CLOSE_BRACE)
5302 ret.original_code = ERROR_MARK;
5303 ret.original_type = NULL;
5304 braces.skip_until_found_close (parser);
5305 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5306 obstack_free (&braced_init_obstack, NULL);
5309 location_t close_loc = next_tok->location;
5310 c_parser_consume_token (parser);
5311 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5312 obstack_free (&braced_init_obstack, NULL);
5313 set_c_expr_source_range (&ret, brace_loc, close_loc);
5317 /* Parse a nested initializer, including designators. */
5320 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5322 /* Parse any designator or designator list. A single array
5323 designator may have the subsequent "=" omitted in GNU C, but a
5324 longer list or a structure member designator may not. */
5325 if (c_parser_next_token_is (parser, CPP_NAME)
5326 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5328 /* Old-style structure member designator. */
5329 set_init_label (c_parser_peek_token (parser)->location,
5330 c_parser_peek_token (parser)->value,
5331 c_parser_peek_token (parser)->location,
5332 braced_init_obstack);
5333 /* Use the colon as the error location. */
5334 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5335 "obsolete use of designated initializer with %<:%>");
5336 c_parser_consume_token (parser);
5337 c_parser_consume_token (parser);
5341 /* des_seen is 0 if there have been no designators, 1 if there
5342 has been a single array designator and 2 otherwise. */
5344 /* Location of a designator. */
5345 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5346 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5347 || c_parser_next_token_is (parser, CPP_DOT))
5349 int des_prev = des_seen;
5351 des_loc = c_parser_peek_token (parser)->location;
5354 if (c_parser_next_token_is (parser, CPP_DOT))
5357 c_parser_consume_token (parser);
5358 if (c_parser_next_token_is (parser, CPP_NAME))
5360 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5361 c_parser_peek_token (parser)->location,
5362 braced_init_obstack);
5363 c_parser_consume_token (parser);
5369 init.original_code = ERROR_MARK;
5370 init.original_type = NULL;
5371 c_parser_error (parser, "expected identifier");
5372 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5373 process_init_element (input_location, init, false,
5374 braced_init_obstack);
5381 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5382 location_t array_index_loc = UNKNOWN_LOCATION;
5383 /* ??? Following the old parser, [ objc-receiver
5384 objc-message-args ] is accepted as an initializer,
5385 being distinguished from a designator by what follows
5386 the first assignment expression inside the square
5387 brackets, but after a first array designator a
5388 subsequent square bracket is for Objective-C taken to
5389 start an expression, using the obsolete form of
5390 designated initializer without '=', rather than
5391 possibly being a second level of designation: in LALR
5392 terms, the '[' is shifted rather than reducing
5393 designator to designator-list. */
5394 if (des_prev == 1 && c_dialect_objc ())
5396 des_seen = des_prev;
5399 if (des_prev == 0 && c_dialect_objc ())
5401 /* This might be an array designator or an
5402 Objective-C message expression. If the former,
5403 continue parsing here; if the latter, parse the
5404 remainder of the initializer given the starting
5405 primary-expression. ??? It might make sense to
5406 distinguish when des_prev == 1 as well; see
5407 previous comment. */
5409 struct c_expr mexpr;
5410 c_parser_consume_token (parser);
5411 if (c_parser_peek_token (parser)->type == CPP_NAME
5412 && ((c_parser_peek_token (parser)->id_kind
5414 || (c_parser_peek_token (parser)->id_kind
5415 == C_ID_CLASSNAME)))
5417 /* Type name receiver. */
5418 tree id = c_parser_peek_token (parser)->value;
5419 c_parser_consume_token (parser);
5420 rec = objc_get_class_reference (id);
5421 goto parse_message_args;
5423 first = c_parser_expr_no_commas (parser, NULL).value;
5424 mark_exp_read (first);
5425 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5426 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5427 goto array_desig_after_first;
5428 /* Expression receiver. So far only one part
5429 without commas has been parsed; there might be
5430 more of the expression. */
5432 while (c_parser_next_token_is (parser, CPP_COMMA))
5435 location_t comma_loc, exp_loc;
5436 comma_loc = c_parser_peek_token (parser)->location;
5437 c_parser_consume_token (parser);
5438 exp_loc = c_parser_peek_token (parser)->location;
5439 next = c_parser_expr_no_commas (parser, NULL);
5440 next = convert_lvalue_to_rvalue (exp_loc, next,
5442 rec = build_compound_expr (comma_loc, rec, next.value);
5445 /* Now parse the objc-message-args. */
5446 args = c_parser_objc_message_args (parser);
5447 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5450 = objc_build_message_expr (rec, args);
5451 mexpr.original_code = ERROR_MARK;
5452 mexpr.original_type = NULL;
5453 /* Now parse and process the remainder of the
5454 initializer, starting with this message
5455 expression as a primary-expression. */
5456 c_parser_initval (parser, &mexpr, braced_init_obstack);
5459 c_parser_consume_token (parser);
5460 array_index_loc = c_parser_peek_token (parser)->location;
5461 first = c_parser_expr_no_commas (parser, NULL).value;
5462 mark_exp_read (first);
5463 array_desig_after_first:
5464 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5466 ellipsis_loc = c_parser_peek_token (parser)->location;
5467 c_parser_consume_token (parser);
5468 second = c_parser_expr_no_commas (parser, NULL).value;
5469 mark_exp_read (second);
5473 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5475 c_parser_consume_token (parser);
5476 set_init_index (array_index_loc, first, second,
5477 braced_init_obstack);
5479 pedwarn (ellipsis_loc, OPT_Wpedantic,
5480 "ISO C forbids specifying range of elements to initialize");
5483 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5489 if (c_parser_next_token_is (parser, CPP_EQ))
5491 pedwarn_c90 (des_loc, OPT_Wpedantic,
5492 "ISO C90 forbids specifying subobject "
5494 c_parser_consume_token (parser);
5499 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5500 "obsolete use of designated initializer without %<=%>");
5505 init.original_code = ERROR_MARK;
5506 init.original_type = NULL;
5507 c_parser_error (parser, "expected %<=%>");
5508 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5509 process_init_element (input_location, init, false,
5510 braced_init_obstack);
5516 c_parser_initval (parser, NULL, braced_init_obstack);
5519 /* Parse a nested initializer; as c_parser_initializer but parses
5520 initializers within braced lists, after any designators have been
5521 applied. If AFTER is not NULL then it is an Objective-C message
5522 expression which is the primary-expression starting the
5526 c_parser_initval (c_parser *parser, struct c_expr *after,
5527 struct obstack * braced_init_obstack)
5530 gcc_assert (!after || c_dialect_objc ());
5531 location_t loc = c_parser_peek_token (parser)->location;
5533 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5534 init = c_parser_braced_init (parser, NULL_TREE, true,
5535 braced_init_obstack);
5538 init = c_parser_expr_no_commas (parser, after);
5539 if (init.value != NULL_TREE
5540 && TREE_CODE (init.value) != STRING_CST
5541 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5542 init = convert_lvalue_to_rvalue (loc, init, true, true);
5544 process_init_element (loc, init, false, braced_init_obstack);
5547 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5548 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5551 { block-item-list[opt] }
5552 { label-declarations block-item-list }
5556 block-item-list block-item
5569 { label-declarations block-item-list }
5572 __extension__ nested-declaration
5573 nested-function-definition
5577 label-declarations label-declaration
5580 __label__ identifier-list ;
5582 Allowing the mixing of declarations and code is new in C99. The
5583 GNU syntax also permits (not shown above) labels at the end of
5584 compound statements, which yield an error. We don't allow labels
5585 on declarations; this might seem like a natural extension, but
5586 there would be a conflict between gnu-attributes on the label and
5587 prefix gnu-attributes on the declaration. ??? The syntax follows the
5588 old parser in requiring something after label declarations.
5589 Although they are erroneous if the labels declared aren't defined,
5590 is it useful for the syntax to be this way?
5611 cancellation-point-directive */
5614 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5617 location_t brace_loc;
5618 brace_loc = c_parser_peek_token (parser)->location;
5619 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5621 /* Ensure a scope is entered and left anyway to avoid confusion
5622 if we have just prepared to enter a function body. */
5623 stmt = c_begin_compound_stmt (true);
5624 c_end_compound_stmt (brace_loc, stmt, true);
5625 return error_mark_node;
5627 stmt = c_begin_compound_stmt (true);
5628 location_t end_loc = c_parser_compound_statement_nostart (parser);
5632 return c_end_compound_stmt (brace_loc, stmt, true);
5635 /* Parse a compound statement except for the opening brace. This is
5636 used for parsing both compound statements and statement expressions
5637 (which follow different paths to handling the opening). */
5640 c_parser_compound_statement_nostart (c_parser *parser)
5642 bool last_stmt = false;
5643 bool last_label = false;
5644 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5645 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5646 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5648 location_t endloc = c_parser_peek_token (parser)->location;
5649 add_debug_begin_stmt (endloc);
5650 c_parser_consume_token (parser);
5653 mark_valid_location_for_stdc_pragma (true);
5654 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5656 /* Read zero or more forward-declarations for labels that nested
5657 functions can jump to. */
5658 mark_valid_location_for_stdc_pragma (false);
5659 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5661 label_loc = c_parser_peek_token (parser)->location;
5662 c_parser_consume_token (parser);
5663 /* Any identifiers, including those declared as type names,
5668 if (c_parser_next_token_is_not (parser, CPP_NAME))
5670 c_parser_error (parser, "expected identifier");
5674 = declare_label (c_parser_peek_token (parser)->value);
5675 C_DECLARED_LABEL_FLAG (label) = 1;
5676 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5677 c_parser_consume_token (parser);
5678 if (c_parser_next_token_is (parser, CPP_COMMA))
5679 c_parser_consume_token (parser);
5683 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5685 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5687 /* We must now have at least one statement, label or declaration. */
5688 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5690 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5691 c_parser_error (parser, "expected declaration or statement");
5692 location_t endloc = c_parser_peek_token (parser)->location;
5693 c_parser_consume_token (parser);
5696 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5698 location_t loc = c_parser_peek_token (parser)->location;
5699 loc = expansion_point_location_if_in_system_header (loc);
5700 /* Standard attributes may start a label, statement or declaration. */
5702 = c_parser_nth_token_starts_std_attributes (parser, 1);
5703 tree std_attrs = NULL_TREE;
5705 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5706 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5707 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5708 || (c_parser_next_token_is (parser, CPP_NAME)
5709 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5711 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5712 label_loc = c_parser_peek_2nd_token (parser)->location;
5714 label_loc = c_parser_peek_token (parser)->location;
5717 mark_valid_location_for_stdc_pragma (false);
5718 c_parser_label (parser, std_attrs);
5720 else if (c_parser_next_tokens_start_declaration (parser)
5722 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5725 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5726 "a label can only be part of a statement and "
5727 "a declaration is not a statement");
5729 mark_valid_location_for_stdc_pragma (false);
5730 bool fallthru_attr_p = false;
5731 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5732 true, true, true, NULL,
5733 NULL, have_std_attrs, std_attrs,
5734 NULL, &fallthru_attr_p);
5736 if (last_stmt && !fallthru_attr_p)
5737 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5738 "ISO C90 forbids mixed declarations and code");
5739 last_stmt = fallthru_attr_p;
5742 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5744 /* __extension__ can start a declaration, but is also an
5745 unary operator that can start an expression. Consume all
5746 but the last of a possible series of __extension__ to
5747 determine which. If standard attributes have already
5748 been seen, it must start a statement, not a declaration,
5749 but standard attributes starting a declaration may appear
5750 after __extension__. */
5751 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5752 && (c_parser_peek_2nd_token (parser)->keyword
5754 c_parser_consume_token (parser);
5756 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5757 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5760 ext = disable_extension_diagnostics ();
5761 c_parser_consume_token (parser);
5763 mark_valid_location_for_stdc_pragma (false);
5764 c_parser_declaration_or_fndef (parser, true, true, true, true,
5766 /* Following the old parser, __extension__ does not
5767 disable this diagnostic. */
5768 restore_extension_diagnostics (ext);
5770 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5771 "ISO C90 forbids mixed declarations and code");
5777 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5780 c_parser_error (parser, "expected declaration or statement");
5781 /* External pragmas, and some omp pragmas, are not associated
5782 with regular c code, and so are not to be considered statements
5783 syntactically. This ensures that the user doesn't put them
5784 places that would turn into syntax errors if the directive
5786 if (c_parser_pragma (parser,
5787 last_label ? pragma_stmt : pragma_compound,
5789 last_label = false, last_stmt = true;
5791 else if (c_parser_next_token_is (parser, CPP_EOF))
5793 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5794 c_parser_error (parser, "expected declaration or statement");
5795 return c_parser_peek_token (parser)->location;
5797 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5799 if (parser->in_if_block)
5801 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5802 error_at (loc, "expected %<}%> before %<else%>");
5803 return c_parser_peek_token (parser)->location;
5807 error_at (loc, "%<else%> without a previous %<if%>");
5808 c_parser_consume_token (parser);
5815 c_warn_unused_attributes (std_attrs);
5818 mark_valid_location_for_stdc_pragma (false);
5819 c_parser_statement_after_labels (parser, NULL);
5822 parser->error = false;
5825 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5826 location_t endloc = c_parser_peek_token (parser)->location;
5827 c_parser_consume_token (parser);
5828 /* Restore the value we started with. */
5829 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5833 /* Parse all consecutive labels, possibly preceded by standard
5834 attributes. In this context, a statement is required, not a
5835 declaration, so attributes must be followed by a statement that is
5836 not just a semicolon. */
5839 c_parser_all_labels (c_parser *parser)
5841 tree std_attrs = NULL;
5842 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5844 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5845 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5846 c_parser_error (parser, "expected statement");
5848 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5849 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5850 || (c_parser_next_token_is (parser, CPP_NAME)
5851 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5853 c_parser_label (parser, std_attrs);
5855 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5857 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5858 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5859 c_parser_error (parser, "expected statement");
5863 c_warn_unused_attributes (std_attrs);
5866 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5869 identifier : gnu-attributes[opt]
5870 case constant-expression :
5876 case constant-expression ... constant-expression :
5878 The use of gnu-attributes on labels is a GNU extension. The syntax in
5879 GNU C accepts any expressions without commas, non-constant
5880 expressions being rejected later. Any standard
5881 attribute-specifier-sequence before the first label has been parsed
5882 in the caller, to distinguish statements from declarations. Any
5883 attribute-specifier-sequence after the label is parsed in this
5886 c_parser_label (c_parser *parser, tree std_attrs)
5888 location_t loc1 = c_parser_peek_token (parser)->location;
5889 tree label = NULL_TREE;
5891 /* Remember whether this case or a user-defined label is allowed to fall
5893 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5895 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5898 c_parser_consume_token (parser);
5899 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5900 if (c_parser_next_token_is (parser, CPP_COLON))
5902 c_parser_consume_token (parser);
5903 label = do_case (loc1, exp1, NULL_TREE);
5905 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5907 c_parser_consume_token (parser);
5908 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5909 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5910 label = do_case (loc1, exp1, exp2);
5913 c_parser_error (parser, "expected %<:%> or %<...%>");
5915 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5917 c_parser_consume_token (parser);
5918 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5919 label = do_case (loc1, NULL_TREE, NULL_TREE);
5923 tree name = c_parser_peek_token (parser)->value;
5926 location_t loc2 = c_parser_peek_token (parser)->location;
5927 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5928 c_parser_consume_token (parser);
5929 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5930 c_parser_consume_token (parser);
5931 attrs = c_parser_gnu_attributes (parser);
5932 tlab = define_label (loc2, name);
5935 decl_attributes (&tlab, attrs, 0);
5936 decl_attributes (&tlab, std_attrs, 0);
5937 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5940 && c_parser_next_tokens_start_declaration (parser))
5941 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5942 " label and declaration appertains to the label");
5946 if (TREE_CODE (label) == LABEL_EXPR)
5947 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5949 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5953 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5957 attribute-specifier-sequence[opt] compound-statement
5958 expression-statement
5959 attribute-specifier-sequence[opt] selection-statement
5960 attribute-specifier-sequence[opt] iteration-statement
5961 attribute-specifier-sequence[opt] jump-statement
5964 attribute-specifier-sequence[opt] label statement
5966 expression-statement:
5968 attribute-specifier-sequence expression ;
5970 selection-statement:
5974 iteration-statement:
5983 return expression[opt] ;
5988 attribute-specifier-sequence[opt] asm-statement
5993 expression-statement:
5999 attribute-specifier-sequence[opt] objc-throw-statement
6000 attribute-specifier-sequence[opt] objc-try-catch-statement
6001 attribute-specifier-sequence[opt] objc-synchronized-statement
6003 objc-throw-statement:
6010 attribute-specifier-sequence[opt] openacc-construct
6019 parallel-directive structured-block
6022 kernels-directive structured-block
6025 data-directive structured-block
6028 loop-directive structured-block
6033 attribute-specifier-sequence[opt] openmp-construct
6042 parallel-for-construct
6043 parallel-for-simd-construct
6044 parallel-sections-construct
6051 parallel-directive structured-block
6054 for-directive iteration-statement
6057 simd-directive iteration-statements
6060 for-simd-directive iteration-statements
6063 sections-directive section-scope
6066 single-directive structured-block
6068 parallel-for-construct:
6069 parallel-for-directive iteration-statement
6071 parallel-for-simd-construct:
6072 parallel-for-simd-directive iteration-statement
6074 parallel-sections-construct:
6075 parallel-sections-directive section-scope
6078 master-directive structured-block
6081 critical-directive structured-block
6084 atomic-directive expression-statement
6087 ordered-directive structured-block
6089 Transactional Memory:
6092 attribute-specifier-sequence[opt] transaction-statement
6093 attribute-specifier-sequence[opt] transaction-cancel-statement
6095 IF_P is used to track whether there's a (possibly labeled) if statement
6096 which is not enclosed in braces and has an else clause. This is used to
6097 implement -Wparentheses. */
6100 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6102 c_parser_all_labels (parser);
6103 if (loc_after_labels)
6104 *loc_after_labels = c_parser_peek_token (parser)->location;
6105 c_parser_statement_after_labels (parser, if_p, NULL);
6108 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6109 of if-else-if conditions. All labels and standard attributes have
6110 been parsed in the caller.
6112 IF_P is used to track whether there's a (possibly labeled) if statement
6113 which is not enclosed in braces and has an else clause. This is used to
6114 implement -Wparentheses. */
6117 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6120 location_t loc = c_parser_peek_token (parser)->location;
6121 tree stmt = NULL_TREE;
6122 bool in_if_block = parser->in_if_block;
6123 parser->in_if_block = false;
6127 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6128 add_debug_begin_stmt (loc);
6131 switch (c_parser_peek_token (parser)->type)
6133 case CPP_OPEN_BRACE:
6134 add_stmt (c_parser_compound_statement (parser));
6137 switch (c_parser_peek_token (parser)->keyword)
6140 c_parser_if_statement (parser, if_p, chain);
6143 c_parser_switch_statement (parser, if_p);
6146 c_parser_while_statement (parser, false, 0, if_p);
6149 c_parser_do_statement (parser, false, 0);
6152 c_parser_for_statement (parser, false, 0, if_p);
6155 c_parser_consume_token (parser);
6156 if (c_parser_next_token_is (parser, CPP_NAME))
6158 stmt = c_finish_goto_label (loc,
6159 c_parser_peek_token (parser)->value);
6160 c_parser_consume_token (parser);
6162 else if (c_parser_next_token_is (parser, CPP_MULT))
6166 c_parser_consume_token (parser);
6167 val = c_parser_expression (parser);
6168 val = convert_lvalue_to_rvalue (loc, val, false, true);
6169 stmt = c_finish_goto_ptr (loc, val);
6172 c_parser_error (parser, "expected identifier or %<*%>");
6173 goto expect_semicolon;
6175 c_parser_consume_token (parser);
6176 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6177 goto expect_semicolon;
6179 c_parser_consume_token (parser);
6180 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6181 goto expect_semicolon;
6183 c_parser_consume_token (parser);
6184 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6186 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6187 c_parser_consume_token (parser);
6191 location_t xloc = c_parser_peek_token (parser)->location;
6192 struct c_expr expr = c_parser_expression_conv (parser);
6193 mark_exp_read (expr.value);
6194 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6195 expr.value, expr.original_type);
6196 goto expect_semicolon;
6200 stmt = c_parser_asm_statement (parser);
6202 case RID_TRANSACTION_ATOMIC:
6203 case RID_TRANSACTION_RELAXED:
6204 stmt = c_parser_transaction (parser,
6205 c_parser_peek_token (parser)->keyword);
6207 case RID_TRANSACTION_CANCEL:
6208 stmt = c_parser_transaction_cancel (parser);
6209 goto expect_semicolon;
6211 gcc_assert (c_dialect_objc ());
6212 c_parser_consume_token (parser);
6213 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6215 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6216 c_parser_consume_token (parser);
6220 struct c_expr expr = c_parser_expression (parser);
6221 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6222 expr.value = c_fully_fold (expr.value, false, NULL);
6223 stmt = objc_build_throw_stmt (loc, expr.value);
6224 goto expect_semicolon;
6228 gcc_assert (c_dialect_objc ());
6229 c_parser_objc_try_catch_finally_statement (parser);
6231 case RID_AT_SYNCHRONIZED:
6232 gcc_assert (c_dialect_objc ());
6233 c_parser_objc_synchronized_statement (parser);
6237 /* Allow '__attribute__((fallthrough));'. */
6238 tree attrs = c_parser_gnu_attributes (parser);
6239 if (attribute_fallthrough_p (attrs))
6241 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6243 tree fn = build_call_expr_internal_loc (loc,
6248 c_parser_consume_token (parser);
6251 warning_at (loc, OPT_Wattributes,
6252 "%<fallthrough%> attribute not followed "
6255 else if (attrs != NULL_TREE)
6256 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6257 " can be applied to a null statement");
6265 c_parser_consume_token (parser);
6267 case CPP_CLOSE_PAREN:
6268 case CPP_CLOSE_SQUARE:
6269 /* Avoid infinite loop in error recovery:
6270 c_parser_skip_until_found stops at a closing nesting
6271 delimiter without consuming it, but here we need to consume
6272 it to proceed further. */
6273 c_parser_error (parser, "expected statement");
6274 c_parser_consume_token (parser);
6277 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6282 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6284 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6287 /* Two cases cannot and do not have line numbers associated: If stmt
6288 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6289 cannot hold line numbers. But that's OK because the statement
6290 will either be changed to a MODIFY_EXPR during gimplification of
6291 the statement expr, or discarded. If stmt was compound, but
6292 without new variables, we will have skipped the creation of a
6293 BIND and will have a bare STATEMENT_LIST. But that's OK because
6294 (recursively) all of the component statements should already have
6295 line numbers assigned. ??? Can we discard no-op statements
6297 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6298 protected_set_expr_location (stmt, loc);
6300 parser->in_if_block = in_if_block;
6303 /* Parse the condition from an if, do, while or for statements. */
6306 c_parser_condition (c_parser *parser)
6308 location_t loc = c_parser_peek_token (parser)->location;
6310 cond = c_parser_expression_conv (parser).value;
6311 cond = c_objc_common_truthvalue_conversion (loc, cond);
6312 cond = c_fully_fold (cond, false, NULL);
6313 if (warn_sequence_point)
6314 verify_sequence_points (cond);
6318 /* Parse a parenthesized condition from an if, do or while statement.
6324 c_parser_paren_condition (c_parser *parser)
6327 matching_parens parens;
6328 if (!parens.require_open (parser))
6329 return error_mark_node;
6330 cond = c_parser_condition (parser);
6331 parens.skip_until_found_close (parser);
6335 /* Parse a statement which is a block in C99.
6337 IF_P is used to track whether there's a (possibly labeled) if statement
6338 which is not enclosed in braces and has an else clause. This is used to
6339 implement -Wparentheses. */
6342 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6343 location_t *loc_after_labels)
6345 tree block = c_begin_compound_stmt (flag_isoc99);
6346 location_t loc = c_parser_peek_token (parser)->location;
6347 c_parser_statement (parser, if_p, loc_after_labels);
6348 return c_end_compound_stmt (loc, block, flag_isoc99);
6351 /* Parse the body of an if statement. This is just parsing a
6352 statement but (a) it is a block in C99, (b) we track whether the
6353 body is an if statement for the sake of -Wparentheses warnings, (c)
6354 we handle an empty body specially for the sake of -Wempty-body
6355 warnings, and (d) we call parser_compound_statement directly
6356 because c_parser_statement_after_labels resets
6357 parser->in_if_block.
6359 IF_P is used to track whether there's a (possibly labeled) if statement
6360 which is not enclosed in braces and has an else clause. This is used to
6361 implement -Wparentheses. */
6364 c_parser_if_body (c_parser *parser, bool *if_p,
6365 const token_indent_info &if_tinfo)
6367 tree block = c_begin_compound_stmt (flag_isoc99);
6368 location_t body_loc = c_parser_peek_token (parser)->location;
6369 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6370 token_indent_info body_tinfo
6371 = get_token_indent_info (c_parser_peek_token (parser));
6373 c_parser_all_labels (parser);
6374 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6376 location_t loc = c_parser_peek_token (parser)->location;
6377 add_stmt (build_empty_stmt (loc));
6378 c_parser_consume_token (parser);
6379 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6380 warning_at (loc, OPT_Wempty_body,
6381 "suggest braces around empty body in an %<if%> statement");
6383 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6384 add_stmt (c_parser_compound_statement (parser));
6387 body_loc_after_labels = c_parser_peek_token (parser)->location;
6388 c_parser_statement_after_labels (parser, if_p);
6391 token_indent_info next_tinfo
6392 = get_token_indent_info (c_parser_peek_token (parser));
6393 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6394 if (body_loc_after_labels != UNKNOWN_LOCATION
6395 && next_tinfo.type != CPP_SEMICOLON)
6396 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6397 if_tinfo.location, RID_IF);
6399 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6402 /* Parse the else body of an if statement. This is just parsing a
6403 statement but (a) it is a block in C99, (b) we handle an empty body
6404 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6405 of if-else-if conditions. */
6408 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6411 location_t body_loc = c_parser_peek_token (parser)->location;
6412 tree block = c_begin_compound_stmt (flag_isoc99);
6413 token_indent_info body_tinfo
6414 = get_token_indent_info (c_parser_peek_token (parser));
6415 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6417 c_parser_all_labels (parser);
6418 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6420 location_t loc = c_parser_peek_token (parser)->location;
6423 "suggest braces around empty body in an %<else%> statement");
6424 add_stmt (build_empty_stmt (loc));
6425 c_parser_consume_token (parser);
6429 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6430 body_loc_after_labels = c_parser_peek_token (parser)->location;
6431 c_parser_statement_after_labels (parser, NULL, chain);
6434 token_indent_info next_tinfo
6435 = get_token_indent_info (c_parser_peek_token (parser));
6436 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6437 if (body_loc_after_labels != UNKNOWN_LOCATION
6438 && next_tinfo.type != CPP_SEMICOLON)
6439 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6440 else_tinfo.location, RID_ELSE);
6442 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6445 /* We might need to reclassify any previously-lexed identifier, e.g.
6446 when we've left a for loop with an if-statement without else in the
6447 body - we might have used a wrong scope for the token. See PR67784. */
6450 c_parser_maybe_reclassify_token (c_parser *parser)
6452 if (c_parser_next_token_is (parser, CPP_NAME))
6454 c_token *token = c_parser_peek_token (parser);
6456 if (token->id_kind != C_ID_CLASSNAME)
6458 tree decl = lookup_name (token->value);
6460 token->id_kind = C_ID_ID;
6463 if (TREE_CODE (decl) == TYPE_DECL)
6464 token->id_kind = C_ID_TYPENAME;
6466 else if (c_dialect_objc ())
6468 tree objc_interface_decl = objc_is_class_name (token->value);
6469 /* Objective-C class names are in the same namespace as
6470 variables and typedefs, and hence are shadowed by local
6472 if (objc_interface_decl)
6474 token->value = objc_interface_decl;
6475 token->id_kind = C_ID_CLASSNAME;
6482 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6485 if ( expression ) statement
6486 if ( expression ) statement else statement
6488 CHAIN is a vector of if-else-if conditions.
6489 IF_P is used to track whether there's a (possibly labeled) if statement
6490 which is not enclosed in braces and has an else clause. This is used to
6491 implement -Wparentheses. */
6494 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6499 bool nested_if = false;
6500 tree first_body, second_body;
6503 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6504 token_indent_info if_tinfo
6505 = get_token_indent_info (c_parser_peek_token (parser));
6506 c_parser_consume_token (parser);
6507 block = c_begin_compound_stmt (flag_isoc99);
6508 loc = c_parser_peek_token (parser)->location;
6509 cond = c_parser_paren_condition (parser);
6510 in_if_block = parser->in_if_block;
6511 parser->in_if_block = true;
6512 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6513 parser->in_if_block = in_if_block;
6515 if (warn_duplicated_cond)
6516 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6518 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6520 token_indent_info else_tinfo
6521 = get_token_indent_info (c_parser_peek_token (parser));
6522 c_parser_consume_token (parser);
6523 if (warn_duplicated_cond)
6525 if (c_parser_next_token_is_keyword (parser, RID_IF)
6528 /* We've got "if (COND) else if (COND2)". Start the
6529 condition chain and add COND as the first element. */
6530 chain = new vec<tree> ();
6531 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6532 chain->safe_push (cond);
6534 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6535 /* This is if-else without subsequent if. Zap the condition
6536 chain; we would have already warned at this point. */
6539 second_body = c_parser_else_body (parser, else_tinfo, chain);
6540 /* Set IF_P to true to indicate that this if statement has an
6541 else clause. This may trigger the Wparentheses warning
6542 below when we get back up to the parent if statement. */
6548 second_body = NULL_TREE;
6550 /* Diagnose an ambiguous else if if-then-else is nested inside
6553 warning_at (loc, OPT_Wdangling_else,
6554 "suggest explicit braces to avoid ambiguous %<else%>");
6556 if (warn_duplicated_cond)
6557 /* This if statement does not have an else clause. We don't
6558 need the condition chain anymore. */
6561 c_finish_if_stmt (loc, cond, first_body, second_body);
6562 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6564 c_parser_maybe_reclassify_token (parser);
6567 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6570 switch (expression) statement
6574 c_parser_switch_statement (c_parser *parser, bool *if_p)
6577 tree block, expr, body;
6578 unsigned char save_in_statement;
6579 location_t switch_loc = c_parser_peek_token (parser)->location;
6580 location_t switch_cond_loc;
6581 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6582 c_parser_consume_token (parser);
6583 block = c_begin_compound_stmt (flag_isoc99);
6584 bool explicit_cast_p = false;
6585 matching_parens parens;
6586 if (parens.require_open (parser))
6588 switch_cond_loc = c_parser_peek_token (parser)->location;
6589 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6590 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6591 explicit_cast_p = true;
6592 ce = c_parser_expression (parser);
6593 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6595 /* ??? expr has no valid location? */
6596 parens.skip_until_found_close (parser);
6600 switch_cond_loc = UNKNOWN_LOCATION;
6601 expr = error_mark_node;
6602 ce.original_type = error_mark_node;
6604 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6605 save_in_statement = in_statement;
6606 in_statement |= IN_SWITCH_STMT;
6607 location_t loc_after_labels;
6608 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6609 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6610 location_t next_loc = c_parser_peek_token (parser)->location;
6611 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6612 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6614 c_finish_switch (body, ce.original_type);
6615 in_statement = save_in_statement;
6616 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6617 c_parser_maybe_reclassify_token (parser);
6620 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6623 while (expression) statement
6625 IF_P is used to track whether there's a (possibly labeled) if statement
6626 which is not enclosed in braces and has an else clause. This is used to
6627 implement -Wparentheses. */
6630 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6633 tree block, cond, body;
6634 unsigned char save_in_statement;
6636 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6637 token_indent_info while_tinfo
6638 = get_token_indent_info (c_parser_peek_token (parser));
6639 c_parser_consume_token (parser);
6640 block = c_begin_compound_stmt (flag_isoc99);
6641 loc = c_parser_peek_token (parser)->location;
6642 cond = c_parser_paren_condition (parser);
6643 if (ivdep && cond != error_mark_node)
6644 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6645 build_int_cst (integer_type_node,
6646 annot_expr_ivdep_kind),
6648 if (unroll && cond != error_mark_node)
6649 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6650 build_int_cst (integer_type_node,
6651 annot_expr_unroll_kind),
6652 build_int_cst (integer_type_node, unroll));
6653 save_in_statement = in_statement;
6654 in_statement = IN_ITERATION_STMT;
6656 token_indent_info body_tinfo
6657 = get_token_indent_info (c_parser_peek_token (parser));
6659 location_t loc_after_labels;
6660 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6661 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6662 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6663 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6664 c_parser_maybe_reclassify_token (parser);
6666 token_indent_info next_tinfo
6667 = get_token_indent_info (c_parser_peek_token (parser));
6668 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6670 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6671 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6672 while_tinfo.location, RID_WHILE);
6674 in_statement = save_in_statement;
6677 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6680 do statement while ( expression ) ;
6684 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6686 tree block, cond, body;
6687 unsigned char save_in_statement;
6689 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6690 c_parser_consume_token (parser);
6691 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6692 warning_at (c_parser_peek_token (parser)->location,
6694 "suggest braces around empty body in %<do%> statement");
6695 block = c_begin_compound_stmt (flag_isoc99);
6696 loc = c_parser_peek_token (parser)->location;
6697 save_in_statement = in_statement;
6698 in_statement = IN_ITERATION_STMT;
6699 body = c_parser_c99_block_statement (parser, NULL);
6700 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6701 in_statement = save_in_statement;
6702 cond = c_parser_paren_condition (parser);
6703 if (ivdep && cond != error_mark_node)
6704 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6705 build_int_cst (integer_type_node,
6706 annot_expr_ivdep_kind),
6708 if (unroll && cond != error_mark_node)
6709 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6710 build_int_cst (integer_type_node,
6711 annot_expr_unroll_kind),
6712 build_int_cst (integer_type_node, unroll));
6713 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6714 c_parser_skip_to_end_of_block_or_statement (parser);
6716 add_stmt (build_stmt (loc, DO_STMT, cond, body));
6717 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6720 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6723 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6724 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6726 The form with a declaration is new in C99.
6728 ??? In accordance with the old parser, the declaration may be a
6729 nested function, which is then rejected in check_for_loop_decls,
6730 but does it make any sense for this to be included in the grammar?
6731 Note in particular that the nested function does not include a
6732 trailing ';', whereas the "declaration" production includes one.
6733 Also, can we reject bad declarations earlier and cheaper than
6734 check_for_loop_decls?
6736 In Objective-C, there are two additional variants:
6739 for ( expression in expresssion ) statement
6740 for ( declaration in expression ) statement
6742 This is inconsistent with C, because the second variant is allowed
6743 even if c99 is not enabled.
6745 The rest of the comment documents these Objective-C foreach-statement.
6747 Here is the canonical example of the first variant:
6748 for (object in array) { do something with object }
6749 we call the first expression ("object") the "object_expression" and
6750 the second expression ("array") the "collection_expression".
6751 object_expression must be an lvalue of type "id" (a generic Objective-C
6752 object) because the loop works by assigning to object_expression the
6753 various objects from the collection_expression. collection_expression
6754 must evaluate to something of type "id" which responds to the method
6755 countByEnumeratingWithState:objects:count:.
6757 The canonical example of the second variant is:
6758 for (id object in array) { do something with object }
6759 which is completely equivalent to
6762 for (object in array) { do something with object }
6764 Note that initizializing 'object' in some way (eg, "for ((object =
6765 xxx) in array) { do something with object }") is possibly
6766 technically valid, but completely pointless as 'object' will be
6767 assigned to something else as soon as the loop starts. We should
6768 most likely reject it (TODO).
6770 The beginning of the Objective-C foreach-statement looks exactly
6771 like the beginning of the for-statement, and we can tell it is a
6772 foreach-statement only because the initial declaration or
6773 expression is terminated by 'in' instead of ';'.
6775 IF_P is used to track whether there's a (possibly labeled) if statement
6776 which is not enclosed in braces and has an else clause. This is used to
6777 implement -Wparentheses. */
6780 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6783 tree block, cond, incr, body;
6784 unsigned char save_in_statement;
6785 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6786 /* The following are only used when parsing an ObjC foreach statement. */
6787 tree object_expression;
6788 /* Silence the bogus uninitialized warning. */
6789 tree collection_expression = NULL;
6790 location_t loc = c_parser_peek_token (parser)->location;
6791 location_t for_loc = loc;
6792 bool is_foreach_statement = false;
6793 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6794 token_indent_info for_tinfo
6795 = get_token_indent_info (c_parser_peek_token (parser));
6796 c_parser_consume_token (parser);
6797 /* Open a compound statement in Objective-C as well, just in case this is
6798 as foreach expression. */
6799 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6800 cond = error_mark_node;
6801 incr = error_mark_node;
6802 matching_parens parens;
6803 if (parens.require_open (parser))
6805 /* Parse the initialization declaration or expression. */
6806 object_expression = error_mark_node;
6807 parser->objc_could_be_foreach_context = c_dialect_objc ();
6808 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6810 parser->objc_could_be_foreach_context = false;
6811 c_parser_consume_token (parser);
6812 c_finish_expr_stmt (loc, NULL_TREE);
6814 else if (c_parser_next_tokens_start_declaration (parser)
6815 || c_parser_nth_token_starts_std_attributes (parser, 1))
6817 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6818 &object_expression);
6819 parser->objc_could_be_foreach_context = false;
6821 if (c_parser_next_token_is_keyword (parser, RID_IN))
6823 c_parser_consume_token (parser);
6824 is_foreach_statement = true;
6825 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6826 c_parser_error (parser, "multiple iterating variables in "
6827 "fast enumeration");
6830 check_for_loop_decls (for_loc, flag_isoc99);
6832 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6834 /* __extension__ can start a declaration, but is also an
6835 unary operator that can start an expression. Consume all
6836 but the last of a possible series of __extension__ to
6838 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6839 && (c_parser_peek_2nd_token (parser)->keyword
6841 c_parser_consume_token (parser);
6842 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6843 || c_parser_nth_token_starts_std_attributes (parser, 2))
6846 ext = disable_extension_diagnostics ();
6847 c_parser_consume_token (parser);
6848 c_parser_declaration_or_fndef (parser, true, true, true, true,
6849 true, &object_expression);
6850 parser->objc_could_be_foreach_context = false;
6852 restore_extension_diagnostics (ext);
6853 if (c_parser_next_token_is_keyword (parser, RID_IN))
6855 c_parser_consume_token (parser);
6856 is_foreach_statement = true;
6857 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6858 c_parser_error (parser, "multiple iterating variables in "
6859 "fast enumeration");
6862 check_for_loop_decls (for_loc, flag_isoc99);
6872 tree init_expression;
6873 ce = c_parser_expression (parser);
6874 init_expression = ce.value;
6875 parser->objc_could_be_foreach_context = false;
6876 if (c_parser_next_token_is_keyword (parser, RID_IN))
6878 c_parser_consume_token (parser);
6879 is_foreach_statement = true;
6880 if (! lvalue_p (init_expression))
6881 c_parser_error (parser, "invalid iterating variable in "
6882 "fast enumeration");
6884 = c_fully_fold (init_expression, false, NULL);
6888 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6889 init_expression = ce.value;
6890 c_finish_expr_stmt (loc, init_expression);
6891 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6896 /* Parse the loop condition. In the case of a foreach
6897 statement, there is no loop condition. */
6898 gcc_assert (!parser->objc_could_be_foreach_context);
6899 if (!is_foreach_statement)
6901 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6905 c_parser_error (parser, "missing loop condition in loop "
6906 "with %<GCC ivdep%> pragma");
6907 cond = error_mark_node;
6911 c_parser_error (parser, "missing loop condition in loop "
6912 "with %<GCC unroll%> pragma");
6913 cond = error_mark_node;
6917 c_parser_consume_token (parser);
6923 cond = c_parser_condition (parser);
6924 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6927 if (ivdep && cond != error_mark_node)
6928 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6929 build_int_cst (integer_type_node,
6930 annot_expr_ivdep_kind),
6932 if (unroll && cond != error_mark_node)
6933 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6934 build_int_cst (integer_type_node,
6935 annot_expr_unroll_kind),
6936 build_int_cst (integer_type_node, unroll));
6938 /* Parse the increment expression (the third expression in a
6939 for-statement). In the case of a foreach-statement, this is
6940 the expression that follows the 'in'. */
6941 loc = c_parser_peek_token (parser)->location;
6942 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6944 if (is_foreach_statement)
6946 c_parser_error (parser,
6947 "missing collection in fast enumeration");
6948 collection_expression = error_mark_node;
6951 incr = c_process_expr_stmt (loc, NULL_TREE);
6955 if (is_foreach_statement)
6956 collection_expression
6957 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6960 struct c_expr ce = c_parser_expression (parser);
6961 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6962 incr = c_process_expr_stmt (loc, ce.value);
6965 parens.skip_until_found_close (parser);
6967 save_in_statement = in_statement;
6968 if (is_foreach_statement)
6970 in_statement = IN_OBJC_FOREACH;
6971 save_objc_foreach_break_label = objc_foreach_break_label;
6972 save_objc_foreach_continue_label = objc_foreach_continue_label;
6973 objc_foreach_break_label = create_artificial_label (loc);
6974 objc_foreach_continue_label = create_artificial_label (loc);
6977 in_statement = IN_ITERATION_STMT;
6979 token_indent_info body_tinfo
6980 = get_token_indent_info (c_parser_peek_token (parser));
6982 location_t loc_after_labels;
6983 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6984 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6986 if (is_foreach_statement)
6987 objc_finish_foreach_loop (for_loc, object_expression,
6988 collection_expression, body,
6989 objc_foreach_break_label,
6990 objc_foreach_continue_label);
6992 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
6994 add_stmt (c_end_compound_stmt (for_loc, block,
6995 flag_isoc99 || c_dialect_objc ()));
6996 c_parser_maybe_reclassify_token (parser);
6998 token_indent_info next_tinfo
6999 = get_token_indent_info (c_parser_peek_token (parser));
7000 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
7002 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
7003 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7004 for_tinfo.location, RID_FOR);
7006 in_statement = save_in_statement;
7007 if (is_foreach_statement)
7009 objc_foreach_break_label = save_objc_foreach_break_label;
7010 objc_foreach_continue_label = save_objc_foreach_continue_label;
7014 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7015 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7024 asm-qualifier-list asm-qualifier
7028 asm asm-qualifier-list[opt] ( asm-argument ) ;
7032 asm-string-literal : asm-operands[opt]
7033 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7034 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7036 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7039 The form with asm-goto-operands is valid if and only if the
7040 asm-qualifier-list contains goto, and is the only allowed form in that case.
7041 Duplicate asm-qualifiers are not allowed.
7043 The :: token is considered equivalent to two consecutive : tokens. */
7046 c_parser_asm_statement (c_parser *parser)
7048 tree str, outputs, inputs, clobbers, labels, ret;
7050 location_t asm_loc = c_parser_peek_token (parser)->location;
7051 int section, nsections;
7053 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7054 c_parser_consume_token (parser);
7056 /* Handle the asm-qualifier-list. */
7057 location_t volatile_loc = UNKNOWN_LOCATION;
7058 location_t inline_loc = UNKNOWN_LOCATION;
7059 location_t goto_loc = UNKNOWN_LOCATION;
7062 c_token *token = c_parser_peek_token (parser);
7063 location_t loc = token->location;
7064 switch (token->keyword)
7069 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7070 inform (volatile_loc, "first seen here");
7074 c_parser_consume_token (parser);
7080 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7081 inform (inline_loc, "first seen here");
7085 c_parser_consume_token (parser);
7091 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7092 inform (goto_loc, "first seen here");
7096 c_parser_consume_token (parser);
7101 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7102 c_parser_consume_token (parser);
7111 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7112 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7113 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7117 matching_parens parens;
7118 if (!parens.require_open (parser))
7121 str = c_parser_asm_string_literal (parser);
7122 if (str == NULL_TREE)
7123 goto error_close_paren;
7126 outputs = NULL_TREE;
7128 clobbers = NULL_TREE;
7131 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7134 /* Parse each colon-delimited section of operands. */
7135 nsections = 3 + is_goto;
7136 for (section = 0; section < nsections; ++section)
7138 if (c_parser_next_token_is (parser, CPP_SCOPE))
7141 if (section == nsections)
7143 c_parser_error (parser, "expected %<)%>");
7144 goto error_close_paren;
7146 c_parser_consume_token (parser);
7148 else if (!c_parser_require (parser, CPP_COLON,
7150 ? G_("expected %<:%>")
7151 : G_("expected %<:%> or %<)%>"),
7152 UNKNOWN_LOCATION, is_goto))
7153 goto error_close_paren;
7155 /* Once past any colon, we're no longer a simple asm. */
7158 if ((!c_parser_next_token_is (parser, CPP_COLON)
7159 && !c_parser_next_token_is (parser, CPP_SCOPE)
7160 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7165 outputs = c_parser_asm_operands (parser);
7168 inputs = c_parser_asm_operands (parser);
7171 clobbers = c_parser_asm_clobbers (parser);
7174 labels = c_parser_asm_goto_operands (parser);
7180 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7185 if (!parens.require_close (parser))
7187 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7191 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7192 c_parser_skip_to_end_of_block_or_statement (parser);
7194 ret = build_asm_stmt (is_volatile,
7195 build_asm_expr (asm_loc, str, outputs, inputs,
7196 clobbers, labels, simple, is_inline));
7202 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7206 /* Parse asm operands, a GNU extension.
7210 asm-operands , asm-operand
7213 asm-string-literal ( expression )
7214 [ identifier ] asm-string-literal ( expression )
7218 c_parser_asm_operands (c_parser *parser)
7220 tree list = NULL_TREE;
7225 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7227 c_parser_consume_token (parser);
7228 if (c_parser_next_token_is (parser, CPP_NAME))
7230 tree id = c_parser_peek_token (parser)->value;
7231 c_parser_consume_token (parser);
7232 name = build_string (IDENTIFIER_LENGTH (id),
7233 IDENTIFIER_POINTER (id));
7237 c_parser_error (parser, "expected identifier");
7238 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7241 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7246 str = c_parser_asm_string_literal (parser);
7247 if (str == NULL_TREE)
7249 matching_parens parens;
7250 if (!parens.require_open (parser))
7252 expr = c_parser_expression (parser);
7253 mark_exp_read (expr.value);
7254 if (!parens.require_close (parser))
7256 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7259 list = chainon (list, build_tree_list (build_tree_list (name, str),
7261 if (c_parser_next_token_is (parser, CPP_COMMA))
7262 c_parser_consume_token (parser);
7269 /* Parse asm clobbers, a GNU extension.
7273 asm-clobbers , asm-string-literal
7277 c_parser_asm_clobbers (c_parser *parser)
7279 tree list = NULL_TREE;
7282 tree str = c_parser_asm_string_literal (parser);
7284 list = tree_cons (NULL_TREE, str, list);
7287 if (c_parser_next_token_is (parser, CPP_COMMA))
7288 c_parser_consume_token (parser);
7295 /* Parse asm goto labels, a GNU extension.
7299 asm-goto-operands , identifier
7303 c_parser_asm_goto_operands (c_parser *parser)
7305 tree list = NULL_TREE;
7310 if (c_parser_next_token_is (parser, CPP_NAME))
7312 c_token *tok = c_parser_peek_token (parser);
7314 label = lookup_label_for_goto (tok->location, name);
7315 c_parser_consume_token (parser);
7316 TREE_USED (label) = 1;
7320 c_parser_error (parser, "expected identifier");
7324 name = build_string (IDENTIFIER_LENGTH (name),
7325 IDENTIFIER_POINTER (name));
7326 list = tree_cons (name, label, list);
7327 if (c_parser_next_token_is (parser, CPP_COMMA))
7328 c_parser_consume_token (parser);
7330 return nreverse (list);
7334 /* Parse a possibly concatenated sequence of string literals.
7335 TRANSLATE says whether to translate them to the execution character
7336 set; WIDE_OK says whether any kind of prefixed string literal is
7337 permitted in this context. This code is based on that in
7341 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7345 struct obstack str_ob;
7346 struct obstack loc_ob;
7347 cpp_string str, istr, *strs;
7349 location_t loc, last_tok_loc;
7350 enum cpp_ttype type;
7351 tree value, string_tree;
7353 tok = c_parser_peek_token (parser);
7354 loc = tok->location;
7355 last_tok_loc = linemap_resolve_location (line_table, loc,
7356 LRK_MACRO_DEFINITION_LOCATION,
7365 case CPP_UTF8STRING:
7366 string_tree = tok->value;
7370 c_parser_error (parser, "expected string literal");
7372 ret.value = NULL_TREE;
7373 ret.original_code = ERROR_MARK;
7374 ret.original_type = NULL_TREE;
7378 /* Try to avoid the overhead of creating and destroying an obstack
7379 for the common case of just one string. */
7380 switch (c_parser_peek_2nd_token (parser)->type)
7383 c_parser_consume_token (parser);
7384 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7385 str.len = TREE_STRING_LENGTH (string_tree);
7394 case CPP_UTF8STRING:
7395 gcc_obstack_init (&str_ob);
7396 gcc_obstack_init (&loc_ob);
7400 c_parser_consume_token (parser);
7402 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7403 str.len = TREE_STRING_LENGTH (string_tree);
7404 if (type != tok->type)
7406 if (type == CPP_STRING)
7408 else if (tok->type != CPP_STRING)
7409 error ("unsupported non-standard concatenation "
7410 "of string literals");
7412 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7413 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7414 tok = c_parser_peek_token (parser);
7415 string_tree = tok->value;
7417 = linemap_resolve_location (line_table, tok->location,
7418 LRK_MACRO_DEFINITION_LOCATION, NULL);
7420 while (tok->type == CPP_STRING
7421 || tok->type == CPP_WSTRING
7422 || tok->type == CPP_STRING16
7423 || tok->type == CPP_STRING32
7424 || tok->type == CPP_UTF8STRING);
7425 strs = (cpp_string *) obstack_finish (&str_ob);
7428 if (count > 1 && !in_system_header_at (input_location))
7429 warning (OPT_Wtraditional,
7430 "traditional C rejects string constant concatenation");
7432 if ((type == CPP_STRING || wide_ok)
7434 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7435 (parse_in, strs, count, &istr, type)))
7437 value = build_string (istr.len, (const char *) istr.text);
7438 free (CONST_CAST (unsigned char *, istr.text));
7441 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7442 gcc_assert (g_string_concat_db);
7443 g_string_concat_db->record_string_concatenation (count, locs);
7448 if (type != CPP_STRING && !wide_ok)
7450 error_at (loc, "a wide string is invalid in this context");
7453 /* Callers cannot generally handle error_mark_node in this
7454 context, so return the empty string instead. An error has
7455 been issued, either above or from cpp_interpret_string. */
7460 case CPP_UTF8STRING:
7461 if (type == CPP_UTF8STRING && flag_char8_t)
7463 value = build_string (TYPE_PRECISION (char8_type_node)
7464 / TYPE_PRECISION (char_type_node),
7465 ""); /* char8_t is 8 bits */
7468 value = build_string (1, "");
7471 value = build_string (TYPE_PRECISION (char16_type_node)
7472 / TYPE_PRECISION (char_type_node),
7473 "\0"); /* char16_t is 16 bits */
7476 value = build_string (TYPE_PRECISION (char32_type_node)
7477 / TYPE_PRECISION (char_type_node),
7478 "\0\0\0"); /* char32_t is 32 bits */
7481 value = build_string (TYPE_PRECISION (wchar_type_node)
7482 / TYPE_PRECISION (char_type_node),
7483 "\0\0\0"); /* widest supported wchar_t
7493 TREE_TYPE (value) = char_array_type_node;
7495 case CPP_UTF8STRING:
7497 TREE_TYPE (value) = char8_array_type_node;
7499 TREE_TYPE (value) = char_array_type_node;
7502 TREE_TYPE (value) = char16_array_type_node;
7505 TREE_TYPE (value) = char32_array_type_node;
7508 TREE_TYPE (value) = wchar_array_type_node;
7510 value = fix_string_type (value);
7514 obstack_free (&str_ob, 0);
7515 obstack_free (&loc_ob, 0);
7519 ret.original_code = STRING_CST;
7520 ret.original_type = NULL_TREE;
7521 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7522 parser->seen_string_literal = true;
7526 /* Parse an expression other than a compound expression; that is, an
7527 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7528 AFTER is not NULL then it is an Objective-C message expression which
7529 is the primary-expression starting the expression as an initializer.
7531 assignment-expression:
7532 conditional-expression
7533 unary-expression assignment-operator assignment-expression
7535 assignment-operator: one of
7536 = *= /= %= += -= <<= >>= &= ^= |=
7538 In GNU C we accept any conditional expression on the LHS and
7539 diagnose the invalid lvalue rather than producing a syntax
7542 static struct c_expr
7543 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7544 tree omp_atomic_lhs)
7546 struct c_expr lhs, rhs, ret;
7547 enum tree_code code;
7548 location_t op_location, exp_location;
7549 bool save_in_omp_for = c_in_omp_for;
7550 c_in_omp_for = false;
7551 gcc_assert (!after || c_dialect_objc ());
7552 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7553 op_location = c_parser_peek_token (parser)->location;
7554 switch (c_parser_peek_token (parser)->type)
7563 code = TRUNC_DIV_EXPR;
7566 code = TRUNC_MOD_EXPR;
7581 code = BIT_AND_EXPR;
7584 code = BIT_XOR_EXPR;
7587 code = BIT_IOR_EXPR;
7590 c_in_omp_for = save_in_omp_for;
7593 c_parser_consume_token (parser);
7594 exp_location = c_parser_peek_token (parser)->location;
7595 rhs = c_parser_expr_no_commas (parser, NULL);
7596 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7598 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7599 code, exp_location, rhs.value,
7601 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7602 if (code == NOP_EXPR)
7603 ret.original_code = MODIFY_EXPR;
7606 suppress_warning (ret.value, OPT_Wparentheses);
7607 ret.original_code = ERROR_MARK;
7609 ret.original_type = NULL;
7610 c_in_omp_for = save_in_omp_for;
7614 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7615 AFTER is not NULL then it is an Objective-C message expression which is
7616 the primary-expression starting the expression as an initializer.
7618 conditional-expression:
7619 logical-OR-expression
7620 logical-OR-expression ? expression : conditional-expression
7624 conditional-expression:
7625 logical-OR-expression ? : conditional-expression
7628 static struct c_expr
7629 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7630 tree omp_atomic_lhs)
7632 struct c_expr cond, exp1, exp2, ret;
7633 location_t start, cond_loc, colon_loc;
7635 gcc_assert (!after || c_dialect_objc ());
7637 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7639 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7641 if (cond.value != error_mark_node)
7642 start = cond.get_start ();
7644 start = UNKNOWN_LOCATION;
7645 cond_loc = c_parser_peek_token (parser)->location;
7646 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7647 c_parser_consume_token (parser);
7648 if (c_parser_next_token_is (parser, CPP_COLON))
7650 tree eptype = NULL_TREE;
7652 location_t middle_loc = c_parser_peek_token (parser)->location;
7653 pedwarn (middle_loc, OPT_Wpedantic,
7654 "ISO C forbids omitting the middle term of a %<?:%> expression");
7655 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7657 eptype = TREE_TYPE (cond.value);
7658 cond.value = TREE_OPERAND (cond.value, 0);
7660 tree e = cond.value;
7661 while (TREE_CODE (e) == COMPOUND_EXPR)
7662 e = TREE_OPERAND (e, 1);
7663 warn_for_omitted_condop (middle_loc, e);
7664 /* Make sure first operand is calculated only once. */
7665 exp1.value = save_expr (default_conversion (cond.value));
7667 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7668 exp1.original_type = NULL;
7669 exp1.src_range = cond.src_range;
7670 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7671 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7676 = c_objc_common_truthvalue_conversion
7677 (cond_loc, default_conversion (cond.value));
7678 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7679 exp1 = c_parser_expression_conv (parser);
7680 mark_exp_read (exp1.value);
7681 c_inhibit_evaluation_warnings +=
7682 ((cond.value == truthvalue_true_node)
7683 - (cond.value == truthvalue_false_node));
7686 colon_loc = c_parser_peek_token (parser)->location;
7687 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7689 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7691 ret.original_code = ERROR_MARK;
7692 ret.original_type = NULL;
7696 location_t exp2_loc = c_parser_peek_token (parser)->location;
7697 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7698 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7700 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7701 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7702 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7703 if (UNLIKELY (omp_atomic_lhs != NULL)
7704 && (TREE_CODE (cond.value) == GT_EXPR
7705 || TREE_CODE (cond.value) == LT_EXPR
7706 || TREE_CODE (cond.value) == EQ_EXPR)
7707 && c_tree_equal (exp2.value, omp_atomic_lhs)
7708 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
7709 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
7710 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
7711 cond.value, exp1.value, exp2.value);
7714 = build_conditional_expr (colon_loc, cond.value,
7715 cond.original_code == C_MAYBE_CONST_EXPR,
7716 exp1.value, exp1.original_type, loc1,
7717 exp2.value, exp2.original_type, loc2);
7718 ret.original_code = ERROR_MARK;
7719 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7720 ret.original_type = NULL;
7725 /* If both sides are enum type, the default conversion will have
7726 made the type of the result be an integer type. We want to
7727 remember the enum types we started with. */
7728 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7729 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7730 ret.original_type = ((t1 != error_mark_node
7731 && t2 != error_mark_node
7732 && (TYPE_MAIN_VARIANT (t1)
7733 == TYPE_MAIN_VARIANT (t2)))
7737 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7741 /* Parse a binary expression; that is, a logical-OR-expression (C90
7742 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7743 NULL then it is an Objective-C message expression which is the
7744 primary-expression starting the expression as an initializer.
7746 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7747 when it should be the unfolded lhs. In a valid OpenMP source,
7748 one of the operands of the toplevel binary expression must be equal
7749 to it. In that case, just return a build2 created binary operation
7750 rather than result of parser_build_binary_op.
7752 multiplicative-expression:
7754 multiplicative-expression * cast-expression
7755 multiplicative-expression / cast-expression
7756 multiplicative-expression % cast-expression
7758 additive-expression:
7759 multiplicative-expression
7760 additive-expression + multiplicative-expression
7761 additive-expression - multiplicative-expression
7765 shift-expression << additive-expression
7766 shift-expression >> additive-expression
7768 relational-expression:
7770 relational-expression < shift-expression
7771 relational-expression > shift-expression
7772 relational-expression <= shift-expression
7773 relational-expression >= shift-expression
7775 equality-expression:
7776 relational-expression
7777 equality-expression == relational-expression
7778 equality-expression != relational-expression
7782 AND-expression & equality-expression
7784 exclusive-OR-expression:
7786 exclusive-OR-expression ^ AND-expression
7788 inclusive-OR-expression:
7789 exclusive-OR-expression
7790 inclusive-OR-expression | exclusive-OR-expression
7792 logical-AND-expression:
7793 inclusive-OR-expression
7794 logical-AND-expression && inclusive-OR-expression
7796 logical-OR-expression:
7797 logical-AND-expression
7798 logical-OR-expression || logical-AND-expression
7801 static struct c_expr
7802 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7803 tree omp_atomic_lhs)
7805 /* A binary expression is parsed using operator-precedence parsing,
7806 with the operands being cast expressions. All the binary
7807 operators are left-associative. Thus a binary expression is of
7810 E0 op1 E1 op2 E2 ...
7812 which we represent on a stack. On the stack, the precedence
7813 levels are strictly increasing. When a new operator is
7814 encountered of higher precedence than that at the top of the
7815 stack, it is pushed; its LHS is the top expression, and its RHS
7816 is everything parsed until it is popped. When a new operator is
7817 encountered with precedence less than or equal to that at the top
7818 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7819 by the result of the operation until the operator at the top of
7820 the stack has lower precedence than the new operator or there is
7821 only one element on the stack; then the top expression is the LHS
7822 of the new operator. In the case of logical AND and OR
7823 expressions, we also need to adjust c_inhibit_evaluation_warnings
7824 as appropriate when the operators are pushed and popped. */
7827 /* The expression at this stack level. */
7829 /* The precedence of the operator on its left, PREC_NONE at the
7830 bottom of the stack. */
7831 enum c_parser_prec prec;
7832 /* The operation on its left. */
7834 /* The source location of this operation. */
7836 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7840 /* Location of the binary operator. */
7841 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7844 switch (stack[sp].op) \
7846 case TRUTH_ANDIF_EXPR: \
7847 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7848 == truthvalue_false_node); \
7850 case TRUTH_ORIF_EXPR: \
7851 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7852 == truthvalue_true_node); \
7854 case TRUNC_DIV_EXPR: \
7855 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7856 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7857 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7858 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7860 tree type0 = stack[sp - 1].sizeof_arg; \
7861 tree type1 = stack[sp].sizeof_arg; \
7862 tree first_arg = type0; \
7863 if (!TYPE_P (type0)) \
7864 type0 = TREE_TYPE (type0); \
7865 if (!TYPE_P (type1)) \
7866 type1 = TREE_TYPE (type1); \
7867 if (POINTER_TYPE_P (type0) \
7868 && comptypes (TREE_TYPE (type0), type1) \
7869 && !(TREE_CODE (first_arg) == PARM_DECL \
7870 && C_ARRAY_PARAMETER (first_arg) \
7871 && warn_sizeof_array_argument)) \
7873 auto_diagnostic_group d; \
7874 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7875 "division %<sizeof (%T) / sizeof (%T)%> " \
7876 "does not compute the number of array " \
7879 if (DECL_P (first_arg)) \
7880 inform (DECL_SOURCE_LOCATION (first_arg), \
7881 "first %<sizeof%> operand was declared here"); \
7883 else if (TREE_CODE (type0) == ARRAY_TYPE \
7884 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7885 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7886 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7887 stack[sp].sizeof_arg, type1); \
7893 stack[sp - 1].expr \
7894 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7895 stack[sp - 1].expr, true, true); \
7897 = convert_lvalue_to_rvalue (stack[sp].loc, \
7898 stack[sp].expr, true, true); \
7899 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
7900 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
7901 && ((1 << stack[sp].prec) \
7902 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
7903 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
7904 | (1 << PREC_ADD) | (1 << PREC_MULT) \
7905 | (1 << PREC_EQ)))) \
7906 || ((c_parser_next_token_is (parser, CPP_QUERY) \
7907 || (omp_atomic_lhs == void_list_node \
7908 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
7909 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7910 && stack[sp].op != TRUNC_MOD_EXPR \
7911 && stack[sp].op != GE_EXPR \
7912 && stack[sp].op != LE_EXPR \
7913 && stack[sp].op != NE_EXPR \
7914 && stack[0].expr.value != error_mark_node \
7915 && stack[1].expr.value != error_mark_node \
7916 && (omp_atomic_lhs == void_list_node \
7917 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7918 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
7919 || (stack[sp].op == EQ_EXPR \
7920 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
7922 tree t = make_node (stack[1].op); \
7923 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7924 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7925 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7926 stack[0].expr.value = t; \
7929 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7931 stack[sp - 1].expr, \
7935 gcc_assert (!after || c_dialect_objc ());
7936 stack[0].loc = c_parser_peek_token (parser)->location;
7937 stack[0].expr = c_parser_cast_expression (parser, after);
7938 stack[0].prec = PREC_NONE;
7939 stack[0].sizeof_arg = c_last_sizeof_arg;
7943 enum c_parser_prec oprec;
7944 enum tree_code ocode;
7945 source_range src_range;
7948 switch (c_parser_peek_token (parser)->type)
7956 ocode = TRUNC_DIV_EXPR;
7960 ocode = TRUNC_MOD_EXPR;
7972 ocode = LSHIFT_EXPR;
7976 ocode = RSHIFT_EXPR;
7990 case CPP_GREATER_EQ:
8003 oprec = PREC_BITAND;
8004 ocode = BIT_AND_EXPR;
8007 oprec = PREC_BITXOR;
8008 ocode = BIT_XOR_EXPR;
8012 ocode = BIT_IOR_EXPR;
8015 oprec = PREC_LOGAND;
8016 ocode = TRUTH_ANDIF_EXPR;
8020 ocode = TRUTH_ORIF_EXPR;
8023 /* Not a binary operator, so end of the binary
8027 binary_loc = c_parser_peek_token (parser)->location;
8028 while (oprec <= stack[sp].prec)
8030 c_parser_consume_token (parser);
8033 case TRUTH_ANDIF_EXPR:
8034 src_range = stack[sp].expr.src_range;
8036 = convert_lvalue_to_rvalue (stack[sp].loc,
8037 stack[sp].expr, true, true);
8038 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8039 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8040 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8041 == truthvalue_false_node);
8042 set_c_expr_source_range (&stack[sp].expr, src_range);
8044 case TRUTH_ORIF_EXPR:
8045 src_range = stack[sp].expr.src_range;
8047 = convert_lvalue_to_rvalue (stack[sp].loc,
8048 stack[sp].expr, true, true);
8049 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8050 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8051 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8052 == truthvalue_true_node);
8053 set_c_expr_source_range (&stack[sp].expr, src_range);
8059 stack[sp].loc = binary_loc;
8060 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8061 stack[sp].prec = oprec;
8062 stack[sp].op = ocode;
8063 stack[sp].sizeof_arg = c_last_sizeof_arg;
8068 return stack[0].expr;
8072 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8073 is not NULL then it is an Objective-C message expression which is the
8074 primary-expression starting the expression as an initializer.
8078 ( type-name ) unary-expression
8081 static struct c_expr
8082 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8084 location_t cast_loc = c_parser_peek_token (parser)->location;
8085 gcc_assert (!after || c_dialect_objc ());
8087 return c_parser_postfix_expression_after_primary (parser,
8089 /* If the expression begins with a parenthesized type name, it may
8090 be either a cast or a compound literal; we need to see whether
8091 the next character is '{' to tell the difference. If not, it is
8092 an unary expression. Full detection of unknown typenames here
8093 would require a 3-token lookahead. */
8094 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8095 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8097 struct c_type_name *type_name;
8100 matching_parens parens;
8101 parens.consume_open (parser);
8102 type_name = c_parser_type_name (parser, true);
8103 parens.skip_until_found_close (parser);
8104 if (type_name == NULL)
8107 ret.original_code = ERROR_MARK;
8108 ret.original_type = NULL;
8112 /* Save casted types in the function's used types hash table. */
8113 used_types_insert (type_name->specs->type);
8115 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8116 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8118 if (type_name->specs->alignas_p)
8119 error_at (type_name->specs->locations[cdw_alignas],
8120 "alignment specified for type name in cast");
8122 location_t expr_loc = c_parser_peek_token (parser)->location;
8123 expr = c_parser_cast_expression (parser, NULL);
8124 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8126 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8127 if (ret.value && expr.value)
8128 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8129 ret.original_code = ERROR_MARK;
8130 ret.original_type = NULL;
8134 return c_parser_unary_expression (parser);
8137 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8143 unary-operator cast-expression
8144 sizeof unary-expression
8145 sizeof ( type-name )
8147 unary-operator: one of
8153 __alignof__ unary-expression
8154 __alignof__ ( type-name )
8157 (C11 permits _Alignof with type names only.)
8159 unary-operator: one of
8160 __extension__ __real__ __imag__
8162 Transactional Memory:
8165 transaction-expression
8167 In addition, the GNU syntax treats ++ and -- as unary operators, so
8168 they may be applied to cast expressions with errors for non-lvalues
8171 static struct c_expr
8172 c_parser_unary_expression (c_parser *parser)
8175 struct c_expr ret, op;
8176 location_t op_loc = c_parser_peek_token (parser)->location;
8179 ret.original_code = ERROR_MARK;
8180 ret.original_type = NULL;
8181 switch (c_parser_peek_token (parser)->type)
8184 c_parser_consume_token (parser);
8185 exp_loc = c_parser_peek_token (parser)->location;
8186 op = c_parser_cast_expression (parser, NULL);
8188 op = default_function_array_read_conversion (exp_loc, op);
8189 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8190 case CPP_MINUS_MINUS:
8191 c_parser_consume_token (parser);
8192 exp_loc = c_parser_peek_token (parser)->location;
8193 op = c_parser_cast_expression (parser, NULL);
8195 op = default_function_array_read_conversion (exp_loc, op);
8196 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8198 c_parser_consume_token (parser);
8199 op = c_parser_cast_expression (parser, NULL);
8200 mark_exp_read (op.value);
8201 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8204 c_parser_consume_token (parser);
8205 exp_loc = c_parser_peek_token (parser)->location;
8206 op = c_parser_cast_expression (parser, NULL);
8207 finish = op.get_finish ();
8208 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8209 location_t combined_loc = make_location (op_loc, op_loc, finish);
8210 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8211 ret.src_range.m_start = op_loc;
8212 ret.src_range.m_finish = finish;
8216 if (!c_dialect_objc () && !in_system_header_at (input_location))
8219 "traditional C rejects the unary plus operator");
8220 c_parser_consume_token (parser);
8221 exp_loc = c_parser_peek_token (parser)->location;
8222 op = c_parser_cast_expression (parser, NULL);
8223 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8224 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8226 c_parser_consume_token (parser);
8227 exp_loc = c_parser_peek_token (parser)->location;
8228 op = c_parser_cast_expression (parser, NULL);
8229 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8230 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8232 c_parser_consume_token (parser);
8233 exp_loc = c_parser_peek_token (parser)->location;
8234 op = c_parser_cast_expression (parser, NULL);
8235 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8236 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8238 c_parser_consume_token (parser);
8239 exp_loc = c_parser_peek_token (parser)->location;
8240 op = c_parser_cast_expression (parser, NULL);
8241 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8242 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8244 /* Refer to the address of a label as a pointer. */
8245 c_parser_consume_token (parser);
8246 if (c_parser_next_token_is (parser, CPP_NAME))
8248 ret.value = finish_label_address_expr
8249 (c_parser_peek_token (parser)->value, op_loc);
8250 set_c_expr_source_range (&ret, op_loc,
8251 c_parser_peek_token (parser)->get_finish ());
8252 c_parser_consume_token (parser);
8256 c_parser_error (parser, "expected identifier");
8261 switch (c_parser_peek_token (parser)->keyword)
8264 return c_parser_sizeof_expression (parser);
8266 return c_parser_alignof_expression (parser);
8267 case RID_BUILTIN_HAS_ATTRIBUTE:
8268 return c_parser_has_attribute_expression (parser);
8270 c_parser_consume_token (parser);
8271 ext = disable_extension_diagnostics ();
8272 ret = c_parser_cast_expression (parser, NULL);
8273 restore_extension_diagnostics (ext);
8276 c_parser_consume_token (parser);
8277 exp_loc = c_parser_peek_token (parser)->location;
8278 op = c_parser_cast_expression (parser, NULL);
8279 op = default_function_array_conversion (exp_loc, op);
8280 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8282 c_parser_consume_token (parser);
8283 exp_loc = c_parser_peek_token (parser)->location;
8284 op = c_parser_cast_expression (parser, NULL);
8285 op = default_function_array_conversion (exp_loc, op);
8286 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8287 case RID_TRANSACTION_ATOMIC:
8288 case RID_TRANSACTION_RELAXED:
8289 return c_parser_transaction_expression (parser,
8290 c_parser_peek_token (parser)->keyword);
8292 return c_parser_postfix_expression (parser);
8295 return c_parser_postfix_expression (parser);
8299 /* Parse a sizeof expression. */
8301 static struct c_expr
8302 c_parser_sizeof_expression (c_parser *parser)
8305 struct c_expr result;
8306 location_t expr_loc;
8307 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8310 location_t finish = UNKNOWN_LOCATION;
8312 start = c_parser_peek_token (parser)->location;
8314 c_parser_consume_token (parser);
8315 c_inhibit_evaluation_warnings++;
8317 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8318 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8320 /* Either sizeof ( type-name ) or sizeof unary-expression
8321 starting with a compound literal. */
8322 struct c_type_name *type_name;
8323 matching_parens parens;
8324 parens.consume_open (parser);
8325 expr_loc = c_parser_peek_token (parser)->location;
8326 type_name = c_parser_type_name (parser, true);
8327 parens.skip_until_found_close (parser);
8328 finish = parser->tokens_buf[0].location;
8329 if (type_name == NULL)
8332 c_inhibit_evaluation_warnings--;
8335 ret.original_code = ERROR_MARK;
8336 ret.original_type = NULL;
8339 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8341 expr = c_parser_postfix_expression_after_paren_type (parser,
8344 finish = expr.get_finish ();
8347 /* sizeof ( type-name ). */
8348 if (type_name->specs->alignas_p)
8349 error_at (type_name->specs->locations[cdw_alignas],
8350 "alignment specified for type name in %<sizeof%>");
8351 c_inhibit_evaluation_warnings--;
8353 result = c_expr_sizeof_type (expr_loc, type_name);
8357 expr_loc = c_parser_peek_token (parser)->location;
8358 expr = c_parser_unary_expression (parser);
8359 finish = expr.get_finish ();
8361 c_inhibit_evaluation_warnings--;
8363 mark_exp_read (expr.value);
8364 if (TREE_CODE (expr.value) == COMPONENT_REF
8365 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8366 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8367 result = c_expr_sizeof_expr (expr_loc, expr);
8369 if (finish == UNKNOWN_LOCATION)
8371 set_c_expr_source_range (&result, start, finish);
8375 /* Parse an alignof expression. */
8377 static struct c_expr
8378 c_parser_alignof_expression (c_parser *parser)
8381 location_t start_loc = c_parser_peek_token (parser)->location;
8383 tree alignof_spelling = c_parser_peek_token (parser)->value;
8384 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8385 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8387 /* A diagnostic is not required for the use of this identifier in
8388 the implementation namespace; only diagnose it for the C11
8389 spelling because of existing code using the other spellings. */
8393 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8396 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8399 c_parser_consume_token (parser);
8400 c_inhibit_evaluation_warnings++;
8402 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8403 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8405 /* Either __alignof__ ( type-name ) or __alignof__
8406 unary-expression starting with a compound literal. */
8408 struct c_type_name *type_name;
8410 matching_parens parens;
8411 parens.consume_open (parser);
8412 loc = c_parser_peek_token (parser)->location;
8413 type_name = c_parser_type_name (parser, true);
8414 end_loc = c_parser_peek_token (parser)->location;
8415 parens.skip_until_found_close (parser);
8416 if (type_name == NULL)
8419 c_inhibit_evaluation_warnings--;
8422 ret.original_code = ERROR_MARK;
8423 ret.original_type = NULL;
8426 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8428 expr = c_parser_postfix_expression_after_paren_type (parser,
8433 /* alignof ( type-name ). */
8434 if (type_name->specs->alignas_p)
8435 error_at (type_name->specs->locations[cdw_alignas],
8436 "alignment specified for type name in %qE",
8438 c_inhibit_evaluation_warnings--;
8440 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8442 false, is_c11_alignof, 1);
8443 ret.original_code = ERROR_MARK;
8444 ret.original_type = NULL;
8445 set_c_expr_source_range (&ret, start_loc, end_loc);
8451 expr = c_parser_unary_expression (parser);
8452 end_loc = expr.src_range.m_finish;
8454 mark_exp_read (expr.value);
8455 c_inhibit_evaluation_warnings--;
8459 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8461 ret.value = c_alignof_expr (start_loc, expr.value);
8462 ret.original_code = ERROR_MARK;
8463 ret.original_type = NULL;
8464 set_c_expr_source_range (&ret, start_loc, end_loc);
8469 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8472 static struct c_expr
8473 c_parser_has_attribute_expression (c_parser *parser)
8475 gcc_assert (c_parser_next_token_is_keyword (parser,
8476 RID_BUILTIN_HAS_ATTRIBUTE));
8477 location_t start = c_parser_peek_token (parser)->location;
8478 c_parser_consume_token (parser);
8480 c_inhibit_evaluation_warnings++;
8482 matching_parens parens;
8483 if (!parens.require_open (parser))
8485 c_inhibit_evaluation_warnings--;
8488 struct c_expr result;
8489 result.set_error ();
8490 result.original_code = ERROR_MARK;
8491 result.original_type = NULL;
8495 /* Treat the type argument the same way as in typeof for the purposes
8496 of warnings. FIXME: Generalize this so the warning refers to
8497 __builtin_has_attribute rather than typeof. */
8500 /* The first operand: one of DECL, EXPR, or TYPE. */
8501 tree oper = NULL_TREE;
8502 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8504 struct c_type_name *tname = c_parser_type_name (parser);
8508 oper = groktypename (tname, NULL, NULL);
8509 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8514 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8515 c_inhibit_evaluation_warnings--;
8517 if (cexpr.value != error_mark_node)
8519 mark_exp_read (cexpr.value);
8521 tree etype = TREE_TYPE (oper);
8522 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8523 /* This is returned with the type so that when the type is
8524 evaluated, this can be evaluated. */
8526 oper = c_fully_fold (oper, false, NULL);
8527 pop_maybe_used (was_vm);
8531 struct c_expr result;
8532 result.original_code = ERROR_MARK;
8533 result.original_type = NULL;
8535 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8537 /* Consume the closing parenthesis if that's the next token
8538 in the likely case the built-in was invoked with fewer
8539 than two arguments. */
8540 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8541 c_parser_consume_token (parser);
8542 c_inhibit_evaluation_warnings--;
8543 result.set_error ();
8547 bool save_translate_strings_p = parser->translate_strings_p;
8549 location_t atloc = c_parser_peek_token (parser)->location;
8550 /* Parse a single attribute. Require no leading comma and do not
8551 allow empty attributes. */
8552 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8554 parser->translate_strings_p = save_translate_strings_p;
8556 location_t finish = c_parser_peek_token (parser)->location;
8557 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8558 c_parser_consume_token (parser);
8561 c_parser_error (parser, "expected identifier");
8562 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8564 result.set_error ();
8570 error_at (atloc, "expected identifier");
8571 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8573 result.set_error ();
8577 result.original_code = INTEGER_CST;
8578 result.original_type = boolean_type_node;
8580 if (has_attribute (atloc, oper, attr, default_conversion))
8581 result.value = boolean_true_node;
8583 result.value = boolean_false_node;
8585 set_c_expr_source_range (&result, start, finish);
8589 /* Helper function to read arguments of builtins which are interfaces
8590 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8591 others. The name of the builtin is passed using BNAME parameter.
8592 Function returns true if there were no errors while parsing and
8593 stores the arguments in CEXPR_LIST. If it returns true,
8594 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8597 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8598 vec<c_expr_t, va_gc> **ret_cexpr_list,
8600 location_t *out_close_paren_loc)
8602 location_t loc = c_parser_peek_token (parser)->location;
8603 vec<c_expr_t, va_gc> *cexpr_list;
8605 bool saved_force_folding_builtin_constant_p;
8607 *ret_cexpr_list = NULL;
8608 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8610 error_at (loc, "cannot take address of %qs", bname);
8614 c_parser_consume_token (parser);
8616 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8618 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8619 c_parser_consume_token (parser);
8623 saved_force_folding_builtin_constant_p
8624 = force_folding_builtin_constant_p;
8625 force_folding_builtin_constant_p |= choose_expr_p;
8626 expr = c_parser_expr_no_commas (parser, NULL);
8627 force_folding_builtin_constant_p
8628 = saved_force_folding_builtin_constant_p;
8629 vec_alloc (cexpr_list, 1);
8630 vec_safe_push (cexpr_list, expr);
8631 while (c_parser_next_token_is (parser, CPP_COMMA))
8633 c_parser_consume_token (parser);
8634 expr = c_parser_expr_no_commas (parser, NULL);
8635 vec_safe_push (cexpr_list, expr);
8638 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8639 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8642 *ret_cexpr_list = cexpr_list;
8646 /* This represents a single generic-association. */
8648 struct c_generic_association
8650 /* The location of the starting token of the type. */
8651 location_t type_location;
8652 /* The association's type, or NULL_TREE for 'default'. */
8654 /* The association's expression. */
8655 struct c_expr expression;
8658 /* Parse a generic-selection. (C11 6.5.1.1).
8661 _Generic ( assignment-expression , generic-assoc-list )
8665 generic-assoc-list , generic-association
8667 generic-association:
8668 type-name : assignment-expression
8669 default : assignment-expression
8672 static struct c_expr
8673 c_parser_generic_selection (c_parser *parser)
8675 struct c_expr selector, error_expr;
8677 struct c_generic_association matched_assoc;
8678 int match_found = -1;
8679 location_t generic_loc, selector_loc;
8681 error_expr.original_code = ERROR_MARK;
8682 error_expr.original_type = NULL;
8683 error_expr.set_error ();
8684 matched_assoc.type_location = UNKNOWN_LOCATION;
8685 matched_assoc.type = NULL_TREE;
8686 matched_assoc.expression = error_expr;
8688 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8689 generic_loc = c_parser_peek_token (parser)->location;
8690 c_parser_consume_token (parser);
8692 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8693 "ISO C99 does not support %<_Generic%>");
8695 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8696 "ISO C90 does not support %<_Generic%>");
8698 matching_parens parens;
8699 if (!parens.require_open (parser))
8702 c_inhibit_evaluation_warnings++;
8703 selector_loc = c_parser_peek_token (parser)->location;
8704 selector = c_parser_expr_no_commas (parser, NULL);
8705 selector = default_function_array_conversion (selector_loc, selector);
8706 c_inhibit_evaluation_warnings--;
8708 if (selector.value == error_mark_node)
8710 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8713 mark_exp_read (selector.value);
8714 selector_type = TREE_TYPE (selector.value);
8715 /* In ISO C terms, rvalues (including the controlling expression of
8716 _Generic) do not have qualified types. */
8717 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8718 selector_type = TYPE_MAIN_VARIANT (selector_type);
8719 /* In ISO C terms, _Noreturn is not part of the type of expressions
8720 such as &abort, but in GCC it is represented internally as a type
8722 if (FUNCTION_POINTER_TYPE_P (selector_type)
8723 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8725 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8727 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8729 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8733 auto_vec<c_generic_association> associations;
8736 struct c_generic_association assoc, *iter;
8738 c_token *token = c_parser_peek_token (parser);
8740 assoc.type_location = token->location;
8741 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8743 c_parser_consume_token (parser);
8744 assoc.type = NULL_TREE;
8748 struct c_type_name *type_name;
8750 type_name = c_parser_type_name (parser);
8751 if (type_name == NULL)
8753 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8756 assoc.type = groktypename (type_name, NULL, NULL);
8757 if (assoc.type == error_mark_node)
8759 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8763 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8764 error_at (assoc.type_location,
8765 "%<_Generic%> association has function type");
8766 else if (!COMPLETE_TYPE_P (assoc.type))
8767 error_at (assoc.type_location,
8768 "%<_Generic%> association has incomplete type");
8770 if (variably_modified_type_p (assoc.type, NULL_TREE))
8771 error_at (assoc.type_location,
8772 "%<_Generic%> association has "
8773 "variable length type");
8776 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8778 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8782 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8783 if (assoc.expression.value == error_mark_node)
8785 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8789 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8791 if (assoc.type == NULL_TREE)
8793 if (iter->type == NULL_TREE)
8795 error_at (assoc.type_location,
8796 "duplicate %<default%> case in %<_Generic%>");
8797 inform (iter->type_location, "original %<default%> is here");
8800 else if (iter->type != NULL_TREE)
8802 if (comptypes (assoc.type, iter->type))
8804 error_at (assoc.type_location,
8805 "%<_Generic%> specifies two compatible types");
8806 inform (iter->type_location, "compatible type is here");
8811 if (assoc.type == NULL_TREE)
8813 if (match_found < 0)
8815 matched_assoc = assoc;
8816 match_found = associations.length ();
8819 else if (comptypes (assoc.type, selector_type))
8821 if (match_found < 0 || matched_assoc.type == NULL_TREE)
8823 matched_assoc = assoc;
8824 match_found = associations.length ();
8828 error_at (assoc.type_location,
8829 "%<_Generic%> selector matches multiple associations");
8830 inform (matched_assoc.type_location,
8831 "other match is here");
8835 associations.safe_push (assoc);
8837 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8839 c_parser_consume_token (parser);
8843 struct c_generic_association *iter;
8844 FOR_EACH_VEC_ELT (associations, ix, iter)
8845 if (ix != (unsigned) match_found)
8846 mark_exp_read (iter->expression.value);
8848 if (!parens.require_close (parser))
8850 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8854 if (match_found < 0)
8856 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8857 "compatible with any association",
8862 return matched_assoc.expression;
8865 /* Check the validity of a function pointer argument *EXPR (argument
8866 position POS) to __builtin_tgmath. Return the number of function
8867 arguments if possibly valid; return 0 having reported an error if
8871 check_tgmath_function (c_expr *expr, unsigned int pos)
8873 tree type = TREE_TYPE (expr->value);
8874 if (!FUNCTION_POINTER_TYPE_P (type))
8876 error_at (expr->get_location (),
8877 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8881 type = TREE_TYPE (type);
8882 if (!prototype_p (type))
8884 error_at (expr->get_location (),
8885 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8888 if (stdarg_p (type))
8890 error_at (expr->get_location (),
8891 "argument %u of %<__builtin_tgmath%> has variable arguments",
8895 unsigned int nargs = 0;
8896 function_args_iterator iter;
8898 FOREACH_FUNCTION_ARGS (type, t, iter)
8900 if (t == void_type_node)
8906 error_at (expr->get_location (),
8907 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8913 /* Ways in which a parameter or return value of a type-generic macro
8914 may vary between the different functions the macro may call. */
8915 enum tgmath_parm_kind
8917 tgmath_fixed, tgmath_real, tgmath_complex
8920 /* Helper function for c_parser_postfix_expression. Parse predefined
8923 static struct c_expr
8924 c_parser_predefined_identifier (c_parser *parser)
8926 location_t loc = c_parser_peek_token (parser)->location;
8927 switch (c_parser_peek_token (parser)->keyword)
8929 case RID_FUNCTION_NAME:
8930 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8931 "identifier", "__FUNCTION__");
8933 case RID_PRETTY_FUNCTION_NAME:
8934 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8935 "identifier", "__PRETTY_FUNCTION__");
8937 case RID_C99_FUNCTION_NAME:
8938 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8939 "%<__func__%> predefined identifier");
8946 expr.original_code = ERROR_MARK;
8947 expr.original_type = NULL;
8948 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8949 c_parser_peek_token (parser)->value);
8950 set_c_expr_source_range (&expr, loc, loc);
8951 c_parser_consume_token (parser);
8955 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8956 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8957 call c_parser_postfix_expression_after_paren_type on encountering them.
8961 postfix-expression [ expression ]
8962 postfix-expression ( argument-expression-list[opt] )
8963 postfix-expression . identifier
8964 postfix-expression -> identifier
8965 postfix-expression ++
8966 postfix-expression --
8967 ( type-name ) { initializer-list }
8968 ( type-name ) { initializer-list , }
8970 argument-expression-list:
8972 argument-expression-list , argument-expression
8985 (treated as a keyword in GNU C)
8988 ( compound-statement )
8989 __builtin_va_arg ( assignment-expression , type-name )
8990 __builtin_offsetof ( type-name , offsetof-member-designator )
8991 __builtin_choose_expr ( assignment-expression ,
8992 assignment-expression ,
8993 assignment-expression )
8994 __builtin_types_compatible_p ( type-name , type-name )
8995 __builtin_tgmath ( expr-list )
8996 __builtin_complex ( assignment-expression , assignment-expression )
8997 __builtin_shuffle ( assignment-expression , assignment-expression )
8998 __builtin_shuffle ( assignment-expression ,
8999 assignment-expression ,
9000 assignment-expression, )
9001 __builtin_convertvector ( assignment-expression , type-name )
9002 __builtin_assoc_barrier ( assignment-expression )
9004 offsetof-member-designator:
9006 offsetof-member-designator . identifier
9007 offsetof-member-designator [ expression ]
9012 [ objc-receiver objc-message-args ]
9013 @selector ( objc-selector-arg )
9014 @protocol ( identifier )
9015 @encode ( type-name )
9017 Classname . identifier
9020 static struct c_expr
9021 c_parser_postfix_expression (c_parser *parser)
9023 struct c_expr expr, e1;
9024 struct c_type_name *t1, *t2;
9025 location_t loc = c_parser_peek_token (parser)->location;
9026 source_range tok_range = c_parser_peek_token (parser)->get_range ();
9027 expr.original_code = ERROR_MARK;
9028 expr.original_type = NULL;
9029 switch (c_parser_peek_token (parser)->type)
9032 expr.value = c_parser_peek_token (parser)->value;
9033 set_c_expr_source_range (&expr, tok_range);
9034 loc = c_parser_peek_token (parser)->location;
9035 c_parser_consume_token (parser);
9036 if (TREE_CODE (expr.value) == FIXED_CST
9037 && !targetm.fixed_point_supported_p ())
9039 error_at (loc, "fixed-point types not supported for this target");
9048 expr.value = c_parser_peek_token (parser)->value;
9049 /* For the purpose of warning when a pointer is compared with
9050 a zero character constant. */
9051 expr.original_type = char_type_node;
9052 set_c_expr_source_range (&expr, tok_range);
9053 c_parser_consume_token (parser);
9059 case CPP_UTF8STRING:
9060 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9063 case CPP_OBJC_STRING:
9064 gcc_assert (c_dialect_objc ());
9066 = objc_build_string_object (c_parser_peek_token (parser)->value);
9067 set_c_expr_source_range (&expr, tok_range);
9068 c_parser_consume_token (parser);
9071 switch (c_parser_peek_token (parser)->id_kind)
9075 tree id = c_parser_peek_token (parser)->value;
9076 c_parser_consume_token (parser);
9077 expr.value = build_external_ref (loc, id,
9078 (c_parser_peek_token (parser)->type
9080 &expr.original_type);
9081 set_c_expr_source_range (&expr, tok_range);
9084 case C_ID_CLASSNAME:
9086 /* Here we parse the Objective-C 2.0 Class.name dot
9088 tree class_name = c_parser_peek_token (parser)->value;
9090 c_parser_consume_token (parser);
9091 gcc_assert (c_dialect_objc ());
9092 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9097 if (c_parser_next_token_is_not (parser, CPP_NAME))
9099 c_parser_error (parser, "expected identifier");
9103 c_token *component_tok = c_parser_peek_token (parser);
9104 component = component_tok->value;
9105 location_t end_loc = component_tok->get_finish ();
9106 c_parser_consume_token (parser);
9107 expr.value = objc_build_class_component_ref (class_name,
9109 set_c_expr_source_range (&expr, loc, end_loc);
9113 c_parser_error (parser, "expected expression");
9118 case CPP_OPEN_PAREN:
9119 /* A parenthesized expression, statement expression or compound
9121 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9123 /* A statement expression. */
9125 location_t brace_loc;
9126 c_parser_consume_token (parser);
9127 brace_loc = c_parser_peek_token (parser)->location;
9128 c_parser_consume_token (parser);
9129 /* If we've not yet started the current function's statement list,
9130 or we're in the parameter scope of an old-style function
9131 declaration, statement expressions are not allowed. */
9132 if (!building_stmt_list_p () || old_style_parameter_scope ())
9134 error_at (loc, "braced-group within expression allowed "
9135 "only inside a function");
9136 parser->error = true;
9137 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9138 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9142 stmt = c_begin_stmt_expr ();
9143 c_parser_compound_statement_nostart (parser);
9144 location_t close_loc = c_parser_peek_token (parser)->location;
9145 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9147 pedwarn (loc, OPT_Wpedantic,
9148 "ISO C forbids braced-groups within expressions");
9149 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9150 set_c_expr_source_range (&expr, loc, close_loc);
9151 mark_exp_read (expr.value);
9155 /* A parenthesized expression. */
9156 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9157 c_parser_consume_token (parser);
9158 expr = c_parser_expression (parser);
9159 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9160 suppress_warning (expr.value, OPT_Wparentheses);
9161 if (expr.original_code != C_MAYBE_CONST_EXPR
9162 && expr.original_code != SIZEOF_EXPR)
9163 expr.original_code = ERROR_MARK;
9164 /* Remember that we saw ( ) around the sizeof. */
9165 if (expr.original_code == SIZEOF_EXPR)
9166 expr.original_code = PAREN_SIZEOF_EXPR;
9167 /* Don't change EXPR.ORIGINAL_TYPE. */
9168 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9169 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9170 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9171 "expected %<)%>", loc_open_paren);
9175 switch (c_parser_peek_token (parser)->keyword)
9177 case RID_FUNCTION_NAME:
9178 case RID_PRETTY_FUNCTION_NAME:
9179 case RID_C99_FUNCTION_NAME:
9180 expr = c_parser_predefined_identifier (parser);
9184 location_t start_loc = loc;
9185 c_parser_consume_token (parser);
9186 matching_parens parens;
9187 if (!parens.require_open (parser))
9192 e1 = c_parser_expr_no_commas (parser, NULL);
9193 mark_exp_read (e1.value);
9194 e1.value = c_fully_fold (e1.value, false, NULL);
9195 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9197 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9201 loc = c_parser_peek_token (parser)->location;
9202 t1 = c_parser_type_name (parser);
9203 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9204 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9212 tree type_expr = NULL_TREE;
9213 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9214 groktypename (t1, &type_expr, NULL));
9217 expr.value = build2 (C_MAYBE_CONST_EXPR,
9218 TREE_TYPE (expr.value), type_expr,
9220 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9222 set_c_expr_source_range (&expr, start_loc, end_loc);
9228 c_parser_consume_token (parser);
9229 matching_parens parens;
9230 if (!parens.require_open (parser))
9235 t1 = c_parser_type_name (parser);
9237 parser->error = true;
9238 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9239 gcc_assert (parser->error);
9242 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9246 tree type = groktypename (t1, NULL, NULL);
9248 if (type == error_mark_node)
9249 offsetof_ref = error_mark_node;
9252 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9253 SET_EXPR_LOCATION (offsetof_ref, loc);
9255 /* Parse the second argument to __builtin_offsetof. We
9256 must have one identifier, and beyond that we want to
9257 accept sub structure and sub array references. */
9258 if (c_parser_next_token_is (parser, CPP_NAME))
9260 c_token *comp_tok = c_parser_peek_token (parser);
9262 = build_component_ref (loc, offsetof_ref, comp_tok->value,
9263 comp_tok->location, UNKNOWN_LOCATION);
9264 c_parser_consume_token (parser);
9265 while (c_parser_next_token_is (parser, CPP_DOT)
9266 || c_parser_next_token_is (parser,
9268 || c_parser_next_token_is (parser,
9271 if (c_parser_next_token_is (parser, CPP_DEREF))
9273 loc = c_parser_peek_token (parser)->location;
9274 offsetof_ref = build_array_ref (loc,
9279 else if (c_parser_next_token_is (parser, CPP_DOT))
9282 c_parser_consume_token (parser);
9283 if (c_parser_next_token_is_not (parser,
9286 c_parser_error (parser, "expected identifier");
9289 c_token *comp_tok = c_parser_peek_token (parser);
9291 = build_component_ref (loc, offsetof_ref,
9295 c_parser_consume_token (parser);
9301 loc = c_parser_peek_token (parser)->location;
9302 c_parser_consume_token (parser);
9303 ce = c_parser_expression (parser);
9304 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9306 idx = c_fully_fold (idx, false, NULL);
9307 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9309 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9314 c_parser_error (parser, "expected identifier");
9315 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9316 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9318 expr.value = fold_offsetof (offsetof_ref);
9319 set_c_expr_source_range (&expr, loc, end_loc);
9322 case RID_CHOOSE_EXPR:
9324 vec<c_expr_t, va_gc> *cexpr_list;
9325 c_expr_t *e1_p, *e2_p, *e3_p;
9327 location_t close_paren_loc;
9329 c_parser_consume_token (parser);
9330 if (!c_parser_get_builtin_args (parser,
9331 "__builtin_choose_expr",
9339 if (vec_safe_length (cexpr_list) != 3)
9341 error_at (loc, "wrong number of arguments to "
9342 "%<__builtin_choose_expr%>");
9347 e1_p = &(*cexpr_list)[0];
9348 e2_p = &(*cexpr_list)[1];
9349 e3_p = &(*cexpr_list)[2];
9352 mark_exp_read (e2_p->value);
9353 mark_exp_read (e3_p->value);
9354 if (TREE_CODE (c) != INTEGER_CST
9355 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9357 "first argument to %<__builtin_choose_expr%> not"
9359 constant_expression_warning (c);
9360 expr = integer_zerop (c) ? *e3_p : *e2_p;
9361 set_c_expr_source_range (&expr, loc, close_paren_loc);
9364 case RID_TYPES_COMPATIBLE_P:
9366 c_parser_consume_token (parser);
9367 matching_parens parens;
9368 if (!parens.require_open (parser))
9373 t1 = c_parser_type_name (parser);
9379 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9381 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9385 t2 = c_parser_type_name (parser);
9391 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9392 parens.skip_until_found_close (parser);
9394 e1 = groktypename (t1, NULL, NULL);
9395 e2 = groktypename (t2, NULL, NULL);
9396 if (e1 == error_mark_node || e2 == error_mark_node)
9402 e1 = TYPE_MAIN_VARIANT (e1);
9403 e2 = TYPE_MAIN_VARIANT (e2);
9406 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9407 set_c_expr_source_range (&expr, loc, close_paren_loc);
9410 case RID_BUILTIN_TGMATH:
9412 vec<c_expr_t, va_gc> *cexpr_list;
9413 location_t close_paren_loc;
9415 c_parser_consume_token (parser);
9416 if (!c_parser_get_builtin_args (parser,
9425 if (vec_safe_length (cexpr_list) < 3)
9427 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9434 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9435 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9436 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9442 if (vec_safe_length (cexpr_list) < nargs)
9444 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9448 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9449 if (num_functions < 2)
9451 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9456 /* The first NUM_FUNCTIONS expressions are the function
9457 pointers. The remaining NARGS expressions are the
9458 arguments that are to be passed to one of those
9459 functions, chosen following <tgmath.h> rules. */
9460 for (unsigned int j = 1; j < num_functions; j++)
9462 unsigned int this_nargs
9463 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9464 if (this_nargs == 0)
9469 if (this_nargs != nargs)
9471 error_at ((*cexpr_list)[j].get_location (),
9472 "argument %u of %<__builtin_tgmath%> has "
9473 "wrong number of arguments", j + 1);
9479 /* The functions all have the same number of arguments.
9480 Determine whether arguments and return types vary in
9481 ways permitted for <tgmath.h> functions. */
9482 /* The first entry in each of these vectors is for the
9483 return type, subsequent entries for parameter
9485 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9486 auto_vec<tree> parm_first (nargs + 1);
9487 auto_vec<bool> parm_complex (nargs + 1);
9488 auto_vec<bool> parm_varies (nargs + 1);
9489 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9490 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9491 parm_first.quick_push (first_ret);
9492 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9493 parm_varies.quick_push (false);
9494 function_args_iterator iter;
9496 unsigned int argpos;
9497 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9499 if (t == void_type_node)
9501 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9502 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9503 parm_varies.quick_push (false);
9505 for (unsigned int j = 1; j < num_functions; j++)
9507 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9508 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9509 if (ret != parm_first[0])
9511 parm_varies[0] = true;
9512 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9513 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9515 error_at ((*cexpr_list)[0].get_location (),
9516 "invalid type-generic return type for "
9517 "argument %u of %<__builtin_tgmath%>",
9522 if (!SCALAR_FLOAT_TYPE_P (ret)
9523 && !COMPLEX_FLOAT_TYPE_P (ret))
9525 error_at ((*cexpr_list)[j].get_location (),
9526 "invalid type-generic return type for "
9527 "argument %u of %<__builtin_tgmath%>",
9533 if (TREE_CODE (ret) == COMPLEX_TYPE)
9534 parm_complex[0] = true;
9536 FOREACH_FUNCTION_ARGS (type, t, iter)
9538 if (t == void_type_node)
9540 t = TYPE_MAIN_VARIANT (t);
9541 if (t != parm_first[argpos])
9543 parm_varies[argpos] = true;
9544 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9545 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9547 error_at ((*cexpr_list)[0].get_location (),
9548 "invalid type-generic type for "
9549 "argument %u of argument %u of "
9550 "%<__builtin_tgmath%>", argpos, 1);
9554 if (!SCALAR_FLOAT_TYPE_P (t)
9555 && !COMPLEX_FLOAT_TYPE_P (t))
9557 error_at ((*cexpr_list)[j].get_location (),
9558 "invalid type-generic type for "
9559 "argument %u of argument %u of "
9560 "%<__builtin_tgmath%>", argpos, j + 1);
9565 if (TREE_CODE (t) == COMPLEX_TYPE)
9566 parm_complex[argpos] = true;
9570 enum tgmath_parm_kind max_variation = tgmath_fixed;
9571 for (unsigned int j = 0; j <= nargs; j++)
9573 enum tgmath_parm_kind this_kind;
9576 if (parm_complex[j])
9577 max_variation = this_kind = tgmath_complex;
9580 this_kind = tgmath_real;
9581 if (max_variation != tgmath_complex)
9582 max_variation = tgmath_real;
9586 this_kind = tgmath_fixed;
9587 parm_kind.quick_push (this_kind);
9589 if (max_variation == tgmath_fixed)
9591 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9592 "all have the same type");
9597 /* Identify a parameter (not the return type) that varies,
9598 including with complex types if any variation includes
9599 complex types; there must be at least one such
9601 unsigned int tgarg = 0;
9602 for (unsigned int j = 1; j <= nargs; j++)
9603 if (parm_kind[j] == max_variation)
9610 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9611 "lack type-generic parameter");
9616 /* Determine the type of the relevant parameter for each
9618 auto_vec<tree> tg_type (num_functions);
9619 for (unsigned int j = 0; j < num_functions; j++)
9621 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9623 FOREACH_FUNCTION_ARGS (type, t, iter)
9625 if (argpos == tgarg)
9627 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9634 /* Verify that the corresponding types are different for
9635 all the listed functions. Also determine whether all
9636 the types are complex, whether all the types are
9637 standard or binary, and whether all the types are
9639 bool all_complex = true;
9640 bool all_binary = true;
9641 bool all_decimal = true;
9642 hash_set<tree> tg_types;
9643 FOR_EACH_VEC_ELT (tg_type, i, t)
9645 if (TREE_CODE (t) == COMPLEX_TYPE)
9646 all_decimal = false;
9649 all_complex = false;
9650 if (DECIMAL_FLOAT_TYPE_P (t))
9653 all_decimal = false;
9655 if (tg_types.add (t))
9657 error_at ((*cexpr_list)[i].get_location (),
9658 "duplicate type-generic parameter type for "
9659 "function argument %u of %<__builtin_tgmath%>",
9666 /* Verify that other parameters and the return type whose
9667 types vary have their types varying in the correct
9669 for (unsigned int j = 0; j < num_functions; j++)
9671 tree exp_type = tg_type[j];
9672 tree exp_real_type = exp_type;
9673 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9674 exp_real_type = TREE_TYPE (exp_type);
9675 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9676 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9677 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9678 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9680 error_at ((*cexpr_list)[j].get_location (),
9681 "bad return type for function argument %u "
9682 "of %<__builtin_tgmath%>", j + 1);
9687 FOREACH_FUNCTION_ARGS (type, t, iter)
9689 if (t == void_type_node)
9691 t = TYPE_MAIN_VARIANT (t);
9692 if ((parm_kind[argpos] == tgmath_complex
9694 || (parm_kind[argpos] == tgmath_real
9695 && t != exp_real_type))
9697 error_at ((*cexpr_list)[j].get_location (),
9698 "bad type for argument %u of "
9699 "function argument %u of "
9700 "%<__builtin_tgmath%>", argpos, j + 1);
9708 /* The functions listed are a valid set of functions for a
9709 <tgmath.h> macro to select between. Identify the
9710 matching function, if any. First, the argument types
9711 must be combined following <tgmath.h> rules. Integer
9712 types are treated as _Decimal64 if any type-generic
9713 argument is decimal, or if the only alternatives for
9714 type-generic arguments are of decimal types, and are
9715 otherwise treated as double (or _Complex double for
9716 complex integer types, or _Float64 or _Complex _Float64
9717 if all the return types are the same _FloatN or
9718 _FloatNx type). After that adjustment, types are
9719 combined following the usual arithmetic conversions.
9720 If the function only accepts complex arguments, a
9721 complex type is produced. */
9722 bool arg_complex = all_complex;
9723 bool arg_binary = all_binary;
9724 bool arg_int_decimal = all_decimal;
9725 for (unsigned int j = 1; j <= nargs; j++)
9727 if (parm_kind[j] == tgmath_fixed)
9729 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9730 tree type = TREE_TYPE (ce->value);
9731 if (!INTEGRAL_TYPE_P (type)
9732 && !SCALAR_FLOAT_TYPE_P (type)
9733 && TREE_CODE (type) != COMPLEX_TYPE)
9735 error_at (ce->get_location (),
9736 "invalid type of argument %u of type-generic "
9741 if (DECIMAL_FLOAT_TYPE_P (type))
9743 arg_int_decimal = true;
9746 error_at (ce->get_location (),
9747 "decimal floating-point argument %u to "
9748 "complex-only type-generic function", j);
9752 else if (all_binary)
9754 error_at (ce->get_location (),
9755 "decimal floating-point argument %u to "
9756 "binary-only type-generic function", j);
9760 else if (arg_complex)
9762 error_at (ce->get_location (),
9763 "both complex and decimal floating-point "
9764 "arguments to type-generic function");
9768 else if (arg_binary)
9770 error_at (ce->get_location (),
9771 "both binary and decimal floating-point "
9772 "arguments to type-generic function");
9777 else if (TREE_CODE (type) == COMPLEX_TYPE)
9780 if (COMPLEX_FLOAT_TYPE_P (type))
9784 error_at (ce->get_location (),
9785 "complex argument %u to "
9786 "decimal-only type-generic function", j);
9790 else if (arg_int_decimal)
9792 error_at (ce->get_location (),
9793 "both complex and decimal floating-point "
9794 "arguments to type-generic function");
9799 else if (SCALAR_FLOAT_TYPE_P (type))
9804 error_at (ce->get_location (),
9805 "binary argument %u to "
9806 "decimal-only type-generic function", j);
9810 else if (arg_int_decimal)
9812 error_at (ce->get_location (),
9813 "both binary and decimal floating-point "
9814 "arguments to type-generic function");
9820 /* For a macro rounding its result to a narrower type, map
9821 integer types to _Float64 not double if the return type
9822 is a _FloatN or _FloatNx type. */
9823 bool arg_int_float64 = false;
9824 if (parm_kind[0] == tgmath_fixed
9825 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9826 && float64_type_node != NULL_TREE)
9827 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9828 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9830 arg_int_float64 = true;
9833 tree arg_real = NULL_TREE;
9834 for (unsigned int j = 1; j <= nargs; j++)
9836 if (parm_kind[j] == tgmath_fixed)
9838 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9839 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9840 if (TREE_CODE (type) == COMPLEX_TYPE)
9841 type = TREE_TYPE (type);
9842 if (INTEGRAL_TYPE_P (type))
9843 type = (arg_int_decimal
9844 ? dfloat64_type_node
9847 : double_type_node);
9848 if (arg_real == NULL_TREE)
9851 arg_real = common_type (arg_real, type);
9852 if (arg_real == error_mark_node)
9858 tree arg_type = (arg_complex
9859 ? build_complex_type (arg_real)
9862 /* Look for a function to call with type-generic parameter
9864 c_expr_t *fn = NULL;
9865 for (unsigned int j = 0; j < num_functions; j++)
9867 if (tg_type[j] == arg_type)
9869 fn = &(*cexpr_list)[j];
9874 && parm_kind[0] == tgmath_fixed
9875 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9877 /* Presume this is a macro that rounds its result to a
9878 narrower type, and look for the first function with
9879 at least the range and precision of the argument
9881 for (unsigned int j = 0; j < num_functions; j++)
9884 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9886 tree real_tg_type = (arg_complex
9887 ? TREE_TYPE (tg_type[j])
9889 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9890 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9892 scalar_float_mode arg_mode
9893 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9894 scalar_float_mode tg_mode
9895 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9896 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9897 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9898 if (arg_fmt->b == tg_fmt->b
9899 && arg_fmt->p <= tg_fmt->p
9900 && arg_fmt->emax <= tg_fmt->emax
9901 && (arg_fmt->emin - arg_fmt->p
9902 >= tg_fmt->emin - tg_fmt->p))
9904 fn = &(*cexpr_list)[j];
9911 error_at (loc, "no matching function for type-generic call");
9916 /* Construct a call to FN. */
9917 vec<tree, va_gc> *args;
9918 vec_alloc (args, nargs);
9919 vec<tree, va_gc> *origtypes;
9920 vec_alloc (origtypes, nargs);
9921 auto_vec<location_t> arg_loc (nargs);
9922 for (unsigned int j = 0; j < nargs; j++)
9924 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9925 args->quick_push (ce->value);
9926 arg_loc.quick_push (ce->get_location ());
9927 origtypes->quick_push (ce->original_type);
9929 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9931 set_c_expr_source_range (&expr, loc, close_paren_loc);
9934 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9936 vec<c_expr_t, va_gc> *cexpr_list;
9939 location_t close_paren_loc;
9941 c_parser_consume_token (parser);
9942 if (!c_parser_get_builtin_args (parser,
9943 "__builtin_call_with_static_chain",
9950 if (vec_safe_length (cexpr_list) != 2)
9952 error_at (loc, "wrong number of arguments to "
9953 "%<__builtin_call_with_static_chain%>");
9958 expr = (*cexpr_list)[0];
9959 e2_p = &(*cexpr_list)[1];
9960 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9961 chain_value = e2_p->value;
9962 mark_exp_read (chain_value);
9964 if (TREE_CODE (expr.value) != CALL_EXPR)
9965 error_at (loc, "first argument to "
9966 "%<__builtin_call_with_static_chain%> "
9967 "must be a call expression");
9968 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9969 error_at (loc, "second argument to "
9970 "%<__builtin_call_with_static_chain%> "
9971 "must be a pointer type");
9973 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9974 set_c_expr_source_range (&expr, loc, close_paren_loc);
9977 case RID_BUILTIN_COMPLEX:
9979 vec<c_expr_t, va_gc> *cexpr_list;
9980 c_expr_t *e1_p, *e2_p;
9981 location_t close_paren_loc;
9983 c_parser_consume_token (parser);
9984 if (!c_parser_get_builtin_args (parser,
9985 "__builtin_complex",
9993 if (vec_safe_length (cexpr_list) != 2)
9995 error_at (loc, "wrong number of arguments to "
9996 "%<__builtin_complex%>");
10001 e1_p = &(*cexpr_list)[0];
10002 e2_p = &(*cexpr_list)[1];
10004 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
10005 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
10006 e1_p->value = convert (TREE_TYPE (e1_p->value),
10007 TREE_OPERAND (e1_p->value, 0));
10008 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
10009 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
10010 e2_p->value = convert (TREE_TYPE (e2_p->value),
10011 TREE_OPERAND (e2_p->value, 0));
10012 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10013 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10014 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
10015 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
10017 error_at (loc, "%<__builtin_complex%> operand "
10018 "not of real binary floating-point type");
10022 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10023 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10026 "%<__builtin_complex%> operands of different types");
10030 pedwarn_c90 (loc, OPT_Wpedantic,
10031 "ISO C90 does not support complex types");
10032 expr.value = build2_loc (loc, COMPLEX_EXPR,
10035 (TREE_TYPE (e1_p->value))),
10036 e1_p->value, e2_p->value);
10037 set_c_expr_source_range (&expr, loc, close_paren_loc);
10040 case RID_BUILTIN_SHUFFLE:
10042 vec<c_expr_t, va_gc> *cexpr_list;
10045 location_t close_paren_loc;
10047 c_parser_consume_token (parser);
10048 if (!c_parser_get_builtin_args (parser,
10049 "__builtin_shuffle",
10050 &cexpr_list, false,
10057 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10058 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10060 if (vec_safe_length (cexpr_list) == 2)
10061 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10063 (*cexpr_list)[1].value);
10065 else if (vec_safe_length (cexpr_list) == 3)
10066 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10067 (*cexpr_list)[1].value,
10068 (*cexpr_list)[2].value);
10071 error_at (loc, "wrong number of arguments to "
10072 "%<__builtin_shuffle%>");
10075 set_c_expr_source_range (&expr, loc, close_paren_loc);
10078 case RID_BUILTIN_SHUFFLEVECTOR:
10080 vec<c_expr_t, va_gc> *cexpr_list;
10083 location_t close_paren_loc;
10085 c_parser_consume_token (parser);
10086 if (!c_parser_get_builtin_args (parser,
10087 "__builtin_shufflevector",
10088 &cexpr_list, false,
10095 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10096 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10098 if (vec_safe_length (cexpr_list) < 3)
10100 error_at (loc, "wrong number of arguments to "
10101 "%<__builtin_shuffle%>");
10106 auto_vec<tree, 16> mask;
10107 for (i = 2; i < cexpr_list->length (); ++i)
10108 mask.safe_push ((*cexpr_list)[i].value);
10109 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10110 (*cexpr_list)[1].value,
10113 set_c_expr_source_range (&expr, loc, close_paren_loc);
10116 case RID_BUILTIN_CONVERTVECTOR:
10118 location_t start_loc = loc;
10119 c_parser_consume_token (parser);
10120 matching_parens parens;
10121 if (!parens.require_open (parser))
10126 e1 = c_parser_expr_no_commas (parser, NULL);
10127 mark_exp_read (e1.value);
10128 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10130 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10134 loc = c_parser_peek_token (parser)->location;
10135 t1 = c_parser_type_name (parser);
10136 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10137 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10143 tree type_expr = NULL_TREE;
10144 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10145 groktypename (t1, &type_expr,
10147 set_c_expr_source_range (&expr, start_loc, end_loc);
10151 case RID_BUILTIN_ASSOC_BARRIER:
10153 location_t start_loc = loc;
10154 c_parser_consume_token (parser);
10155 matching_parens parens;
10156 if (!parens.require_open (parser))
10161 e1 = c_parser_expr_no_commas (parser, NULL);
10162 mark_exp_read (e1.value);
10163 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10164 parens.skip_until_found_close (parser);
10165 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10166 set_c_expr_source_range (&expr, start_loc, end_loc);
10169 case RID_AT_SELECTOR:
10171 gcc_assert (c_dialect_objc ());
10172 c_parser_consume_token (parser);
10173 matching_parens parens;
10174 if (!parens.require_open (parser))
10179 tree sel = c_parser_objc_selector_arg (parser);
10180 location_t close_loc = c_parser_peek_token (parser)->location;
10181 parens.skip_until_found_close (parser);
10182 expr.value = objc_build_selector_expr (loc, sel);
10183 set_c_expr_source_range (&expr, loc, close_loc);
10186 case RID_AT_PROTOCOL:
10188 gcc_assert (c_dialect_objc ());
10189 c_parser_consume_token (parser);
10190 matching_parens parens;
10191 if (!parens.require_open (parser))
10196 if (c_parser_next_token_is_not (parser, CPP_NAME))
10198 c_parser_error (parser, "expected identifier");
10199 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10203 tree id = c_parser_peek_token (parser)->value;
10204 c_parser_consume_token (parser);
10205 location_t close_loc = c_parser_peek_token (parser)->location;
10206 parens.skip_until_found_close (parser);
10207 expr.value = objc_build_protocol_expr (id);
10208 set_c_expr_source_range (&expr, loc, close_loc);
10211 case RID_AT_ENCODE:
10213 /* Extension to support C-structures in the archiver. */
10214 gcc_assert (c_dialect_objc ());
10215 c_parser_consume_token (parser);
10216 matching_parens parens;
10217 if (!parens.require_open (parser))
10222 t1 = c_parser_type_name (parser);
10226 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10229 location_t close_loc = c_parser_peek_token (parser)->location;
10230 parens.skip_until_found_close (parser);
10231 tree type = groktypename (t1, NULL, NULL);
10232 expr.value = objc_build_encode_expr (type);
10233 set_c_expr_source_range (&expr, loc, close_loc);
10237 expr = c_parser_generic_selection (parser);
10239 case RID_OMP_ALL_MEMORY:
10240 gcc_assert (flag_openmp);
10241 c_parser_consume_token (parser);
10242 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
10243 "%<depend%> clause");
10247 c_parser_error (parser, "expected expression");
10252 case CPP_OPEN_SQUARE:
10253 if (c_dialect_objc ())
10255 tree receiver, args;
10256 c_parser_consume_token (parser);
10257 receiver = c_parser_objc_receiver (parser);
10258 args = c_parser_objc_message_args (parser);
10259 location_t close_loc = c_parser_peek_token (parser)->location;
10260 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10262 expr.value = objc_build_message_expr (receiver, args);
10263 set_c_expr_source_range (&expr, loc, close_loc);
10266 /* Else fall through to report error. */
10269 c_parser_error (parser, "expected expression");
10274 return c_parser_postfix_expression_after_primary
10275 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10278 /* Parse a postfix expression after a parenthesized type name: the
10279 brace-enclosed initializer of a compound literal, possibly followed
10280 by some postfix operators. This is separate because it is not
10281 possible to tell until after the type name whether a cast
10282 expression has a cast or a compound literal, or whether the operand
10283 of sizeof is a parenthesized type name or starts with a compound
10284 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10285 location of the first token after the parentheses around the type
10288 static struct c_expr
10289 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10290 struct c_type_name *type_name,
10291 location_t type_loc)
10294 struct c_expr init;
10296 struct c_expr expr;
10297 location_t start_loc;
10298 tree type_expr = NULL_TREE;
10299 bool type_expr_const = true;
10300 check_compound_literal_type (type_loc, type_name);
10301 rich_location richloc (line_table, type_loc);
10302 start_init (NULL_TREE, NULL, 0, &richloc);
10303 type = groktypename (type_name, &type_expr, &type_expr_const);
10304 start_loc = c_parser_peek_token (parser)->location;
10305 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10307 error_at (type_loc, "compound literal has variable size");
10308 type = error_mark_node;
10310 init = c_parser_braced_init (parser, type, false, NULL);
10312 maybe_warn_string_init (type_loc, type, init);
10314 if (type != error_mark_node
10315 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10316 && current_function_decl)
10318 error ("compound literal qualified by address-space qualifier");
10319 type = error_mark_node;
10322 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10323 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10324 ? CONSTRUCTOR_NON_CONST (init.value)
10325 : init.original_code == C_MAYBE_CONST_EXPR);
10326 non_const |= !type_expr_const;
10327 unsigned int alignas_align = 0;
10328 if (type != error_mark_node
10329 && type_name->specs->align_log != -1)
10331 alignas_align = 1U << type_name->specs->align_log;
10332 if (alignas_align < min_align_of_type (type))
10334 error_at (type_name->specs->locations[cdw_alignas],
10335 "%<_Alignas%> specifiers cannot reduce "
10336 "alignment of compound literal");
10340 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10342 set_c_expr_source_range (&expr, init.src_range);
10343 expr.original_code = ERROR_MARK;
10344 expr.original_type = NULL;
10345 if (type != error_mark_node
10346 && expr.value != error_mark_node
10349 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10351 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10352 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10356 gcc_assert (!non_const);
10357 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10358 type_expr, expr.value);
10361 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10364 /* Callback function for sizeof_pointer_memaccess_warning to compare
10368 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10370 return comptypes (type1, type2) == 1;
10373 /* Warn for patterns where abs-like function appears to be used incorrectly,
10374 gracefully ignore any non-abs-like function. The warning location should
10375 be LOC. FNDECL is the declaration of called function, it must be a
10376 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10380 warn_for_abs (location_t loc, tree fndecl, tree arg)
10382 /* Avoid warning in unreachable subexpressions. */
10383 if (c_inhibit_evaluation_warnings)
10386 tree atype = TREE_TYPE (arg);
10388 /* Casts from pointers (and thus arrays and fndecls) will generate
10389 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10390 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10391 types and possibly other exotic types. */
10392 if (!INTEGRAL_TYPE_P (atype)
10393 && !SCALAR_FLOAT_TYPE_P (atype)
10394 && TREE_CODE (atype) != COMPLEX_TYPE)
10397 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10402 case BUILT_IN_LABS:
10403 case BUILT_IN_LLABS:
10404 case BUILT_IN_IMAXABS:
10405 if (!INTEGRAL_TYPE_P (atype))
10407 if (SCALAR_FLOAT_TYPE_P (atype))
10408 warning_at (loc, OPT_Wabsolute_value,
10409 "using integer absolute value function %qD when "
10410 "argument is of floating-point type %qT",
10412 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10413 warning_at (loc, OPT_Wabsolute_value,
10414 "using integer absolute value function %qD when "
10415 "argument is of complex type %qT", fndecl, atype);
10417 gcc_unreachable ();
10420 if (TYPE_UNSIGNED (atype))
10421 warning_at (loc, OPT_Wabsolute_value,
10422 "taking the absolute value of unsigned type %qT "
10423 "has no effect", atype);
10426 CASE_FLT_FN (BUILT_IN_FABS):
10427 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10428 if (!SCALAR_FLOAT_TYPE_P (atype)
10429 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10431 if (INTEGRAL_TYPE_P (atype))
10432 warning_at (loc, OPT_Wabsolute_value,
10433 "using floating-point absolute value function %qD "
10434 "when argument is of integer type %qT", fndecl, atype);
10435 else if (DECIMAL_FLOAT_TYPE_P (atype))
10436 warning_at (loc, OPT_Wabsolute_value,
10437 "using floating-point absolute value function %qD "
10438 "when argument is of decimal floating-point type %qT",
10440 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10441 warning_at (loc, OPT_Wabsolute_value,
10442 "using floating-point absolute value function %qD when "
10443 "argument is of complex type %qT", fndecl, atype);
10445 gcc_unreachable ();
10450 CASE_FLT_FN (BUILT_IN_CABS):
10451 if (TREE_CODE (atype) != COMPLEX_TYPE)
10453 if (INTEGRAL_TYPE_P (atype))
10454 warning_at (loc, OPT_Wabsolute_value,
10455 "using complex absolute value function %qD when "
10456 "argument is of integer type %qT", fndecl, atype);
10457 else if (SCALAR_FLOAT_TYPE_P (atype))
10458 warning_at (loc, OPT_Wabsolute_value,
10459 "using complex absolute value function %qD when "
10460 "argument is of floating-point type %qT",
10463 gcc_unreachable ();
10469 case BUILT_IN_FABSD32:
10470 case BUILT_IN_FABSD64:
10471 case BUILT_IN_FABSD128:
10472 if (!DECIMAL_FLOAT_TYPE_P (atype))
10474 if (INTEGRAL_TYPE_P (atype))
10475 warning_at (loc, OPT_Wabsolute_value,
10476 "using decimal floating-point absolute value "
10477 "function %qD when argument is of integer type %qT",
10479 else if (SCALAR_FLOAT_TYPE_P (atype))
10480 warning_at (loc, OPT_Wabsolute_value,
10481 "using decimal floating-point absolute value "
10482 "function %qD when argument is of floating-point "
10483 "type %qT", fndecl, atype);
10484 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10485 warning_at (loc, OPT_Wabsolute_value,
10486 "using decimal floating-point absolute value "
10487 "function %qD when argument is of complex type %qT",
10490 gcc_unreachable ();
10499 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10502 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10503 if (TREE_CODE (atype) == COMPLEX_TYPE)
10505 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10506 atype = TREE_TYPE (atype);
10507 ftype = TREE_TYPE (ftype);
10510 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10511 warning_at (loc, OPT_Wabsolute_value,
10512 "absolute value function %qD given an argument of type %qT "
10513 "but has parameter of type %qT which may cause truncation "
10514 "of value", fndecl, atype, ftype);
10518 /* Parse a postfix expression after the initial primary or compound
10519 literal; that is, parse a series of postfix operators.
10521 EXPR_LOC is the location of the primary expression. */
10523 static struct c_expr
10524 c_parser_postfix_expression_after_primary (c_parser *parser,
10525 location_t expr_loc,
10526 struct c_expr expr)
10528 struct c_expr orig_expr;
10530 location_t sizeof_arg_loc[3], comp_loc;
10531 tree sizeof_arg[3];
10532 unsigned int literal_zero_mask;
10534 vec<tree, va_gc> *exprlist;
10535 vec<tree, va_gc> *origtypes = NULL;
10536 vec<location_t> arg_loc = vNULL;
10542 location_t op_loc = c_parser_peek_token (parser)->location;
10543 switch (c_parser_peek_token (parser)->type)
10545 case CPP_OPEN_SQUARE:
10546 /* Array reference. */
10547 c_parser_consume_token (parser);
10548 idx = c_parser_expression (parser).value;
10549 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10551 start = expr.get_start ();
10552 finish = parser->tokens_buf[0].location;
10553 expr.value = build_array_ref (op_loc, expr.value, idx);
10554 set_c_expr_source_range (&expr, start, finish);
10555 expr.original_code = ERROR_MARK;
10556 expr.original_type = NULL;
10558 case CPP_OPEN_PAREN:
10559 /* Function call. */
10561 matching_parens parens;
10562 parens.consume_open (parser);
10563 for (i = 0; i < 3; i++)
10565 sizeof_arg[i] = NULL_TREE;
10566 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10568 literal_zero_mask = 0;
10569 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10572 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10573 sizeof_arg_loc, sizeof_arg,
10574 &arg_loc, &literal_zero_mask);
10575 parens.skip_until_found_close (parser);
10578 mark_exp_read (expr.value);
10579 if (warn_sizeof_pointer_memaccess)
10580 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10581 expr.value, exprlist,
10583 sizeof_ptr_memacc_comptypes);
10584 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10586 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10587 && vec_safe_length (exprlist) == 3)
10589 tree arg0 = (*exprlist)[0];
10590 tree arg2 = (*exprlist)[2];
10591 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10593 if (warn_absolute_value
10594 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10595 && vec_safe_length (exprlist) == 1)
10596 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10599 start = expr.get_start ();
10600 finish = parser->tokens_buf[0].get_finish ();
10602 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10603 exprlist, origtypes);
10604 set_c_expr_source_range (&expr, start, finish);
10606 expr.original_code = ERROR_MARK;
10607 if (TREE_CODE (expr.value) == INTEGER_CST
10608 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10609 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10610 expr.original_code = C_MAYBE_CONST_EXPR;
10611 expr.original_type = NULL;
10614 release_tree_vector (exprlist);
10615 release_tree_vector (origtypes);
10617 arg_loc.release ();
10620 /* Structure element reference. */
10621 c_parser_consume_token (parser);
10622 expr = default_function_array_conversion (expr_loc, expr);
10623 if (c_parser_next_token_is (parser, CPP_NAME))
10625 c_token *comp_tok = c_parser_peek_token (parser);
10626 ident = comp_tok->value;
10627 comp_loc = comp_tok->location;
10631 c_parser_error (parser, "expected identifier");
10633 expr.original_code = ERROR_MARK;
10634 expr.original_type = NULL;
10637 start = expr.get_start ();
10638 finish = c_parser_peek_token (parser)->get_finish ();
10639 c_parser_consume_token (parser);
10640 expr.value = build_component_ref (op_loc, expr.value, ident,
10641 comp_loc, UNKNOWN_LOCATION);
10642 set_c_expr_source_range (&expr, start, finish);
10643 expr.original_code = ERROR_MARK;
10644 if (TREE_CODE (expr.value) != COMPONENT_REF)
10645 expr.original_type = NULL;
10648 /* Remember the original type of a bitfield. */
10649 tree field = TREE_OPERAND (expr.value, 1);
10650 if (TREE_CODE (field) != FIELD_DECL)
10651 expr.original_type = NULL;
10653 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10657 /* Structure element reference. */
10658 c_parser_consume_token (parser);
10659 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10660 if (c_parser_next_token_is (parser, CPP_NAME))
10662 c_token *comp_tok = c_parser_peek_token (parser);
10663 ident = comp_tok->value;
10664 comp_loc = comp_tok->location;
10668 c_parser_error (parser, "expected identifier");
10670 expr.original_code = ERROR_MARK;
10671 expr.original_type = NULL;
10674 start = expr.get_start ();
10675 finish = c_parser_peek_token (parser)->get_finish ();
10676 c_parser_consume_token (parser);
10677 expr.value = build_component_ref (op_loc,
10678 build_indirect_ref (op_loc,
10682 expr.get_location ());
10683 set_c_expr_source_range (&expr, start, finish);
10684 expr.original_code = ERROR_MARK;
10685 if (TREE_CODE (expr.value) != COMPONENT_REF)
10686 expr.original_type = NULL;
10689 /* Remember the original type of a bitfield. */
10690 tree field = TREE_OPERAND (expr.value, 1);
10691 if (TREE_CODE (field) != FIELD_DECL)
10692 expr.original_type = NULL;
10694 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10697 case CPP_PLUS_PLUS:
10698 /* Postincrement. */
10699 start = expr.get_start ();
10700 finish = c_parser_peek_token (parser)->get_finish ();
10701 c_parser_consume_token (parser);
10702 expr = default_function_array_read_conversion (expr_loc, expr);
10703 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10704 expr.value, false);
10705 set_c_expr_source_range (&expr, start, finish);
10706 expr.original_code = ERROR_MARK;
10707 expr.original_type = NULL;
10709 case CPP_MINUS_MINUS:
10710 /* Postdecrement. */
10711 start = expr.get_start ();
10712 finish = c_parser_peek_token (parser)->get_finish ();
10713 c_parser_consume_token (parser);
10714 expr = default_function_array_read_conversion (expr_loc, expr);
10715 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10716 expr.value, false);
10717 set_c_expr_source_range (&expr, start, finish);
10718 expr.original_code = ERROR_MARK;
10719 expr.original_type = NULL;
10727 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10730 assignment-expression
10731 expression , assignment-expression
10734 static struct c_expr
10735 c_parser_expression (c_parser *parser)
10737 location_t tloc = c_parser_peek_token (parser)->location;
10738 struct c_expr expr;
10739 expr = c_parser_expr_no_commas (parser, NULL);
10740 if (c_parser_next_token_is (parser, CPP_COMMA))
10741 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10742 while (c_parser_next_token_is (parser, CPP_COMMA))
10744 struct c_expr next;
10746 location_t loc = c_parser_peek_token (parser)->location;
10747 location_t expr_loc;
10748 c_parser_consume_token (parser);
10749 expr_loc = c_parser_peek_token (parser)->location;
10750 lhsval = expr.value;
10751 while (TREE_CODE (lhsval) == COMPOUND_EXPR
10752 || TREE_CODE (lhsval) == NOP_EXPR)
10754 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10755 lhsval = TREE_OPERAND (lhsval, 1);
10757 lhsval = TREE_OPERAND (lhsval, 0);
10759 if (DECL_P (lhsval) || handled_component_p (lhsval))
10760 mark_exp_read (lhsval);
10761 next = c_parser_expr_no_commas (parser, NULL);
10762 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10763 expr.value = build_compound_expr (loc, expr.value, next.value);
10764 expr.original_code = COMPOUND_EXPR;
10765 expr.original_type = next.original_type;
10770 /* Parse an expression and convert functions or arrays to pointers and
10771 lvalues to rvalues. */
10773 static struct c_expr
10774 c_parser_expression_conv (c_parser *parser)
10776 struct c_expr expr;
10777 location_t loc = c_parser_peek_token (parser)->location;
10778 expr = c_parser_expression (parser);
10779 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10783 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10784 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10787 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10790 if (idx >= HOST_BITS_PER_INT)
10793 c_token *tok = c_parser_peek_token (parser);
10802 /* If a parameter is literal zero alone, remember it
10803 for -Wmemset-transposed-args warning. */
10804 if (integer_zerop (tok->value)
10805 && !TREE_OVERFLOW (tok->value)
10806 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10807 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10808 *literal_zero_mask |= 1U << idx;
10814 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10815 functions and arrays to pointers and lvalues to rvalues. If
10816 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10817 locations of function arguments into this vector.
10819 nonempty-expr-list:
10820 assignment-expression
10821 nonempty-expr-list , assignment-expression
10824 static vec<tree, va_gc> *
10825 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10826 vec<tree, va_gc> **p_orig_types,
10827 location_t *sizeof_arg_loc, tree *sizeof_arg,
10828 vec<location_t> *locations,
10829 unsigned int *literal_zero_mask)
10831 vec<tree, va_gc> *ret;
10832 vec<tree, va_gc> *orig_types;
10833 struct c_expr expr;
10834 unsigned int idx = 0;
10836 ret = make_tree_vector ();
10837 if (p_orig_types == NULL)
10840 orig_types = make_tree_vector ();
10842 if (literal_zero_mask)
10843 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10844 expr = c_parser_expr_no_commas (parser, NULL);
10846 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10848 expr.value = c_fully_fold (expr.value, false, NULL);
10849 ret->quick_push (expr.value);
10851 orig_types->quick_push (expr.original_type);
10853 locations->safe_push (expr.get_location ());
10854 if (sizeof_arg != NULL
10855 && (expr.original_code == SIZEOF_EXPR
10856 || expr.original_code == PAREN_SIZEOF_EXPR))
10858 sizeof_arg[0] = c_last_sizeof_arg;
10859 sizeof_arg_loc[0] = c_last_sizeof_loc;
10861 while (c_parser_next_token_is (parser, CPP_COMMA))
10863 c_parser_consume_token (parser);
10864 if (literal_zero_mask)
10865 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10866 expr = c_parser_expr_no_commas (parser, NULL);
10868 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10871 expr.value = c_fully_fold (expr.value, false, NULL);
10872 vec_safe_push (ret, expr.value);
10874 vec_safe_push (orig_types, expr.original_type);
10876 locations->safe_push (expr.get_location ());
10878 && sizeof_arg != NULL
10879 && (expr.original_code == SIZEOF_EXPR
10880 || expr.original_code == PAREN_SIZEOF_EXPR))
10882 sizeof_arg[idx] = c_last_sizeof_arg;
10883 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10887 *p_orig_types = orig_types;
10891 /* Parse Objective-C-specific constructs. */
10893 /* Parse an objc-class-definition.
10895 objc-class-definition:
10896 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10897 objc-class-instance-variables[opt] objc-methodprotolist @end
10898 @implementation identifier objc-superclass[opt]
10899 objc-class-instance-variables[opt]
10900 @interface identifier ( identifier ) objc-protocol-refs[opt]
10901 objc-methodprotolist @end
10902 @interface identifier ( ) objc-protocol-refs[opt]
10903 objc-methodprotolist @end
10904 @implementation identifier ( identifier )
10909 "@interface identifier (" must start "@interface identifier (
10910 identifier ) ...": objc-methodprotolist in the first production may
10911 not start with a parenthesized identifier as a declarator of a data
10912 definition with no declaration specifiers if the objc-superclass,
10913 objc-protocol-refs and objc-class-instance-variables are omitted. */
10916 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10921 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10923 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10926 gcc_unreachable ();
10928 c_parser_consume_token (parser);
10929 if (c_parser_next_token_is_not (parser, CPP_NAME))
10931 c_parser_error (parser, "expected identifier");
10934 id1 = c_parser_peek_token (parser)->value;
10935 location_t loc1 = c_parser_peek_token (parser)->location;
10936 c_parser_consume_token (parser);
10937 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10939 /* We have a category or class extension. */
10941 tree proto = NULL_TREE;
10942 matching_parens parens;
10943 parens.consume_open (parser);
10944 if (c_parser_next_token_is_not (parser, CPP_NAME))
10946 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10948 /* We have a class extension. */
10953 c_parser_error (parser, "expected identifier or %<)%>");
10954 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10960 id2 = c_parser_peek_token (parser)->value;
10961 c_parser_consume_token (parser);
10963 parens.skip_until_found_close (parser);
10966 objc_start_category_implementation (id1, id2);
10969 if (c_parser_next_token_is (parser, CPP_LESS))
10970 proto = c_parser_objc_protocol_refs (parser);
10971 objc_start_category_interface (id1, id2, proto, attributes);
10972 c_parser_objc_methodprotolist (parser);
10973 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10974 objc_finish_interface ();
10977 if (c_parser_next_token_is (parser, CPP_COLON))
10979 c_parser_consume_token (parser);
10980 if (c_parser_next_token_is_not (parser, CPP_NAME))
10982 c_parser_error (parser, "expected identifier");
10985 superclass = c_parser_peek_token (parser)->value;
10986 c_parser_consume_token (parser);
10989 superclass = NULL_TREE;
10992 tree proto = NULL_TREE;
10993 if (c_parser_next_token_is (parser, CPP_LESS))
10994 proto = c_parser_objc_protocol_refs (parser);
10995 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
10998 objc_start_class_implementation (id1, superclass);
10999 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11000 c_parser_objc_class_instance_variables (parser);
11003 objc_continue_interface ();
11004 c_parser_objc_methodprotolist (parser);
11005 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11006 objc_finish_interface ();
11010 objc_continue_implementation ();
11015 /* Parse objc-class-instance-variables.
11017 objc-class-instance-variables:
11018 { objc-instance-variable-decl-list[opt] }
11020 objc-instance-variable-decl-list:
11021 objc-visibility-spec
11022 objc-instance-variable-decl ;
11024 objc-instance-variable-decl-list objc-visibility-spec
11025 objc-instance-variable-decl-list objc-instance-variable-decl ;
11026 objc-instance-variable-decl-list ;
11028 objc-visibility-spec:
11033 objc-instance-variable-decl:
11038 c_parser_objc_class_instance_variables (c_parser *parser)
11040 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
11041 c_parser_consume_token (parser);
11042 while (c_parser_next_token_is_not (parser, CPP_EOF))
11045 /* Parse any stray semicolon. */
11046 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11048 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11049 "extra semicolon");
11050 c_parser_consume_token (parser);
11053 /* Stop if at the end of the instance variables. */
11054 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11056 c_parser_consume_token (parser);
11059 /* Parse any objc-visibility-spec. */
11060 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11062 c_parser_consume_token (parser);
11063 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11066 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11068 c_parser_consume_token (parser);
11069 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11072 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11074 c_parser_consume_token (parser);
11075 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11078 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11080 c_parser_consume_token (parser);
11081 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11084 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11086 c_parser_pragma (parser, pragma_external, NULL);
11090 /* Parse some comma-separated declarations. */
11091 decls = c_parser_struct_declaration (parser);
11094 /* There is a syntax error. We want to skip the offending
11095 tokens up to the next ';' (included) or '}'
11098 /* First, skip manually a ')' or ']'. This is because they
11099 reduce the nesting level, so c_parser_skip_until_found()
11100 wouldn't be able to skip past them. */
11101 c_token *token = c_parser_peek_token (parser);
11102 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11103 c_parser_consume_token (parser);
11105 /* Then, do the standard skipping. */
11106 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11108 /* We hopefully recovered. Start normal parsing again. */
11109 parser->error = false;
11114 /* Comma-separated instance variables are chained together
11115 in reverse order; add them one by one. */
11116 tree ivar = nreverse (decls);
11117 for (; ivar; ivar = DECL_CHAIN (ivar))
11118 objc_add_instance_variable (copy_node (ivar));
11120 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11124 /* Parse an objc-class-declaration.
11126 objc-class-declaration:
11127 @class identifier-list ;
11131 c_parser_objc_class_declaration (c_parser *parser)
11133 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11134 c_parser_consume_token (parser);
11135 /* Any identifiers, including those declared as type names, are OK
11140 if (c_parser_next_token_is_not (parser, CPP_NAME))
11142 c_parser_error (parser, "expected identifier");
11143 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11144 parser->error = false;
11147 id = c_parser_peek_token (parser)->value;
11148 objc_declare_class (id);
11149 c_parser_consume_token (parser);
11150 if (c_parser_next_token_is (parser, CPP_COMMA))
11151 c_parser_consume_token (parser);
11155 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11158 /* Parse an objc-alias-declaration.
11160 objc-alias-declaration:
11161 @compatibility_alias identifier identifier ;
11165 c_parser_objc_alias_declaration (c_parser *parser)
11168 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11169 c_parser_consume_token (parser);
11170 if (c_parser_next_token_is_not (parser, CPP_NAME))
11172 c_parser_error (parser, "expected identifier");
11173 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11176 id1 = c_parser_peek_token (parser)->value;
11177 c_parser_consume_token (parser);
11178 if (c_parser_next_token_is_not (parser, CPP_NAME))
11180 c_parser_error (parser, "expected identifier");
11181 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11184 id2 = c_parser_peek_token (parser)->value;
11185 c_parser_consume_token (parser);
11186 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11187 objc_declare_alias (id1, id2);
11190 /* Parse an objc-protocol-definition.
11192 objc-protocol-definition:
11193 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11194 @protocol identifier-list ;
11196 "@protocol identifier ;" should be resolved as "@protocol
11197 identifier-list ;": objc-methodprotolist may not start with a
11198 semicolon in the first alternative if objc-protocol-refs are
11202 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11204 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11206 c_parser_consume_token (parser);
11207 if (c_parser_next_token_is_not (parser, CPP_NAME))
11209 c_parser_error (parser, "expected identifier");
11212 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11213 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11215 /* Any identifiers, including those declared as type names, are
11220 if (c_parser_next_token_is_not (parser, CPP_NAME))
11222 c_parser_error (parser, "expected identifier");
11225 id = c_parser_peek_token (parser)->value;
11226 objc_declare_protocol (id, attributes);
11227 c_parser_consume_token (parser);
11228 if (c_parser_next_token_is (parser, CPP_COMMA))
11229 c_parser_consume_token (parser);
11233 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11237 tree id = c_parser_peek_token (parser)->value;
11238 tree proto = NULL_TREE;
11239 c_parser_consume_token (parser);
11240 if (c_parser_next_token_is (parser, CPP_LESS))
11241 proto = c_parser_objc_protocol_refs (parser);
11242 parser->objc_pq_context = true;
11243 objc_start_protocol (id, proto, attributes);
11244 c_parser_objc_methodprotolist (parser);
11245 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11246 parser->objc_pq_context = false;
11247 objc_finish_interface ();
11251 /* Parse an objc-method-type.
11257 Return true if it is a class method (+) and false if it is
11258 an instance method (-).
11261 c_parser_objc_method_type (c_parser *parser)
11263 switch (c_parser_peek_token (parser)->type)
11266 c_parser_consume_token (parser);
11269 c_parser_consume_token (parser);
11272 gcc_unreachable ();
11276 /* Parse an objc-method-definition.
11278 objc-method-definition:
11279 objc-method-type objc-method-decl ;[opt] compound-statement
11283 c_parser_objc_method_definition (c_parser *parser)
11285 bool is_class_method = c_parser_objc_method_type (parser);
11286 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11287 parser->objc_pq_context = true;
11288 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11290 if (decl == error_mark_node)
11291 return; /* Bail here. */
11293 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11295 c_parser_consume_token (parser);
11296 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11297 "extra semicolon in method definition specified");
11300 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11302 c_parser_error (parser, "expected %<{%>");
11306 parser->objc_pq_context = false;
11307 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11309 add_stmt (c_parser_compound_statement (parser));
11310 objc_finish_method_definition (current_function_decl);
11314 /* This code is executed when we find a method definition
11315 outside of an @implementation context (or invalid for other
11316 reasons). Parse the method (to keep going) but do not emit
11319 c_parser_compound_statement (parser);
11323 /* Parse an objc-methodprotolist.
11325 objc-methodprotolist:
11327 objc-methodprotolist objc-methodproto
11328 objc-methodprotolist declaration
11329 objc-methodprotolist ;
11333 The declaration is a data definition, which may be missing
11334 declaration specifiers under the same rules and diagnostics as
11335 other data definitions outside functions, and the stray semicolon
11336 is diagnosed the same way as a stray semicolon outside a
11340 c_parser_objc_methodprotolist (c_parser *parser)
11344 /* The list is terminated by @end. */
11345 switch (c_parser_peek_token (parser)->type)
11347 case CPP_SEMICOLON:
11348 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11349 "ISO C does not allow extra %<;%> outside of a function");
11350 c_parser_consume_token (parser);
11354 c_parser_objc_methodproto (parser);
11357 c_parser_pragma (parser, pragma_external, NULL);
11362 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11364 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11365 c_parser_objc_at_property_declaration (parser);
11366 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11368 objc_set_method_opt (true);
11369 c_parser_consume_token (parser);
11371 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11373 objc_set_method_opt (false);
11374 c_parser_consume_token (parser);
11377 c_parser_declaration_or_fndef (parser, false, false, true,
11384 /* Parse an objc-methodproto.
11387 objc-method-type objc-method-decl ;
11391 c_parser_objc_methodproto (c_parser *parser)
11393 bool is_class_method = c_parser_objc_method_type (parser);
11394 tree decl, attributes = NULL_TREE;
11396 /* Remember protocol qualifiers in prototypes. */
11397 parser->objc_pq_context = true;
11398 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11400 /* Forget protocol qualifiers now. */
11401 parser->objc_pq_context = false;
11403 /* Do not allow the presence of attributes to hide an erroneous
11404 method implementation in the interface section. */
11405 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11407 c_parser_error (parser, "expected %<;%>");
11411 if (decl != error_mark_node)
11412 objc_add_method_declaration (is_class_method, decl, attributes);
11414 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11417 /* If we are at a position that method attributes may be present, check that
11418 there are not any parsed already (a syntax error) and then collect any
11419 specified at the current location. Finally, if new attributes were present,
11420 check that the next token is legal ( ';' for decls and '{' for defs). */
11423 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11428 c_parser_error (parser,
11429 "method attributes must be specified at the end only");
11430 *attributes = NULL_TREE;
11434 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11435 *attributes = c_parser_gnu_attributes (parser);
11437 /* If there were no attributes here, just report any earlier error. */
11438 if (*attributes == NULL_TREE || bad)
11441 /* If the attributes are followed by a ; or {, then just report any earlier
11443 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11444 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11447 /* We've got attributes, but not at the end. */
11448 c_parser_error (parser,
11449 "expected %<;%> or %<{%> after method attribute definition");
11453 /* Parse an objc-method-decl.
11456 ( objc-type-name ) objc-selector
11458 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11459 objc-keyword-selector objc-optparmlist
11462 objc-keyword-selector:
11464 objc-keyword-selector objc-keyword-decl
11467 objc-selector : ( objc-type-name ) identifier
11468 objc-selector : identifier
11469 : ( objc-type-name ) identifier
11473 objc-optparms objc-optellipsis
11477 objc-opt-parms , parameter-declaration
11485 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11486 tree *attributes, tree *expr)
11488 tree type = NULL_TREE;
11490 tree parms = NULL_TREE;
11491 bool ellipsis = false;
11492 bool attr_err = false;
11494 *attributes = NULL_TREE;
11495 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11497 matching_parens parens;
11498 parens.consume_open (parser);
11499 type = c_parser_objc_type_name (parser);
11500 parens.skip_until_found_close (parser);
11502 sel = c_parser_objc_selector (parser);
11503 /* If there is no selector, or a colon follows, we have an
11504 objc-keyword-selector. If there is a selector, and a colon does
11505 not follow, that selector ends the objc-method-decl. */
11506 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11509 tree list = NULL_TREE;
11512 tree atype = NULL_TREE, id, keyworddecl;
11513 tree param_attr = NULL_TREE;
11514 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11516 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11518 c_parser_consume_token (parser);
11519 atype = c_parser_objc_type_name (parser);
11520 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11523 /* New ObjC allows attributes on method parameters. */
11524 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11525 param_attr = c_parser_gnu_attributes (parser);
11526 if (c_parser_next_token_is_not (parser, CPP_NAME))
11528 c_parser_error (parser, "expected identifier");
11529 return error_mark_node;
11531 id = c_parser_peek_token (parser)->value;
11532 c_parser_consume_token (parser);
11533 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11534 list = chainon (list, keyworddecl);
11535 tsel = c_parser_objc_selector (parser);
11536 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11540 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11542 /* Parse the optional parameter list. Optional Objective-C
11543 method parameters follow the C syntax, and may include '...'
11544 to denote a variable number of arguments. */
11545 parms = make_node (TREE_LIST);
11546 while (c_parser_next_token_is (parser, CPP_COMMA))
11548 struct c_parm *parm;
11549 c_parser_consume_token (parser);
11550 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11553 c_parser_consume_token (parser);
11554 attr_err |= c_parser_objc_maybe_method_attributes
11555 (parser, attributes) ;
11558 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11561 parms = chainon (parms,
11562 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11567 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11571 c_parser_error (parser, "objective-c method declaration is expected");
11572 return error_mark_node;
11576 return error_mark_node;
11578 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11581 /* Parse an objc-type-name.
11584 objc-type-qualifiers[opt] type-name
11585 objc-type-qualifiers[opt]
11587 objc-type-qualifiers:
11588 objc-type-qualifier
11589 objc-type-qualifiers objc-type-qualifier
11591 objc-type-qualifier: one of
11592 in out inout bycopy byref oneway
11596 c_parser_objc_type_name (c_parser *parser)
11598 tree quals = NULL_TREE;
11599 struct c_type_name *type_name = NULL;
11600 tree type = NULL_TREE;
11603 c_token *token = c_parser_peek_token (parser);
11604 if (token->type == CPP_KEYWORD
11605 && (token->keyword == RID_IN
11606 || token->keyword == RID_OUT
11607 || token->keyword == RID_INOUT
11608 || token->keyword == RID_BYCOPY
11609 || token->keyword == RID_BYREF
11610 || token->keyword == RID_ONEWAY))
11612 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11613 c_parser_consume_token (parser);
11618 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11619 type_name = c_parser_type_name (parser);
11621 type = groktypename (type_name, NULL, NULL);
11623 /* If the type is unknown, and error has already been produced and
11624 we need to recover from the error. In that case, use NULL_TREE
11625 for the type, as if no type had been specified; this will use the
11626 default type ('id') which is good for error recovery. */
11627 if (type == error_mark_node)
11630 return build_tree_list (quals, type);
11633 /* Parse objc-protocol-refs.
11635 objc-protocol-refs:
11636 < identifier-list >
11640 c_parser_objc_protocol_refs (c_parser *parser)
11642 tree list = NULL_TREE;
11643 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11644 c_parser_consume_token (parser);
11645 /* Any identifiers, including those declared as type names, are OK
11650 if (c_parser_next_token_is_not (parser, CPP_NAME))
11652 c_parser_error (parser, "expected identifier");
11655 id = c_parser_peek_token (parser)->value;
11656 list = chainon (list, build_tree_list (NULL_TREE, id));
11657 c_parser_consume_token (parser);
11658 if (c_parser_next_token_is (parser, CPP_COMMA))
11659 c_parser_consume_token (parser);
11663 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11667 /* Parse an objc-try-catch-finally-statement.
11669 objc-try-catch-finally-statement:
11670 @try compound-statement objc-catch-list[opt]
11671 @try compound-statement objc-catch-list[opt] @finally compound-statement
11674 @catch ( objc-catch-parameter-declaration ) compound-statement
11675 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11677 objc-catch-parameter-declaration:
11678 parameter-declaration
11681 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11683 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11684 for C++. Keep them in sync. */
11687 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11689 location_t location;
11692 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11693 c_parser_consume_token (parser);
11694 location = c_parser_peek_token (parser)->location;
11695 objc_maybe_warn_exceptions (location);
11696 stmt = c_parser_compound_statement (parser);
11697 objc_begin_try_stmt (location, stmt);
11699 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11701 struct c_parm *parm;
11702 tree parameter_declaration = error_mark_node;
11703 bool seen_open_paren = false;
11705 c_parser_consume_token (parser);
11706 matching_parens parens;
11707 if (!parens.require_open (parser))
11708 seen_open_paren = true;
11709 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11711 /* We have "@catch (...)" (where the '...' are literally
11712 what is in the code). Skip the '...'.
11713 parameter_declaration is set to NULL_TREE, and
11714 objc_being_catch_clauses() knows that that means
11716 c_parser_consume_token (parser);
11717 parameter_declaration = NULL_TREE;
11721 /* We have "@catch (NSException *exception)" or something
11722 like that. Parse the parameter declaration. */
11723 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11725 parameter_declaration = error_mark_node;
11727 parameter_declaration = grokparm (parm, NULL);
11729 if (seen_open_paren)
11730 parens.require_close (parser);
11733 /* If there was no open parenthesis, we are recovering from
11734 an error, and we are trying to figure out what mistake
11735 the user has made. */
11737 /* If there is an immediate closing parenthesis, the user
11738 probably forgot the opening one (ie, they typed "@catch
11739 NSException *e)". Parse the closing parenthesis and keep
11741 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11742 c_parser_consume_token (parser);
11744 /* If these is no immediate closing parenthesis, the user
11745 probably doesn't know that parenthesis are required at
11746 all (ie, they typed "@catch NSException *e"). So, just
11747 forget about the closing parenthesis and keep going. */
11749 objc_begin_catch_clause (parameter_declaration);
11750 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11751 c_parser_compound_statement_nostart (parser);
11752 objc_finish_catch_clause ();
11754 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11756 c_parser_consume_token (parser);
11757 location = c_parser_peek_token (parser)->location;
11758 stmt = c_parser_compound_statement (parser);
11759 objc_build_finally_clause (location, stmt);
11761 objc_finish_try_stmt ();
11764 /* Parse an objc-synchronized-statement.
11766 objc-synchronized-statement:
11767 @synchronized ( expression ) compound-statement
11771 c_parser_objc_synchronized_statement (c_parser *parser)
11775 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11776 c_parser_consume_token (parser);
11777 loc = c_parser_peek_token (parser)->location;
11778 objc_maybe_warn_exceptions (loc);
11779 matching_parens parens;
11780 if (parens.require_open (parser))
11782 struct c_expr ce = c_parser_expression (parser);
11783 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11785 expr = c_fully_fold (expr, false, NULL);
11786 parens.skip_until_found_close (parser);
11789 expr = error_mark_node;
11790 stmt = c_parser_compound_statement (parser);
11791 objc_build_synchronized (loc, expr, stmt);
11794 /* Parse an objc-selector; return NULL_TREE without an error if the
11795 next token is not an objc-selector.
11800 enum struct union if else while do for switch case default
11801 break continue return goto asm sizeof typeof __alignof
11802 unsigned long const short volatile signed restrict _Complex
11803 in out inout bycopy byref oneway int char float double void _Bool
11806 ??? Why this selection of keywords but not, for example, storage
11807 class specifiers? */
11810 c_parser_objc_selector (c_parser *parser)
11812 c_token *token = c_parser_peek_token (parser);
11813 tree value = token->value;
11814 if (token->type == CPP_NAME)
11816 c_parser_consume_token (parser);
11819 if (token->type != CPP_KEYWORD)
11821 switch (token->keyword)
11860 CASE_RID_FLOATN_NX:
11864 case RID_AUTO_TYPE:
11869 c_parser_consume_token (parser);
11876 /* Parse an objc-selector-arg.
11880 objc-keywordname-list
11882 objc-keywordname-list:
11884 objc-keywordname-list objc-keywordname
11892 c_parser_objc_selector_arg (c_parser *parser)
11894 tree sel = c_parser_objc_selector (parser);
11895 tree list = NULL_TREE;
11897 && c_parser_next_token_is_not (parser, CPP_COLON)
11898 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11902 if (c_parser_next_token_is (parser, CPP_SCOPE))
11904 c_parser_consume_token (parser);
11905 list = chainon (list, build_tree_list (sel, NULL_TREE));
11906 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11910 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11912 list = chainon (list, build_tree_list (sel, NULL_TREE));
11914 sel = c_parser_objc_selector (parser);
11916 && c_parser_next_token_is_not (parser, CPP_COLON)
11917 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11923 /* Parse an objc-receiver.
11932 c_parser_objc_receiver (c_parser *parser)
11934 location_t loc = c_parser_peek_token (parser)->location;
11936 if (c_parser_peek_token (parser)->type == CPP_NAME
11937 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11938 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11940 tree id = c_parser_peek_token (parser)->value;
11941 c_parser_consume_token (parser);
11942 return objc_get_class_reference (id);
11944 struct c_expr ce = c_parser_expression (parser);
11945 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11946 return c_fully_fold (ce.value, false, NULL);
11949 /* Parse objc-message-args.
11953 objc-keywordarg-list
11955 objc-keywordarg-list:
11957 objc-keywordarg-list objc-keywordarg
11960 objc-selector : objc-keywordexpr
11965 c_parser_objc_message_args (c_parser *parser)
11967 tree sel = c_parser_objc_selector (parser);
11968 tree list = NULL_TREE;
11969 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11974 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11975 return error_mark_node;
11976 keywordexpr = c_parser_objc_keywordexpr (parser);
11977 list = chainon (list, build_tree_list (sel, keywordexpr));
11978 sel = c_parser_objc_selector (parser);
11979 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11985 /* Parse an objc-keywordexpr.
11992 c_parser_objc_keywordexpr (c_parser *parser)
11995 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11996 NULL, NULL, NULL, NULL);
11997 if (vec_safe_length (expr_list) == 1)
11999 /* Just return the expression, remove a level of
12001 ret = (*expr_list)[0];
12005 /* We have a comma expression, we will collapse later. */
12006 ret = build_tree_list_vec (expr_list);
12008 release_tree_vector (expr_list);
12012 /* A check, needed in several places, that ObjC interface, implementation or
12013 method definitions are not prefixed by incorrect items. */
12015 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
12016 struct c_declspecs *specs)
12018 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
12019 || specs->typespec_kind != ctsk_none)
12021 c_parser_error (parser,
12022 "no type or storage class may be specified here,");
12023 c_parser_skip_to_end_of_block_or_statement (parser);
12029 /* Parse an Objective-C @property declaration. The syntax is:
12031 objc-property-declaration:
12032 '@property' objc-property-attributes[opt] struct-declaration ;
12034 objc-property-attributes:
12035 '(' objc-property-attribute-list ')'
12037 objc-property-attribute-list:
12038 objc-property-attribute
12039 objc-property-attribute-list, objc-property-attribute
12041 objc-property-attribute
12042 'getter' = identifier
12043 'setter' = identifier
12052 @property NSString *name;
12053 @property (readonly) id object;
12054 @property (retain, nonatomic, getter=getTheName) id name;
12055 @property int a, b, c;
12057 PS: This function is identical to cp_parser_objc_at_propery_declaration
12058 for C++. Keep them in sync. */
12060 c_parser_objc_at_property_declaration (c_parser *parser)
12062 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12063 location_t loc = c_parser_peek_token (parser)->location;
12064 c_parser_consume_token (parser); /* Eat '@property'. */
12066 /* Parse the optional attribute list.
12068 A list of parsed, but not verified, attributes. */
12069 vec<property_attribute_info *> prop_attr_list = vNULL;
12071 bool syntax_error = false;
12072 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12074 matching_parens parens;
12076 location_t attr_start = c_parser_peek_token (parser)->location;
12078 parens.consume_open (parser);
12080 /* Property attribute keywords are valid now. */
12081 parser->objc_property_attr_context = true;
12083 /* Allow @property (), with a warning. */
12084 location_t attr_end = c_parser_peek_token (parser)->location;
12086 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12088 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12089 warning_at (attr_comb, OPT_Wattributes,
12090 "empty property attribute list");
12095 c_token *token = c_parser_peek_token (parser);
12096 attr_start = token->location;
12097 attr_end = get_finish (token->location);
12098 location_t attr_comb = make_location (attr_start, attr_start,
12101 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12103 warning_at (attr_comb, OPT_Wattributes,
12104 "missing property attribute");
12105 if (token->type == CPP_CLOSE_PAREN)
12107 c_parser_consume_token (parser);
12111 tree attr_name = NULL_TREE;
12112 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12113 bool add_at = false;
12114 if (token->type == CPP_KEYWORD)
12116 keyword = token->keyword;
12117 if (OBJC_IS_AT_KEYWORD (keyword))
12119 /* For '@' keywords the token value has the keyword,
12120 prepend the '@' for diagnostics. */
12121 attr_name = token->value;
12125 attr_name = ridpointers[(int)keyword];
12127 else if (token->type == CPP_NAME)
12128 attr_name = token->value;
12129 c_parser_consume_token (parser);
12131 enum objc_property_attribute_kind prop_kind
12132 = objc_prop_attr_kind_for_rid (keyword);
12133 property_attribute_info *prop
12134 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12135 prop_attr_list.safe_push (prop);
12138 switch (prop->prop_kind)
12141 case OBJC_PROPERTY_ATTR_UNKNOWN:
12143 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12144 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12146 error_at (attr_comb, "unknown property attribute");
12147 prop->parse_error = syntax_error = true;
12150 case OBJC_PROPERTY_ATTR_GETTER:
12151 case OBJC_PROPERTY_ATTR_SETTER:
12152 if (c_parser_next_token_is_not (parser, CPP_EQ))
12154 attr_comb = make_location (attr_end, attr_start, attr_end);
12155 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12157 prop->parse_error = syntax_error = true;
12160 token = c_parser_peek_token (parser);
12161 attr_end = token->location;
12162 c_parser_consume_token (parser); /* eat the = */
12163 if (c_parser_next_token_is_not (parser, CPP_NAME))
12165 attr_comb = make_location (attr_end, attr_start, attr_end);
12166 error_at (attr_comb, "expected %qE selector name",
12168 prop->parse_error = syntax_error = true;
12171 /* Get the end of the method name, and consume the name. */
12172 token = c_parser_peek_token (parser);
12173 attr_end = get_finish (token->location);
12174 meth_name = token->value;
12175 c_parser_consume_token (parser);
12176 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12178 if (c_parser_next_token_is_not (parser, CPP_COLON))
12180 attr_comb = make_location (attr_end, attr_start,
12182 error_at (attr_comb, "setter method names must"
12183 " terminate with %<:%>");
12184 prop->parse_error = syntax_error = true;
12188 attr_end = get_finish (c_parser_peek_token
12189 (parser)->location);
12190 c_parser_consume_token (parser);
12192 attr_comb = make_location (attr_start, attr_start,
12196 attr_comb = make_location (attr_start, attr_start,
12198 prop->ident = meth_name;
12199 /* Updated location including all that was successfully
12201 prop->prop_loc = attr_comb;
12205 /* If we see a comma here, then keep going - even if we already
12206 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12207 this makes a more useful output and avoid spurious warnings about
12208 missing attributes that are, in fact, specified after the one with
12209 the syntax error. */
12210 if (c_parser_next_token_is (parser, CPP_COMMA))
12211 c_parser_consume_token (parser);
12215 parser->objc_property_attr_context = false;
12217 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12218 /* We don't really want to chew the whole of the file looking for a
12219 matching closing parenthesis, so we will try to read the decl and
12220 let the error handling for that close out the statement. */
12223 syntax_error = false, parens.skip_until_found_close (parser);
12226 /* 'properties' is the list of properties that we read. Usually a
12227 single one, but maybe more (eg, in "@property int a, b, c;" there
12229 tree properties = c_parser_struct_declaration (parser);
12231 if (properties == error_mark_node)
12232 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12235 if (properties == NULL_TREE)
12236 c_parser_error (parser, "expected identifier");
12239 /* Comma-separated properties are chained together in reverse order;
12240 add them one by one. */
12241 properties = nreverse (properties);
12242 for (; properties; properties = TREE_CHAIN (properties))
12243 objc_add_property_declaration (loc, copy_node (properties),
12246 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12249 while (!prop_attr_list.is_empty())
12250 delete prop_attr_list.pop ();
12251 prop_attr_list.release ();
12252 parser->error = false;
12255 /* Parse an Objective-C @synthesize declaration. The syntax is:
12257 objc-synthesize-declaration:
12258 @synthesize objc-synthesize-identifier-list ;
12260 objc-synthesize-identifier-list:
12261 objc-synthesize-identifier
12262 objc-synthesize-identifier-list, objc-synthesize-identifier
12264 objc-synthesize-identifier
12266 identifier = identifier
12269 @synthesize MyProperty;
12270 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12272 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12273 for C++. Keep them in sync.
12276 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12278 tree list = NULL_TREE;
12280 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12281 loc = c_parser_peek_token (parser)->location;
12283 c_parser_consume_token (parser);
12286 tree property, ivar;
12287 if (c_parser_next_token_is_not (parser, CPP_NAME))
12289 c_parser_error (parser, "expected identifier");
12290 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12291 /* Once we find the semicolon, we can resume normal parsing.
12292 We have to reset parser->error manually because
12293 c_parser_skip_until_found() won't reset it for us if the
12294 next token is precisely a semicolon. */
12295 parser->error = false;
12298 property = c_parser_peek_token (parser)->value;
12299 c_parser_consume_token (parser);
12300 if (c_parser_next_token_is (parser, CPP_EQ))
12302 c_parser_consume_token (parser);
12303 if (c_parser_next_token_is_not (parser, CPP_NAME))
12305 c_parser_error (parser, "expected identifier");
12306 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12307 parser->error = false;
12310 ivar = c_parser_peek_token (parser)->value;
12311 c_parser_consume_token (parser);
12315 list = chainon (list, build_tree_list (ivar, property));
12316 if (c_parser_next_token_is (parser, CPP_COMMA))
12317 c_parser_consume_token (parser);
12321 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12322 objc_add_synthesize_declaration (loc, list);
12325 /* Parse an Objective-C @dynamic declaration. The syntax is:
12327 objc-dynamic-declaration:
12328 @dynamic identifier-list ;
12331 @dynamic MyProperty;
12332 @dynamic MyProperty, AnotherProperty;
12334 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12335 for C++. Keep them in sync.
12338 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12340 tree list = NULL_TREE;
12342 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12343 loc = c_parser_peek_token (parser)->location;
12345 c_parser_consume_token (parser);
12349 if (c_parser_next_token_is_not (parser, CPP_NAME))
12351 c_parser_error (parser, "expected identifier");
12352 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12353 parser->error = false;
12356 property = c_parser_peek_token (parser)->value;
12357 list = chainon (list, build_tree_list (NULL_TREE, property));
12358 c_parser_consume_token (parser);
12359 if (c_parser_next_token_is (parser, CPP_COMMA))
12360 c_parser_consume_token (parser);
12364 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12365 objc_add_dynamic_declaration (loc, list);
12369 /* Parse a pragma GCC ivdep. */
12372 c_parse_pragma_ivdep (c_parser *parser)
12374 c_parser_consume_pragma (parser);
12375 c_parser_skip_to_pragma_eol (parser);
12379 /* Parse a pragma GCC unroll. */
12381 static unsigned short
12382 c_parser_pragma_unroll (c_parser *parser)
12384 unsigned short unroll;
12385 c_parser_consume_pragma (parser);
12386 location_t location = c_parser_peek_token (parser)->location;
12387 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12388 mark_exp_read (expr);
12389 expr = c_fully_fold (expr, false, NULL);
12390 HOST_WIDE_INT lunroll = 0;
12391 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12392 || TREE_CODE (expr) != INTEGER_CST
12393 || (lunroll = tree_to_shwi (expr)) < 0
12394 || lunroll >= USHRT_MAX)
12396 error_at (location, "%<#pragma GCC unroll%> requires an"
12397 " assignment-expression that evaluates to a non-negative"
12398 " integral constant less than %u", USHRT_MAX);
12403 unroll = (unsigned short)lunroll;
12408 c_parser_skip_to_pragma_eol (parser);
12412 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12413 should be considered, statements. ALLOW_STMT is true if we're within
12414 the context of a function and such pragmas are to be allowed. Returns
12415 true if we actually parsed such a pragma. */
12418 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12421 const char *construct = NULL;
12423 input_location = c_parser_peek_token (parser)->location;
12424 id = c_parser_peek_token (parser)->pragma_kind;
12425 gcc_assert (id != PRAGMA_NONE);
12429 case PRAGMA_OACC_DECLARE:
12430 c_parser_oacc_declare (parser);
12433 case PRAGMA_OACC_ENTER_DATA:
12434 if (context != pragma_compound)
12436 construct = "acc enter data";
12438 if (context == pragma_stmt)
12440 error_at (c_parser_peek_token (parser)->location,
12441 "%<#pragma %s%> may only be used in compound "
12442 "statements", construct);
12443 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12448 c_parser_oacc_enter_exit_data (parser, true);
12451 case PRAGMA_OACC_EXIT_DATA:
12452 if (context != pragma_compound)
12454 construct = "acc exit data";
12457 c_parser_oacc_enter_exit_data (parser, false);
12460 case PRAGMA_OACC_ROUTINE:
12461 if (context != pragma_external)
12463 error_at (c_parser_peek_token (parser)->location,
12464 "%<#pragma acc routine%> must be at file scope");
12465 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12468 c_parser_oacc_routine (parser, context);
12471 case PRAGMA_OACC_UPDATE:
12472 if (context != pragma_compound)
12474 construct = "acc update";
12477 c_parser_oacc_update (parser);
12480 case PRAGMA_OMP_BARRIER:
12481 if (context != pragma_compound)
12483 construct = "omp barrier";
12486 c_parser_omp_barrier (parser);
12489 case PRAGMA_OMP_DEPOBJ:
12490 if (context != pragma_compound)
12492 construct = "omp depobj";
12495 c_parser_omp_depobj (parser);
12498 case PRAGMA_OMP_FLUSH:
12499 if (context != pragma_compound)
12501 construct = "omp flush";
12504 c_parser_omp_flush (parser);
12507 case PRAGMA_OMP_TASKWAIT:
12508 if (context != pragma_compound)
12510 construct = "omp taskwait";
12513 c_parser_omp_taskwait (parser);
12516 case PRAGMA_OMP_TASKYIELD:
12517 if (context != pragma_compound)
12519 construct = "omp taskyield";
12522 c_parser_omp_taskyield (parser);
12525 case PRAGMA_OMP_CANCEL:
12526 if (context != pragma_compound)
12528 construct = "omp cancel";
12531 c_parser_omp_cancel (parser);
12534 case PRAGMA_OMP_CANCELLATION_POINT:
12535 return c_parser_omp_cancellation_point (parser, context);
12537 case PRAGMA_OMP_THREADPRIVATE:
12538 c_parser_omp_threadprivate (parser);
12541 case PRAGMA_OMP_TARGET:
12542 return c_parser_omp_target (parser, context, if_p);
12544 case PRAGMA_OMP_END_DECLARE_TARGET:
12545 c_parser_omp_end_declare_target (parser);
12548 case PRAGMA_OMP_SCAN:
12549 error_at (c_parser_peek_token (parser)->location,
12550 "%<#pragma omp scan%> may only be used in "
12551 "a loop construct with %<inscan%> %<reduction%> clause");
12552 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12555 case PRAGMA_OMP_SECTION:
12556 error_at (c_parser_peek_token (parser)->location,
12557 "%<#pragma omp section%> may only be used in "
12558 "%<#pragma omp sections%> construct");
12559 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12562 case PRAGMA_OMP_DECLARE:
12563 return c_parser_omp_declare (parser, context);
12565 case PRAGMA_OMP_REQUIRES:
12566 if (context != pragma_external)
12568 error_at (c_parser_peek_token (parser)->location,
12569 "%<#pragma omp requires%> may only be used at file scope");
12570 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12573 c_parser_omp_requires (parser);
12576 case PRAGMA_OMP_NOTHING:
12577 c_parser_omp_nothing (parser);
12580 case PRAGMA_OMP_ERROR:
12581 return c_parser_omp_error (parser, context);
12583 case PRAGMA_OMP_ORDERED:
12584 return c_parser_omp_ordered (parser, context, if_p);
12588 const bool ivdep = c_parse_pragma_ivdep (parser);
12589 unsigned short unroll;
12590 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12591 unroll = c_parser_pragma_unroll (parser);
12594 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12595 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12596 && !c_parser_next_token_is_keyword (parser, RID_DO))
12598 c_parser_error (parser, "for, while or do statement expected");
12601 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12602 c_parser_for_statement (parser, ivdep, unroll, if_p);
12603 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12604 c_parser_while_statement (parser, ivdep, unroll, if_p);
12606 c_parser_do_statement (parser, ivdep, unroll);
12610 case PRAGMA_UNROLL:
12612 unsigned short unroll = c_parser_pragma_unroll (parser);
12614 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12615 ivdep = c_parse_pragma_ivdep (parser);
12618 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12619 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12620 && !c_parser_next_token_is_keyword (parser, RID_DO))
12622 c_parser_error (parser, "for, while or do statement expected");
12625 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12626 c_parser_for_statement (parser, ivdep, unroll, if_p);
12627 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12628 c_parser_while_statement (parser, ivdep, unroll, if_p);
12630 c_parser_do_statement (parser, ivdep, unroll);
12634 case PRAGMA_GCC_PCH_PREPROCESS:
12635 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12636 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12639 case PRAGMA_OACC_WAIT:
12640 if (context != pragma_compound)
12642 construct = "acc wait";
12645 /* FALL THROUGH. */
12648 if (id < PRAGMA_FIRST_EXTERNAL)
12650 if (context != pragma_stmt && context != pragma_compound)
12653 c_parser_error (parser, "expected declaration specifiers");
12654 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12657 c_parser_omp_construct (parser, if_p);
12663 c_parser_consume_pragma (parser);
12664 c_invoke_pragma_handler (id);
12666 /* Skip to EOL, but suppress any error message. Those will have been
12667 generated by the handler routine through calling error, as opposed
12668 to calling c_parser_error. */
12669 parser->error = true;
12670 c_parser_skip_to_pragma_eol (parser);
12675 /* The interface the pragma parsers have to the lexer. */
12678 pragma_lex (tree *value, location_t *loc)
12680 c_token *tok = c_parser_peek_token (the_parser);
12681 enum cpp_ttype ret = tok->type;
12683 *value = tok->value;
12685 *loc = tok->location;
12687 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12689 else if (ret == CPP_STRING)
12690 *value = c_parser_string_literal (the_parser, false, false).value;
12693 if (ret == CPP_KEYWORD)
12695 c_parser_consume_token (the_parser);
12702 c_parser_pragma_pch_preprocess (c_parser *parser)
12706 parser->lex_joined_string = true;
12707 c_parser_consume_pragma (parser);
12708 if (c_parser_next_token_is (parser, CPP_STRING))
12710 name = c_parser_peek_token (parser)->value;
12711 c_parser_consume_token (parser);
12714 c_parser_error (parser, "expected string literal");
12715 c_parser_skip_to_pragma_eol (parser);
12716 parser->lex_joined_string = false;
12719 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12722 /* OpenACC and OpenMP parsing routines. */
12724 /* Returns name of the next clause.
12725 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12726 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12727 returned and the token is consumed. */
12729 static pragma_omp_clause
12730 c_parser_omp_clause_name (c_parser *parser)
12732 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12734 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12735 result = PRAGMA_OACC_CLAUSE_AUTO;
12736 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12737 result = PRAGMA_OMP_CLAUSE_IF;
12738 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12739 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12740 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12741 result = PRAGMA_OMP_CLAUSE_FOR;
12742 else if (c_parser_next_token_is (parser, CPP_NAME))
12744 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12749 if (!strcmp ("affinity", p))
12750 result = PRAGMA_OMP_CLAUSE_AFFINITY;
12751 else if (!strcmp ("aligned", p))
12752 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12753 else if (!strcmp ("allocate", p))
12754 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12755 else if (!strcmp ("async", p))
12756 result = PRAGMA_OACC_CLAUSE_ASYNC;
12757 else if (!strcmp ("attach", p))
12758 result = PRAGMA_OACC_CLAUSE_ATTACH;
12761 if (!strcmp ("bind", p))
12762 result = PRAGMA_OMP_CLAUSE_BIND;
12765 if (!strcmp ("collapse", p))
12766 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12767 else if (!strcmp ("copy", p))
12768 result = PRAGMA_OACC_CLAUSE_COPY;
12769 else if (!strcmp ("copyin", p))
12770 result = PRAGMA_OMP_CLAUSE_COPYIN;
12771 else if (!strcmp ("copyout", p))
12772 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12773 else if (!strcmp ("copyprivate", p))
12774 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12775 else if (!strcmp ("create", p))
12776 result = PRAGMA_OACC_CLAUSE_CREATE;
12779 if (!strcmp ("defaultmap", p))
12780 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12781 else if (!strcmp ("delete", p))
12782 result = PRAGMA_OACC_CLAUSE_DELETE;
12783 else if (!strcmp ("depend", p))
12784 result = PRAGMA_OMP_CLAUSE_DEPEND;
12785 else if (!strcmp ("detach", p))
12786 result = PRAGMA_OACC_CLAUSE_DETACH;
12787 else if (!strcmp ("device", p))
12788 result = PRAGMA_OMP_CLAUSE_DEVICE;
12789 else if (!strcmp ("deviceptr", p))
12790 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12791 else if (!strcmp ("device_resident", p))
12792 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12793 else if (!strcmp ("device_type", p))
12794 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12795 else if (!strcmp ("dist_schedule", p))
12796 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12799 if (!strcmp ("enter", p))
12800 result = PRAGMA_OMP_CLAUSE_ENTER;
12803 if (!strcmp ("filter", p))
12804 result = PRAGMA_OMP_CLAUSE_FILTER;
12805 else if (!strcmp ("final", p))
12806 result = PRAGMA_OMP_CLAUSE_FINAL;
12807 else if (!strcmp ("finalize", p))
12808 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12809 else if (!strcmp ("firstprivate", p))
12810 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12811 else if (!strcmp ("from", p))
12812 result = PRAGMA_OMP_CLAUSE_FROM;
12815 if (!strcmp ("gang", p))
12816 result = PRAGMA_OACC_CLAUSE_GANG;
12817 else if (!strcmp ("grainsize", p))
12818 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12821 if (!strcmp ("has_device_addr", p))
12822 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
12823 else if (!strcmp ("hint", p))
12824 result = PRAGMA_OMP_CLAUSE_HINT;
12825 else if (!strcmp ("host", p))
12826 result = PRAGMA_OACC_CLAUSE_HOST;
12829 if (!strcmp ("if_present", p))
12830 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12831 else if (!strcmp ("in_reduction", p))
12832 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12833 else if (!strcmp ("inbranch", p))
12834 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12835 else if (!strcmp ("independent", p))
12836 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12837 else if (!strcmp ("is_device_ptr", p))
12838 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12841 if (!strcmp ("lastprivate", p))
12842 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12843 else if (!strcmp ("linear", p))
12844 result = PRAGMA_OMP_CLAUSE_LINEAR;
12845 else if (!strcmp ("link", p))
12846 result = PRAGMA_OMP_CLAUSE_LINK;
12849 if (!strcmp ("map", p))
12850 result = PRAGMA_OMP_CLAUSE_MAP;
12851 else if (!strcmp ("mergeable", p))
12852 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12855 if (!strcmp ("no_create", p))
12856 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12857 else if (!strcmp ("nogroup", p))
12858 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12859 else if (!strcmp ("nohost", p))
12860 result = PRAGMA_OACC_CLAUSE_NOHOST;
12861 else if (!strcmp ("nontemporal", p))
12862 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12863 else if (!strcmp ("notinbranch", p))
12864 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12865 else if (!strcmp ("nowait", p))
12866 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12867 else if (!strcmp ("num_gangs", p))
12868 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12869 else if (!strcmp ("num_tasks", p))
12870 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12871 else if (!strcmp ("num_teams", p))
12872 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12873 else if (!strcmp ("num_threads", p))
12874 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12875 else if (!strcmp ("num_workers", p))
12876 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12879 if (!strcmp ("ordered", p))
12880 result = PRAGMA_OMP_CLAUSE_ORDERED;
12881 else if (!strcmp ("order", p))
12882 result = PRAGMA_OMP_CLAUSE_ORDER;
12885 if (!strcmp ("parallel", p))
12886 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12887 else if (!strcmp ("present", p))
12888 result = PRAGMA_OACC_CLAUSE_PRESENT;
12889 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12891 else if (!strcmp ("present_or_copy", p)
12892 || !strcmp ("pcopy", p))
12893 result = PRAGMA_OACC_CLAUSE_COPY;
12894 else if (!strcmp ("present_or_copyin", p)
12895 || !strcmp ("pcopyin", p))
12896 result = PRAGMA_OACC_CLAUSE_COPYIN;
12897 else if (!strcmp ("present_or_copyout", p)
12898 || !strcmp ("pcopyout", p))
12899 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12900 else if (!strcmp ("present_or_create", p)
12901 || !strcmp ("pcreate", p))
12902 result = PRAGMA_OACC_CLAUSE_CREATE;
12903 else if (!strcmp ("priority", p))
12904 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12905 else if (!strcmp ("private", p))
12906 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12907 else if (!strcmp ("proc_bind", p))
12908 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12911 if (!strcmp ("reduction", p))
12912 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12915 if (!strcmp ("safelen", p))
12916 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12917 else if (!strcmp ("schedule", p))
12918 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12919 else if (!strcmp ("sections", p))
12920 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12921 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12922 result = PRAGMA_OACC_CLAUSE_HOST;
12923 else if (!strcmp ("seq", p))
12924 result = PRAGMA_OACC_CLAUSE_SEQ;
12925 else if (!strcmp ("shared", p))
12926 result = PRAGMA_OMP_CLAUSE_SHARED;
12927 else if (!strcmp ("simd", p))
12928 result = PRAGMA_OMP_CLAUSE_SIMD;
12929 else if (!strcmp ("simdlen", p))
12930 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12933 if (!strcmp ("task_reduction", p))
12934 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12935 else if (!strcmp ("taskgroup", p))
12936 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12937 else if (!strcmp ("thread_limit", p))
12938 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12939 else if (!strcmp ("threads", p))
12940 result = PRAGMA_OMP_CLAUSE_THREADS;
12941 else if (!strcmp ("tile", p))
12942 result = PRAGMA_OACC_CLAUSE_TILE;
12943 else if (!strcmp ("to", p))
12944 result = PRAGMA_OMP_CLAUSE_TO;
12947 if (!strcmp ("uniform", p))
12948 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12949 else if (!strcmp ("untied", p))
12950 result = PRAGMA_OMP_CLAUSE_UNTIED;
12951 else if (!strcmp ("use_device", p))
12952 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12953 else if (!strcmp ("use_device_addr", p))
12954 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12955 else if (!strcmp ("use_device_ptr", p))
12956 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12959 if (!strcmp ("vector", p))
12960 result = PRAGMA_OACC_CLAUSE_VECTOR;
12961 else if (!strcmp ("vector_length", p))
12962 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12965 if (!strcmp ("wait", p))
12966 result = PRAGMA_OACC_CLAUSE_WAIT;
12967 else if (!strcmp ("worker", p))
12968 result = PRAGMA_OACC_CLAUSE_WORKER;
12973 if (result != PRAGMA_OMP_CLAUSE_NONE)
12974 c_parser_consume_token (parser);
12979 /* Validate that a clause of the given type does not already exist. */
12982 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12985 if (tree c = omp_find_clause (clauses, code))
12986 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12990 Parse wait clause or wait directive parameters. */
12993 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12995 vec<tree, va_gc> *args;
12998 matching_parens parens;
12999 if (!parens.require_open (parser))
13002 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
13003 args_tree = build_tree_list_vec (args);
13005 for (t = args_tree; t; t = TREE_CHAIN (t))
13007 tree targ = TREE_VALUE (t);
13009 if (targ != error_mark_node)
13011 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
13013 c_parser_error (parser, "expression must be integral");
13014 targ = error_mark_node;
13018 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
13020 OMP_CLAUSE_DECL (c) = targ;
13021 OMP_CLAUSE_CHAIN (c) = list;
13027 release_tree_vector (args);
13028 parens.require_close (parser);
13032 /* OpenACC 2.0, OpenMP 2.5:
13035 variable-list , identifier
13037 If KIND is nonzero, create the appropriate node and install the
13038 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13039 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13041 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13042 return the list created.
13044 The optional ALLOW_DEREF argument is true if list items can use the deref
13049 tree low_bound, length;
13052 omp_dim (tree lb, tree len, location_t lo, bool nc)
13053 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13057 c_parser_omp_variable_list (c_parser *parser,
13058 location_t clause_loc,
13059 enum omp_clause_code kind, tree list,
13060 bool allow_deref = false)
13062 auto_vec<omp_dim> dims;
13063 bool array_section_p;
13064 auto_vec<c_token> tokens;
13065 unsigned int tokens_avail = 0;
13070 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13072 if (c_parser_next_token_is_not (parser, CPP_NAME)
13073 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13075 struct c_expr expr;
13076 if (kind == OMP_CLAUSE_DEPEND
13077 && c_parser_next_token_is_keyword (parser,
13078 RID_OMP_ALL_MEMORY)
13079 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13080 || (c_parser_peek_2nd_token (parser)->type
13081 == CPP_CLOSE_PAREN)))
13083 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
13084 c_parser_consume_token (parser);
13087 expr = c_parser_expr_no_commas (parser, NULL);
13088 if (expr.value != error_mark_node)
13090 tree u = build_omp_clause (clause_loc, kind);
13091 OMP_CLAUSE_DECL (u) = expr.value;
13092 OMP_CLAUSE_CHAIN (u) = list;
13096 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13099 c_parser_consume_token (parser);
13104 tokens.truncate (0);
13105 unsigned int nesting_depth = 0;
13108 c_token *token = c_parser_peek_token (parser);
13109 switch (token->type)
13112 case CPP_PRAGMA_EOL:
13114 case CPP_OPEN_BRACE:
13115 case CPP_OPEN_PAREN:
13116 case CPP_OPEN_SQUARE:
13119 case CPP_CLOSE_BRACE:
13120 case CPP_CLOSE_PAREN:
13121 case CPP_CLOSE_SQUARE:
13122 if (nesting_depth-- == 0)
13126 if (nesting_depth == 0)
13131 tokens.safe_push (*token);
13132 c_parser_consume_token (parser);
13138 /* Make sure nothing tries to read past the end of the tokens. */
13140 memset (&eof_token, 0, sizeof (eof_token));
13141 eof_token.type = CPP_EOF;
13142 tokens.safe_push (eof_token);
13143 tokens.safe_push (eof_token);
13145 tokens_avail = parser->tokens_avail;
13146 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13147 parser->tokens = tokens.address ();
13148 parser->tokens_avail = tokens.length ();
13151 tree t = NULL_TREE;
13153 if (c_parser_next_token_is (parser, CPP_NAME)
13154 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13156 t = lookup_name (c_parser_peek_token (parser)->value);
13158 if (t == NULL_TREE)
13160 undeclared_variable (c_parser_peek_token (parser)->location,
13161 c_parser_peek_token (parser)->value);
13162 t = error_mark_node;
13165 c_parser_consume_token (parser);
13167 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13168 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13169 || (c_parser_peek_token (parser)->keyword
13170 == RID_PRETTY_FUNCTION_NAME)
13171 || (c_parser_peek_token (parser)->keyword
13172 == RID_C99_FUNCTION_NAME)))
13173 t = c_parser_predefined_identifier (parser).value;
13177 c_parser_error (parser, "expected identifier");
13181 if (t == error_mark_node)
13183 else if (kind != 0)
13187 case OMP_CLAUSE__CACHE_:
13188 /* The OpenACC cache directive explicitly only allows "array
13189 elements or subarrays". */
13190 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13192 c_parser_error (parser, "expected %<[%>");
13193 t = error_mark_node;
13197 case OMP_CLAUSE_MAP:
13198 case OMP_CLAUSE_FROM:
13199 case OMP_CLAUSE_TO:
13200 start_component_ref:
13201 while (c_parser_next_token_is (parser, CPP_DOT)
13203 && c_parser_next_token_is (parser, CPP_DEREF)))
13205 location_t op_loc = c_parser_peek_token (parser)->location;
13206 location_t arrow_loc = UNKNOWN_LOCATION;
13207 if (c_parser_next_token_is (parser, CPP_DEREF))
13211 t_expr.original_code = ERROR_MARK;
13212 t_expr.original_type = NULL;
13213 set_c_expr_source_range (&t_expr, op_loc, op_loc);
13214 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13216 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13217 arrow_loc = t_expr.get_location ();
13219 c_parser_consume_token (parser);
13220 if (!c_parser_next_token_is (parser, CPP_NAME))
13222 c_parser_error (parser, "expected identifier");
13223 t = error_mark_node;
13227 c_token *comp_tok = c_parser_peek_token (parser);
13228 tree ident = comp_tok->value;
13229 location_t comp_loc = comp_tok->location;
13230 c_parser_consume_token (parser);
13231 t = build_component_ref (op_loc, t, ident, comp_loc,
13235 case OMP_CLAUSE_AFFINITY:
13236 case OMP_CLAUSE_DEPEND:
13237 case OMP_CLAUSE_REDUCTION:
13238 case OMP_CLAUSE_IN_REDUCTION:
13239 case OMP_CLAUSE_TASK_REDUCTION:
13240 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13241 array_section_p = false;
13243 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13245 location_t loc = UNKNOWN_LOCATION;
13246 tree low_bound = NULL_TREE, length = NULL_TREE;
13247 bool no_colon = false;
13249 c_parser_consume_token (parser);
13250 if (!c_parser_next_token_is (parser, CPP_COLON))
13252 location_t expr_loc
13253 = c_parser_peek_token (parser)->location;
13254 c_expr expr = c_parser_expression (parser);
13255 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13257 low_bound = expr.value;
13260 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13262 length = integer_one_node;
13267 /* Look for `:'. */
13268 if (!c_parser_require (parser, CPP_COLON,
13271 t = error_mark_node;
13274 array_section_p = true;
13275 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13277 location_t expr_loc
13278 = c_parser_peek_token (parser)->location;
13279 c_expr expr = c_parser_expression (parser);
13280 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13282 length = expr.value;
13285 /* Look for the closing `]'. */
13286 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13289 t = error_mark_node;
13293 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13296 if (t != error_mark_node)
13298 if ((kind == OMP_CLAUSE_MAP
13299 || kind == OMP_CLAUSE_FROM
13300 || kind == OMP_CLAUSE_TO)
13301 && !array_section_p
13302 && (c_parser_next_token_is (parser, CPP_DOT)
13304 && c_parser_next_token_is (parser,
13307 for (unsigned i = 0; i < dims.length (); i++)
13309 gcc_assert (dims[i].length == integer_one_node);
13310 t = build_array_ref (dims[i].loc,
13311 t, dims[i].low_bound);
13313 goto start_component_ref;
13316 for (unsigned i = 0; i < dims.length (); i++)
13317 t = tree_cons (dims[i].low_bound, dims[i].length, t);
13320 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13321 && t != error_mark_node
13322 && parser->tokens_avail != 2)
13324 if (array_section_p)
13326 error_at (c_parser_peek_token (parser)->location,
13327 "expected %<)%> or %<,%>");
13328 t = error_mark_node;
13332 parser->tokens = tokens.address ();
13333 parser->tokens_avail = tokens.length ();
13335 t = c_parser_expr_no_commas (parser, NULL).value;
13336 if (t != error_mark_node && parser->tokens_avail != 2)
13338 error_at (c_parser_peek_token (parser)->location,
13339 "expected %<)%> or %<,%>");
13340 t = error_mark_node;
13349 if (t != error_mark_node)
13351 tree u = build_omp_clause (clause_loc, kind);
13352 OMP_CLAUSE_DECL (u) = t;
13353 OMP_CLAUSE_CHAIN (u) = list;
13358 list = tree_cons (t, NULL_TREE, list);
13360 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13362 parser->tokens = &parser->tokens_buf[0];
13363 parser->tokens_avail = tokens_avail;
13365 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13368 c_parser_consume_token (parser);
13375 /* Similarly, but expect leading and trailing parenthesis. This is a very
13376 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13377 argument is true if list items can use the deref (->) operator. */
13380 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13381 tree list, bool allow_deref = false)
13383 /* The clauses location. */
13384 location_t loc = c_parser_peek_token (parser)->location;
13386 matching_parens parens;
13387 if (parens.require_open (parser))
13389 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13390 parens.skip_until_found_close (parser);
13396 copy ( variable-list )
13397 copyin ( variable-list )
13398 copyout ( variable-list )
13399 create ( variable-list )
13400 delete ( variable-list )
13401 present ( variable-list )
13404 no_create ( variable-list )
13405 attach ( variable-list )
13406 detach ( variable-list ) */
13409 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13412 enum gomp_map_kind kind;
13415 case PRAGMA_OACC_CLAUSE_ATTACH:
13416 kind = GOMP_MAP_ATTACH;
13418 case PRAGMA_OACC_CLAUSE_COPY:
13419 kind = GOMP_MAP_TOFROM;
13421 case PRAGMA_OACC_CLAUSE_COPYIN:
13422 kind = GOMP_MAP_TO;
13424 case PRAGMA_OACC_CLAUSE_COPYOUT:
13425 kind = GOMP_MAP_FROM;
13427 case PRAGMA_OACC_CLAUSE_CREATE:
13428 kind = GOMP_MAP_ALLOC;
13430 case PRAGMA_OACC_CLAUSE_DELETE:
13431 kind = GOMP_MAP_RELEASE;
13433 case PRAGMA_OACC_CLAUSE_DETACH:
13434 kind = GOMP_MAP_DETACH;
13436 case PRAGMA_OACC_CLAUSE_DEVICE:
13437 kind = GOMP_MAP_FORCE_TO;
13439 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13440 kind = GOMP_MAP_DEVICE_RESIDENT;
13442 case PRAGMA_OACC_CLAUSE_HOST:
13443 kind = GOMP_MAP_FORCE_FROM;
13445 case PRAGMA_OACC_CLAUSE_LINK:
13446 kind = GOMP_MAP_LINK;
13448 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13449 kind = GOMP_MAP_IF_PRESENT;
13451 case PRAGMA_OACC_CLAUSE_PRESENT:
13452 kind = GOMP_MAP_FORCE_PRESENT;
13455 gcc_unreachable ();
13458 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13460 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13461 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13467 deviceptr ( variable-list ) */
13470 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13472 location_t loc = c_parser_peek_token (parser)->location;
13475 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13476 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13477 variable-list must only allow for pointer variables. */
13478 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13479 for (t = vars; t && t; t = TREE_CHAIN (t))
13481 tree v = TREE_PURPOSE (t);
13483 /* FIXME diagnostics: Ideally we should keep individual
13484 locations for all the variables in the var list to make the
13485 following errors more precise. Perhaps
13486 c_parser_omp_var_list_parens() should construct a list of
13487 locations to go along with the var list. */
13489 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13490 error_at (loc, "%qD is not a variable", v);
13491 else if (TREE_TYPE (v) == error_mark_node)
13493 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13494 error_at (loc, "%qD is not a pointer variable", v);
13496 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13497 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13498 OMP_CLAUSE_DECL (u) = v;
13499 OMP_CLAUSE_CHAIN (u) = list;
13506 /* OpenACC 2.0, OpenMP 3.0:
13507 collapse ( constant-expression ) */
13510 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13512 tree c, num = error_mark_node;
13516 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13517 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13519 loc = c_parser_peek_token (parser)->location;
13520 matching_parens parens;
13521 if (parens.require_open (parser))
13523 num = c_parser_expr_no_commas (parser, NULL).value;
13524 parens.skip_until_found_close (parser);
13526 if (num == error_mark_node)
13528 mark_exp_read (num);
13529 num = c_fully_fold (num, false, NULL);
13530 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13531 || !tree_fits_shwi_p (num)
13532 || (n = tree_to_shwi (num)) <= 0
13536 "collapse argument needs positive constant integer expression");
13539 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13540 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13541 OMP_CLAUSE_CHAIN (c) = list;
13546 copyin ( variable-list ) */
13549 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13551 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13555 copyprivate ( variable-list ) */
13558 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13560 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13564 default ( none | shared )
13567 default ( private | firstprivate )
13570 default ( none | present ) */
13573 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13575 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13576 location_t loc = c_parser_peek_token (parser)->location;
13579 matching_parens parens;
13580 if (!parens.require_open (parser))
13582 if (c_parser_next_token_is (parser, CPP_NAME))
13584 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13589 if (strcmp ("none", p) != 0)
13591 kind = OMP_CLAUSE_DEFAULT_NONE;
13597 if (strcmp ("present", p) != 0)
13599 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13603 if (strcmp ("private", p) != 0)
13605 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
13610 if (strcmp ("firstprivate", p) != 0 || is_oacc)
13612 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13616 if (strcmp ("shared", p) != 0 || is_oacc)
13618 kind = OMP_CLAUSE_DEFAULT_SHARED;
13625 c_parser_consume_token (parser);
13631 c_parser_error (parser, "expected %<none%> or %<present%>");
13633 c_parser_error (parser, "expected %<none%>, %<shared%>, "
13634 "%<private%> or %<firstprivate%>");
13636 parens.skip_until_found_close (parser);
13638 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13641 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13642 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13643 OMP_CLAUSE_CHAIN (c) = list;
13644 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13650 firstprivate ( variable-list ) */
13653 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13655 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13659 final ( expression ) */
13662 c_parser_omp_clause_final (c_parser *parser, tree list)
13664 location_t loc = c_parser_peek_token (parser)->location;
13665 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13667 matching_parens parens;
13669 if (!parens.require_open (parser))
13670 t = error_mark_node;
13673 location_t eloc = c_parser_peek_token (parser)->location;
13674 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13675 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13676 t = c_objc_common_truthvalue_conversion (eloc, t);
13677 t = c_fully_fold (t, false, NULL);
13678 parens.skip_until_found_close (parser);
13681 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13683 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13684 OMP_CLAUSE_FINAL_EXPR (c) = t;
13685 OMP_CLAUSE_CHAIN (c) = list;
13689 c_parser_error (parser, "expected %<(%>");
13694 /* OpenACC, OpenMP 2.5:
13698 if ( directive-name-modifier : expression )
13700 directive-name-modifier:
13701 parallel | task | taskloop | target data | target | target update
13702 | target enter data | target exit data
13705 directive-name-modifier:
13706 ... | simd | cancel */
13709 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13711 location_t location = c_parser_peek_token (parser)->location;
13712 enum tree_code if_modifier = ERROR_MARK;
13714 matching_parens parens;
13715 if (!parens.require_open (parser))
13718 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13720 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13722 if (strcmp (p, "cancel") == 0)
13723 if_modifier = VOID_CST;
13724 else if (strcmp (p, "parallel") == 0)
13725 if_modifier = OMP_PARALLEL;
13726 else if (strcmp (p, "simd") == 0)
13727 if_modifier = OMP_SIMD;
13728 else if (strcmp (p, "task") == 0)
13729 if_modifier = OMP_TASK;
13730 else if (strcmp (p, "taskloop") == 0)
13731 if_modifier = OMP_TASKLOOP;
13732 else if (strcmp (p, "target") == 0)
13734 if_modifier = OMP_TARGET;
13735 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13737 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13738 if (strcmp ("data", p) == 0)
13739 if_modifier = OMP_TARGET_DATA;
13740 else if (strcmp ("update", p) == 0)
13741 if_modifier = OMP_TARGET_UPDATE;
13742 else if (strcmp ("enter", p) == 0)
13743 if_modifier = OMP_TARGET_ENTER_DATA;
13744 else if (strcmp ("exit", p) == 0)
13745 if_modifier = OMP_TARGET_EXIT_DATA;
13746 if (if_modifier != OMP_TARGET)
13749 c_parser_consume_token (parser);
13753 location_t loc = c_parser_peek_2nd_token (parser)->location;
13754 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13756 if_modifier = ERROR_MARK;
13758 if (if_modifier == OMP_TARGET_ENTER_DATA
13759 || if_modifier == OMP_TARGET_EXIT_DATA)
13761 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13763 p = IDENTIFIER_POINTER
13764 (c_parser_peek_2nd_token (parser)->value);
13765 if (strcmp ("data", p) == 0)
13769 c_parser_consume_token (parser);
13773 = c_parser_peek_2nd_token (parser)->location;
13774 error_at (loc, "expected %<data%>");
13775 if_modifier = ERROR_MARK;
13780 if (if_modifier != ERROR_MARK)
13782 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13784 c_parser_consume_token (parser);
13785 c_parser_consume_token (parser);
13791 location_t loc = c_parser_peek_2nd_token (parser)->location;
13792 error_at (loc, "expected %<:%>");
13794 if_modifier = ERROR_MARK;
13799 location_t loc = c_parser_peek_token (parser)->location;
13800 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13801 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13802 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13803 t = c_fully_fold (t, false, NULL);
13804 parens.skip_until_found_close (parser);
13806 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13807 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13809 if (if_modifier != ERROR_MARK
13810 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13812 const char *p = NULL;
13813 switch (if_modifier)
13815 case VOID_CST: p = "cancel"; break;
13816 case OMP_PARALLEL: p = "parallel"; break;
13817 case OMP_SIMD: p = "simd"; break;
13818 case OMP_TASK: p = "task"; break;
13819 case OMP_TASKLOOP: p = "taskloop"; break;
13820 case OMP_TARGET_DATA: p = "target data"; break;
13821 case OMP_TARGET: p = "target"; break;
13822 case OMP_TARGET_UPDATE: p = "target update"; break;
13823 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13824 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13825 default: gcc_unreachable ();
13827 error_at (location, "too many %<if%> clauses with %qs modifier",
13831 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13834 error_at (location, "too many %<if%> clauses");
13836 error_at (location, "too many %<if%> clauses without modifier");
13839 else if (if_modifier == ERROR_MARK
13840 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13842 error_at (location, "if any %<if%> clause has modifier, then all "
13843 "%<if%> clauses have to use modifier");
13848 c = build_omp_clause (location, OMP_CLAUSE_IF);
13849 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13850 OMP_CLAUSE_IF_EXPR (c) = t;
13851 OMP_CLAUSE_CHAIN (c) = list;
13856 lastprivate ( variable-list )
13859 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13862 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13864 /* The clauses location. */
13865 location_t loc = c_parser_peek_token (parser)->location;
13867 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13869 bool conditional = false;
13870 if (c_parser_next_token_is (parser, CPP_NAME)
13871 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13874 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13875 if (strcmp (p, "conditional") == 0)
13877 conditional = true;
13878 c_parser_consume_token (parser);
13879 c_parser_consume_token (parser);
13882 tree nlist = c_parser_omp_variable_list (parser, loc,
13883 OMP_CLAUSE_LASTPRIVATE, list);
13884 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13886 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13887 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13897 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13901 /* FIXME: Should we allow duplicates? */
13902 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13904 c = build_omp_clause (c_parser_peek_token (parser)->location,
13905 OMP_CLAUSE_MERGEABLE);
13906 OMP_CLAUSE_CHAIN (c) = list;
13915 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13918 location_t loc = c_parser_peek_token (parser)->location;
13920 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13922 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13923 OMP_CLAUSE_CHAIN (c) = list;
13928 num_threads ( expression ) */
13931 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13933 location_t num_threads_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);
13943 parens.skip_until_found_close (parser);
13945 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13947 c_parser_error (parser, "expected integer expression");
13951 /* Attempt to statically determine when the number isn't positive. */
13952 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13953 build_int_cst (TREE_TYPE (t), 0));
13954 protected_set_expr_location (c, expr_loc);
13955 if (c == boolean_true_node)
13957 warning_at (expr_loc, 0,
13958 "%<num_threads%> value must be positive");
13959 t = integer_one_node;
13962 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13964 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13965 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13966 OMP_CLAUSE_CHAIN (c) = list;
13974 num_tasks ( expression )
13977 num_tasks ( strict : expression ) */
13980 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13982 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13983 matching_parens parens;
13984 if (parens.require_open (parser))
13986 bool strict = false;
13987 if (c_parser_next_token_is (parser, CPP_NAME)
13988 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
13989 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
13993 c_parser_consume_token (parser);
13994 c_parser_consume_token (parser);
13997 location_t expr_loc = c_parser_peek_token (parser)->location;
13998 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13999 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14000 tree c, t = expr.value;
14001 t = c_fully_fold (t, false, NULL);
14003 parens.skip_until_found_close (parser);
14005 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14007 c_parser_error (parser, "expected integer expression");
14011 /* Attempt to statically determine when the number isn't positive. */
14012 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14013 build_int_cst (TREE_TYPE (t), 0));
14014 if (CAN_HAVE_LOCATION_P (c))
14015 SET_EXPR_LOCATION (c, expr_loc);
14016 if (c == boolean_true_node)
14018 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
14019 t = integer_one_node;
14022 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
14024 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
14025 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
14026 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
14027 OMP_CLAUSE_CHAIN (c) = list;
14035 grainsize ( expression )
14038 grainsize ( strict : expression ) */
14041 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
14043 location_t grainsize_loc = c_parser_peek_token (parser)->location;
14044 matching_parens parens;
14045 if (parens.require_open (parser))
14047 bool strict = false;
14048 if (c_parser_next_token_is (parser, CPP_NAME)
14049 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14050 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14054 c_parser_consume_token (parser);
14055 c_parser_consume_token (parser);
14058 location_t expr_loc = c_parser_peek_token (parser)->location;
14059 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14060 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14061 tree c, t = expr.value;
14062 t = c_fully_fold (t, false, NULL);
14064 parens.skip_until_found_close (parser);
14066 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14068 c_parser_error (parser, "expected integer expression");
14072 /* Attempt to statically determine when the number isn't positive. */
14073 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14074 build_int_cst (TREE_TYPE (t), 0));
14075 if (CAN_HAVE_LOCATION_P (c))
14076 SET_EXPR_LOCATION (c, expr_loc);
14077 if (c == boolean_true_node)
14079 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14080 t = integer_one_node;
14083 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14085 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14086 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14087 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14088 OMP_CLAUSE_CHAIN (c) = list;
14096 priority ( expression ) */
14099 c_parser_omp_clause_priority (c_parser *parser, tree list)
14101 location_t priority_loc = c_parser_peek_token (parser)->location;
14102 matching_parens parens;
14103 if (parens.require_open (parser))
14105 location_t expr_loc = c_parser_peek_token (parser)->location;
14106 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14107 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14108 tree c, t = expr.value;
14109 t = c_fully_fold (t, false, NULL);
14111 parens.skip_until_found_close (parser);
14113 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14115 c_parser_error (parser, "expected integer expression");
14119 /* Attempt to statically determine when the number isn't
14121 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14122 build_int_cst (TREE_TYPE (t), 0));
14123 if (CAN_HAVE_LOCATION_P (c))
14124 SET_EXPR_LOCATION (c, expr_loc);
14125 if (c == boolean_true_node)
14127 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14128 t = integer_one_node;
14131 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14133 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14134 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14135 OMP_CLAUSE_CHAIN (c) = list;
14143 hint ( expression ) */
14146 c_parser_omp_clause_hint (c_parser *parser, tree list)
14148 location_t hint_loc = c_parser_peek_token (parser)->location;
14149 matching_parens parens;
14150 if (parens.require_open (parser))
14152 location_t expr_loc = c_parser_peek_token (parser)->location;
14153 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14154 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14155 tree c, t = expr.value;
14156 t = c_fully_fold (t, false, NULL);
14157 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14158 || TREE_CODE (t) != INTEGER_CST
14159 || tree_int_cst_sgn (t) == -1)
14161 c_parser_error (parser, "expected constant integer expression "
14162 "with valid sync-hint value");
14165 parens.skip_until_found_close (parser);
14166 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14168 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14169 OMP_CLAUSE_HINT_EXPR (c) = t;
14170 OMP_CLAUSE_CHAIN (c) = list;
14178 filter ( integer-expression ) */
14181 c_parser_omp_clause_filter (c_parser *parser, tree list)
14183 location_t hint_loc = c_parser_peek_token (parser)->location;
14184 matching_parens parens;
14185 if (parens.require_open (parser))
14187 location_t expr_loc = c_parser_peek_token (parser)->location;
14188 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14189 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14190 tree c, t = expr.value;
14191 t = c_fully_fold (t, false, NULL);
14192 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14194 c_parser_error (parser, "expected integer expression");
14197 parens.skip_until_found_close (parser);
14198 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14200 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14201 OMP_CLAUSE_FILTER_EXPR (c) = t;
14202 OMP_CLAUSE_CHAIN (c) = list;
14210 defaultmap ( tofrom : scalar )
14213 defaultmap ( implicit-behavior [ : variable-category ] ) */
14216 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14218 location_t loc = c_parser_peek_token (parser)->location;
14221 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14222 enum omp_clause_defaultmap_kind category
14223 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14225 matching_parens parens;
14226 if (!parens.require_open (parser))
14228 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14230 else if (!c_parser_next_token_is (parser, CPP_NAME))
14233 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14234 "%<tofrom%>, %<firstprivate%>, %<none%> "
14239 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14244 if (strcmp ("alloc", p) == 0)
14245 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14247 goto invalid_behavior;
14251 if (strcmp ("default", p) == 0)
14252 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14254 goto invalid_behavior;
14258 if (strcmp ("firstprivate", p) == 0)
14259 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14260 else if (strcmp ("from", p) == 0)
14261 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14263 goto invalid_behavior;
14267 if (strcmp ("none", p) == 0)
14268 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14270 goto invalid_behavior;
14274 if (strcmp ("tofrom", p) == 0)
14275 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14276 else if (strcmp ("to", p) == 0)
14277 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14279 goto invalid_behavior;
14283 goto invalid_behavior;
14285 c_parser_consume_token (parser);
14287 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14289 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14291 if (!c_parser_next_token_is (parser, CPP_NAME))
14294 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14298 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14302 if (strcmp ("aggregate", p) == 0)
14303 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14305 goto invalid_category;
14309 if (strcmp ("pointer", p) == 0)
14310 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14312 goto invalid_category;
14316 if (strcmp ("scalar", p) == 0)
14317 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14319 goto invalid_category;
14323 goto invalid_category;
14326 c_parser_consume_token (parser);
14328 parens.skip_until_found_close (parser);
14330 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14331 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14332 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14333 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14334 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14335 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14337 enum omp_clause_defaultmap_kind cat = category;
14338 location_t loc = OMP_CLAUSE_LOCATION (c);
14339 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14340 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14344 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14347 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14350 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14353 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14357 gcc_unreachable ();
14360 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14363 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14368 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14369 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14370 OMP_CLAUSE_CHAIN (c) = list;
14374 parens.skip_until_found_close (parser);
14379 use_device ( variable-list )
14382 use_device_ptr ( variable-list ) */
14385 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14387 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14392 use_device_addr ( variable-list ) */
14395 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14397 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14402 has_device_addr ( variable-list ) */
14405 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
14407 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
14412 is_device_ptr ( variable-list ) */
14415 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14417 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14421 num_gangs ( expression )
14422 num_workers ( expression )
14423 vector_length ( expression ) */
14426 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14429 location_t loc = c_parser_peek_token (parser)->location;
14431 matching_parens parens;
14432 if (!parens.require_open (parser))
14435 location_t expr_loc = c_parser_peek_token (parser)->location;
14436 c_expr expr = c_parser_expression (parser);
14437 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14438 tree c, t = expr.value;
14439 t = c_fully_fold (t, false, NULL);
14441 parens.skip_until_found_close (parser);
14443 if (t == error_mark_node)
14445 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14447 error_at (expr_loc, "%qs expression must be integral",
14448 omp_clause_code_name[code]);
14452 /* Attempt to statically determine when the number isn't positive. */
14453 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14454 build_int_cst (TREE_TYPE (t), 0));
14455 protected_set_expr_location (c, expr_loc);
14456 if (c == boolean_true_node)
14458 warning_at (expr_loc, 0,
14459 "%qs value must be positive",
14460 omp_clause_code_name[code]);
14461 t = integer_one_node;
14464 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14466 c = build_omp_clause (loc, code);
14467 OMP_CLAUSE_OPERAND (c, 0) = t;
14468 OMP_CLAUSE_CHAIN (c) = list;
14474 gang [( gang-arg-list )]
14475 worker [( [num:] int-expr )]
14476 vector [( [length:] int-expr )]
14478 where gang-arg is one of:
14483 and size-expr may be:
14490 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14491 omp_clause_code kind,
14492 const char *str, tree list)
14494 const char *id = "num";
14495 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14497 if (kind == OMP_CLAUSE_VECTOR)
14500 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14502 c_parser_consume_token (parser);
14506 c_token *next = c_parser_peek_token (parser);
14509 /* Gang static argument. */
14510 if (kind == OMP_CLAUSE_GANG
14511 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14513 c_parser_consume_token (parser);
14515 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14516 goto cleanup_error;
14519 if (ops[idx] != NULL_TREE)
14521 c_parser_error (parser, "too many %<static%> arguments");
14522 goto cleanup_error;
14525 /* Check for the '*' argument. */
14526 if (c_parser_next_token_is (parser, CPP_MULT)
14527 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14528 || c_parser_peek_2nd_token (parser)->type
14529 == CPP_CLOSE_PAREN))
14531 c_parser_consume_token (parser);
14532 ops[idx] = integer_minus_one_node;
14534 if (c_parser_next_token_is (parser, CPP_COMMA))
14536 c_parser_consume_token (parser);
14543 /* Worker num: argument and vector length: arguments. */
14544 else if (c_parser_next_token_is (parser, CPP_NAME)
14545 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14546 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14548 c_parser_consume_token (parser); /* id */
14549 c_parser_consume_token (parser); /* ':' */
14552 /* Now collect the actual argument. */
14553 if (ops[idx] != NULL_TREE)
14555 c_parser_error (parser, "unexpected argument");
14556 goto cleanup_error;
14559 location_t expr_loc = c_parser_peek_token (parser)->location;
14560 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14561 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14562 tree expr = cexpr.value;
14563 if (expr == error_mark_node)
14564 goto cleanup_error;
14566 expr = c_fully_fold (expr, false, NULL);
14568 /* Attempt to statically determine when the number isn't a
14569 positive integer. */
14571 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14573 c_parser_error (parser, "expected integer expression");
14577 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14578 build_int_cst (TREE_TYPE (expr), 0));
14579 if (c == boolean_true_node)
14581 warning_at (loc, 0,
14582 "%qs value must be positive", str);
14583 expr = integer_one_node;
14588 if (kind == OMP_CLAUSE_GANG
14589 && c_parser_next_token_is (parser, CPP_COMMA))
14591 c_parser_consume_token (parser);
14598 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14599 goto cleanup_error;
14602 check_no_duplicate_clause (list, kind, str);
14604 c = build_omp_clause (loc, kind);
14607 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14609 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14610 OMP_CLAUSE_CHAIN (c) = list;
14615 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14627 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14630 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14632 tree c = build_omp_clause (loc, code);
14633 OMP_CLAUSE_CHAIN (c) = list;
14639 async [( int-expr )] */
14642 c_parser_oacc_clause_async (c_parser *parser, tree list)
14645 location_t loc = c_parser_peek_token (parser)->location;
14647 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14649 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14651 c_parser_consume_token (parser);
14653 t = c_parser_expr_no_commas (parser, NULL).value;
14654 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14655 c_parser_error (parser, "expected integer expression");
14656 else if (t == error_mark_node
14657 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14661 t = c_fully_fold (t, false, NULL);
14663 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14665 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14666 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14667 OMP_CLAUSE_CHAIN (c) = list;
14674 tile ( size-expr-list ) */
14677 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14679 tree c, expr = error_mark_node;
14681 tree tile = NULL_TREE;
14683 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14684 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14686 loc = c_parser_peek_token (parser)->location;
14687 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14692 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14695 if (c_parser_next_token_is (parser, CPP_MULT)
14696 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14697 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14699 c_parser_consume_token (parser);
14700 expr = integer_zero_node;
14704 location_t expr_loc = c_parser_peek_token (parser)->location;
14705 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14706 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14707 expr = cexpr.value;
14709 if (expr == error_mark_node)
14711 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14716 expr = c_fully_fold (expr, false, NULL);
14718 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14719 || !tree_fits_shwi_p (expr)
14720 || tree_to_shwi (expr) <= 0)
14722 error_at (expr_loc, "%<tile%> argument needs positive"
14723 " integral constant");
14724 expr = integer_zero_node;
14728 tile = tree_cons (NULL_TREE, expr, tile);
14730 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14732 /* Consume the trailing ')'. */
14733 c_parser_consume_token (parser);
14735 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14736 tile = nreverse (tile);
14737 OMP_CLAUSE_TILE_LIST (c) = tile;
14738 OMP_CLAUSE_CHAIN (c) = list;
14743 wait [( int-expr-list )] */
14746 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14748 location_t clause_loc = c_parser_peek_token (parser)->location;
14750 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14751 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14754 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14756 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14757 OMP_CLAUSE_CHAIN (c) = list;
14766 order ( concurrent )
14769 order ( order-modifier : concurrent )
14776 c_parser_omp_clause_order (c_parser *parser, tree list)
14778 location_t loc = c_parser_peek_token (parser)->location;
14781 bool unconstrained = false;
14782 bool reproducible = false;
14784 matching_parens parens;
14785 if (!parens.require_open (parser))
14787 if (c_parser_next_token_is (parser, CPP_NAME)
14788 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14790 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14791 if (strcmp (p, "unconstrained") == 0)
14792 unconstrained = true;
14793 else if (strcmp (p, "reproducible") == 0)
14794 reproducible = true;
14797 c_parser_error (parser, "expected %<reproducible%> or "
14798 "%<unconstrained%>");
14801 c_parser_consume_token (parser);
14802 c_parser_consume_token (parser);
14804 if (!c_parser_next_token_is (parser, CPP_NAME))
14806 c_parser_error (parser, "expected %<concurrent%>");
14809 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14810 if (strcmp (p, "concurrent") != 0)
14812 c_parser_error (parser, "expected %<concurrent%>");
14815 c_parser_consume_token (parser);
14816 parens.skip_until_found_close (parser);
14817 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
14818 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14819 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
14820 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
14821 OMP_CLAUSE_CHAIN (c) = list;
14825 parens.skip_until_found_close (parser);
14831 bind ( teams | parallel | thread ) */
14834 c_parser_omp_clause_bind (c_parser *parser, tree list)
14836 location_t loc = c_parser_peek_token (parser)->location;
14839 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14841 matching_parens parens;
14842 if (!parens.require_open (parser))
14844 if (!c_parser_next_token_is (parser, CPP_NAME))
14847 c_parser_error (parser,
14848 "expected %<teams%>, %<parallel%> or %<thread%>");
14849 parens.skip_until_found_close (parser);
14852 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14853 if (strcmp (p, "teams") == 0)
14854 kind = OMP_CLAUSE_BIND_TEAMS;
14855 else if (strcmp (p, "parallel") == 0)
14856 kind = OMP_CLAUSE_BIND_PARALLEL;
14857 else if (strcmp (p, "thread") != 0)
14859 c_parser_consume_token (parser);
14860 parens.skip_until_found_close (parser);
14861 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14862 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14863 OMP_CLAUSE_BIND_KIND (c) = kind;
14864 OMP_CLAUSE_CHAIN (c) = list;
14873 ordered ( constant-expression ) */
14876 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14878 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14880 tree c, num = NULL_TREE;
14882 location_t loc = c_parser_peek_token (parser)->location;
14883 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14885 matching_parens parens;
14886 parens.consume_open (parser);
14887 num = c_parser_expr_no_commas (parser, NULL).value;
14888 parens.skip_until_found_close (parser);
14890 if (num == error_mark_node)
14894 mark_exp_read (num);
14895 num = c_fully_fold (num, false, NULL);
14896 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14897 || !tree_fits_shwi_p (num)
14898 || (n = tree_to_shwi (num)) <= 0
14901 error_at (loc, "ordered argument needs positive "
14902 "constant integer expression");
14906 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14907 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14908 OMP_CLAUSE_CHAIN (c) = list;
14913 private ( variable-list ) */
14916 c_parser_omp_clause_private (c_parser *parser, tree list)
14918 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14922 reduction ( reduction-operator : variable-list )
14924 reduction-operator:
14925 One of: + * - & ^ | && ||
14929 reduction-operator:
14930 One of: + * - & ^ | && || max min
14934 reduction-operator:
14935 One of: + * - & ^ | && ||
14939 reduction ( reduction-modifier, reduction-operator : variable-list )
14940 in_reduction ( reduction-operator : variable-list )
14941 task_reduction ( reduction-operator : variable-list ) */
14944 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14945 bool is_omp, tree list)
14947 location_t clause_loc = c_parser_peek_token (parser)->location;
14948 matching_parens parens;
14949 if (parens.require_open (parser))
14952 bool inscan = false;
14953 enum tree_code code = ERROR_MARK;
14954 tree reduc_id = NULL_TREE;
14956 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14958 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14959 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14961 c_parser_consume_token (parser);
14962 c_parser_consume_token (parser);
14964 else if (c_parser_next_token_is (parser, CPP_NAME)
14965 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14968 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14969 if (strcmp (p, "task") == 0)
14971 else if (strcmp (p, "inscan") == 0)
14973 if (task || inscan)
14975 c_parser_consume_token (parser);
14976 c_parser_consume_token (parser);
14981 switch (c_parser_peek_token (parser)->type)
14993 code = BIT_AND_EXPR;
14996 code = BIT_XOR_EXPR;
14999 code = BIT_IOR_EXPR;
15002 code = TRUTH_ANDIF_EXPR;
15005 code = TRUTH_ORIF_EXPR;
15010 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15011 if (strcmp (p, "min") == 0)
15016 if (strcmp (p, "max") == 0)
15021 reduc_id = c_parser_peek_token (parser)->value;
15025 c_parser_error (parser,
15026 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15027 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15028 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15031 c_parser_consume_token (parser);
15032 reduc_id = c_omp_reduction_id (code, reduc_id);
15033 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15037 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
15038 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15040 tree d = OMP_CLAUSE_DECL (c), type;
15041 if (TREE_CODE (d) != TREE_LIST)
15042 type = TREE_TYPE (d);
15047 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
15049 type = TREE_TYPE (t);
15052 if (TREE_CODE (type) != POINTER_TYPE
15053 && TREE_CODE (type) != ARRAY_TYPE)
15055 type = TREE_TYPE (type);
15059 while (TREE_CODE (type) == ARRAY_TYPE)
15060 type = TREE_TYPE (type);
15061 OMP_CLAUSE_REDUCTION_CODE (c) = code;
15063 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15065 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15066 if (code == ERROR_MARK
15067 || !(INTEGRAL_TYPE_P (type)
15068 || TREE_CODE (type) == REAL_TYPE
15069 || TREE_CODE (type) == COMPLEX_TYPE))
15070 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15071 = c_omp_reduction_lookup (reduc_id,
15072 TYPE_MAIN_VARIANT (type));
15077 parens.skip_until_found_close (parser);
15083 schedule ( schedule-kind )
15084 schedule ( schedule-kind , expression )
15087 static | dynamic | guided | runtime | auto
15090 schedule ( schedule-modifier : schedule-kind )
15091 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15099 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15102 location_t loc = c_parser_peek_token (parser)->location;
15103 int modifiers = 0, nmodifiers = 0;
15105 matching_parens parens;
15106 if (!parens.require_open (parser))
15109 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15111 location_t comma = UNKNOWN_LOCATION;
15112 while (c_parser_next_token_is (parser, CPP_NAME))
15114 tree kind = c_parser_peek_token (parser)->value;
15115 const char *p = IDENTIFIER_POINTER (kind);
15116 if (strcmp ("simd", p) == 0)
15117 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15118 else if (strcmp ("monotonic", p) == 0)
15119 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15120 else if (strcmp ("nonmonotonic", p) == 0)
15121 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15124 comma = UNKNOWN_LOCATION;
15125 c_parser_consume_token (parser);
15126 if (nmodifiers++ == 0
15127 && c_parser_next_token_is (parser, CPP_COMMA))
15129 comma = c_parser_peek_token (parser)->location;
15130 c_parser_consume_token (parser);
15134 c_parser_require (parser, CPP_COLON, "expected %<:%>");
15138 if (comma != UNKNOWN_LOCATION)
15139 error_at (comma, "expected %<:%>");
15141 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15142 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15143 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15144 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15146 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15151 if (c_parser_next_token_is (parser, CPP_NAME))
15153 tree kind = c_parser_peek_token (parser)->value;
15154 const char *p = IDENTIFIER_POINTER (kind);
15159 if (strcmp ("dynamic", p) != 0)
15161 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15165 if (strcmp ("guided", p) != 0)
15167 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15171 if (strcmp ("runtime", p) != 0)
15173 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15180 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15181 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15182 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15183 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15187 c_parser_consume_token (parser);
15188 if (c_parser_next_token_is (parser, CPP_COMMA))
15191 c_parser_consume_token (parser);
15193 here = c_parser_peek_token (parser)->location;
15194 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15195 expr = convert_lvalue_to_rvalue (here, expr, false, true);
15197 t = c_fully_fold (t, false, NULL);
15199 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15200 error_at (here, "schedule %<runtime%> does not take "
15201 "a %<chunk_size%> parameter");
15202 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15204 "schedule %<auto%> does not take "
15205 "a %<chunk_size%> parameter");
15206 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15208 /* Attempt to statically determine when the number isn't
15210 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15211 build_int_cst (TREE_TYPE (t), 0));
15212 protected_set_expr_location (s, loc);
15213 if (s == boolean_true_node)
15215 warning_at (loc, 0,
15216 "chunk size value must be positive");
15217 t = integer_one_node;
15219 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15222 c_parser_error (parser, "expected integer expression");
15224 parens.skip_until_found_close (parser);
15227 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15228 "expected %<,%> or %<)%>");
15230 OMP_CLAUSE_SCHEDULE_KIND (c)
15231 = (enum omp_clause_schedule_kind)
15232 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15234 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15235 OMP_CLAUSE_CHAIN (c) = list;
15239 c_parser_error (parser, "invalid schedule kind");
15240 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15245 shared ( variable-list ) */
15248 c_parser_omp_clause_shared (c_parser *parser, tree list)
15250 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15257 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15261 /* FIXME: Should we allow duplicates? */
15262 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15264 c = build_omp_clause (c_parser_peek_token (parser)->location,
15265 OMP_CLAUSE_UNTIED);
15266 OMP_CLAUSE_CHAIN (c) = list;
15276 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15277 enum omp_clause_code code, tree list)
15279 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15281 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15282 OMP_CLAUSE_CHAIN (c) = list;
15294 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15295 enum omp_clause_code code, tree list)
15297 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15298 OMP_CLAUSE_CHAIN (c) = list;
15307 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15309 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15310 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15311 OMP_CLAUSE_NOGROUP);
15312 OMP_CLAUSE_CHAIN (c) = list;
15321 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15322 enum omp_clause_code code, tree list)
15324 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15325 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15326 OMP_CLAUSE_CHAIN (c) = list;
15331 num_teams ( expression )
15334 num_teams ( expression : expression ) */
15337 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15339 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15340 matching_parens parens;
15341 if (parens.require_open (parser))
15343 location_t upper_loc = c_parser_peek_token (parser)->location;
15344 location_t lower_loc = UNKNOWN_LOCATION;
15345 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15346 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15347 tree c, upper = expr.value, lower = NULL_TREE;
15348 upper = c_fully_fold (upper, false, NULL);
15350 if (c_parser_next_token_is (parser, CPP_COLON))
15352 c_parser_consume_token (parser);
15353 lower_loc = upper_loc;
15355 upper_loc = c_parser_peek_token (parser)->location;
15356 expr = c_parser_expr_no_commas (parser, NULL);
15357 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15358 upper = expr.value;
15359 upper = c_fully_fold (upper, false, NULL);
15362 parens.skip_until_found_close (parser);
15364 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
15365 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
15367 c_parser_error (parser, "expected integer expression");
15371 /* Attempt to statically determine when the number isn't positive. */
15372 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
15373 build_int_cst (TREE_TYPE (upper), 0));
15374 protected_set_expr_location (c, upper_loc);
15375 if (c == boolean_true_node)
15377 warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
15378 upper = integer_one_node;
15382 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
15383 build_int_cst (TREE_TYPE (lower), 0));
15384 protected_set_expr_location (c, lower_loc);
15385 if (c == boolean_true_node)
15387 warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
15390 else if (TREE_CODE (lower) == INTEGER_CST
15391 && TREE_CODE (upper) == INTEGER_CST
15392 && tree_int_cst_lt (upper, lower))
15394 warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
15395 "than upper bound %qE", lower, upper);
15400 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15402 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15403 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
15404 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
15405 OMP_CLAUSE_CHAIN (c) = list;
15413 thread_limit ( expression ) */
15416 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15418 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15419 matching_parens parens;
15420 if (parens.require_open (parser))
15422 location_t expr_loc = c_parser_peek_token (parser)->location;
15423 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15424 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15425 tree c, t = expr.value;
15426 t = c_fully_fold (t, false, NULL);
15428 parens.skip_until_found_close (parser);
15430 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15432 c_parser_error (parser, "expected integer expression");
15436 /* Attempt to statically determine when the number isn't positive. */
15437 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15438 build_int_cst (TREE_TYPE (t), 0));
15439 protected_set_expr_location (c, expr_loc);
15440 if (c == boolean_true_node)
15442 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15443 t = integer_one_node;
15446 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15449 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15450 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15451 OMP_CLAUSE_CHAIN (c) = list;
15459 aligned ( variable-list )
15460 aligned ( variable-list : constant-expression ) */
15463 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15465 location_t clause_loc = c_parser_peek_token (parser)->location;
15468 matching_parens parens;
15469 if (!parens.require_open (parser))
15472 nl = c_parser_omp_variable_list (parser, clause_loc,
15473 OMP_CLAUSE_ALIGNED, list);
15475 if (c_parser_next_token_is (parser, CPP_COLON))
15477 c_parser_consume_token (parser);
15478 location_t expr_loc = c_parser_peek_token (parser)->location;
15479 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15480 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15481 tree alignment = expr.value;
15482 alignment = c_fully_fold (alignment, false, NULL);
15483 if (TREE_CODE (alignment) != INTEGER_CST
15484 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15485 || tree_int_cst_sgn (alignment) != 1)
15487 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15488 "be positive constant integer expression");
15489 alignment = NULL_TREE;
15492 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15493 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15496 parens.skip_until_found_close (parser);
15501 allocate ( variable-list )
15502 allocate ( expression : variable-list )
15505 allocate ( allocator-modifier : variable-list )
15506 allocate ( allocator-modifier , allocator-modifier : variable-list )
15508 allocator-modifier:
15509 allocator ( expression )
15510 align ( expression ) */
15513 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15515 location_t clause_loc = c_parser_peek_token (parser)->location;
15517 tree allocator = NULL_TREE;
15518 tree align = NULL_TREE;
15520 matching_parens parens;
15521 if (!parens.require_open (parser))
15524 if ((c_parser_next_token_is_not (parser, CPP_NAME)
15525 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15526 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15527 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15529 bool has_modifiers = false;
15530 tree orig_type = NULL_TREE;
15531 if (c_parser_next_token_is (parser, CPP_NAME)
15532 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15534 unsigned int n = 3;
15536 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15537 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
15538 && c_parser_check_balanced_raw_token_sequence (parser, &n)
15539 && (c_parser_peek_nth_token_raw (parser, n)->type
15540 == CPP_CLOSE_PAREN))
15542 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15544 has_modifiers = true;
15545 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15547 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
15549 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
15550 == CPP_OPEN_PAREN))
15552 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
15553 const char *q = IDENTIFIER_POINTER (tok->value);
15555 if ((strcmp (q, "allocator") == 0
15556 || strcmp (q, "align") == 0)
15557 && c_parser_check_balanced_raw_token_sequence (parser,
15559 && (c_parser_peek_nth_token_raw (parser, n)->type
15560 == CPP_CLOSE_PAREN)
15561 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15563 has_modifiers = true;
15568 c_parser_consume_token (parser);
15569 matching_parens parens2;;
15570 parens2.require_open (parser);
15571 location_t expr_loc = c_parser_peek_token (parser)->location;
15572 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15573 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15574 if (strcmp (p, "allocator") == 0)
15576 allocator = expr.value;
15577 allocator = c_fully_fold (allocator, false, NULL);
15578 orig_type = expr.original_type
15579 ? expr.original_type : TREE_TYPE (allocator);
15580 orig_type = TYPE_MAIN_VARIANT (orig_type);
15584 align = expr.value;
15585 align = c_fully_fold (align, false, NULL);
15587 parens2.skip_until_found_close (parser);
15588 if (c_parser_next_token_is (parser, CPP_COMMA))
15590 c_parser_consume_token (parser);
15591 c_token *tok = c_parser_peek_token (parser);
15592 const char *q = "";
15593 if (c_parser_next_token_is (parser, CPP_NAME))
15594 q = IDENTIFIER_POINTER (tok->value);
15595 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
15597 c_parser_error (parser, "expected %<allocator%> or "
15599 parens.skip_until_found_close (parser);
15602 else if (strcmp (p, q) == 0)
15604 error_at (tok->location, "duplicate %qs modifier", p);
15605 parens.skip_until_found_close (parser);
15608 c_parser_consume_token (parser);
15609 if (!parens2.require_open (parser))
15611 parens.skip_until_found_close (parser);
15614 expr_loc = c_parser_peek_token (parser)->location;
15615 expr = c_parser_expr_no_commas (parser, NULL);
15616 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15618 if (strcmp (q, "allocator") == 0)
15620 allocator = expr.value;
15621 allocator = c_fully_fold (allocator, false, NULL);
15622 orig_type = expr.original_type
15623 ? expr.original_type : TREE_TYPE (allocator);
15624 orig_type = TYPE_MAIN_VARIANT (orig_type);
15628 align = expr.value;
15629 align = c_fully_fold (align, false, NULL);
15631 parens2.skip_until_found_close (parser);
15635 if (!has_modifiers)
15637 location_t expr_loc = c_parser_peek_token (parser)->location;
15638 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15639 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15640 allocator = expr.value;
15641 allocator = c_fully_fold (allocator, false, NULL);
15642 orig_type = expr.original_type
15643 ? expr.original_type : TREE_TYPE (allocator);
15644 orig_type = TYPE_MAIN_VARIANT (orig_type);
15647 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15648 || TREE_CODE (orig_type) != ENUMERAL_TYPE
15649 || (TYPE_NAME (orig_type)
15650 != get_identifier ("omp_allocator_handle_t"))))
15652 error_at (clause_loc, "%<allocate%> clause allocator expression "
15653 "has type %qT rather than "
15654 "%<omp_allocator_handle_t%>",
15655 TREE_TYPE (allocator));
15656 allocator = NULL_TREE;
15659 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
15660 || !tree_fits_uhwi_p (align)
15661 || !integer_pow2p (align)))
15663 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
15664 "argument needs to be positive constant "
15665 "power of two integer expression");
15668 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15670 parens.skip_until_found_close (parser);
15675 nl = c_parser_omp_variable_list (parser, clause_loc,
15676 OMP_CLAUSE_ALLOCATE, list);
15678 if (allocator || align)
15679 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15681 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15682 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
15685 parens.skip_until_found_close (parser);
15690 linear ( variable-list )
15691 linear ( variable-list : expression )
15694 linear ( modifier ( variable-list ) )
15695 linear ( modifier ( variable-list ) : expression )
15701 linear ( variable-list : modifiers-list )
15705 step ( expression ) */
15708 c_parser_omp_clause_linear (c_parser *parser, tree list)
15710 location_t clause_loc = c_parser_peek_token (parser)->location;
15712 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15713 bool old_linear_modifier = false;
15715 matching_parens parens;
15716 if (!parens.require_open (parser))
15719 if (c_parser_next_token_is (parser, CPP_NAME))
15721 c_token *tok = c_parser_peek_token (parser);
15722 const char *p = IDENTIFIER_POINTER (tok->value);
15723 if (strcmp ("val", p) == 0)
15724 kind = OMP_CLAUSE_LINEAR_VAL;
15725 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15726 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15727 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15729 old_linear_modifier = true;
15730 c_parser_consume_token (parser);
15731 c_parser_consume_token (parser);
15735 nl = c_parser_omp_variable_list (parser, clause_loc,
15736 OMP_CLAUSE_LINEAR, list);
15738 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15739 parens.skip_until_found_close (parser);
15741 if (c_parser_next_token_is (parser, CPP_COLON))
15743 c_parser_consume_token (parser);
15744 location_t expr_loc = c_parser_peek_token (parser)->location;
15745 bool has_modifiers = false;
15746 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
15747 && c_parser_next_token_is (parser, CPP_NAME))
15749 c_token *tok = c_parser_peek_token (parser);
15750 const char *p = IDENTIFIER_POINTER (tok->value);
15751 unsigned int pos = 0;
15752 if (strcmp ("val", p) == 0)
15754 else if (strcmp ("step", p) == 0
15755 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15758 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
15759 && (c_parser_peek_nth_token_raw (parser, pos)->type
15760 == CPP_CLOSE_PAREN))
15767 tok = c_parser_peek_nth_token_raw (parser, pos);
15768 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
15769 has_modifiers = true;
15775 while (c_parser_next_token_is (parser, CPP_NAME))
15777 c_token *tok = c_parser_peek_token (parser);
15778 const char *p = IDENTIFIER_POINTER (tok->value);
15779 if (strcmp ("val", p) == 0)
15781 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15782 error_at (tok->location, "multiple linear modifiers");
15783 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15784 c_parser_consume_token (parser);
15786 else if (strcmp ("step", p) == 0)
15788 c_parser_consume_token (parser);
15789 matching_parens parens2;
15790 if (parens2.require_open (parser))
15793 error_at (tok->location,
15794 "multiple %<step%> modifiers");
15795 expr_loc = c_parser_peek_token (parser)->location;
15796 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15797 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15799 step = c_fully_fold (expr.value, false, NULL);
15800 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15802 error_at (clause_loc, "%<linear%> clause step "
15803 "expression must be integral");
15804 step = integer_one_node;
15806 parens2.skip_until_found_close (parser);
15813 if (c_parser_next_token_is (parser, CPP_COMMA))
15815 c_parser_consume_token (parser);
15821 step = integer_one_node;
15825 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15826 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15827 step = c_fully_fold (expr.value, false, NULL);
15828 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15830 error_at (clause_loc, "%<linear%> clause step expression must "
15832 step = integer_one_node;
15838 step = integer_one_node;
15840 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15842 OMP_CLAUSE_LINEAR_STEP (c) = step;
15843 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15844 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
15847 parens.skip_until_found_close (parser);
15852 nontemporal ( variable-list ) */
15855 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15857 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15861 safelen ( constant-expression ) */
15864 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15866 location_t clause_loc = c_parser_peek_token (parser)->location;
15869 matching_parens parens;
15870 if (!parens.require_open (parser))
15873 location_t expr_loc = c_parser_peek_token (parser)->location;
15874 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15875 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15877 t = c_fully_fold (t, false, NULL);
15878 if (TREE_CODE (t) != INTEGER_CST
15879 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15880 || tree_int_cst_sgn (t) != 1)
15882 error_at (clause_loc, "%<safelen%> clause expression must "
15883 "be positive constant integer expression");
15887 parens.skip_until_found_close (parser);
15888 if (t == NULL_TREE || t == error_mark_node)
15891 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15893 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15894 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15895 OMP_CLAUSE_CHAIN (c) = list;
15900 simdlen ( constant-expression ) */
15903 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15905 location_t clause_loc = c_parser_peek_token (parser)->location;
15908 matching_parens parens;
15909 if (!parens.require_open (parser))
15912 location_t expr_loc = c_parser_peek_token (parser)->location;
15913 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15914 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15916 t = c_fully_fold (t, false, NULL);
15917 if (TREE_CODE (t) != INTEGER_CST
15918 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15919 || tree_int_cst_sgn (t) != 1)
15921 error_at (clause_loc, "%<simdlen%> clause expression must "
15922 "be positive constant integer expression");
15926 parens.skip_until_found_close (parser);
15927 if (t == NULL_TREE || t == error_mark_node)
15930 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15932 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15933 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15934 OMP_CLAUSE_CHAIN (c) = list;
15940 identifier [+/- integer]
15941 vec , identifier [+/- integer]
15945 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15949 if (c_parser_next_token_is_not (parser, CPP_NAME)
15950 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15952 c_parser_error (parser, "expected identifier");
15956 while (c_parser_next_token_is (parser, CPP_NAME)
15957 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15959 tree t = lookup_name (c_parser_peek_token (parser)->value);
15960 tree addend = NULL;
15962 if (t == NULL_TREE)
15964 undeclared_variable (c_parser_peek_token (parser)->location,
15965 c_parser_peek_token (parser)->value);
15966 t = error_mark_node;
15969 c_parser_consume_token (parser);
15972 if (c_parser_next_token_is (parser, CPP_MINUS))
15974 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15976 addend = integer_zero_node;
15978 goto add_to_vector;
15980 c_parser_consume_token (parser);
15982 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15984 c_parser_error (parser, "expected integer");
15988 addend = c_parser_peek_token (parser)->value;
15989 if (TREE_CODE (addend) != INTEGER_CST)
15991 c_parser_error (parser, "expected integer");
15994 c_parser_consume_token (parser);
15997 if (t != error_mark_node)
15999 vec = tree_cons (addend, t, vec);
16001 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
16004 if (c_parser_next_token_is_not (parser, CPP_COMMA)
16005 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
16006 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
16009 c_parser_consume_token (parser);
16012 if (vec == NULL_TREE)
16015 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
16016 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
16017 OMP_CLAUSE_DECL (u) = nreverse (vec);
16018 OMP_CLAUSE_CHAIN (u) = list;
16023 iterators ( iterators-definition )
16025 iterators-definition:
16027 iterator-specifier , iterators-definition
16029 iterator-specifier:
16030 identifier = range-specification
16031 iterator-type identifier = range-specification
16033 range-specification:
16035 begin : end : step */
16038 c_parser_omp_iterators (c_parser *parser)
16040 tree ret = NULL_TREE, *last = &ret;
16041 c_parser_consume_token (parser);
16045 matching_parens parens;
16046 if (!parens.require_open (parser))
16047 return error_mark_node;
16051 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
16052 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
16054 struct c_type_name *type = c_parser_type_name (parser);
16056 iter_type = groktypename (type, &type_expr, NULL);
16058 if (iter_type == NULL_TREE)
16059 iter_type = integer_type_node;
16061 location_t loc = c_parser_peek_token (parser)->location;
16062 if (!c_parser_next_token_is (parser, CPP_NAME))
16064 c_parser_error (parser, "expected identifier");
16068 tree id = c_parser_peek_token (parser)->value;
16069 c_parser_consume_token (parser);
16071 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16074 location_t eloc = c_parser_peek_token (parser)->location;
16075 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16076 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16077 tree begin = expr.value;
16079 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16082 eloc = c_parser_peek_token (parser)->location;
16083 expr = c_parser_expr_no_commas (parser, NULL);
16084 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16085 tree end = expr.value;
16087 tree step = integer_one_node;
16088 if (c_parser_next_token_is (parser, CPP_COLON))
16090 c_parser_consume_token (parser);
16091 eloc = c_parser_peek_token (parser)->location;
16092 expr = c_parser_expr_no_commas (parser, NULL);
16093 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16097 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
16098 DECL_ARTIFICIAL (iter_var) = 1;
16099 DECL_CONTEXT (iter_var) = current_function_decl;
16100 pushdecl (iter_var);
16102 *last = make_tree_vec (6);
16103 TREE_VEC_ELT (*last, 0) = iter_var;
16104 TREE_VEC_ELT (*last, 1) = begin;
16105 TREE_VEC_ELT (*last, 2) = end;
16106 TREE_VEC_ELT (*last, 3) = step;
16107 last = &TREE_CHAIN (*last);
16109 if (c_parser_next_token_is (parser, CPP_COMMA))
16111 c_parser_consume_token (parser);
16118 parens.skip_until_found_close (parser);
16119 return ret ? ret : error_mark_node;
16123 affinity ( [aff-modifier :] variable-list )
16125 iterator ( iterators-definition ) */
16128 c_parser_omp_clause_affinity (c_parser *parser, tree list)
16130 location_t clause_loc = c_parser_peek_token (parser)->location;
16131 tree nl, iterators = NULL_TREE;
16133 matching_parens parens;
16134 if (!parens.require_open (parser))
16137 if (c_parser_next_token_is (parser, CPP_NAME))
16139 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16140 bool parse_iter = ((strcmp ("iterator", p) == 0)
16141 && (c_parser_peek_2nd_token (parser)->type
16142 == CPP_OPEN_PAREN));
16146 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
16147 && (c_parser_peek_nth_token_raw (parser, n)->type
16148 == CPP_CLOSE_PAREN)
16149 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
16154 iterators = c_parser_omp_iterators (parser);
16155 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16159 parens.skip_until_found_close (parser);
16164 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16168 tree block = pop_scope ();
16169 if (iterators != error_mark_node)
16171 TREE_VEC_ELT (iterators, 5) = block;
16172 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16173 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16174 OMP_CLAUSE_DECL (c));
16178 parens.skip_until_found_close (parser);
16184 depend ( depend-kind: variable-list )
16192 depend ( sink : vec )
16195 depend ( depend-modifier , depend-kind: variable-list )
16198 in | out | inout | mutexinoutset | depobj | inoutset
16201 iterator ( iterators-definition ) */
16204 c_parser_omp_clause_depend (c_parser *parser, tree list)
16206 location_t clause_loc = c_parser_peek_token (parser)->location;
16207 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16208 tree nl, c, iterators = NULL_TREE;
16210 matching_parens parens;
16211 if (!parens.require_open (parser))
16216 if (c_parser_next_token_is_not (parser, CPP_NAME))
16219 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16220 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16222 iterators = c_parser_omp_iterators (parser);
16223 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16226 if (strcmp ("in", p) == 0)
16227 kind = OMP_CLAUSE_DEPEND_IN;
16228 else if (strcmp ("inout", p) == 0)
16229 kind = OMP_CLAUSE_DEPEND_INOUT;
16230 else if (strcmp ("inoutset", p) == 0)
16231 kind = OMP_CLAUSE_DEPEND_INOUTSET;
16232 else if (strcmp ("mutexinoutset", p) == 0)
16233 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16234 else if (strcmp ("out", p) == 0)
16235 kind = OMP_CLAUSE_DEPEND_OUT;
16236 else if (strcmp ("depobj", p) == 0)
16237 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16238 else if (strcmp ("sink", p) == 0)
16239 kind = OMP_CLAUSE_DEPEND_SINK;
16240 else if (strcmp ("source", p) == 0)
16241 kind = OMP_CLAUSE_DEPEND_SOURCE;
16248 c_parser_consume_token (parser);
16251 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
16254 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16255 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
16256 iterators = NULL_TREE;
16259 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
16261 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
16262 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16263 OMP_CLAUSE_DECL (c) = NULL_TREE;
16264 OMP_CLAUSE_CHAIN (c) = list;
16265 parens.skip_until_found_close (parser);
16269 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16272 if (kind == OMP_CLAUSE_DEPEND_SINK)
16273 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
16276 nl = c_parser_omp_variable_list (parser, clause_loc,
16277 OMP_CLAUSE_DEPEND, list);
16281 tree block = pop_scope ();
16282 if (iterators == error_mark_node)
16283 iterators = NULL_TREE;
16285 TREE_VEC_ELT (iterators, 5) = block;
16288 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16290 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16292 OMP_CLAUSE_DECL (c)
16293 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16297 parens.skip_until_found_close (parser);
16301 c_parser_error (parser, "invalid depend kind");
16303 parens.skip_until_found_close (parser);
16310 map ( map-kind: variable-list )
16311 map ( variable-list )
16314 alloc | to | from | tofrom
16318 alloc | to | from | tofrom | release | delete
16320 map ( always [,] map-kind: variable-list )
16323 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16329 c_parser_omp_clause_map (c_parser *parser, tree list)
16331 location_t clause_loc = c_parser_peek_token (parser)->location;
16332 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
16335 matching_parens parens;
16336 if (!parens.require_open (parser))
16340 int map_kind_pos = 0;
16341 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
16343 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
16345 map_kind_pos = pos;
16349 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
16354 int always_modifier = 0;
16355 int close_modifier = 0;
16356 for (int pos = 1; pos < map_kind_pos; ++pos)
16358 c_token *tok = c_parser_peek_token (parser);
16360 if (tok->type == CPP_COMMA)
16362 c_parser_consume_token (parser);
16366 const char *p = IDENTIFIER_POINTER (tok->value);
16367 if (strcmp ("always", p) == 0)
16369 if (always_modifier)
16371 c_parser_error (parser, "too many %<always%> modifiers");
16372 parens.skip_until_found_close (parser);
16377 else if (strcmp ("close", p) == 0)
16379 if (close_modifier)
16381 c_parser_error (parser, "too many %<close%> modifiers");
16382 parens.skip_until_found_close (parser);
16389 c_parser_error (parser, "%<#pragma omp target%> with "
16390 "modifier other than %<always%> or "
16391 "%<close%> on %<map%> clause");
16392 parens.skip_until_found_close (parser);
16396 c_parser_consume_token (parser);
16399 if (c_parser_next_token_is (parser, CPP_NAME)
16400 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16402 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16403 if (strcmp ("alloc", p) == 0)
16404 kind = GOMP_MAP_ALLOC;
16405 else if (strcmp ("to", p) == 0)
16406 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
16407 else if (strcmp ("from", p) == 0)
16408 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
16409 else if (strcmp ("tofrom", p) == 0)
16410 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
16411 else if (strcmp ("release", p) == 0)
16412 kind = GOMP_MAP_RELEASE;
16413 else if (strcmp ("delete", p) == 0)
16414 kind = GOMP_MAP_DELETE;
16417 c_parser_error (parser, "invalid map kind");
16418 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16422 c_parser_consume_token (parser);
16423 c_parser_consume_token (parser);
16426 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
16429 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16430 OMP_CLAUSE_SET_MAP_KIND (c, kind);
16432 parens.skip_until_found_close (parser);
16437 device ( expression )
16440 device ( [device-modifier :] integer-expression )
16443 ancestor | device_num */
16446 c_parser_omp_clause_device (c_parser *parser, tree list)
16448 location_t clause_loc = c_parser_peek_token (parser)->location;
16449 location_t expr_loc;
16452 bool ancestor = false;
16454 matching_parens parens;
16455 if (!parens.require_open (parser))
16458 if (c_parser_next_token_is (parser, CPP_NAME)
16459 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16461 c_token *tok = c_parser_peek_token (parser);
16462 const char *p = IDENTIFIER_POINTER (tok->value);
16463 if (strcmp ("ancestor", p) == 0)
16465 /* A requires directive with the reverse_offload clause must be
16467 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
16469 error_at (tok->location, "%<ancestor%> device modifier not "
16470 "preceded by %<requires%> directive "
16471 "with %<reverse_offload%> clause");
16472 parens.skip_until_found_close (parser);
16477 else if (strcmp ("device_num", p) == 0)
16481 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
16482 parens.skip_until_found_close (parser);
16485 c_parser_consume_token (parser);
16486 c_parser_consume_token (parser);
16489 expr_loc = c_parser_peek_token (parser)->location;
16490 expr = c_parser_expr_no_commas (parser, NULL);
16491 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16493 t = c_fully_fold (t, false, NULL);
16495 parens.skip_until_found_close (parser);
16497 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16499 c_parser_error (parser, "expected integer expression");
16502 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
16504 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
16509 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
16511 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
16513 OMP_CLAUSE_DEVICE_ID (c) = t;
16514 OMP_CLAUSE_CHAIN (c) = list;
16515 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
16522 dist_schedule ( static )
16523 dist_schedule ( static , expression ) */
16526 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
16528 tree c, t = NULL_TREE;
16529 location_t loc = c_parser_peek_token (parser)->location;
16531 matching_parens parens;
16532 if (!parens.require_open (parser))
16535 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
16537 c_parser_error (parser, "invalid dist_schedule kind");
16538 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16543 c_parser_consume_token (parser);
16544 if (c_parser_next_token_is (parser, CPP_COMMA))
16546 c_parser_consume_token (parser);
16548 location_t expr_loc = c_parser_peek_token (parser)->location;
16549 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16550 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16552 t = c_fully_fold (t, false, NULL);
16553 parens.skip_until_found_close (parser);
16556 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16557 "expected %<,%> or %<)%>");
16559 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16560 "dist_schedule"); */
16561 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
16562 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
16563 if (t == error_mark_node)
16566 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
16567 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
16568 OMP_CLAUSE_CHAIN (c) = list;
16573 proc_bind ( proc-bind-kind )
16576 primary | master | close | spread
16577 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16580 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16582 location_t clause_loc = c_parser_peek_token (parser)->location;
16583 enum omp_clause_proc_bind_kind kind;
16586 matching_parens parens;
16587 if (!parens.require_open (parser))
16590 if (c_parser_next_token_is (parser, CPP_NAME))
16592 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16593 if (strcmp ("primary", p) == 0)
16594 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16595 else if (strcmp ("master", p) == 0)
16596 kind = OMP_CLAUSE_PROC_BIND_MASTER;
16597 else if (strcmp ("close", p) == 0)
16598 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16599 else if (strcmp ("spread", p) == 0)
16600 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16607 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16608 c_parser_consume_token (parser);
16609 parens.skip_until_found_close (parser);
16610 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16611 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16612 OMP_CLAUSE_CHAIN (c) = list;
16616 c_parser_error (parser, "invalid proc_bind kind");
16617 parens.skip_until_found_close (parser);
16622 device_type ( host | nohost | any ) */
16625 c_parser_omp_clause_device_type (c_parser *parser, tree list)
16627 location_t clause_loc = c_parser_peek_token (parser)->location;
16628 enum omp_clause_device_type_kind kind;
16631 matching_parens parens;
16632 if (!parens.require_open (parser))
16635 if (c_parser_next_token_is (parser, CPP_NAME))
16637 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16638 if (strcmp ("host", p) == 0)
16639 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
16640 else if (strcmp ("nohost", p) == 0)
16641 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
16642 else if (strcmp ("any", p) == 0)
16643 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
16650 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16652 c_parser_consume_token (parser);
16653 parens.skip_until_found_close (parser);
16654 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
16655 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
16656 OMP_CLAUSE_CHAIN (c) = list;
16660 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
16661 parens.skip_until_found_close (parser);
16666 to ( variable-list ) */
16669 c_parser_omp_clause_to (c_parser *parser, tree list)
16671 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
16675 from ( variable-list ) */
16678 c_parser_omp_clause_from (c_parser *parser, tree list)
16680 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
16684 uniform ( variable-list ) */
16687 c_parser_omp_clause_uniform (c_parser *parser, tree list)
16689 /* The clauses location. */
16690 location_t loc = c_parser_peek_token (parser)->location;
16692 matching_parens parens;
16693 if (parens.require_open (parser))
16695 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
16697 parens.skip_until_found_close (parser);
16703 detach ( event-handle ) */
16706 c_parser_omp_clause_detach (c_parser *parser, tree list)
16708 matching_parens parens;
16709 location_t clause_loc = c_parser_peek_token (parser)->location;
16711 if (!parens.require_open (parser))
16714 if (c_parser_next_token_is_not (parser, CPP_NAME)
16715 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16717 c_parser_error (parser, "expected identifier");
16718 parens.skip_until_found_close (parser);
16722 tree t = lookup_name (c_parser_peek_token (parser)->value);
16723 if (t == NULL_TREE)
16725 undeclared_variable (c_parser_peek_token (parser)->location,
16726 c_parser_peek_token (parser)->value);
16727 parens.skip_until_found_close (parser);
16730 c_parser_consume_token (parser);
16732 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16733 if (!INTEGRAL_TYPE_P (type)
16734 || TREE_CODE (type) != ENUMERAL_TYPE
16735 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16737 error_at (clause_loc, "%<detach%> clause event handle "
16738 "has type %qT rather than "
16739 "%<omp_event_handle_t%>",
16741 parens.skip_until_found_close (parser);
16745 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16746 OMP_CLAUSE_DECL (u) = t;
16747 OMP_CLAUSE_CHAIN (u) = list;
16748 parens.skip_until_found_close (parser);
16752 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16753 is a bitmask in MASK. Return the list of clauses found. */
16756 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16757 const char *where, bool finish_p = true)
16759 tree clauses = NULL;
16762 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16765 pragma_omp_clause c_kind;
16766 const char *c_name;
16767 tree prev = clauses;
16769 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16770 c_parser_consume_token (parser);
16772 here = c_parser_peek_token (parser)->location;
16773 c_kind = c_parser_omp_clause_name (parser);
16777 case PRAGMA_OACC_CLAUSE_ASYNC:
16778 clauses = c_parser_oacc_clause_async (parser, clauses);
16781 case PRAGMA_OACC_CLAUSE_AUTO:
16782 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16786 case PRAGMA_OACC_CLAUSE_ATTACH:
16787 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16790 case PRAGMA_OACC_CLAUSE_COLLAPSE:
16791 clauses = c_parser_omp_clause_collapse (parser, clauses);
16792 c_name = "collapse";
16794 case PRAGMA_OACC_CLAUSE_COPY:
16795 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16798 case PRAGMA_OACC_CLAUSE_COPYIN:
16799 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16802 case PRAGMA_OACC_CLAUSE_COPYOUT:
16803 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16804 c_name = "copyout";
16806 case PRAGMA_OACC_CLAUSE_CREATE:
16807 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16810 case PRAGMA_OACC_CLAUSE_DELETE:
16811 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16814 case PRAGMA_OMP_CLAUSE_DEFAULT:
16815 clauses = c_parser_omp_clause_default (parser, clauses, true);
16816 c_name = "default";
16818 case PRAGMA_OACC_CLAUSE_DETACH:
16819 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16822 case PRAGMA_OACC_CLAUSE_DEVICE:
16823 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16826 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16827 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16828 c_name = "deviceptr";
16830 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16831 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16832 c_name = "device_resident";
16834 case PRAGMA_OACC_CLAUSE_FINALIZE:
16835 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16837 c_name = "finalize";
16839 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16840 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16841 c_name = "firstprivate";
16843 case PRAGMA_OACC_CLAUSE_GANG:
16845 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16848 case PRAGMA_OACC_CLAUSE_HOST:
16849 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16852 case PRAGMA_OACC_CLAUSE_IF:
16853 clauses = c_parser_omp_clause_if (parser, clauses, false);
16856 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16857 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16859 c_name = "if_present";
16861 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16862 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16864 c_name = "independent";
16866 case PRAGMA_OACC_CLAUSE_LINK:
16867 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16870 case PRAGMA_OACC_CLAUSE_NO_CREATE:
16871 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16872 c_name = "no_create";
16874 case PRAGMA_OACC_CLAUSE_NOHOST:
16875 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
16879 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16880 clauses = c_parser_oacc_single_int_clause (parser,
16881 OMP_CLAUSE_NUM_GANGS,
16883 c_name = "num_gangs";
16885 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16886 clauses = c_parser_oacc_single_int_clause (parser,
16887 OMP_CLAUSE_NUM_WORKERS,
16889 c_name = "num_workers";
16891 case PRAGMA_OACC_CLAUSE_PRESENT:
16892 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16893 c_name = "present";
16895 case PRAGMA_OACC_CLAUSE_PRIVATE:
16896 clauses = c_parser_omp_clause_private (parser, clauses);
16897 c_name = "private";
16899 case PRAGMA_OACC_CLAUSE_REDUCTION:
16901 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16903 c_name = "reduction";
16905 case PRAGMA_OACC_CLAUSE_SEQ:
16906 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16910 case PRAGMA_OACC_CLAUSE_TILE:
16911 clauses = c_parser_oacc_clause_tile (parser, clauses);
16914 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16915 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16916 c_name = "use_device";
16918 case PRAGMA_OACC_CLAUSE_VECTOR:
16920 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16923 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16924 clauses = c_parser_oacc_single_int_clause (parser,
16925 OMP_CLAUSE_VECTOR_LENGTH,
16927 c_name = "vector_length";
16929 case PRAGMA_OACC_CLAUSE_WAIT:
16930 clauses = c_parser_oacc_clause_wait (parser, clauses);
16933 case PRAGMA_OACC_CLAUSE_WORKER:
16935 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16939 c_parser_error (parser, "expected %<#pragma acc%> clause");
16945 if (((mask >> c_kind) & 1) == 0)
16947 /* Remove the invalid clause(s) from the list to avoid
16948 confusing the rest of the compiler. */
16950 error_at (here, "%qs is not valid for %qs", c_name, where);
16955 c_parser_skip_to_pragma_eol (parser);
16958 return c_finish_omp_clauses (clauses, C_ORT_ACC);
16963 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16964 is a bitmask in MASK. Return the list of clauses found.
16965 FINISH_P set if c_finish_omp_clauses should be called.
16966 NESTED non-zero if clauses should be terminated by closing paren instead
16967 of end of pragma. If it is 2, additionally commas are required in between
16971 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16972 const char *where, bool finish_p = true,
16975 tree clauses = NULL;
16978 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16981 pragma_omp_clause c_kind;
16982 const char *c_name;
16983 tree prev = clauses;
16985 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16990 if (c_parser_next_token_is (parser, CPP_COMMA))
16991 c_parser_consume_token (parser);
16992 else if (nested == 2)
16993 error_at (c_parser_peek_token (parser)->location,
16994 "clauses in %<simd%> trait should be separated "
16998 here = c_parser_peek_token (parser)->location;
16999 c_kind = c_parser_omp_clause_name (parser);
17003 case PRAGMA_OMP_CLAUSE_BIND:
17004 clauses = c_parser_omp_clause_bind (parser, clauses);
17007 case PRAGMA_OMP_CLAUSE_COLLAPSE:
17008 clauses = c_parser_omp_clause_collapse (parser, clauses);
17009 c_name = "collapse";
17011 case PRAGMA_OMP_CLAUSE_COPYIN:
17012 clauses = c_parser_omp_clause_copyin (parser, clauses);
17015 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
17016 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
17017 c_name = "copyprivate";
17019 case PRAGMA_OMP_CLAUSE_DEFAULT:
17020 clauses = c_parser_omp_clause_default (parser, clauses, false);
17021 c_name = "default";
17023 case PRAGMA_OMP_CLAUSE_DETACH:
17024 clauses = c_parser_omp_clause_detach (parser, clauses);
17027 case PRAGMA_OMP_CLAUSE_FILTER:
17028 clauses = c_parser_omp_clause_filter (parser, clauses);
17031 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
17032 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
17033 c_name = "firstprivate";
17035 case PRAGMA_OMP_CLAUSE_FINAL:
17036 clauses = c_parser_omp_clause_final (parser, clauses);
17039 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
17040 clauses = c_parser_omp_clause_grainsize (parser, clauses);
17041 c_name = "grainsize";
17043 case PRAGMA_OMP_CLAUSE_HINT:
17044 clauses = c_parser_omp_clause_hint (parser, clauses);
17047 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
17048 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
17049 c_name = "defaultmap";
17051 case PRAGMA_OMP_CLAUSE_IF:
17052 clauses = c_parser_omp_clause_if (parser, clauses, true);
17055 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
17057 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
17059 c_name = "in_reduction";
17061 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
17062 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
17063 c_name = "lastprivate";
17065 case PRAGMA_OMP_CLAUSE_MERGEABLE:
17066 clauses = c_parser_omp_clause_mergeable (parser, clauses);
17067 c_name = "mergeable";
17069 case PRAGMA_OMP_CLAUSE_NOWAIT:
17070 clauses = c_parser_omp_clause_nowait (parser, clauses);
17073 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
17074 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
17075 c_name = "num_tasks";
17077 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
17078 clauses = c_parser_omp_clause_num_threads (parser, clauses);
17079 c_name = "num_threads";
17081 case PRAGMA_OMP_CLAUSE_ORDER:
17082 clauses = c_parser_omp_clause_order (parser, clauses);
17085 case PRAGMA_OMP_CLAUSE_ORDERED:
17086 clauses = c_parser_omp_clause_ordered (parser, clauses);
17087 c_name = "ordered";
17089 case PRAGMA_OMP_CLAUSE_PRIORITY:
17090 clauses = c_parser_omp_clause_priority (parser, clauses);
17091 c_name = "priority";
17093 case PRAGMA_OMP_CLAUSE_PRIVATE:
17094 clauses = c_parser_omp_clause_private (parser, clauses);
17095 c_name = "private";
17097 case PRAGMA_OMP_CLAUSE_REDUCTION:
17099 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17101 c_name = "reduction";
17103 case PRAGMA_OMP_CLAUSE_SCHEDULE:
17104 clauses = c_parser_omp_clause_schedule (parser, clauses);
17105 c_name = "schedule";
17107 case PRAGMA_OMP_CLAUSE_SHARED:
17108 clauses = c_parser_omp_clause_shared (parser, clauses);
17111 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
17113 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
17115 c_name = "task_reduction";
17117 case PRAGMA_OMP_CLAUSE_UNTIED:
17118 clauses = c_parser_omp_clause_untied (parser, clauses);
17121 case PRAGMA_OMP_CLAUSE_INBRANCH:
17122 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
17124 c_name = "inbranch";
17126 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
17127 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
17128 c_name = "nontemporal";
17130 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
17131 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
17133 c_name = "notinbranch";
17135 case PRAGMA_OMP_CLAUSE_PARALLEL:
17137 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
17139 c_name = "parallel";
17143 error_at (here, "%qs must be the first clause of %qs",
17148 case PRAGMA_OMP_CLAUSE_FOR:
17150 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
17154 goto clause_not_first;
17156 case PRAGMA_OMP_CLAUSE_SECTIONS:
17158 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17160 c_name = "sections";
17162 goto clause_not_first;
17164 case PRAGMA_OMP_CLAUSE_TASKGROUP:
17166 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17168 c_name = "taskgroup";
17170 goto clause_not_first;
17172 case PRAGMA_OMP_CLAUSE_LINK:
17174 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17177 case PRAGMA_OMP_CLAUSE_TO:
17178 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17180 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17182 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
17183 OMP_CLAUSE_ENTER_TO (c) = 1;
17187 clauses = c_parser_omp_clause_to (parser, clauses);
17190 case PRAGMA_OMP_CLAUSE_FROM:
17191 clauses = c_parser_omp_clause_from (parser, clauses);
17194 case PRAGMA_OMP_CLAUSE_UNIFORM:
17195 clauses = c_parser_omp_clause_uniform (parser, clauses);
17196 c_name = "uniform";
17198 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17199 clauses = c_parser_omp_clause_num_teams (parser, clauses);
17200 c_name = "num_teams";
17202 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17203 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17204 c_name = "thread_limit";
17206 case PRAGMA_OMP_CLAUSE_ALIGNED:
17207 clauses = c_parser_omp_clause_aligned (parser, clauses);
17208 c_name = "aligned";
17210 case PRAGMA_OMP_CLAUSE_ALLOCATE:
17211 clauses = c_parser_omp_clause_allocate (parser, clauses);
17212 c_name = "allocate";
17214 case PRAGMA_OMP_CLAUSE_LINEAR:
17215 clauses = c_parser_omp_clause_linear (parser, clauses);
17218 case PRAGMA_OMP_CLAUSE_AFFINITY:
17219 clauses = c_parser_omp_clause_affinity (parser, clauses);
17220 c_name = "affinity";
17222 case PRAGMA_OMP_CLAUSE_DEPEND:
17223 clauses = c_parser_omp_clause_depend (parser, clauses);
17226 case PRAGMA_OMP_CLAUSE_MAP:
17227 clauses = c_parser_omp_clause_map (parser, clauses);
17230 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17231 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17232 c_name = "use_device_ptr";
17234 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17235 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17236 c_name = "use_device_addr";
17238 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17239 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17240 c_name = "has_device_addr";
17242 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17243 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17244 c_name = "is_device_ptr";
17246 case PRAGMA_OMP_CLAUSE_DEVICE:
17247 clauses = c_parser_omp_clause_device (parser, clauses);
17250 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
17251 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
17252 c_name = "dist_schedule";
17254 case PRAGMA_OMP_CLAUSE_PROC_BIND:
17255 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
17256 c_name = "proc_bind";
17258 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
17259 clauses = c_parser_omp_clause_device_type (parser, clauses);
17260 c_name = "device_type";
17262 case PRAGMA_OMP_CLAUSE_SAFELEN:
17263 clauses = c_parser_omp_clause_safelen (parser, clauses);
17264 c_name = "safelen";
17266 case PRAGMA_OMP_CLAUSE_SIMDLEN:
17267 clauses = c_parser_omp_clause_simdlen (parser, clauses);
17268 c_name = "simdlen";
17270 case PRAGMA_OMP_CLAUSE_NOGROUP:
17271 clauses = c_parser_omp_clause_nogroup (parser, clauses);
17272 c_name = "nogroup";
17274 case PRAGMA_OMP_CLAUSE_THREADS:
17276 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
17278 c_name = "threads";
17280 case PRAGMA_OMP_CLAUSE_SIMD:
17282 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
17286 case PRAGMA_OMP_CLAUSE_ENTER:
17288 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17293 c_parser_error (parser, "expected %<#pragma omp%> clause");
17299 if (((mask >> c_kind) & 1) == 0)
17301 /* Remove the invalid clause(s) from the list to avoid
17302 confusing the rest of the compiler. */
17304 error_at (here, "%qs is not valid for %qs", c_name, where);
17310 c_parser_skip_to_pragma_eol (parser);
17314 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
17315 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
17316 return c_finish_omp_clauses (clauses, C_ORT_OMP);
17322 /* OpenACC 2.0, OpenMP 2.5:
17326 In practice, we're also interested in adding the statement to an
17327 outer node. So it is convenient if we work around the fact that
17328 c_parser_statement calls add_stmt. */
17331 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
17333 tree stmt = push_stmt_list ();
17334 c_parser_statement (parser, if_p);
17335 return pop_stmt_list (stmt);
17339 # pragma acc cache (variable-list) new-line
17341 LOC is the location of the #pragma token.
17345 c_parser_oacc_cache (location_t loc, c_parser *parser)
17347 tree stmt, clauses;
17349 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
17350 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17352 c_parser_skip_to_pragma_eol (parser);
17354 stmt = make_node (OACC_CACHE);
17355 TREE_TYPE (stmt) = void_type_node;
17356 OACC_CACHE_CLAUSES (stmt) = clauses;
17357 SET_EXPR_LOCATION (stmt, loc);
17364 # pragma acc data oacc-data-clause[optseq] new-line
17367 LOC is the location of the #pragma token.
17370 #define OACC_DATA_CLAUSE_MASK \
17371 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17372 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17373 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17374 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17375 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17376 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17377 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17378 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17382 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
17384 tree stmt, clauses, block;
17386 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
17387 "#pragma acc data");
17389 block = c_begin_omp_parallel ();
17390 add_stmt (c_parser_omp_structured_block (parser, if_p));
17392 stmt = c_finish_oacc_data (loc, clauses, block);
17398 # pragma acc declare oacc-data-clause[optseq] new-line
17401 #define OACC_DECLARE_CLAUSE_MASK \
17402 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17404 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17412 c_parser_oacc_declare (c_parser *parser)
17414 location_t pragma_loc = c_parser_peek_token (parser)->location;
17415 tree clauses, stmt, t, decl;
17417 bool error = false;
17419 c_parser_consume_pragma (parser);
17421 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
17422 "#pragma acc declare");
17425 error_at (pragma_loc,
17426 "no valid clauses specified in %<#pragma acc declare%>");
17430 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
17432 location_t loc = OMP_CLAUSE_LOCATION (t);
17433 decl = OMP_CLAUSE_DECL (t);
17434 if (!DECL_P (decl))
17436 error_at (loc, "array section in %<#pragma acc declare%>");
17441 switch (OMP_CLAUSE_MAP_KIND (t))
17443 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17444 case GOMP_MAP_ALLOC:
17446 case GOMP_MAP_FORCE_DEVICEPTR:
17447 case GOMP_MAP_DEVICE_RESIDENT:
17450 case GOMP_MAP_LINK:
17451 if (!global_bindings_p ()
17452 && (TREE_STATIC (decl)
17453 || !DECL_EXTERNAL (decl)))
17456 "%qD must be a global variable in "
17457 "%<#pragma acc declare link%>",
17465 if (global_bindings_p ())
17467 error_at (loc, "invalid OpenACC clause at file scope");
17471 if (DECL_EXTERNAL (decl))
17474 "invalid use of %<extern%> variable %qD "
17475 "in %<#pragma acc declare%>", decl);
17479 else if (TREE_PUBLIC (decl))
17482 "invalid use of %<global%> variable %qD "
17483 "in %<#pragma acc declare%>", decl);
17490 if (!c_check_in_current_scope (decl))
17493 "%qD must be a variable declared in the same scope as "
17494 "%<#pragma acc declare%>", decl);
17499 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
17500 || lookup_attribute ("omp declare target link",
17501 DECL_ATTRIBUTES (decl)))
17503 error_at (loc, "variable %qD used more than once with "
17504 "%<#pragma acc declare%>", decl);
17513 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
17514 id = get_identifier ("omp declare target link");
17516 id = get_identifier ("omp declare target");
17518 DECL_ATTRIBUTES (decl)
17519 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
17521 if (global_bindings_p ())
17523 symtab_node *node = symtab_node::get (decl);
17526 node->offloadable = 1;
17527 if (ENABLE_OFFLOADING)
17529 g->have_offload = true;
17530 if (is_a <varpool_node *> (node))
17531 vec_safe_push (offload_vars, decl);
17538 if (error || global_bindings_p ())
17541 stmt = make_node (OACC_DECLARE);
17542 TREE_TYPE (stmt) = void_type_node;
17543 OACC_DECLARE_CLAUSES (stmt) = clauses;
17544 SET_EXPR_LOCATION (stmt, pragma_loc);
17552 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17556 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17559 LOC is the location of the #pragma token.
17562 #define OACC_ENTER_DATA_CLAUSE_MASK \
17563 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17567 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17570 #define OACC_EXIT_DATA_CLAUSE_MASK \
17571 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17580 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
17582 location_t loc = c_parser_peek_token (parser)->location;
17583 tree clauses, stmt;
17584 const char *p = "";
17586 c_parser_consume_pragma (parser);
17588 if (c_parser_next_token_is (parser, CPP_NAME))
17590 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17591 c_parser_consume_token (parser);
17594 if (strcmp (p, "data") != 0)
17596 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17597 enter ? "enter" : "exit");
17598 parser->error = true;
17599 c_parser_skip_to_pragma_eol (parser);
17604 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17605 "#pragma acc enter data");
17607 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17608 "#pragma acc exit data");
17610 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17612 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17613 enter ? "enter" : "exit");
17617 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
17618 TREE_TYPE (stmt) = void_type_node;
17619 OMP_STANDALONE_CLAUSES (stmt) = clauses;
17620 SET_EXPR_LOCATION (stmt, loc);
17626 # pragma acc host_data oacc-data-clause[optseq] new-line
17630 #define OACC_HOST_DATA_CLAUSE_MASK \
17631 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17636 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
17638 tree stmt, clauses, block;
17640 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
17641 "#pragma acc host_data");
17643 block = c_begin_omp_parallel ();
17644 add_stmt (c_parser_omp_structured_block (parser, if_p));
17645 stmt = c_finish_oacc_host_data (loc, clauses, block);
17652 # pragma acc loop oacc-loop-clause[optseq] new-line
17655 LOC is the location of the #pragma token.
17658 #define OACC_LOOP_CLAUSE_MASK \
17659 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17660 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17661 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17662 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17663 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17664 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17665 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17666 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17668 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17670 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
17671 omp_clause_mask mask, tree *cclauses, bool *if_p)
17673 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
17675 strcat (p_name, " loop");
17676 mask |= OACC_LOOP_CLAUSE_MASK;
17678 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
17682 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
17684 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
17686 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17689 tree block = c_begin_compound_stmt (true);
17690 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
17692 block = c_end_compound_stmt (loc, block, true);
17699 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17704 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17709 # pragma acc serial oacc-serial-clause[optseq] new-line
17712 LOC is the location of the #pragma token.
17715 #define OACC_KERNELS_CLAUSE_MASK \
17716 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17728 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17729 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17730 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17732 #define OACC_PARALLEL_CLAUSE_MASK \
17733 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17752 #define OACC_SERIAL_CLAUSE_MASK \
17753 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17754 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17755 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17756 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17757 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17758 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17759 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17760 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17761 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17762 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17763 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17764 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17765 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17766 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17767 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17770 c_parser_oacc_compute (location_t loc, c_parser *parser,
17771 enum pragma_kind p_kind, char *p_name, bool *if_p)
17773 omp_clause_mask mask;
17774 enum tree_code code;
17777 case PRAGMA_OACC_KERNELS:
17778 strcat (p_name, " kernels");
17779 mask = OACC_KERNELS_CLAUSE_MASK;
17780 code = OACC_KERNELS;
17782 case PRAGMA_OACC_PARALLEL:
17783 strcat (p_name, " parallel");
17784 mask = OACC_PARALLEL_CLAUSE_MASK;
17785 code = OACC_PARALLEL;
17787 case PRAGMA_OACC_SERIAL:
17788 strcat (p_name, " serial");
17789 mask = OACC_SERIAL_CLAUSE_MASK;
17790 code = OACC_SERIAL;
17793 gcc_unreachable ();
17796 if (c_parser_next_token_is (parser, CPP_NAME))
17798 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17799 if (strcmp (p, "loop") == 0)
17801 c_parser_consume_token (parser);
17802 tree block = c_begin_omp_parallel ();
17804 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17805 return c_finish_omp_construct (loc, code, block, clauses);
17809 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17811 tree block = c_begin_omp_parallel ();
17812 add_stmt (c_parser_omp_structured_block (parser, if_p));
17814 return c_finish_omp_construct (loc, code, block, clauses);
17818 # pragma acc routine oacc-routine-clause[optseq] new-line
17819 function-definition
17821 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17824 #define OACC_ROUTINE_CLAUSE_MASK \
17825 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17831 /* Parse an OpenACC routine directive. For named directives, we apply
17832 immediately to the named function. For unnamed ones we then parse
17833 a declaration or definition, which must be for a function. */
17836 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17838 gcc_checking_assert (context == pragma_external);
17840 oacc_routine_data data;
17841 data.error_seen = false;
17842 data.fndecl_seen = false;
17843 data.loc = c_parser_peek_token (parser)->location;
17845 c_parser_consume_pragma (parser);
17847 /* Look for optional '( name )'. */
17848 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17850 c_parser_consume_token (parser); /* '(' */
17852 tree decl = NULL_TREE;
17853 c_token *name_token = c_parser_peek_token (parser);
17854 location_t name_loc = name_token->location;
17855 if (name_token->type == CPP_NAME
17856 && (name_token->id_kind == C_ID_ID
17857 || name_token->id_kind == C_ID_TYPENAME))
17859 decl = lookup_name (name_token->value);
17861 error_at (name_loc,
17862 "%qE has not been declared", name_token->value);
17863 c_parser_consume_token (parser);
17866 c_parser_error (parser, "expected function name");
17869 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17871 c_parser_skip_to_pragma_eol (parser, false);
17876 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17877 "#pragma acc routine");
17878 /* The clauses are in reverse order; fix that to make later diagnostic
17879 emission easier. */
17880 data.clauses = nreverse (data.clauses);
17882 if (TREE_CODE (decl) != FUNCTION_DECL)
17884 error_at (name_loc, "%qD does not refer to a function", decl);
17888 c_finish_oacc_routine (&data, decl, false);
17890 else /* No optional '( name )'. */
17893 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17894 "#pragma acc routine");
17895 /* The clauses are in reverse order; fix that to make later diagnostic
17896 emission easier. */
17897 data.clauses = nreverse (data.clauses);
17899 /* Emit a helpful diagnostic if there's another pragma following this
17900 one. Also don't allow a static assertion declaration, as in the
17901 following we'll just parse a *single* "declaration or function
17902 definition", and the static assertion counts an one. */
17903 if (c_parser_next_token_is (parser, CPP_PRAGMA)
17904 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17906 error_at (data.loc,
17907 "%<#pragma acc routine%> not immediately followed by"
17908 " function declaration or definition");
17909 /* ..., and then just keep going. */
17913 /* We only have to consider the pragma_external case here. */
17914 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17915 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17917 int ext = disable_extension_diagnostics ();
17919 c_parser_consume_token (parser);
17920 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17921 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17922 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17923 NULL, NULL, false, NULL, &data);
17924 restore_extension_diagnostics (ext);
17927 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17928 NULL, NULL, false, NULL, &data);
17932 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17933 IS_DEFN is true if we're applying it to the definition. */
17936 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17939 /* Keep going if we're in error reporting mode. */
17940 if (data->error_seen
17941 || fndecl == error_mark_node)
17944 if (data->fndecl_seen)
17946 error_at (data->loc,
17947 "%<#pragma acc routine%> not immediately followed by"
17948 " a single function declaration or definition");
17949 data->error_seen = true;
17952 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17954 error_at (data->loc,
17955 "%<#pragma acc routine%> not immediately followed by"
17956 " function declaration or definition");
17957 data->error_seen = true;
17962 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17963 "#pragma acc routine");
17964 if (compatible < 0)
17966 data->error_seen = true;
17969 if (compatible > 0)
17974 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17976 error_at (data->loc,
17978 ? G_("%<#pragma acc routine%> must be applied before use")
17979 : G_("%<#pragma acc routine%> must be applied before"
17981 data->error_seen = true;
17985 /* Set the routine's level of parallelism. */
17986 tree dims = oacc_build_routine_dims (data->clauses);
17987 oacc_replace_fn_attrib (fndecl, dims);
17989 /* Add an "omp declare target" attribute. */
17990 DECL_ATTRIBUTES (fndecl)
17991 = tree_cons (get_identifier ("omp declare target"),
17992 data->clauses, DECL_ATTRIBUTES (fndecl));
17995 /* Remember that we've used this "#pragma acc routine". */
17996 data->fndecl_seen = true;
18000 # pragma acc update oacc-update-clause[optseq] new-line
18003 #define OACC_UPDATE_CLAUSE_MASK \
18004 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18005 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
18006 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
18007 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18008 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
18009 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18012 c_parser_oacc_update (c_parser *parser)
18014 location_t loc = c_parser_peek_token (parser)->location;
18016 c_parser_consume_pragma (parser);
18018 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
18019 "#pragma acc update");
18020 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
18023 "%<#pragma acc update%> must contain at least one "
18024 "%<device%> or %<host%> or %<self%> clause");
18031 tree stmt = make_node (OACC_UPDATE);
18032 TREE_TYPE (stmt) = void_type_node;
18033 OACC_UPDATE_CLAUSES (stmt) = clauses;
18034 SET_EXPR_LOCATION (stmt, loc);
18039 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18041 LOC is the location of the #pragma token.
18044 #define OACC_WAIT_CLAUSE_MASK \
18045 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18048 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
18050 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
18052 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
18053 list = c_parser_oacc_wait_list (parser, loc, list);
18055 strcpy (p_name, " wait");
18056 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
18057 stmt = c_finish_oacc_wait (loc, list, clauses);
18064 # pragma omp allocate (list) [allocator(allocator)] */
18067 c_parser_omp_allocate (location_t loc, c_parser *parser)
18069 tree allocator = NULL_TREE;
18070 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
18071 if (c_parser_next_token_is (parser, CPP_NAME))
18073 matching_parens parens;
18074 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18075 c_parser_consume_token (parser);
18076 if (strcmp ("allocator", p) != 0)
18077 error_at (c_parser_peek_token (parser)->location,
18078 "expected %<allocator%>");
18079 else if (parens.require_open (parser))
18081 location_t expr_loc = c_parser_peek_token (parser)->location;
18082 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18083 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18084 allocator = expr.value;
18085 allocator = c_fully_fold (allocator, false, NULL);
18087 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
18088 orig_type = TYPE_MAIN_VARIANT (orig_type);
18089 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
18090 || TREE_CODE (orig_type) != ENUMERAL_TYPE
18091 || TYPE_NAME (orig_type)
18092 != get_identifier ("omp_allocator_handle_t"))
18094 error_at (expr_loc, "%<allocator%> clause allocator expression "
18095 "has type %qT rather than "
18096 "%<omp_allocator_handle_t%>",
18097 TREE_TYPE (allocator));
18098 allocator = NULL_TREE;
18100 parens.skip_until_found_close (parser);
18103 c_parser_skip_to_pragma_eol (parser);
18106 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
18107 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18109 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
18113 # pragma omp atomic new-line
18117 x binop= expr | x++ | ++x | x-- | --x
18119 +, *, -, /, &, ^, |, <<, >>
18121 where x is an lvalue expression with scalar type.
18124 # pragma omp atomic new-line
18127 # pragma omp atomic read new-line
18130 # pragma omp atomic write new-line
18133 # pragma omp atomic update new-line
18136 # pragma omp atomic capture new-line
18139 # pragma omp atomic capture new-line
18147 expression-stmt | x = x binop expr
18149 v = expression-stmt
18151 { v = x; update-stmt; } | { update-stmt; v = x; }
18155 expression-stmt | x = x binop expr | x = expr binop x
18159 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18162 # pragma omp atomic compare new-line
18163 conditional-update-atomic
18165 # pragma omp atomic compare capture new-line
18166 conditional-update-capture-atomic
18168 conditional-update-atomic:
18169 cond-expr-stmt | cond-update-stmt
18171 x = expr ordop x ? expr : x;
18172 x = x ordop expr ? expr : x;
18173 x = x == e ? d : x;
18175 if (expr ordop x) { x = expr; }
18176 if (x ordop expr) { x = expr; }
18177 if (x == e) { x = d; }
18180 conditional-update-capture-atomic:
18182 { v = x; cond-expr-stmt }
18183 { cond-expr-stmt v = x; }
18184 { v = x; cond-update-stmt }
18185 { cond-update-stmt v = x; }
18186 if (x == e) { x = d; } else { v = x; }
18187 { r = x == e; if (r) { x = d; } }
18188 { r = x == e; if (r) { x = d; } else { v = x; } }
18190 where x, r and v are lvalue expressions with scalar type,
18191 expr, e and d are expressions with scalar type and e might be
18194 LOC is the location of the #pragma token. */
18197 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18199 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18200 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18201 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
18202 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
18203 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
18204 struct c_expr expr;
18206 bool structured_block = false;
18207 bool swapped = false;
18210 tree clauses = NULL_TREE;
18211 bool capture = false;
18212 bool compare = false;
18214 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18215 bool no_semicolon = false;
18216 bool extra_scope = false;
18218 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18221 && c_parser_next_token_is (parser, CPP_COMMA)
18222 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18223 c_parser_consume_token (parser);
18227 if (c_parser_next_token_is (parser, CPP_NAME))
18230 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18231 location_t cloc = c_parser_peek_token (parser)->location;
18232 enum tree_code new_code = ERROR_MARK;
18233 enum omp_memory_order new_memory_order
18234 = OMP_MEMORY_ORDER_UNSPECIFIED;
18235 bool new_capture = false;
18236 bool new_compare = false;
18237 bool new_weak = false;
18238 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18240 if (!strcmp (p, "read"))
18241 new_code = OMP_ATOMIC_READ;
18242 else if (!strcmp (p, "write"))
18243 new_code = NOP_EXPR;
18244 else if (!strcmp (p, "update"))
18245 new_code = OMP_ATOMIC;
18246 else if (openacc && !strcmp (p, "capture"))
18247 new_code = OMP_ATOMIC_CAPTURE_NEW;
18251 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18252 "or %<capture%> clause");
18254 else if (!strcmp (p, "capture"))
18255 new_capture = true;
18256 else if (!strcmp (p, "compare"))
18257 new_compare = true;
18258 else if (!strcmp (p, "weak"))
18260 else if (!strcmp (p, "fail"))
18262 matching_parens parens;
18264 c_parser_consume_token (parser);
18265 if (!parens.require_open (parser))
18268 if (c_parser_next_token_is (parser, CPP_NAME))
18271 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18273 if (!strcmp (q, "seq_cst"))
18274 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
18275 else if (!strcmp (q, "acquire"))
18276 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
18277 else if (!strcmp (q, "relaxed"))
18278 new_fail = OMP_MEMORY_ORDER_RELAXED;
18281 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18283 c_parser_consume_token (parser);
18284 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18285 error_at (cloc, "too many %qs clauses", "fail");
18290 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
18292 parens.skip_until_found_close (parser);
18295 else if (!strcmp (p, "seq_cst"))
18296 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18297 else if (!strcmp (p, "acq_rel"))
18298 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18299 else if (!strcmp (p, "release"))
18300 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
18301 else if (!strcmp (p, "acquire"))
18302 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18303 else if (!strcmp (p, "relaxed"))
18304 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
18305 else if (!strcmp (p, "hint"))
18307 c_parser_consume_token (parser);
18308 clauses = c_parser_omp_clause_hint (parser, clauses);
18314 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18315 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18316 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18317 "%<relaxed%> or %<hint%> clause");
18321 if (new_code != ERROR_MARK)
18323 /* OpenACC permits 'update capture'. */
18325 && code == OMP_ATOMIC
18326 && new_code == OMP_ATOMIC_CAPTURE_NEW)
18328 else if (code != ERROR_MARK)
18329 error_at (cloc, "too many atomic clauses");
18333 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18335 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18336 error_at (cloc, "too many memory order clauses");
18338 memory_order = new_memory_order;
18340 else if (new_capture)
18343 error_at (cloc, "too many %qs clauses", "capture");
18347 else if (new_compare)
18350 error_at (cloc, "too many %qs clauses", "compare");
18357 error_at (cloc, "too many %qs clauses", "weak");
18361 c_parser_consume_token (parser);
18367 c_parser_skip_to_pragma_eol (parser);
18369 if (code == ERROR_MARK)
18373 if (code != OMP_ATOMIC)
18374 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18375 "clauses", "capture");
18377 code = OMP_ATOMIC_CAPTURE_NEW;
18379 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
18381 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18382 "clauses", "compare");
18385 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
18387 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
18388 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18390 if (weak && !compare)
18392 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
18396 memory_order = OMP_MEMORY_ORDER_RELAXED;
18397 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
18400 = (enum omp_requires) (omp_requires_mask
18401 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
18402 switch ((enum omp_memory_order)
18403 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
18405 case OMP_MEMORY_ORDER_UNSPECIFIED:
18406 case OMP_MEMORY_ORDER_RELAXED:
18407 memory_order = OMP_MEMORY_ORDER_RELAXED;
18409 case OMP_MEMORY_ORDER_SEQ_CST:
18410 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18412 case OMP_MEMORY_ORDER_ACQ_REL:
18415 case OMP_ATOMIC_READ:
18416 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18418 case NOP_EXPR: /* atomic write */
18419 memory_order = OMP_MEMORY_ORDER_RELEASE;
18422 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18427 gcc_unreachable ();
18433 case OMP_ATOMIC_READ:
18434 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
18436 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
18437 "%<release%> clause");
18438 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18440 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18441 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18443 case NOP_EXPR: /* atomic write */
18444 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
18446 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
18447 "%<acquire%> clause");
18448 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18450 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18451 memory_order = OMP_MEMORY_ORDER_RELEASE;
18456 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18458 = (enum omp_memory_order) (memory_order
18459 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
18463 case OMP_ATOMIC_READ:
18464 case NOP_EXPR: /* atomic write */
18465 v = c_parser_cast_expression (parser, NULL).value;
18466 non_lvalue_p = !lvalue_p (v);
18467 v = c_fully_fold (v, false, NULL, true);
18468 if (v == error_mark_node)
18471 v = non_lvalue (v);
18472 loc = c_parser_peek_token (parser)->location;
18473 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18475 if (code == NOP_EXPR)
18477 lhs = c_parser_expression (parser).value;
18478 lhs = c_fully_fold (lhs, false, NULL);
18479 if (lhs == error_mark_node)
18484 lhs = c_parser_cast_expression (parser, NULL).value;
18485 non_lvalue_p = !lvalue_p (lhs);
18486 lhs = c_fully_fold (lhs, false, NULL, true);
18487 if (lhs == error_mark_node)
18490 lhs = non_lvalue (lhs);
18492 if (code == NOP_EXPR)
18494 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18502 case OMP_ATOMIC_CAPTURE_NEW:
18503 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18505 c_parser_consume_token (parser);
18506 structured_block = true;
18509 && c_parser_next_token_is_keyword (parser, RID_IF))
18513 v = c_parser_cast_expression (parser, NULL).value;
18514 non_lvalue_p = !lvalue_p (v);
18515 v = c_fully_fold (v, false, NULL, true);
18516 if (v == error_mark_node)
18519 v = non_lvalue (v);
18520 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18522 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18524 eloc = c_parser_peek_token (parser)->location;
18525 error_at (eloc, "expected expression");
18534 /* For structured_block case we don't know yet whether
18535 old or new x should be captured. */
18537 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18539 c_parser_consume_token (parser);
18541 matching_parens parens;
18542 if (!parens.require_open (parser))
18544 eloc = c_parser_peek_token (parser)->location;
18548 cmp_expr = c_parser_cast_expression (parser, NULL);
18549 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
18552 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
18553 parens.skip_until_found_close (parser);
18554 if (cmp_expr.value == error_mark_node)
18558 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
18560 cmp_expr.value = rhs1;
18562 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
18564 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18566 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18568 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18569 "expected %<==%> comparison in %<if%> condition");
18572 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
18573 && TREE_CODE (cmp_expr.value) != LT_EXPR)
18575 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18576 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18580 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18583 extra_scope = true;
18584 eloc = c_parser_peek_token (parser)->location;
18585 expr = c_parser_cast_expression (parser, NULL);
18587 expr = default_function_array_conversion (eloc, expr);
18588 unfolded_lhs = expr.value;
18589 lhs = c_fully_fold (lhs, false, NULL, true);
18591 if (lhs == error_mark_node)
18593 if (!lvalue_p (unfolded_lhs))
18594 lhs = non_lvalue (lhs);
18595 if (!c_parser_next_token_is (parser, CPP_EQ))
18597 c_parser_error (parser, "expected %<=%>");
18600 c_parser_consume_token (parser);
18601 eloc = c_parser_peek_token (parser)->location;
18602 expr = c_parser_expr_no_commas (parser, NULL);
18605 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18608 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18611 extra_scope = false;
18612 no_semicolon = true;
18614 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
18616 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18618 opcode = COND_EXPR;
18619 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18620 false, NULL, true);
18621 rhs1 = c_fully_fold (rhs1, false, NULL, true);
18623 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
18625 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18626 ? MIN_EXPR : MAX_EXPR);
18627 rhs = c_fully_fold (rhs1, false, NULL, true);
18628 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
18629 false, NULL, true);
18634 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18636 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
18637 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
18639 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18640 ? MAX_EXPR : MIN_EXPR);
18641 rhs = c_fully_fold (rhs1, false, NULL, true);
18642 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18643 false, NULL, true);
18648 c_parser_error (parser,
18649 "invalid form of %<#pragma omp atomic compare%>");
18653 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
18655 if (code != OMP_ATOMIC_CAPTURE_NEW
18656 || (structured_block && r == NULL_TREE)
18657 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
18659 eloc = c_parser_peek_token (parser)->location;
18660 error_at (eloc, "unexpected %<else%>");
18664 c_parser_consume_token (parser);
18666 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18669 extra_scope = true;
18670 v = c_parser_cast_expression (parser, NULL).value;
18671 non_lvalue_p = !lvalue_p (v);
18672 v = c_fully_fold (v, false, NULL, true);
18673 if (v == error_mark_node)
18676 v = non_lvalue (v);
18677 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18680 expr = c_parser_expr_no_commas (parser, NULL);
18682 if (!c_tree_equal (expr.value, unfolded_lhs))
18685 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18688 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18691 extra_scope = false;
18692 code = OMP_ATOMIC_CAPTURE_OLD;
18693 if (r == NULL_TREE)
18694 /* Signal to c_finish_omp_atomic that in
18695 if (x == e) { x = d; } else { v = x; }
18696 case the store to v should be conditional. */
18697 r = void_list_node;
18699 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18701 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
18704 else if (code == OMP_ATOMIC_CAPTURE_NEW
18710 eloc = c_parser_peek_token (parser)->location;
18711 expr = c_parser_cast_expression (parser, NULL);
18713 expr = default_function_array_conversion (eloc, expr);
18714 unfolded_lhs = expr.value;
18715 lhs = c_fully_fold (lhs, false, NULL, true);
18717 switch (TREE_CODE (lhs))
18720 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
18724 c_parser_skip_to_end_of_block_or_statement (parser);
18725 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18726 c_parser_consume_token (parser);
18727 if (structured_block)
18729 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18730 c_parser_consume_token (parser);
18731 else if (code == OMP_ATOMIC_CAPTURE_NEW)
18733 c_parser_skip_to_end_of_block_or_statement (parser);
18734 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18735 c_parser_consume_token (parser);
18740 case POSTINCREMENT_EXPR:
18741 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18742 code = OMP_ATOMIC_CAPTURE_OLD;
18744 case PREINCREMENT_EXPR:
18745 lhs = TREE_OPERAND (lhs, 0);
18746 unfolded_lhs = NULL_TREE;
18747 opcode = PLUS_EXPR;
18748 rhs = integer_one_node;
18750 goto invalid_compare;
18753 case POSTDECREMENT_EXPR:
18754 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18755 code = OMP_ATOMIC_CAPTURE_OLD;
18757 case PREDECREMENT_EXPR:
18758 lhs = TREE_OPERAND (lhs, 0);
18759 unfolded_lhs = NULL_TREE;
18760 opcode = MINUS_EXPR;
18761 rhs = integer_one_node;
18763 goto invalid_compare;
18766 case COMPOUND_EXPR:
18767 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
18768 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
18769 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
18770 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
18771 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18772 (TREE_OPERAND (lhs, 1), 0), 0)))
18774 /* Undo effects of boolean_increment for post {in,de}crement. */
18775 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
18778 if (TREE_CODE (lhs) == MODIFY_EXPR
18779 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
18781 /* Undo effects of boolean_increment. */
18782 if (integer_onep (TREE_OPERAND (lhs, 1)))
18784 /* This is pre or post increment. */
18785 rhs = TREE_OPERAND (lhs, 1);
18786 lhs = TREE_OPERAND (lhs, 0);
18787 unfolded_lhs = NULL_TREE;
18789 if (code == OMP_ATOMIC_CAPTURE_NEW
18790 && !structured_block
18791 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18792 code = OMP_ATOMIC_CAPTURE_OLD;
18794 goto invalid_compare;
18797 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
18798 && TREE_OPERAND (lhs, 0)
18799 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
18801 /* This is pre or post decrement. */
18802 rhs = TREE_OPERAND (lhs, 1);
18803 lhs = TREE_OPERAND (lhs, 0);
18804 unfolded_lhs = NULL_TREE;
18806 if (code == OMP_ATOMIC_CAPTURE_NEW
18807 && !structured_block
18808 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18809 code = OMP_ATOMIC_CAPTURE_OLD;
18811 goto invalid_compare;
18817 if (!lvalue_p (unfolded_lhs))
18818 lhs = non_lvalue (lhs);
18819 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
18821 c_parser_error (parser, "expected %<=%>");
18824 switch (c_parser_peek_token (parser)->type)
18827 opcode = MULT_EXPR;
18830 opcode = TRUNC_DIV_EXPR;
18833 opcode = PLUS_EXPR;
18836 opcode = MINUS_EXPR;
18838 case CPP_LSHIFT_EQ:
18839 opcode = LSHIFT_EXPR;
18841 case CPP_RSHIFT_EQ:
18842 opcode = RSHIFT_EXPR;
18845 opcode = BIT_AND_EXPR;
18848 opcode = BIT_IOR_EXPR;
18851 opcode = BIT_XOR_EXPR;
18854 c_parser_consume_token (parser);
18855 eloc = c_parser_peek_token (parser)->location;
18856 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
18858 switch (TREE_CODE (rhs1))
18861 case TRUNC_DIV_EXPR:
18872 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
18874 opcode = TREE_CODE (rhs1);
18875 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18877 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18881 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
18883 opcode = TREE_CODE (rhs1);
18884 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18886 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18888 swapped = !commutative_tree_code (opcode);
18895 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
18896 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
18897 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
18899 if (!TREE_OPERAND (rhs1, 1))
18901 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
18903 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18906 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18908 opcode = COND_EXPR;
18909 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18911 false, NULL, true);
18912 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
18916 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18917 TREE_OPERAND (rhs1, 1)))
18919 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18920 ? MIN_EXPR : MAX_EXPR);
18921 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18923 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18925 false, NULL, true);
18929 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18931 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18934 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18935 TREE_OPERAND (rhs1, 1)))
18937 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18938 ? MAX_EXPR : MIN_EXPR);
18939 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18941 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18943 false, NULL, true);
18950 || code != OMP_ATOMIC_CAPTURE_NEW
18951 || !structured_block
18955 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
18956 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
18960 c_parser_consume_token (parser);
18969 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
18971 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18973 code = OMP_ATOMIC_CAPTURE_OLD;
18976 expr = default_function_array_read_conversion (eloc, expr);
18977 unfolded_lhs1 = expr.value;
18978 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
18980 c_parser_consume_token (parser);
18983 if (structured_block && !compare)
18986 expr = default_function_array_read_conversion (eloc, expr);
18987 rhs = c_fully_fold (expr.value, false, NULL, true);
18992 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
18995 c_parser_error (parser,
18996 "invalid operator for %<#pragma omp atomic%>");
19000 /* Arrange to pass the location of the assignment operator to
19001 c_finish_omp_atomic. */
19002 loc = c_parser_peek_token (parser)->location;
19003 c_parser_consume_token (parser);
19004 eloc = c_parser_peek_token (parser)->location;
19005 expr = c_parser_expression (parser);
19006 expr = default_function_array_read_conversion (eloc, expr);
19008 rhs = c_fully_fold (rhs, false, NULL, true);
19012 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
19015 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
19017 no_semicolon = false;
19018 v = c_parser_cast_expression (parser, NULL).value;
19019 non_lvalue_p = !lvalue_p (v);
19020 v = c_fully_fold (v, false, NULL, true);
19021 if (v == error_mark_node)
19024 v = non_lvalue (v);
19025 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19027 eloc = c_parser_peek_token (parser)->location;
19028 expr = c_parser_cast_expression (parser, NULL);
19030 expr = default_function_array_read_conversion (eloc, expr);
19031 unfolded_lhs1 = expr.value;
19032 lhs1 = c_fully_fold (lhs1, false, NULL, true);
19033 if (lhs1 == error_mark_node)
19035 if (!lvalue_p (unfolded_lhs1))
19036 lhs1 = non_lvalue (lhs1);
19038 if (structured_block)
19041 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19042 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
19045 if (weak && opcode != COND_EXPR)
19047 error_at (loc, "%<weak%> clause requires atomic equality comparison");
19050 if (unfolded_lhs && unfolded_lhs1
19051 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
19053 error ("%<#pragma omp atomic capture%> uses two different "
19054 "expressions for memory");
19055 stmt = error_mark_node;
19058 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
19059 swapped, memory_order, weak);
19060 if (stmt != error_mark_node)
19063 if (!structured_block && !no_semicolon)
19064 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19069 # pragma omp barrier new-line
19073 c_parser_omp_barrier (c_parser *parser)
19075 location_t loc = c_parser_peek_token (parser)->location;
19076 c_parser_consume_pragma (parser);
19077 c_parser_skip_to_pragma_eol (parser);
19079 c_finish_omp_barrier (loc);
19083 # pragma omp critical [(name)] new-line
19087 # pragma omp critical [(name) [hint(expression)]] new-line
19089 LOC is the location of the #pragma itself. */
19091 #define OMP_CRITICAL_CLAUSE_MASK \
19092 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19095 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
19097 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
19099 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19101 c_parser_consume_token (parser);
19102 if (c_parser_next_token_is (parser, CPP_NAME))
19104 name = c_parser_peek_token (parser)->value;
19105 c_parser_consume_token (parser);
19106 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
19109 c_parser_error (parser, "expected identifier");
19111 if (c_parser_next_token_is (parser, CPP_COMMA)
19112 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
19113 c_parser_consume_token (parser);
19115 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
19116 "#pragma omp critical");
19117 stmt = c_parser_omp_structured_block (parser, if_p);
19118 return c_finish_omp_critical (loc, stmt, name, clauses);
19122 # pragma omp depobj ( depobj ) depobj-clause new-line
19125 depend (dependence-type : locator)
19127 update (dependence-type)
19136 c_parser_omp_depobj (c_parser *parser)
19138 location_t loc = c_parser_peek_token (parser)->location;
19139 c_parser_consume_pragma (parser);
19140 matching_parens parens;
19141 if (!parens.require_open (parser))
19143 c_parser_skip_to_pragma_eol (parser);
19147 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
19148 if (depobj != error_mark_node)
19150 if (!lvalue_p (depobj))
19152 error_at (EXPR_LOC_OR_LOC (depobj, loc),
19153 "%<depobj%> expression is not lvalue expression");
19154 depobj = error_mark_node;
19158 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
19160 if (addr == error_mark_node)
19161 depobj = error_mark_node;
19163 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
19164 addr, RO_UNARY_STAR);
19168 parens.skip_until_found_close (parser);
19169 tree clause = NULL_TREE;
19170 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
19171 location_t c_loc = c_parser_peek_token (parser)->location;
19172 if (c_parser_next_token_is (parser, CPP_NAME))
19174 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19176 c_parser_consume_token (parser);
19177 if (!strcmp ("depend", p))
19179 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19180 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19182 clause = error_mark_node;
19184 else if (!strcmp ("destroy", p))
19185 kind = OMP_CLAUSE_DEPEND_LAST;
19186 else if (!strcmp ("update", p))
19188 matching_parens c_parens;
19189 if (c_parens.require_open (parser))
19191 location_t c2_loc = c_parser_peek_token (parser)->location;
19192 if (c_parser_next_token_is (parser, CPP_NAME))
19195 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19197 c_parser_consume_token (parser);
19198 if (!strcmp ("in", p2))
19199 kind = OMP_CLAUSE_DEPEND_IN;
19200 else if (!strcmp ("out", p2))
19201 kind = OMP_CLAUSE_DEPEND_OUT;
19202 else if (!strcmp ("inout", p2))
19203 kind = OMP_CLAUSE_DEPEND_INOUT;
19204 else if (!strcmp ("mutexinoutset", p2))
19205 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
19206 else if (!strcmp ("inoutset", p2))
19207 kind = OMP_CLAUSE_DEPEND_INOUTSET;
19209 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
19211 clause = error_mark_node;
19212 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
19213 "%<mutexinoutset%> or %<inoutset%>");
19215 c_parens.skip_until_found_close (parser);
19218 clause = error_mark_node;
19221 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
19223 clause = error_mark_node;
19224 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
19226 c_parser_skip_to_pragma_eol (parser);
19228 c_finish_omp_depobj (loc, depobj, kind, clause);
19233 # pragma omp flush flush-vars[opt] new-line
19239 # pragma omp flush memory-order-clause new-line */
19242 c_parser_omp_flush (c_parser *parser)
19244 location_t loc = c_parser_peek_token (parser)->location;
19245 c_parser_consume_pragma (parser);
19246 enum memmodel mo = MEMMODEL_LAST;
19247 if (c_parser_next_token_is (parser, CPP_NAME))
19250 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19252 if (!strcmp (p, "seq_cst"))
19253 mo = MEMMODEL_SEQ_CST;
19254 else if (!strcmp (p, "acq_rel"))
19255 mo = MEMMODEL_ACQ_REL;
19256 else if (!strcmp (p, "release"))
19257 mo = MEMMODEL_RELEASE;
19258 else if (!strcmp (p, "acquire"))
19259 mo = MEMMODEL_ACQUIRE;
19261 error_at (c_parser_peek_token (parser)->location,
19262 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19264 c_parser_consume_token (parser);
19266 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19268 if (mo != MEMMODEL_LAST)
19269 error_at (c_parser_peek_token (parser)->location,
19270 "%<flush%> list specified together with memory order "
19272 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
19274 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19275 c_parser_error (parser, "expected %<(%> or end of line");
19276 c_parser_skip_to_pragma_eol (parser);
19278 c_finish_omp_flush (loc, mo);
19281 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19282 separating directive. */
19285 c_parser_omp_structured_block_sequence (c_parser *parser,
19286 enum pragma_kind kind)
19288 tree stmt = push_stmt_list ();
19289 c_parser_statement (parser, NULL);
19292 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19294 if (c_parser_next_token_is (parser, CPP_EOF))
19297 if (kind != PRAGMA_NONE
19298 && c_parser_peek_token (parser)->pragma_kind == kind)
19300 c_parser_statement (parser, NULL);
19303 return pop_stmt_list (stmt);
19309 { structured-block scan-directive structured-block } */
19312 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
19316 tree clauses = NULL_TREE;
19318 loc = c_parser_peek_token (parser)->location;
19319 if (!open_brace_parsed
19320 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19322 /* Avoid skipping until the end of the block. */
19323 parser->error = false;
19327 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
19328 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
19329 SET_EXPR_LOCATION (substmt, loc);
19330 add_stmt (substmt);
19332 loc = c_parser_peek_token (parser)->location;
19333 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
19335 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
19337 c_parser_consume_pragma (parser);
19339 if (c_parser_next_token_is (parser, CPP_NAME))
19342 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19343 if (strcmp (p, "inclusive") == 0)
19344 clause = OMP_CLAUSE_INCLUSIVE;
19345 else if (strcmp (p, "exclusive") == 0)
19346 clause = OMP_CLAUSE_EXCLUSIVE;
19348 if (clause != OMP_CLAUSE_ERROR)
19350 c_parser_consume_token (parser);
19351 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
19354 c_parser_error (parser, "expected %<inclusive%> or "
19355 "%<exclusive%> clause");
19356 c_parser_skip_to_pragma_eol (parser);
19359 error ("expected %<#pragma omp scan%>");
19361 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19362 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
19363 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
19364 SET_EXPR_LOCATION (substmt, loc);
19365 add_stmt (substmt);
19367 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19371 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19372 The real trick here is to determine the loop control variable early
19373 so that we can push a new decl if necessary to make it private.
19374 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19378 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
19379 tree clauses, tree *cclauses, bool *if_p)
19381 tree decl, cond, incr, body, init, stmt, cl;
19382 unsigned char save_in_statement;
19383 tree declv, condv, incrv, initv, ret = NULL_TREE;
19384 tree pre_body = NULL_TREE, this_pre_body;
19385 tree ordered_cl = NULL_TREE;
19386 bool fail = false, open_brace_parsed = false;
19387 int i, collapse = 1, ordered = 0, count, nbraces = 0;
19388 location_t for_loc;
19389 bool tiling = false;
19390 bool inscan = false;
19391 vec<tree, va_gc> *for_block = make_tree_vector ();
19393 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
19394 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
19395 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
19396 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
19399 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
19401 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
19402 && OMP_CLAUSE_ORDERED_EXPR (cl))
19405 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
19407 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
19408 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
19409 && (code == OMP_SIMD || code == OMP_FOR))
19412 if (ordered && ordered < collapse)
19414 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
19415 "%<ordered%> clause parameter is less than %<collapse%>");
19416 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
19417 = build_int_cst (NULL_TREE, collapse);
19418 ordered = collapse;
19422 for (tree *pc = &clauses; *pc; )
19423 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
19425 error_at (OMP_CLAUSE_LOCATION (*pc),
19426 "%<linear%> clause may not be specified together "
19427 "with %<ordered%> clause with a parameter");
19428 *pc = OMP_CLAUSE_CHAIN (*pc);
19431 pc = &OMP_CLAUSE_CHAIN (*pc);
19434 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
19435 count = ordered ? ordered : collapse;
19437 declv = make_tree_vec (count);
19438 initv = make_tree_vec (count);
19439 condv = make_tree_vec (count);
19440 incrv = make_tree_vec (count);
19442 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
19444 c_parser_error (parser, "for statement expected");
19447 for_loc = c_parser_peek_token (parser)->location;
19448 c_parser_consume_token (parser);
19450 /* Forbid break/continue in the loop initializer, condition, and
19451 increment expressions. */
19452 save_in_statement = in_statement;
19453 in_statement = IN_OMP_BLOCK;
19455 for (i = 0; i < count; i++)
19457 int bracecount = 0;
19459 matching_parens parens;
19460 if (!parens.require_open (parser))
19463 /* Parse the initialization declaration or expression. */
19464 if (c_parser_next_tokens_start_declaration (parser))
19467 vec_safe_push (for_block, c_begin_compound_stmt (true));
19468 this_pre_body = push_stmt_list ();
19469 c_in_omp_for = true;
19470 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
19471 c_in_omp_for = false;
19474 this_pre_body = pop_stmt_list (this_pre_body);
19478 pre_body = push_stmt_list ();
19480 add_stmt (this_pre_body);
19481 pre_body = pop_stmt_list (pre_body);
19484 pre_body = this_pre_body;
19486 decl = check_for_loop_decls (for_loc, flag_isoc99);
19489 if (DECL_INITIAL (decl) == error_mark_node)
19490 decl = error_mark_node;
19493 else if (c_parser_next_token_is (parser, CPP_NAME)
19494 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
19496 struct c_expr decl_exp;
19497 struct c_expr init_exp;
19498 location_t init_loc;
19500 decl_exp = c_parser_postfix_expression (parser);
19501 decl = decl_exp.value;
19503 c_parser_require (parser, CPP_EQ, "expected %<=%>");
19505 init_loc = c_parser_peek_token (parser)->location;
19506 init_exp = c_parser_expr_no_commas (parser, NULL);
19507 init_exp = default_function_array_read_conversion (init_loc,
19509 c_in_omp_for = true;
19510 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
19511 NOP_EXPR, init_loc, init_exp.value,
19512 init_exp.original_type);
19513 c_in_omp_for = false;
19514 init = c_process_expr_stmt (init_loc, init);
19516 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19521 c_parser_error (parser,
19522 "expected iteration declaration or initialization");
19523 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19529 /* Parse the loop condition. */
19531 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
19533 location_t cond_loc = c_parser_peek_token (parser)->location;
19534 c_in_omp_for = true;
19535 struct c_expr cond_expr
19536 = c_parser_binary_expression (parser, NULL, NULL_TREE);
19537 c_in_omp_for = false;
19539 cond = cond_expr.value;
19540 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
19541 switch (cond_expr.original_code)
19549 if (code != OACC_LOOP)
19553 /* Can't be cond = error_mark_node, because we want to preserve
19554 the location until c_finish_omp_for. */
19555 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
19558 protected_set_expr_location (cond, cond_loc);
19560 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19562 /* Parse the increment expression. */
19564 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
19566 location_t incr_loc = c_parser_peek_token (parser)->location;
19568 incr = c_process_expr_stmt (incr_loc,
19569 c_parser_expression (parser).value);
19571 parens.skip_until_found_close (parser);
19573 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
19577 TREE_VEC_ELT (declv, i) = decl;
19578 TREE_VEC_ELT (initv, i) = init;
19579 TREE_VEC_ELT (condv, i) = cond;
19580 TREE_VEC_ELT (incrv, i) = incr;
19584 if (i == count - 1)
19587 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19588 in between the collapsed for loops to be still considered perfectly
19589 nested. Hopefully the final version clarifies this.
19590 For now handle (multiple) {'s and empty statements. */
19593 if (c_parser_next_token_is_keyword (parser, RID_FOR))
19595 c_parser_consume_token (parser);
19598 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19600 c_parser_consume_token (parser);
19603 else if (bracecount
19604 && c_parser_next_token_is (parser, CPP_SEMICOLON))
19605 c_parser_consume_token (parser);
19608 c_parser_error (parser, "not enough perfectly nested loops");
19611 open_brace_parsed = true;
19621 nbraces += bracecount;
19627 in_statement = IN_OMP_FOR;
19628 body = push_stmt_list ();
19631 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
19632 else if (open_brace_parsed)
19634 location_t here = c_parser_peek_token (parser)->location;
19635 stmt = c_begin_compound_stmt (true);
19636 c_parser_compound_statement_nostart (parser);
19637 add_stmt (c_end_compound_stmt (here, stmt, true));
19640 add_stmt (c_parser_c99_block_statement (parser, if_p));
19642 body = pop_stmt_list (body);
19643 in_statement = save_in_statement;
19647 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19649 c_parser_consume_token (parser);
19652 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
19653 c_parser_consume_token (parser);
19656 c_parser_error (parser, "collapsed loops not perfectly nested");
19659 location_t here = c_parser_peek_token (parser)->location;
19660 stmt = c_begin_compound_stmt (true);
19662 c_parser_compound_statement_nostart (parser);
19663 body = c_end_compound_stmt (here, stmt, true);
19670 /* Only bother calling c_finish_omp_for if we haven't already generated
19671 an error from the initialization parsing. */
19674 c_in_omp_for = true;
19675 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
19676 incrv, body, pre_body, true);
19677 c_in_omp_for = false;
19679 /* Check for iterators appearing in lb, b or incr expressions. */
19680 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
19687 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
19689 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
19690 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
19691 tree decl = TREE_OPERAND (init, 0);
19692 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
19693 gcc_assert (COMPARISON_CLASS_P (cond));
19694 gcc_assert (TREE_OPERAND (cond, 0) == decl);
19696 tree op0 = TREE_OPERAND (init, 1);
19697 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19698 || TREE_CODE (op0) != TREE_VEC)
19699 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
19702 TREE_VEC_ELT (op0, 1)
19703 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
19704 TREE_VEC_ELT (op0, 2)
19705 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
19708 tree op1 = TREE_OPERAND (cond, 1);
19709 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19710 || TREE_CODE (op1) != TREE_VEC)
19711 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
19714 TREE_VEC_ELT (op1, 1)
19715 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
19716 TREE_VEC_ELT (op1, 2)
19717 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
19721 if (cclauses != NULL
19722 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
19725 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
19726 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
19727 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
19728 c = &OMP_CLAUSE_CHAIN (*c);
19731 for (i = 0; i < count; i++)
19732 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
19735 c = &OMP_CLAUSE_CHAIN (*c);
19736 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
19739 "iteration variable %qD should not be firstprivate",
19740 OMP_CLAUSE_DECL (*c));
19741 *c = OMP_CLAUSE_CHAIN (*c);
19745 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19747 *c = OMP_CLAUSE_CHAIN (*c);
19748 if (code == OMP_SIMD)
19750 OMP_CLAUSE_CHAIN (l)
19751 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19752 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
19756 OMP_CLAUSE_CHAIN (l) = clauses;
19762 OMP_FOR_CLAUSES (stmt) = clauses;
19767 while (!for_block->is_empty ())
19769 /* FIXME diagnostics: LOC below should be the actual location of
19770 this particular for block. We need to build a list of
19771 locations to go along with FOR_BLOCK. */
19772 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
19775 release_tree_vector (for_block);
19779 /* Helper function for OpenMP parsing, split clauses and call
19780 finish_omp_clauses on each of the set of clauses afterwards. */
19783 omp_split_clauses (location_t loc, enum tree_code code,
19784 omp_clause_mask mask, tree clauses, tree *cclauses)
19787 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
19788 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
19790 cclauses[i] = c_finish_omp_clauses (cclauses[i],
19791 i == C_OMP_CLAUSE_SPLIT_TARGET
19792 ? C_ORT_OMP_TARGET : C_ORT_OMP);
19796 #pragma omp loop loop-clause[optseq] new-line
19799 LOC is the location of the #pragma token.
19802 #define OMP_LOOP_CLAUSE_MASK \
19803 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19811 c_parser_omp_loop (location_t loc, c_parser *parser,
19812 char *p_name, omp_clause_mask mask, tree *cclauses,
19815 tree block, clauses, ret;
19817 strcat (p_name, " loop");
19818 mask |= OMP_LOOP_CLAUSE_MASK;
19820 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19823 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
19824 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
19827 block = c_begin_compound_stmt (true);
19828 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
19829 block = c_end_compound_stmt (loc, block, true);
19836 #pragma omp simd simd-clause[optseq] new-line
19839 LOC is the location of the #pragma token.
19842 #define OMP_SIMD_CLAUSE_MASK \
19843 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19844 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19845 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19848 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19849 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19850 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19851 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19852 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19853 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19856 c_parser_omp_simd (location_t loc, c_parser *parser,
19857 char *p_name, omp_clause_mask mask, tree *cclauses,
19860 tree block, clauses, ret;
19862 strcat (p_name, " simd");
19863 mask |= OMP_SIMD_CLAUSE_MASK;
19865 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19868 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
19869 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
19870 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
19871 OMP_CLAUSE_ORDERED);
19872 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
19874 error_at (OMP_CLAUSE_LOCATION (c),
19875 "%<ordered%> clause with parameter may not be specified "
19876 "on %qs construct", p_name);
19877 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
19881 block = c_begin_compound_stmt (true);
19882 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
19883 block = c_end_compound_stmt (loc, block, true);
19890 #pragma omp for for-clause[optseq] new-line
19894 #pragma omp for simd for-simd-clause[optseq] new-line
19897 LOC is the location of the #pragma token.
19900 #define OMP_FOR_CLAUSE_MASK \
19901 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19906 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
19907 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
19908 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19914 c_parser_omp_for (location_t loc, c_parser *parser,
19915 char *p_name, omp_clause_mask mask, tree *cclauses,
19918 tree block, clauses, ret;
19920 strcat (p_name, " for");
19921 mask |= OMP_FOR_CLAUSE_MASK;
19922 /* parallel for{, simd} disallows nowait clause, but for
19923 target {teams distribute ,}parallel for{, simd} it should be accepted. */
19924 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
19925 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
19926 /* Composite distribute parallel for{, simd} disallows ordered clause. */
19927 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19928 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
19930 if (c_parser_next_token_is (parser, CPP_NAME))
19932 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19934 if (strcmp (p, "simd") == 0)
19936 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19937 if (cclauses == NULL)
19938 cclauses = cclauses_buf;
19940 c_parser_consume_token (parser);
19941 if (!flag_openmp) /* flag_openmp_simd */
19942 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19944 block = c_begin_compound_stmt (true);
19945 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
19946 block = c_end_compound_stmt (loc, block, true);
19947 if (ret == NULL_TREE)
19949 ret = make_node (OMP_FOR);
19950 TREE_TYPE (ret) = void_type_node;
19951 OMP_FOR_BODY (ret) = block;
19952 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19953 SET_EXPR_LOCATION (ret, loc);
19958 if (!flag_openmp) /* flag_openmp_simd */
19960 c_parser_skip_to_pragma_eol (parser, false);
19964 /* Composite distribute parallel for disallows linear clause. */
19965 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19966 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
19968 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19971 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
19972 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19975 block = c_begin_compound_stmt (true);
19976 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
19977 block = c_end_compound_stmt (loc, block, true);
19983 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
19984 omp_clause_mask, tree *, bool *);
19987 # pragma omp master new-line
19990 LOC is the location of the #pragma token.
19994 c_parser_omp_master (location_t loc, c_parser *parser,
19995 char *p_name, omp_clause_mask mask, tree *cclauses,
19998 tree block, clauses, ret;
20000 strcat (p_name, " master");
20002 if (c_parser_next_token_is (parser, CPP_NAME))
20004 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20006 if (strcmp (p, "taskloop") == 0)
20008 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20009 if (cclauses == NULL)
20010 cclauses = cclauses_buf;
20012 c_parser_consume_token (parser);
20013 if (!flag_openmp) /* flag_openmp_simd */
20014 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20016 block = c_begin_compound_stmt (true);
20017 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20019 block = c_end_compound_stmt (loc, block, true);
20020 if (ret == NULL_TREE)
20022 ret = c_finish_omp_master (loc, block);
20023 OMP_MASTER_COMBINED (ret) = 1;
20027 if (!flag_openmp) /* flag_openmp_simd */
20029 c_parser_skip_to_pragma_eol (parser, false);
20035 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
20036 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
20039 c_parser_skip_to_pragma_eol (parser);
20041 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
20046 # pragma omp masked masked-clauses new-line
20049 LOC is the location of the #pragma token.
20052 #define OMP_MASKED_CLAUSE_MASK \
20053 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20056 c_parser_omp_masked (location_t loc, c_parser *parser,
20057 char *p_name, omp_clause_mask mask, tree *cclauses,
20060 tree block, clauses, ret;
20062 strcat (p_name, " masked");
20063 mask |= OMP_MASKED_CLAUSE_MASK;
20065 if (c_parser_next_token_is (parser, CPP_NAME))
20067 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20069 if (strcmp (p, "taskloop") == 0)
20071 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20072 if (cclauses == NULL)
20073 cclauses = cclauses_buf;
20075 c_parser_consume_token (parser);
20076 if (!flag_openmp) /* flag_openmp_simd */
20077 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20079 block = c_begin_compound_stmt (true);
20080 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20082 block = c_end_compound_stmt (loc, block, true);
20083 if (ret == NULL_TREE)
20085 ret = c_finish_omp_masked (loc, block,
20086 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
20087 OMP_MASKED_COMBINED (ret) = 1;
20091 if (!flag_openmp) /* flag_openmp_simd */
20093 c_parser_skip_to_pragma_eol (parser, false);
20097 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20100 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
20101 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
20104 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
20110 # pragma omp ordered new-line
20114 # pragma omp ordered ordered-clauses new-line
20117 # pragma omp ordered depend-clauses new-line */
20119 #define OMP_ORDERED_CLAUSE_MASK \
20120 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20121 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20123 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20124 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20127 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
20130 location_t loc = c_parser_peek_token (parser)->location;
20131 c_parser_consume_pragma (parser);
20133 if (context != pragma_stmt && context != pragma_compound)
20135 c_parser_error (parser, "expected declaration specifiers");
20136 c_parser_skip_to_pragma_eol (parser, false);
20140 if (c_parser_next_token_is (parser, CPP_NAME))
20142 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20144 if (!strcmp ("depend", p))
20146 if (!flag_openmp) /* flag_openmp_simd */
20148 c_parser_skip_to_pragma_eol (parser, false);
20151 if (context == pragma_stmt)
20154 "%<#pragma omp ordered%> with %<depend%> clause may "
20155 "only be used in compound statements");
20156 c_parser_skip_to_pragma_eol (parser, false);
20161 = c_parser_omp_all_clauses (parser,
20162 OMP_ORDERED_DEPEND_CLAUSE_MASK,
20163 "#pragma omp ordered");
20164 c_finish_omp_ordered (loc, clauses, NULL_TREE);
20169 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20170 "#pragma omp ordered");
20172 if (!flag_openmp /* flag_openmp_simd */
20173 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20176 c_finish_omp_ordered (loc, clauses,
20177 c_parser_omp_structured_block (parser, if_p));
20184 { section-sequence }
20187 section-directive[opt] structured-block
20188 section-sequence section-directive structured-block
20190 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20192 SECTIONS_LOC is the location of the #pragma omp sections. */
20195 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20197 tree stmt, substmt;
20198 bool error_suppress = false;
20201 loc = c_parser_peek_token (parser)->location;
20202 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20204 /* Avoid skipping until the end of the block. */
20205 parser->error = false;
20209 stmt = push_stmt_list ();
20211 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
20213 substmt = c_parser_omp_structured_block_sequence (parser,
20214 PRAGMA_OMP_SECTION);
20215 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20216 SET_EXPR_LOCATION (substmt, loc);
20217 add_stmt (substmt);
20222 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20224 if (c_parser_next_token_is (parser, CPP_EOF))
20227 loc = c_parser_peek_token (parser)->location;
20228 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
20230 c_parser_consume_pragma (parser);
20231 c_parser_skip_to_pragma_eol (parser);
20232 error_suppress = false;
20234 else if (!error_suppress)
20236 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
20237 error_suppress = true;
20240 substmt = c_parser_omp_structured_block_sequence (parser,
20241 PRAGMA_OMP_SECTION);
20242 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20243 SET_EXPR_LOCATION (substmt, loc);
20244 add_stmt (substmt);
20246 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20247 "expected %<#pragma omp section%> or %<}%>");
20249 substmt = pop_stmt_list (stmt);
20251 stmt = make_node (OMP_SECTIONS);
20252 SET_EXPR_LOCATION (stmt, sections_loc);
20253 TREE_TYPE (stmt) = void_type_node;
20254 OMP_SECTIONS_BODY (stmt) = substmt;
20256 return add_stmt (stmt);
20260 # pragma omp sections sections-clause[optseq] newline
20263 LOC is the location of the #pragma token.
20266 #define OMP_SECTIONS_CLAUSE_MASK \
20267 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20268 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20269 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20270 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20271 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20272 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20275 c_parser_omp_sections (location_t loc, c_parser *parser,
20276 char *p_name, omp_clause_mask mask, tree *cclauses)
20278 tree block, clauses, ret;
20280 strcat (p_name, " sections");
20281 mask |= OMP_SECTIONS_CLAUSE_MASK;
20283 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20285 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20288 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
20289 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
20292 block = c_begin_compound_stmt (true);
20293 ret = c_parser_omp_sections_scope (loc, parser);
20295 OMP_SECTIONS_CLAUSES (ret) = clauses;
20296 block = c_end_compound_stmt (loc, block, true);
20303 # pragma omp parallel parallel-clause[optseq] new-line
20305 # pragma omp parallel for parallel-for-clause[optseq] new-line
20307 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20311 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20314 LOC is the location of the #pragma token.
20317 #define OMP_PARALLEL_CLAUSE_MASK \
20318 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20319 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20320 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20321 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20322 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20323 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20324 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20325 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20326 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20327 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20330 c_parser_omp_parallel (location_t loc, c_parser *parser,
20331 char *p_name, omp_clause_mask mask, tree *cclauses,
20334 tree stmt, clauses, block;
20336 strcat (p_name, " parallel");
20337 mask |= OMP_PARALLEL_CLAUSE_MASK;
20338 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20339 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
20340 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
20341 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
20343 if (c_parser_next_token_is_keyword (parser, RID_FOR))
20345 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20346 if (cclauses == NULL)
20347 cclauses = cclauses_buf;
20349 c_parser_consume_token (parser);
20350 if (!flag_openmp) /* flag_openmp_simd */
20351 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20352 block = c_begin_omp_parallel ();
20353 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20355 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20357 if (ret == NULL_TREE)
20359 OMP_PARALLEL_COMBINED (stmt) = 1;
20362 /* When combined with distribute, parallel has to be followed by for.
20363 #pragma omp target parallel is allowed though. */
20365 && (mask & (OMP_CLAUSE_MASK_1
20366 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20368 error_at (loc, "expected %<for%> after %qs", p_name);
20369 c_parser_skip_to_pragma_eol (parser);
20372 else if (c_parser_next_token_is (parser, CPP_NAME))
20374 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20375 if (cclauses == NULL && strcmp (p, "masked") == 0)
20377 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20378 cclauses = cclauses_buf;
20380 c_parser_consume_token (parser);
20381 if (!flag_openmp) /* flag_openmp_simd */
20382 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20384 block = c_begin_omp_parallel ();
20385 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20387 stmt = c_finish_omp_parallel (loc,
20388 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20392 /* masked does have just filter clause, but during gimplification
20393 isn't represented by a gimplification omp context, so for
20394 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20396 #pragma omp parallel masked
20397 #pragma omp taskloop simd lastprivate (x)
20398 isn't confused with
20399 #pragma omp parallel masked taskloop simd lastprivate (x) */
20400 if (OMP_MASKED_COMBINED (ret))
20401 OMP_PARALLEL_COMBINED (stmt) = 1;
20404 else if (cclauses == NULL && strcmp (p, "master") == 0)
20406 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20407 cclauses = cclauses_buf;
20409 c_parser_consume_token (parser);
20410 if (!flag_openmp) /* flag_openmp_simd */
20411 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20413 block = c_begin_omp_parallel ();
20414 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20416 stmt = c_finish_omp_parallel (loc,
20417 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20421 /* master doesn't have any clauses and during gimplification
20422 isn't represented by a gimplification omp context, so for
20423 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20425 #pragma omp parallel master
20426 #pragma omp taskloop simd lastprivate (x)
20427 isn't confused with
20428 #pragma omp parallel master taskloop simd lastprivate (x) */
20429 if (OMP_MASTER_COMBINED (ret))
20430 OMP_PARALLEL_COMBINED (stmt) = 1;
20433 else if (strcmp (p, "loop") == 0)
20435 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20436 if (cclauses == NULL)
20437 cclauses = cclauses_buf;
20439 c_parser_consume_token (parser);
20440 if (!flag_openmp) /* flag_openmp_simd */
20441 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20443 block = c_begin_omp_parallel ();
20444 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20447 = c_finish_omp_parallel (loc,
20448 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20450 if (ret == NULL_TREE)
20452 OMP_PARALLEL_COMBINED (stmt) = 1;
20455 else if (!flag_openmp) /* flag_openmp_simd */
20457 c_parser_skip_to_pragma_eol (parser, false);
20460 else if (cclauses == NULL && strcmp (p, "sections") == 0)
20462 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20463 cclauses = cclauses_buf;
20465 c_parser_consume_token (parser);
20466 block = c_begin_omp_parallel ();
20467 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
20468 stmt = c_finish_omp_parallel (loc,
20469 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20471 OMP_PARALLEL_COMBINED (stmt) = 1;
20475 else if (!flag_openmp) /* flag_openmp_simd */
20477 c_parser_skip_to_pragma_eol (parser, false);
20481 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20484 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
20485 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
20488 block = c_begin_omp_parallel ();
20489 c_parser_statement (parser, if_p);
20490 stmt = c_finish_omp_parallel (loc, clauses, block);
20496 # pragma omp single single-clause[optseq] new-line
20499 LOC is the location of the #pragma.
20502 #define OMP_SINGLE_CLAUSE_MASK \
20503 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20504 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20505 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20506 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20510 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
20512 tree stmt = make_node (OMP_SINGLE);
20513 SET_EXPR_LOCATION (stmt, loc);
20514 TREE_TYPE (stmt) = void_type_node;
20516 OMP_SINGLE_CLAUSES (stmt)
20517 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
20518 "#pragma omp single");
20519 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20521 return add_stmt (stmt);
20525 # pragma omp scope scope-clause[optseq] new-line
20528 LOC is the location of the #pragma.
20531 #define OMP_SCOPE_CLAUSE_MASK \
20532 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20533 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20534 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20535 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20536 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20539 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
20541 tree stmt = make_node (OMP_SCOPE);
20542 SET_EXPR_LOCATION (stmt, loc);
20543 TREE_TYPE (stmt) = void_type_node;
20545 OMP_SCOPE_CLAUSES (stmt)
20546 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
20547 "#pragma omp scope");
20548 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20550 return add_stmt (stmt);
20554 # pragma omp task task-clause[optseq] new-line
20556 LOC is the location of the #pragma.
20559 #define OMP_TASK_CLAUSE_MASK \
20560 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20561 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20562 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20563 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20567 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20570 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20571 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20576 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
20578 tree clauses, block;
20580 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
20581 "#pragma omp task");
20583 block = c_begin_omp_task ();
20584 c_parser_statement (parser, if_p);
20585 return c_finish_omp_task (loc, clauses, block);
20589 # pragma omp taskwait new-line
20592 # pragma omp taskwait taskwait-clause[optseq] new-line
20595 #define OMP_TASKWAIT_CLAUSE_MASK \
20596 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20597 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20600 c_parser_omp_taskwait (c_parser *parser)
20602 location_t loc = c_parser_peek_token (parser)->location;
20603 c_parser_consume_pragma (parser);
20606 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
20607 "#pragma omp taskwait");
20611 tree stmt = make_node (OMP_TASK);
20612 TREE_TYPE (stmt) = void_node;
20613 OMP_TASK_CLAUSES (stmt) = clauses;
20614 OMP_TASK_BODY (stmt) = NULL_TREE;
20615 SET_EXPR_LOCATION (stmt, loc);
20619 c_finish_omp_taskwait (loc);
20623 # pragma omp taskyield new-line
20627 c_parser_omp_taskyield (c_parser *parser)
20629 location_t loc = c_parser_peek_token (parser)->location;
20630 c_parser_consume_pragma (parser);
20631 c_parser_skip_to_pragma_eol (parser);
20633 c_finish_omp_taskyield (loc);
20637 # pragma omp taskgroup new-line
20640 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20643 #define OMP_TASKGROUP_CLAUSE_MASK \
20644 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20645 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20648 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
20650 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
20651 "#pragma omp taskgroup");
20653 tree body = c_parser_omp_structured_block (parser, if_p);
20654 return c_finish_omp_taskgroup (loc, body, clauses);
20658 # pragma omp cancel cancel-clause[optseq] new-line
20660 LOC is the location of the #pragma.
20663 #define OMP_CANCEL_CLAUSE_MASK \
20664 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20665 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20666 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20668 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20671 c_parser_omp_cancel (c_parser *parser)
20673 location_t loc = c_parser_peek_token (parser)->location;
20675 c_parser_consume_pragma (parser);
20676 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
20677 "#pragma omp cancel");
20679 c_finish_omp_cancel (loc, clauses);
20683 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20685 LOC is the location of the #pragma.
20688 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20689 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20690 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20691 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20692 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20695 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
20697 location_t loc = c_parser_peek_token (parser)->location;
20699 bool point_seen = false;
20701 c_parser_consume_pragma (parser);
20702 if (c_parser_next_token_is (parser, CPP_NAME))
20704 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20705 if (strcmp (p, "point") == 0)
20707 c_parser_consume_token (parser);
20713 c_parser_error (parser, "expected %<point%>");
20714 c_parser_skip_to_pragma_eol (parser);
20718 if (context != pragma_compound)
20720 if (context == pragma_stmt)
20722 "%<#pragma %s%> may only be used in compound statements",
20723 "omp cancellation point");
20725 c_parser_error (parser, "expected declaration specifiers");
20726 c_parser_skip_to_pragma_eol (parser, false);
20731 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
20732 "#pragma omp cancellation point");
20734 c_finish_omp_cancellation_point (loc, clauses);
20739 #pragma omp distribute distribute-clause[optseq] new-line
20742 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20743 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20752 c_parser_omp_distribute (location_t loc, c_parser *parser,
20753 char *p_name, omp_clause_mask mask, tree *cclauses,
20756 tree clauses, block, ret;
20758 strcat (p_name, " distribute");
20759 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
20761 if (c_parser_next_token_is (parser, CPP_NAME))
20763 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20765 bool parallel = false;
20767 if (strcmp (p, "simd") == 0)
20770 parallel = strcmp (p, "parallel") == 0;
20771 if (parallel || simd)
20773 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20774 if (cclauses == NULL)
20775 cclauses = cclauses_buf;
20776 c_parser_consume_token (parser);
20777 if (!flag_openmp) /* flag_openmp_simd */
20780 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20783 return c_parser_omp_parallel (loc, parser, p_name, mask,
20786 block = c_begin_compound_stmt (true);
20788 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20791 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
20793 block = c_end_compound_stmt (loc, block, true);
20796 ret = make_node (OMP_DISTRIBUTE);
20797 TREE_TYPE (ret) = void_type_node;
20798 OMP_FOR_BODY (ret) = block;
20799 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20800 SET_EXPR_LOCATION (ret, loc);
20805 if (!flag_openmp) /* flag_openmp_simd */
20807 c_parser_skip_to_pragma_eol (parser, false);
20811 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20814 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
20815 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20818 block = c_begin_compound_stmt (true);
20819 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
20821 block = c_end_compound_stmt (loc, block, true);
20828 # pragma omp teams teams-clause[optseq] new-line
20829 structured-block */
20831 #define OMP_TEAMS_CLAUSE_MASK \
20832 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20835 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20842 c_parser_omp_teams (location_t loc, c_parser *parser,
20843 char *p_name, omp_clause_mask mask, tree *cclauses,
20846 tree clauses, block, ret;
20848 strcat (p_name, " teams");
20849 mask |= OMP_TEAMS_CLAUSE_MASK;
20851 if (c_parser_next_token_is (parser, CPP_NAME))
20853 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20854 if (strcmp (p, "distribute") == 0)
20856 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20857 if (cclauses == NULL)
20858 cclauses = cclauses_buf;
20860 c_parser_consume_token (parser);
20861 if (!flag_openmp) /* flag_openmp_simd */
20862 return c_parser_omp_distribute (loc, parser, p_name, mask,
20864 block = c_begin_omp_parallel ();
20865 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
20867 block = c_end_compound_stmt (loc, block, true);
20870 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20871 ret = make_node (OMP_TEAMS);
20872 TREE_TYPE (ret) = void_type_node;
20873 OMP_TEAMS_CLAUSES (ret) = clauses;
20874 OMP_TEAMS_BODY (ret) = block;
20875 OMP_TEAMS_COMBINED (ret) = 1;
20876 SET_EXPR_LOCATION (ret, loc);
20877 return add_stmt (ret);
20879 else if (strcmp (p, "loop") == 0)
20881 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20882 if (cclauses == NULL)
20883 cclauses = cclauses_buf;
20885 c_parser_consume_token (parser);
20886 if (!flag_openmp) /* flag_openmp_simd */
20887 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20889 block = c_begin_omp_parallel ();
20890 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
20891 block = c_end_compound_stmt (loc, block, true);
20894 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20895 ret = make_node (OMP_TEAMS);
20896 TREE_TYPE (ret) = void_type_node;
20897 OMP_TEAMS_CLAUSES (ret) = clauses;
20898 OMP_TEAMS_BODY (ret) = block;
20899 OMP_TEAMS_COMBINED (ret) = 1;
20900 SET_EXPR_LOCATION (ret, loc);
20901 return add_stmt (ret);
20904 if (!flag_openmp) /* flag_openmp_simd */
20906 c_parser_skip_to_pragma_eol (parser, false);
20910 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20913 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
20914 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20917 tree stmt = make_node (OMP_TEAMS);
20918 TREE_TYPE (stmt) = void_type_node;
20919 OMP_TEAMS_CLAUSES (stmt) = clauses;
20920 block = c_begin_omp_parallel ();
20921 add_stmt (c_parser_omp_structured_block (parser, if_p));
20922 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20923 SET_EXPR_LOCATION (stmt, loc);
20925 return add_stmt (stmt);
20929 # pragma omp target data target-data-clause[optseq] new-line
20930 structured-block */
20932 #define OMP_TARGET_DATA_CLAUSE_MASK \
20933 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20936 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20937 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20940 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
20944 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
20947 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
20948 "#pragma omp target data");
20949 c_omp_adjust_map_clauses (clauses, false);
20951 for (tree *pc = &clauses; *pc;)
20953 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20954 switch (OMP_CLAUSE_MAP_KIND (*pc))
20957 case GOMP_MAP_ALWAYS_TO:
20958 case GOMP_MAP_FROM:
20959 case GOMP_MAP_ALWAYS_FROM:
20960 case GOMP_MAP_TOFROM:
20961 case GOMP_MAP_ALWAYS_TOFROM:
20962 case GOMP_MAP_ALLOC:
20965 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20966 case GOMP_MAP_ALWAYS_POINTER:
20967 case GOMP_MAP_ATTACH_DETACH:
20971 error_at (OMP_CLAUSE_LOCATION (*pc),
20972 "%<#pragma omp target data%> with map-type other "
20973 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20974 "on %<map%> clause");
20975 *pc = OMP_CLAUSE_CHAIN (*pc);
20978 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
20979 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
20981 pc = &OMP_CLAUSE_CHAIN (*pc);
20988 "%<#pragma omp target data%> must contain at least "
20989 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
20994 tree stmt = make_node (OMP_TARGET_DATA);
20995 TREE_TYPE (stmt) = void_type_node;
20996 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
20997 keep_next_level ();
20998 tree block = c_begin_compound_stmt (true);
20999 add_stmt (c_parser_omp_structured_block (parser, if_p));
21000 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21002 SET_EXPR_LOCATION (stmt, loc);
21003 return add_stmt (stmt);
21007 # pragma omp target update target-update-clause[optseq] new-line */
21009 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
21010 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
21011 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21012 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21013 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21014 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21015 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21018 c_parser_omp_target_update (location_t loc, c_parser *parser,
21019 enum pragma_context context)
21021 if (context == pragma_stmt)
21023 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21024 "omp target update");
21025 c_parser_skip_to_pragma_eol (parser, false);
21030 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
21031 "#pragma omp target update");
21032 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
21033 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
21036 "%<#pragma omp target update%> must contain at least one "
21037 "%<from%> or %<to%> clauses");
21043 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21045 tree stmt = make_node (OMP_TARGET_UPDATE);
21046 TREE_TYPE (stmt) = void_type_node;
21047 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
21048 SET_EXPR_LOCATION (stmt, loc);
21054 # pragma omp target enter data target-data-clause[optseq] new-line */
21056 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21057 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21060 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21061 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21064 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
21065 enum pragma_context context)
21067 bool data_seen = false;
21068 if (c_parser_next_token_is (parser, CPP_NAME))
21070 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21071 if (strcmp (p, "data") == 0)
21073 c_parser_consume_token (parser);
21079 c_parser_error (parser, "expected %<data%>");
21080 c_parser_skip_to_pragma_eol (parser);
21084 if (context == pragma_stmt)
21086 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21087 "omp target enter data");
21088 c_parser_skip_to_pragma_eol (parser, false);
21094 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21097 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
21098 "#pragma omp target enter data");
21099 c_omp_adjust_map_clauses (clauses, false);
21101 for (tree *pc = &clauses; *pc;)
21103 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21104 switch (OMP_CLAUSE_MAP_KIND (*pc))
21107 case GOMP_MAP_ALWAYS_TO:
21108 case GOMP_MAP_ALLOC:
21111 case GOMP_MAP_TOFROM:
21112 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
21115 case GOMP_MAP_ALWAYS_TOFROM:
21116 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
21119 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21120 case GOMP_MAP_ALWAYS_POINTER:
21121 case GOMP_MAP_ATTACH_DETACH:
21125 error_at (OMP_CLAUSE_LOCATION (*pc),
21126 "%<#pragma omp target enter data%> with map-type other "
21127 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21128 *pc = OMP_CLAUSE_CHAIN (*pc);
21131 pc = &OMP_CLAUSE_CHAIN (*pc);
21138 "%<#pragma omp target enter data%> must contain at least "
21139 "one %<map%> clause");
21143 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
21144 TREE_TYPE (stmt) = void_type_node;
21145 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
21146 SET_EXPR_LOCATION (stmt, loc);
21152 # pragma omp target exit data target-data-clause[optseq] new-line */
21154 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21155 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21162 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
21163 enum pragma_context context)
21165 bool data_seen = false;
21166 if (c_parser_next_token_is (parser, CPP_NAME))
21168 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21169 if (strcmp (p, "data") == 0)
21171 c_parser_consume_token (parser);
21177 c_parser_error (parser, "expected %<data%>");
21178 c_parser_skip_to_pragma_eol (parser);
21182 if (context == pragma_stmt)
21184 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21185 "omp target exit data");
21186 c_parser_skip_to_pragma_eol (parser, false);
21192 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21195 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21196 "#pragma omp target exit data");
21197 c_omp_adjust_map_clauses (clauses, false);
21199 for (tree *pc = &clauses; *pc;)
21201 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21202 switch (OMP_CLAUSE_MAP_KIND (*pc))
21204 case GOMP_MAP_FROM:
21205 case GOMP_MAP_ALWAYS_FROM:
21206 case GOMP_MAP_RELEASE:
21207 case GOMP_MAP_DELETE:
21210 case GOMP_MAP_TOFROM:
21211 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
21214 case GOMP_MAP_ALWAYS_TOFROM:
21215 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
21218 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21219 case GOMP_MAP_ALWAYS_POINTER:
21220 case GOMP_MAP_ATTACH_DETACH:
21224 error_at (OMP_CLAUSE_LOCATION (*pc),
21225 "%<#pragma omp target exit data%> with map-type other "
21226 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
21227 "on %<map%> clause");
21228 *pc = OMP_CLAUSE_CHAIN (*pc);
21231 pc = &OMP_CLAUSE_CHAIN (*pc);
21238 "%<#pragma omp target exit data%> must contain at least one "
21243 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
21244 TREE_TYPE (stmt) = void_type_node;
21245 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
21246 SET_EXPR_LOCATION (stmt, loc);
21252 # pragma omp target target-clause[optseq] new-line
21253 structured-block */
21255 #define OMP_TARGET_CLAUSE_MASK \
21256 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21257 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21258 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21259 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21260 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21261 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21262 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21263 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21264 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21265 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21266 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21268 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21271 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
21273 location_t loc = c_parser_peek_token (parser)->location;
21274 c_parser_consume_pragma (parser);
21275 tree *pc = NULL, stmt, block;
21277 if (context != pragma_stmt && context != pragma_compound)
21279 c_parser_error (parser, "expected declaration specifiers");
21280 c_parser_skip_to_pragma_eol (parser);
21286 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21288 if (c_parser_next_token_is (parser, CPP_NAME))
21290 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21291 enum tree_code ccode = ERROR_MARK;
21293 if (strcmp (p, "teams") == 0)
21295 else if (strcmp (p, "parallel") == 0)
21296 ccode = OMP_PARALLEL;
21297 else if (strcmp (p, "simd") == 0)
21299 if (ccode != ERROR_MARK)
21301 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
21302 char p_name[sizeof ("#pragma omp target teams distribute "
21303 "parallel for simd")];
21305 c_parser_consume_token (parser);
21306 strcpy (p_name, "#pragma omp target");
21307 if (!flag_openmp) /* flag_openmp_simd */
21313 stmt = c_parser_omp_teams (loc, parser, p_name,
21314 OMP_TARGET_CLAUSE_MASK,
21318 stmt = c_parser_omp_parallel (loc, parser, p_name,
21319 OMP_TARGET_CLAUSE_MASK,
21323 stmt = c_parser_omp_simd (loc, parser, p_name,
21324 OMP_TARGET_CLAUSE_MASK,
21328 gcc_unreachable ();
21330 return stmt != NULL_TREE;
21332 keep_next_level ();
21333 tree block = c_begin_compound_stmt (true), ret;
21337 ret = c_parser_omp_teams (loc, parser, p_name,
21338 OMP_TARGET_CLAUSE_MASK, cclauses,
21342 ret = c_parser_omp_parallel (loc, parser, p_name,
21343 OMP_TARGET_CLAUSE_MASK, cclauses,
21347 ret = c_parser_omp_simd (loc, parser, p_name,
21348 OMP_TARGET_CLAUSE_MASK, cclauses,
21352 gcc_unreachable ();
21354 block = c_end_compound_stmt (loc, block, true);
21355 if (ret == NULL_TREE)
21357 if (ccode == OMP_TEAMS)
21358 /* For combined target teams, ensure the num_teams and
21359 thread_limit clause expressions are evaluated on the host,
21360 before entering the target construct. */
21361 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21362 c; c = OMP_CLAUSE_CHAIN (c))
21363 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
21364 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
21366 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
21367 if (OMP_CLAUSE_OPERAND (c, i)
21368 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
21370 tree expr = OMP_CLAUSE_OPERAND (c, i);
21371 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
21372 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
21373 expr, NULL_TREE, NULL_TREE);
21375 OMP_CLAUSE_OPERAND (c, i) = expr;
21376 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
21377 OMP_CLAUSE_FIRSTPRIVATE);
21378 OMP_CLAUSE_DECL (tc) = tmp;
21379 OMP_CLAUSE_CHAIN (tc)
21380 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21381 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
21383 tree stmt = make_node (OMP_TARGET);
21384 TREE_TYPE (stmt) = void_type_node;
21385 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21386 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21387 OMP_TARGET_BODY (stmt) = block;
21388 OMP_TARGET_COMBINED (stmt) = 1;
21389 SET_EXPR_LOCATION (stmt, loc);
21391 pc = &OMP_TARGET_CLAUSES (stmt);
21392 goto check_clauses;
21394 else if (!flag_openmp) /* flag_openmp_simd */
21396 c_parser_skip_to_pragma_eol (parser, false);
21399 else if (strcmp (p, "data") == 0)
21401 c_parser_consume_token (parser);
21402 c_parser_omp_target_data (loc, parser, if_p);
21405 else if (strcmp (p, "enter") == 0)
21407 c_parser_consume_token (parser);
21408 return c_parser_omp_target_enter_data (loc, parser, context);
21410 else if (strcmp (p, "exit") == 0)
21412 c_parser_consume_token (parser);
21413 return c_parser_omp_target_exit_data (loc, parser, context);
21415 else if (strcmp (p, "update") == 0)
21417 c_parser_consume_token (parser);
21418 return c_parser_omp_target_update (loc, parser, context);
21421 if (!flag_openmp) /* flag_openmp_simd */
21423 c_parser_skip_to_pragma_eol (parser, false);
21427 stmt = make_node (OMP_TARGET);
21428 TREE_TYPE (stmt) = void_type_node;
21430 OMP_TARGET_CLAUSES (stmt)
21431 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
21432 "#pragma omp target", false);
21433 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
21434 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
21436 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
21437 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
21438 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
21439 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
21440 OMP_CLAUSE_CHAIN (c) = nc;
21442 OMP_TARGET_CLAUSES (stmt)
21443 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
21444 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21446 pc = &OMP_TARGET_CLAUSES (stmt);
21447 keep_next_level ();
21448 block = c_begin_compound_stmt (true);
21449 add_stmt (c_parser_omp_structured_block (parser, if_p));
21450 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21452 SET_EXPR_LOCATION (stmt, loc);
21458 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21459 switch (OMP_CLAUSE_MAP_KIND (*pc))
21462 case GOMP_MAP_ALWAYS_TO:
21463 case GOMP_MAP_FROM:
21464 case GOMP_MAP_ALWAYS_FROM:
21465 case GOMP_MAP_TOFROM:
21466 case GOMP_MAP_ALWAYS_TOFROM:
21467 case GOMP_MAP_ALLOC:
21468 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21469 case GOMP_MAP_ALWAYS_POINTER:
21470 case GOMP_MAP_ATTACH_DETACH:
21473 error_at (OMP_CLAUSE_LOCATION (*pc),
21474 "%<#pragma omp target%> with map-type other "
21475 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21476 "on %<map%> clause");
21477 *pc = OMP_CLAUSE_CHAIN (*pc);
21480 pc = &OMP_CLAUSE_CHAIN (*pc);
21482 cfun->has_omp_target = true;
21487 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21490 # pragma omp declare variant (identifier) match(context-selector) new-line
21493 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21494 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21502 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
21504 c_token *token = c_parser_peek_token (parser);
21505 gcc_assert (token->type == CPP_NAME);
21506 tree kind = token->value;
21507 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
21508 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
21510 auto_vec<c_token> clauses;
21511 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21513 c_token *token = c_parser_peek_token (parser);
21514 if (token->type == CPP_EOF)
21516 c_parser_skip_to_pragma_eol (parser);
21519 clauses.safe_push (*token);
21520 c_parser_consume_token (parser);
21522 clauses.safe_push (*c_parser_peek_token (parser));
21523 c_parser_skip_to_pragma_eol (parser);
21525 while (c_parser_next_token_is (parser, CPP_PRAGMA))
21527 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
21528 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
21529 || c_parser_peek_2nd_token (parser)->value != kind)
21531 error ("%<#pragma omp declare %s%> must be followed by "
21532 "function declaration or definition or another "
21533 "%<#pragma omp declare %s%>",
21534 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
21537 c_parser_consume_pragma (parser);
21538 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21540 c_token *token = c_parser_peek_token (parser);
21541 if (token->type == CPP_EOF)
21543 c_parser_skip_to_pragma_eol (parser);
21546 clauses.safe_push (*token);
21547 c_parser_consume_token (parser);
21549 clauses.safe_push (*c_parser_peek_token (parser));
21550 c_parser_skip_to_pragma_eol (parser);
21553 /* Make sure nothing tries to read past the end of the tokens. */
21555 memset (&eof_token, 0, sizeof (eof_token));
21556 eof_token.type = CPP_EOF;
21557 clauses.safe_push (eof_token);
21558 clauses.safe_push (eof_token);
21562 case pragma_external:
21563 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21564 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21566 int ext = disable_extension_diagnostics ();
21568 c_parser_consume_token (parser);
21569 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21570 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21571 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21573 restore_extension_diagnostics (ext);
21576 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21579 case pragma_struct:
21582 error ("%<#pragma omp declare %s%> must be followed by "
21583 "function declaration or definition",
21584 IDENTIFIER_POINTER (kind));
21586 case pragma_compound:
21587 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21588 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21590 int ext = disable_extension_diagnostics ();
21592 c_parser_consume_token (parser);
21593 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21594 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21595 if (c_parser_next_tokens_start_declaration (parser))
21597 c_parser_declaration_or_fndef (parser, true, true, true, true,
21598 true, NULL, &clauses);
21599 restore_extension_diagnostics (ext);
21602 restore_extension_diagnostics (ext);
21604 else if (c_parser_next_tokens_start_declaration (parser))
21606 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
21610 error ("%<#pragma omp declare %s%> must be followed by "
21611 "function declaration or definition",
21612 IDENTIFIER_POINTER (kind));
21615 gcc_unreachable ();
21619 static const char *const omp_construct_selectors[] = {
21620 "simd", "target", "teams", "parallel", "for", NULL };
21621 static const char *const omp_device_selectors[] = {
21622 "kind", "isa", "arch", NULL };
21623 static const char *const omp_implementation_selectors[] = {
21624 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21625 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
21626 static const char *const omp_user_selectors[] = {
21627 "condition", NULL };
21632 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21635 score(score-expression) */
21638 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
21640 tree ret = NULL_TREE;
21644 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21645 || c_parser_next_token_is (parser, CPP_NAME))
21646 selector = c_parser_peek_token (parser)->value;
21649 c_parser_error (parser, "expected trait selector name");
21650 return error_mark_node;
21653 tree properties = NULL_TREE;
21654 const char *const *selectors = NULL;
21655 bool allow_score = true;
21656 bool allow_user = false;
21657 int property_limit = 0;
21658 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
21659 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
21660 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
21661 switch (IDENTIFIER_POINTER (set)[0])
21663 case 'c': /* construct */
21664 selectors = omp_construct_selectors;
21665 allow_score = false;
21666 property_limit = 1;
21667 property_kind = CTX_PROPERTY_SIMD;
21669 case 'd': /* device */
21670 selectors = omp_device_selectors;
21671 allow_score = false;
21673 property_limit = 3;
21674 property_kind = CTX_PROPERTY_NAME_LIST;
21676 case 'i': /* implementation */
21677 selectors = omp_implementation_selectors;
21679 property_limit = 3;
21680 property_kind = CTX_PROPERTY_NAME_LIST;
21682 case 'u': /* user */
21683 selectors = omp_user_selectors;
21684 property_limit = 1;
21685 property_kind = CTX_PROPERTY_EXPR;
21688 gcc_unreachable ();
21690 for (int i = 0; ; i++)
21692 if (selectors[i] == NULL)
21696 property_kind = CTX_PROPERTY_USER;
21701 error_at (c_parser_peek_token (parser)->location,
21702 "selector %qs not allowed for context selector "
21703 "set %qs", IDENTIFIER_POINTER (selector),
21704 IDENTIFIER_POINTER (set));
21705 c_parser_consume_token (parser);
21706 return error_mark_node;
21709 if (i == property_limit)
21710 property_kind = CTX_PROPERTY_NONE;
21711 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
21714 if (property_kind == CTX_PROPERTY_NAME_LIST
21715 && IDENTIFIER_POINTER (set)[0] == 'i'
21716 && strcmp (IDENTIFIER_POINTER (selector),
21717 "atomic_default_mem_order") == 0)
21718 property_kind = CTX_PROPERTY_ID;
21720 c_parser_consume_token (parser);
21722 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21724 if (property_kind == CTX_PROPERTY_NONE)
21726 error_at (c_parser_peek_token (parser)->location,
21727 "selector %qs does not accept any properties",
21728 IDENTIFIER_POINTER (selector));
21729 return error_mark_node;
21732 matching_parens parens;
21733 parens.require_open (parser);
21735 c_token *token = c_parser_peek_token (parser);
21737 && c_parser_next_token_is (parser, CPP_NAME)
21738 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
21739 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
21741 c_parser_consume_token (parser);
21743 matching_parens parens2;
21744 parens2.require_open (parser);
21745 tree score = c_parser_expr_no_commas (parser, NULL).value;
21746 parens2.skip_until_found_close (parser);
21747 c_parser_require (parser, CPP_COLON, "expected %<:%>");
21748 if (score != error_mark_node)
21750 mark_exp_read (score);
21751 score = c_fully_fold (score, false, NULL);
21752 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
21753 || TREE_CODE (score) != INTEGER_CST)
21754 error_at (token->location, "score argument must be "
21755 "constant integer expression");
21756 else if (tree_int_cst_sgn (score) < 0)
21757 error_at (token->location, "score argument must be "
21760 properties = tree_cons (get_identifier (" score"),
21761 score, properties);
21763 token = c_parser_peek_token (parser);
21766 switch (property_kind)
21769 case CTX_PROPERTY_USER:
21772 t = c_parser_expr_no_commas (parser, NULL).value;
21773 if (TREE_CODE (t) == STRING_CST)
21774 properties = tree_cons (NULL_TREE, t, properties);
21775 else if (t != error_mark_node)
21778 t = c_fully_fold (t, false, NULL);
21779 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21780 || !tree_fits_shwi_p (t))
21781 error_at (token->location, "property must be "
21782 "constant integer expression or string "
21785 properties = tree_cons (NULL_TREE, t, properties);
21788 return error_mark_node;
21790 if (c_parser_next_token_is (parser, CPP_COMMA))
21791 c_parser_consume_token (parser);
21797 case CTX_PROPERTY_ID:
21798 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21799 || c_parser_next_token_is (parser, CPP_NAME))
21801 tree prop = c_parser_peek_token (parser)->value;
21802 c_parser_consume_token (parser);
21803 properties = tree_cons (prop, NULL_TREE, properties);
21807 c_parser_error (parser, "expected identifier");
21808 return error_mark_node;
21811 case CTX_PROPERTY_NAME_LIST:
21814 tree prop = NULL_TREE, value = NULL_TREE;
21815 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21816 || c_parser_next_token_is (parser, CPP_NAME))
21818 prop = c_parser_peek_token (parser)->value;
21819 c_parser_consume_token (parser);
21821 else if (c_parser_next_token_is (parser, CPP_STRING))
21822 value = c_parser_string_literal (parser, false,
21826 c_parser_error (parser, "expected identifier or "
21828 return error_mark_node;
21831 properties = tree_cons (prop, value, properties);
21833 if (c_parser_next_token_is (parser, CPP_COMMA))
21834 c_parser_consume_token (parser);
21840 case CTX_PROPERTY_EXPR:
21841 t = c_parser_expr_no_commas (parser, NULL).value;
21842 if (t != error_mark_node)
21845 t = c_fully_fold (t, false, NULL);
21846 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21847 || !tree_fits_shwi_p (t))
21848 error_at (token->location, "property must be "
21849 "constant integer expression");
21851 properties = tree_cons (NULL_TREE, t, properties);
21854 return error_mark_node;
21856 case CTX_PROPERTY_SIMD:
21857 if (parms == NULL_TREE)
21859 error_at (token->location, "properties for %<simd%> "
21860 "selector may not be specified in "
21861 "%<metadirective%>");
21862 return error_mark_node;
21865 c = c_parser_omp_all_clauses (parser,
21866 OMP_DECLARE_SIMD_CLAUSE_MASK,
21868 c = c_omp_declare_simd_clauses_to_numbers (parms
21870 ? NULL_TREE : parms,
21875 gcc_unreachable ();
21878 parens.skip_until_found_close (parser);
21879 properties = nreverse (properties);
21881 else if (property_kind == CTX_PROPERTY_NAME_LIST
21882 || property_kind == CTX_PROPERTY_ID
21883 || property_kind == CTX_PROPERTY_EXPR)
21885 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
21886 return error_mark_node;
21889 ret = tree_cons (selector, properties, ret);
21891 if (c_parser_next_token_is (parser, CPP_COMMA))
21892 c_parser_consume_token (parser);
21898 return nreverse (ret);
21903 trait-set-selector[,trait-set-selector[,...]]
21905 trait-set-selector:
21906 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21908 trait-set-selector-name:
21915 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
21917 tree ret = NULL_TREE;
21920 const char *setp = "";
21921 if (c_parser_next_token_is (parser, CPP_NAME))
21922 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21926 if (strcmp (setp, "construct") == 0)
21930 if (strcmp (setp, "device") == 0)
21934 if (strcmp (setp, "implementation") == 0)
21938 if (strcmp (setp, "user") == 0)
21946 c_parser_error (parser, "expected %<construct%>, %<device%>, "
21947 "%<implementation%> or %<user%>");
21948 return error_mark_node;
21951 tree set = c_parser_peek_token (parser)->value;
21952 c_parser_consume_token (parser);
21954 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21955 return error_mark_node;
21957 matching_braces braces;
21958 if (!braces.require_open (parser))
21959 return error_mark_node;
21961 tree selectors = c_parser_omp_context_selector (parser, set, parms);
21962 if (selectors == error_mark_node)
21963 ret = error_mark_node;
21964 else if (ret != error_mark_node)
21965 ret = tree_cons (set, selectors, ret);
21967 braces.skip_until_found_close (parser);
21969 if (c_parser_next_token_is (parser, CPP_COMMA))
21970 c_parser_consume_token (parser);
21976 if (ret == error_mark_node)
21978 return nreverse (ret);
21981 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21982 that into "omp declare variant base" attribute. */
21985 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
21987 matching_parens parens;
21988 if (!parens.require_open (parser))
21991 c_parser_skip_to_pragma_eol (parser, false);
21995 if (c_parser_next_token_is_not (parser, CPP_NAME)
21996 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
21998 c_parser_error (parser, "expected identifier");
22002 c_token *token = c_parser_peek_token (parser);
22003 tree variant = lookup_name (token->value);
22005 if (variant == NULL_TREE)
22007 undeclared_variable (token->location, token->value);
22008 variant = error_mark_node;
22011 c_parser_consume_token (parser);
22013 parens.require_close (parser);
22015 const char *clause = "";
22016 location_t match_loc = c_parser_peek_token (parser)->location;
22017 if (c_parser_next_token_is (parser, CPP_NAME))
22018 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22019 if (strcmp (clause, "match"))
22021 c_parser_error (parser, "expected %<match%>");
22025 c_parser_consume_token (parser);
22027 if (!parens.require_open (parser))
22030 if (parms == NULL_TREE)
22031 parms = error_mark_node;
22033 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
22034 if (ctx == error_mark_node)
22036 ctx = omp_check_context_selector (match_loc, ctx);
22037 if (ctx != error_mark_node && variant != error_mark_node)
22039 if (TREE_CODE (variant) != FUNCTION_DECL)
22041 error_at (token->location, "variant %qD is not a function", variant);
22042 variant = error_mark_node;
22044 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
22045 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
22047 error_at (token->location, "variant %qD and base %qD have "
22048 "incompatible types", variant, fndecl);
22049 variant = error_mark_node;
22051 else if (fndecl_built_in_p (variant)
22052 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22053 "__builtin_", strlen ("__builtin_")) == 0
22054 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22055 "__sync_", strlen ("__sync_")) == 0
22056 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22057 "__atomic_", strlen ("__atomic_")) == 0))
22059 error_at (token->location, "variant %qD is a built-in", variant);
22060 variant = error_mark_node;
22062 if (variant != error_mark_node)
22064 C_DECL_USED (variant) = 1;
22065 tree construct = omp_get_context_selector (ctx, "construct", NULL);
22066 omp_mark_declare_variant (match_loc, variant, construct);
22067 if (omp_context_selector_matches (ctx))
22070 = tree_cons (get_identifier ("omp declare variant base"),
22071 build_tree_list (variant, ctx),
22072 DECL_ATTRIBUTES (fndecl));
22073 DECL_ATTRIBUTES (fndecl) = attr;
22078 parens.require_close (parser);
22079 c_parser_skip_to_pragma_eol (parser);
22082 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22083 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22084 or "omp declare variant base" attribute. */
22087 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
22088 vec<c_token> *pclauses)
22090 vec<c_token> &clauses = *pclauses;
22092 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22093 indicates error has been reported and CPP_PRAGMA that
22094 c_finish_omp_declare_simd has already processed the tokens. */
22095 if (clauses.exists () && clauses[0].type == CPP_EOF)
22097 const char *kind = "simd";
22098 if (clauses.exists ()
22099 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
22100 kind = IDENTIFIER_POINTER (clauses[0].value);
22101 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
22102 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
22104 error ("%<#pragma omp declare %s%> not immediately followed by "
22105 "a function declaration or definition", kind);
22106 clauses[0].type = CPP_EOF;
22109 if (clauses.exists () && clauses[0].type != CPP_NAME)
22111 error_at (DECL_SOURCE_LOCATION (fndecl),
22112 "%<#pragma omp declare %s%> not immediately followed by "
22113 "a single function declaration or definition", kind);
22114 clauses[0].type = CPP_EOF;
22118 if (parms == NULL_TREE)
22119 parms = DECL_ARGUMENTS (fndecl);
22121 unsigned int tokens_avail = parser->tokens_avail;
22122 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22124 parser->tokens = clauses.address ();
22125 parser->tokens_avail = clauses.length ();
22127 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22128 while (parser->tokens_avail > 3)
22130 c_token *token = c_parser_peek_token (parser);
22131 gcc_assert (token->type == CPP_NAME
22132 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
22133 c_parser_consume_token (parser);
22134 parser->in_pragma = true;
22136 if (strcmp (kind, "simd") == 0)
22139 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
22140 "#pragma omp declare simd");
22141 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
22142 if (c != NULL_TREE)
22143 c = tree_cons (NULL_TREE, c, NULL_TREE);
22144 c = build_tree_list (get_identifier ("omp declare simd"), c);
22145 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
22146 DECL_ATTRIBUTES (fndecl) = c;
22150 gcc_assert (strcmp (kind, "variant") == 0);
22151 c_finish_omp_declare_variant (parser, fndecl, parms);
22155 parser->tokens = &parser->tokens_buf[0];
22156 parser->tokens_avail = tokens_avail;
22157 if (clauses.exists ())
22158 clauses[0].type = CPP_PRAGMA;
22163 # pragma omp declare target new-line
22164 declarations and definitions
22165 # pragma omp end declare target new-line
22168 # pragma omp declare target ( extended-list ) new-line
22170 # pragma omp declare target declare-target-clauses[seq] new-line */
22172 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22173 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22174 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22175 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22179 c_parser_omp_declare_target (c_parser *parser)
22181 tree clauses = NULL_TREE;
22182 int device_type = 0;
22183 bool only_device_type = true;
22184 if (c_parser_next_token_is (parser, CPP_NAME))
22185 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
22186 "#pragma omp declare target");
22187 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22189 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
22191 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22192 c_parser_skip_to_pragma_eol (parser);
22196 c_parser_skip_to_pragma_eol (parser);
22197 current_omp_declare_target_attribute++;
22200 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22201 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22202 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22203 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22205 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22207 tree t = OMP_CLAUSE_DECL (c), id;
22208 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
22209 tree at2 = lookup_attribute ("omp declare target link",
22210 DECL_ATTRIBUTES (t));
22211 only_device_type = false;
22212 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
22214 id = get_identifier ("omp declare target link");
22215 std::swap (at1, at2);
22218 id = get_identifier ("omp declare target");
22221 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
22222 error_at (OMP_CLAUSE_LOCATION (c),
22223 "%qD specified both in declare target %<link%> and %qs"
22224 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
22226 error_at (OMP_CLAUSE_LOCATION (c),
22227 "%qD specified both in declare target %<link%> and "
22228 "%<to%> or %<enter%> clauses", t);
22233 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22234 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
22237 symtab_node *node = symtab_node::get (t);
22240 node->offloadable = 1;
22241 if (ENABLE_OFFLOADING)
22243 g->have_offload = true;
22244 if (is_a <varpool_node *> (node))
22245 vec_safe_push (offload_vars, t);
22249 if (TREE_CODE (t) != FUNCTION_DECL)
22251 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
22253 tree at3 = lookup_attribute ("omp declare target host",
22254 DECL_ATTRIBUTES (t));
22255 if (at3 == NULL_TREE)
22257 id = get_identifier ("omp declare target host");
22258 DECL_ATTRIBUTES (t)
22259 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22262 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
22264 tree at3 = lookup_attribute ("omp declare target nohost",
22265 DECL_ATTRIBUTES (t));
22266 if (at3 == NULL_TREE)
22268 id = get_identifier ("omp declare target nohost");
22269 DECL_ATTRIBUTES (t)
22270 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22274 if (device_type && only_device_type)
22275 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
22276 "directive with only %<device_type%> clauses ignored");
22280 c_parser_omp_end_declare_target (c_parser *parser)
22282 location_t loc = c_parser_peek_token (parser)->location;
22283 c_parser_consume_pragma (parser);
22284 if (c_parser_next_token_is (parser, CPP_NAME)
22285 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22288 c_parser_consume_token (parser);
22289 if (c_parser_next_token_is (parser, CPP_NAME)
22290 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22292 c_parser_consume_token (parser);
22295 c_parser_error (parser, "expected %<target%>");
22296 c_parser_skip_to_pragma_eol (parser);
22302 c_parser_error (parser, "expected %<declare%>");
22303 c_parser_skip_to_pragma_eol (parser);
22306 c_parser_skip_to_pragma_eol (parser);
22307 if (!current_omp_declare_target_attribute)
22308 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
22309 "%<#pragma omp declare target%>");
22311 current_omp_declare_target_attribute--;
22316 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22317 initializer-clause[opt] new-line
22319 initializer-clause:
22320 initializer (omp_priv = initializer)
22321 initializer (function-name (argument-list)) */
22324 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
22326 unsigned int tokens_avail = 0, i;
22327 vec<tree> types = vNULL;
22328 vec<c_token> clauses = vNULL;
22329 enum tree_code reduc_code = ERROR_MARK;
22330 tree reduc_id = NULL_TREE;
22332 location_t rloc = c_parser_peek_token (parser)->location;
22334 if (context == pragma_struct || context == pragma_param)
22336 error ("%<#pragma omp declare reduction%> not at file or block scope");
22340 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22343 switch (c_parser_peek_token (parser)->type)
22346 reduc_code = PLUS_EXPR;
22349 reduc_code = MULT_EXPR;
22352 reduc_code = MINUS_EXPR;
22355 reduc_code = BIT_AND_EXPR;
22358 reduc_code = BIT_XOR_EXPR;
22361 reduc_code = BIT_IOR_EXPR;
22364 reduc_code = TRUTH_ANDIF_EXPR;
22367 reduc_code = TRUTH_ORIF_EXPR;
22371 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22372 if (strcmp (p, "min") == 0)
22374 reduc_code = MIN_EXPR;
22377 if (strcmp (p, "max") == 0)
22379 reduc_code = MAX_EXPR;
22382 reduc_id = c_parser_peek_token (parser)->value;
22385 c_parser_error (parser,
22386 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22387 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22391 tree orig_reduc_id, reduc_decl;
22392 orig_reduc_id = reduc_id;
22393 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
22394 reduc_decl = c_omp_reduction_decl (reduc_id);
22395 c_parser_consume_token (parser);
22397 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
22402 location_t loc = c_parser_peek_token (parser)->location;
22403 struct c_type_name *ctype = c_parser_type_name (parser);
22406 type = groktypename (ctype, NULL, NULL);
22407 if (type == error_mark_node)
22409 else if ((INTEGRAL_TYPE_P (type)
22410 || TREE_CODE (type) == REAL_TYPE
22411 || TREE_CODE (type) == COMPLEX_TYPE)
22412 && orig_reduc_id == NULL_TREE)
22413 error_at (loc, "predeclared arithmetic type in "
22414 "%<#pragma omp declare reduction%>");
22415 else if (TREE_CODE (type) == FUNCTION_TYPE
22416 || TREE_CODE (type) == ARRAY_TYPE)
22417 error_at (loc, "function or array type in "
22418 "%<#pragma omp declare reduction%>");
22419 else if (TYPE_ATOMIC (type))
22420 error_at (loc, "%<_Atomic%> qualified type in "
22421 "%<#pragma omp declare reduction%>");
22422 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
22423 error_at (loc, "const, volatile or restrict qualified type in "
22424 "%<#pragma omp declare reduction%>");
22428 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
22429 if (comptypes (TREE_PURPOSE (t), type))
22431 error_at (loc, "redeclaration of %qs "
22432 "%<#pragma omp declare reduction%> for "
22434 IDENTIFIER_POINTER (reduc_id)
22435 + sizeof ("omp declare reduction ") - 1,
22438 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
22440 error_at (ploc, "previous %<#pragma omp declare "
22444 if (t == NULL_TREE)
22445 types.safe_push (type);
22447 if (c_parser_next_token_is (parser, CPP_COMMA))
22448 c_parser_consume_token (parser);
22456 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
22457 || types.is_empty ())
22460 clauses.release ();
22464 c_token *token = c_parser_peek_token (parser);
22465 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
22467 c_parser_consume_token (parser);
22469 c_parser_skip_to_pragma_eol (parser);
22473 if (types.length () > 1)
22475 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22477 c_token *token = c_parser_peek_token (parser);
22478 if (token->type == CPP_EOF)
22480 clauses.safe_push (*token);
22481 c_parser_consume_token (parser);
22483 clauses.safe_push (*c_parser_peek_token (parser));
22484 c_parser_skip_to_pragma_eol (parser);
22486 /* Make sure nothing tries to read past the end of the tokens. */
22488 memset (&eof_token, 0, sizeof (eof_token));
22489 eof_token.type = CPP_EOF;
22490 clauses.safe_push (eof_token);
22491 clauses.safe_push (eof_token);
22494 int errs = errorcount;
22495 FOR_EACH_VEC_ELT (types, i, type)
22497 tokens_avail = parser->tokens_avail;
22498 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22499 if (!clauses.is_empty ())
22501 parser->tokens = clauses.address ();
22502 parser->tokens_avail = clauses.length ();
22503 parser->in_pragma = true;
22506 bool nested = current_function_decl != NULL_TREE;
22508 c_push_function_context ();
22509 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
22510 reduc_id, default_function_type);
22511 current_function_decl = fndecl;
22512 allocate_struct_function (fndecl, true);
22514 tree stmt = push_stmt_list ();
22515 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22516 warn about these. */
22517 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
22518 get_identifier ("omp_out"), type);
22519 DECL_ARTIFICIAL (omp_out) = 1;
22520 DECL_CONTEXT (omp_out) = fndecl;
22521 pushdecl (omp_out);
22522 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
22523 get_identifier ("omp_in"), type);
22524 DECL_ARTIFICIAL (omp_in) = 1;
22525 DECL_CONTEXT (omp_in) = fndecl;
22527 struct c_expr combiner = c_parser_expression (parser);
22528 struct c_expr initializer;
22529 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
22531 initializer.set_error ();
22532 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22534 else if (c_parser_next_token_is (parser, CPP_NAME)
22535 && strcmp (IDENTIFIER_POINTER
22536 (c_parser_peek_token (parser)->value),
22537 "initializer") == 0)
22539 c_parser_consume_token (parser);
22542 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
22543 get_identifier ("omp_priv"), type);
22544 DECL_ARTIFICIAL (omp_priv) = 1;
22545 DECL_INITIAL (omp_priv) = error_mark_node;
22546 DECL_CONTEXT (omp_priv) = fndecl;
22547 pushdecl (omp_priv);
22548 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
22549 get_identifier ("omp_orig"), type);
22550 DECL_ARTIFICIAL (omp_orig) = 1;
22551 DECL_CONTEXT (omp_orig) = fndecl;
22552 pushdecl (omp_orig);
22553 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22555 else if (!c_parser_next_token_is (parser, CPP_NAME))
22557 c_parser_error (parser, "expected %<omp_priv%> or "
22561 else if (strcmp (IDENTIFIER_POINTER
22562 (c_parser_peek_token (parser)->value),
22565 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
22566 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22568 c_parser_error (parser, "expected function-name %<(%>");
22572 initializer = c_parser_postfix_expression (parser);
22573 if (initializer.value
22574 && TREE_CODE (initializer.value) == CALL_EXPR)
22577 tree c = initializer.value;
22578 for (j = 0; j < call_expr_nargs (c); j++)
22580 tree a = CALL_EXPR_ARG (c, j);
22582 if (TREE_CODE (a) == ADDR_EXPR
22583 && TREE_OPERAND (a, 0) == omp_priv)
22586 if (j == call_expr_nargs (c))
22587 error ("one of the initializer call arguments should be "
22593 c_parser_consume_token (parser);
22594 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22598 tree st = push_stmt_list ();
22599 location_t loc = c_parser_peek_token (parser)->location;
22600 rich_location richloc (line_table, loc);
22601 start_init (omp_priv, NULL_TREE, 0, &richloc);
22602 struct c_expr init = c_parser_initializer (parser, omp_priv);
22604 finish_decl (omp_priv, loc, init.value,
22605 init.original_type, NULL_TREE);
22606 pop_stmt_list (st);
22610 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22616 c_parser_skip_to_pragma_eol (parser);
22618 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
22619 DECL_INITIAL (reduc_decl));
22620 DECL_INITIAL (reduc_decl) = t;
22621 DECL_SOURCE_LOCATION (omp_out) = rloc;
22622 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
22623 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
22624 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
22625 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
22626 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
22629 DECL_SOURCE_LOCATION (omp_priv) = rloc;
22630 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
22631 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
22632 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
22633 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
22634 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22635 walk_tree (&DECL_INITIAL (omp_priv),
22636 c_check_omp_declare_reduction_r,
22637 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22641 pop_stmt_list (stmt);
22643 if (cfun->language != NULL)
22645 ggc_free (cfun->language);
22646 cfun->language = NULL;
22649 current_function_decl = NULL_TREE;
22651 c_pop_function_context ();
22653 if (!clauses.is_empty ())
22655 parser->tokens = &parser->tokens_buf[0];
22656 parser->tokens_avail = tokens_avail;
22660 if (errs != errorcount)
22664 clauses.release ();
22670 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22671 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22672 initializer-clause[opt] new-line
22673 #pragma omp declare target new-line
22676 #pragma omp declare variant (identifier) match (context-selector) */
22679 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
22681 c_parser_consume_pragma (parser);
22682 if (c_parser_next_token_is (parser, CPP_NAME))
22684 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22685 if (strcmp (p, "simd") == 0)
22687 /* c_parser_consume_token (parser); done in
22688 c_parser_omp_declare_simd. */
22689 c_parser_omp_declare_simd (parser, context);
22692 if (strcmp (p, "reduction") == 0)
22694 c_parser_consume_token (parser);
22695 c_parser_omp_declare_reduction (parser, context);
22698 if (!flag_openmp) /* flag_openmp_simd */
22700 c_parser_skip_to_pragma_eol (parser, false);
22703 if (strcmp (p, "target") == 0)
22705 c_parser_consume_token (parser);
22706 c_parser_omp_declare_target (parser);
22709 if (strcmp (p, "variant") == 0)
22711 /* c_parser_consume_token (parser); done in
22712 c_parser_omp_declare_simd. */
22713 c_parser_omp_declare_simd (parser, context);
22718 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
22719 "%<target%> or %<variant%>");
22720 c_parser_skip_to_pragma_eol (parser);
22725 #pragma omp requires clauses[optseq] new-line */
22728 c_parser_omp_requires (c_parser *parser)
22731 enum omp_requires new_req = (enum omp_requires) 0;
22733 c_parser_consume_pragma (parser);
22735 location_t loc = c_parser_peek_token (parser)->location;
22736 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22739 && c_parser_next_token_is (parser, CPP_COMMA)
22740 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22741 c_parser_consume_token (parser);
22745 if (c_parser_next_token_is (parser, CPP_NAME))
22748 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22749 location_t cloc = c_parser_peek_token (parser)->location;
22750 enum omp_requires this_req = (enum omp_requires) 0;
22752 if (!strcmp (p, "unified_address"))
22753 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
22754 else if (!strcmp (p, "unified_shared_memory"))
22755 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
22756 else if (!strcmp (p, "dynamic_allocators"))
22757 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
22758 else if (!strcmp (p, "reverse_offload"))
22759 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
22760 else if (!strcmp (p, "atomic_default_mem_order"))
22762 c_parser_consume_token (parser);
22764 matching_parens parens;
22765 if (parens.require_open (parser))
22767 if (c_parser_next_token_is (parser, CPP_NAME))
22769 tree v = c_parser_peek_token (parser)->value;
22770 p = IDENTIFIER_POINTER (v);
22772 if (!strcmp (p, "seq_cst"))
22774 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
22775 else if (!strcmp (p, "relaxed"))
22777 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
22778 else if (!strcmp (p, "acq_rel"))
22780 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
22784 error_at (c_parser_peek_token (parser)->location,
22785 "expected %<seq_cst%>, %<relaxed%> or "
22787 switch (c_parser_peek_token (parser)->type)
22790 case CPP_PRAGMA_EOL:
22791 case CPP_CLOSE_PAREN:
22794 if (c_parser_peek_2nd_token (parser)->type
22795 == CPP_CLOSE_PAREN)
22796 c_parser_consume_token (parser);
22801 c_parser_consume_token (parser);
22803 parens.skip_until_found_close (parser);
22806 c_parser_skip_to_pragma_eol (parser, false);
22814 error_at (cloc, "expected %<unified_address%>, "
22815 "%<unified_shared_memory%>, "
22816 "%<dynamic_allocators%>, "
22817 "%<reverse_offload%> "
22818 "or %<atomic_default_mem_order%> clause");
22819 c_parser_skip_to_pragma_eol (parser, false);
22823 c_parser_consume_token (parser);
22826 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22828 if ((this_req & new_req) != 0)
22829 error_at (cloc, "too many %qs clauses", p);
22830 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
22831 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
22832 error_at (cloc, "%qs clause used lexically after first "
22833 "target construct or offloading API", p);
22835 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22837 error_at (cloc, "too many %qs clauses",
22838 "atomic_default_mem_order");
22839 this_req = (enum omp_requires) 0;
22841 else if ((omp_requires_mask
22842 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22844 error_at (cloc, "more than one %<atomic_default_mem_order%>"
22845 " clause in a single compilation unit");
22847 = (enum omp_requires)
22849 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
22851 else if ((omp_requires_mask
22852 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
22853 error_at (cloc, "%<atomic_default_mem_order%> clause used "
22854 "lexically after first %<atomic%> construct "
22855 "without memory order clause");
22856 new_req = (enum omp_requires) (new_req | this_req);
22858 = (enum omp_requires) (omp_requires_mask | this_req);
22864 c_parser_skip_to_pragma_eol (parser);
22867 error_at (loc, "%<pragma omp requires%> requires at least one clause");
22870 /* Helper function for c_parser_omp_taskloop.
22871 Disallow zero sized or potentially zero sized task reductions. */
22874 c_finish_taskloop_clauses (tree clauses)
22876 tree *pc = &clauses;
22877 for (tree c = clauses; c; c = *pc)
22879 bool remove = false;
22880 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
22882 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
22883 if (integer_zerop (TYPE_SIZE_UNIT (type)))
22885 error_at (OMP_CLAUSE_LOCATION (c),
22886 "zero sized type %qT in %<reduction%> clause", type);
22889 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
22891 error_at (OMP_CLAUSE_LOCATION (c),
22892 "variable sized type %qT in %<reduction%> clause",
22898 *pc = OMP_CLAUSE_CHAIN (c);
22900 pc = &OMP_CLAUSE_CHAIN (c);
22906 #pragma omp taskloop taskloop-clause[optseq] new-line
22909 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22912 #define OMP_TASKLOOP_CLAUSE_MASK \
22913 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
22919 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
22920 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22921 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22922 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22923 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22925 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
22926 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22928 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22929 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22932 c_parser_omp_taskloop (location_t loc, c_parser *parser,
22933 char *p_name, omp_clause_mask mask, tree *cclauses,
22936 tree clauses, block, ret;
22938 strcat (p_name, " taskloop");
22939 mask |= OMP_TASKLOOP_CLAUSE_MASK;
22940 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22942 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
22943 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
22945 if (c_parser_next_token_is (parser, CPP_NAME))
22947 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22949 if (strcmp (p, "simd") == 0)
22951 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22952 if (cclauses == NULL)
22953 cclauses = cclauses_buf;
22954 c_parser_consume_token (parser);
22955 if (!flag_openmp) /* flag_openmp_simd */
22956 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22958 block = c_begin_compound_stmt (true);
22959 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22960 block = c_end_compound_stmt (loc, block, true);
22963 ret = make_node (OMP_TASKLOOP);
22964 TREE_TYPE (ret) = void_type_node;
22965 OMP_FOR_BODY (ret) = block;
22966 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22967 OMP_FOR_CLAUSES (ret)
22968 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
22969 SET_EXPR_LOCATION (ret, loc);
22974 if (!flag_openmp) /* flag_openmp_simd */
22976 c_parser_skip_to_pragma_eol (parser, false);
22980 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22983 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
22984 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22987 clauses = c_finish_taskloop_clauses (clauses);
22988 block = c_begin_compound_stmt (true);
22989 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
22990 block = c_end_compound_stmt (loc, block, true);
22997 #pragma omp nothing new-line */
23000 c_parser_omp_nothing (c_parser *parser)
23002 c_parser_consume_pragma (parser);
23003 c_parser_skip_to_pragma_eol (parser);
23007 #pragma omp error clauses[optseq] new-line */
23010 c_parser_omp_error (c_parser *parser, enum pragma_context context)
23012 int at_compilation = -1;
23013 int severity_fatal = -1;
23014 tree message = NULL_TREE;
23017 location_t loc = c_parser_peek_token (parser)->location;
23019 c_parser_consume_pragma (parser);
23021 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23024 && c_parser_next_token_is (parser, CPP_COMMA)
23025 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23026 c_parser_consume_token (parser);
23030 if (!c_parser_next_token_is (parser, CPP_NAME))
23034 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23035 location_t cloc = c_parser_peek_token (parser)->location;
23036 static const char *args[] = {
23037 "execution", "compilation", "warning", "fatal"
23040 int idx = 0, n = -1;
23041 tree m = NULL_TREE;
23043 if (!strcmp (p, "at"))
23044 v = &at_compilation;
23045 else if (!strcmp (p, "severity"))
23047 v = &severity_fatal;
23050 else if (strcmp (p, "message"))
23053 "expected %<at%>, %<severity%> or %<message%> clause");
23054 c_parser_skip_to_pragma_eol (parser, false);
23058 c_parser_consume_token (parser);
23060 matching_parens parens;
23061 if (parens.require_open (parser))
23065 location_t expr_loc = c_parser_peek_token (parser)->location;
23066 c_expr expr = c_parser_expr_no_commas (parser, NULL);
23067 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
23068 m = convert (const_string_type_node, expr.value);
23069 m = c_fully_fold (m, false, NULL);
23073 if (c_parser_next_token_is (parser, CPP_NAME))
23075 tree val = c_parser_peek_token (parser)->value;
23076 const char *q = IDENTIFIER_POINTER (val);
23078 if (!strcmp (q, args[idx]))
23080 else if (!strcmp (q, args[idx + 1]))
23085 error_at (c_parser_peek_token (parser)->location,
23086 "expected %qs or %qs", args[idx], args[idx + 1]);
23088 switch (c_parser_peek_token (parser)->type)
23091 case CPP_PRAGMA_EOL:
23092 case CPP_CLOSE_PAREN:
23095 if (c_parser_peek_2nd_token (parser)->type
23096 == CPP_CLOSE_PAREN)
23097 c_parser_consume_token (parser);
23102 c_parser_consume_token (parser);
23105 parens.skip_until_found_close (parser);
23111 error_at (cloc, "too many %qs clauses", p);
23121 error_at (cloc, "too many %qs clauses", p);
23131 c_parser_skip_to_pragma_eol (parser);
23135 if (at_compilation == -1)
23136 at_compilation = 1;
23137 if (severity_fatal == -1)
23138 severity_fatal = 1;
23139 if (!at_compilation)
23141 if (context != pragma_compound)
23143 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
23144 "may only be used in compound statements");
23148 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
23149 : BUILT_IN_GOMP_WARNING);
23151 message = build_zero_cst (const_string_type_node);
23152 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
23153 build_all_ones_cst (size_type_node));
23157 const char *msg = NULL;
23160 msg = c_getstr (message);
23162 msg = _("<message unknown at compile time>");
23165 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23166 "%<pragma omp error%> encountered: %s", msg);
23168 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23169 "%<pragma omp error%> encountered");
23173 /* Main entry point to parsing most OpenMP pragmas. */
23176 c_parser_omp_construct (c_parser *parser, bool *if_p)
23178 enum pragma_kind p_kind;
23181 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
23182 omp_clause_mask mask (0);
23184 loc = c_parser_peek_token (parser)->location;
23185 p_kind = c_parser_peek_token (parser)->pragma_kind;
23186 c_parser_consume_pragma (parser);
23190 case PRAGMA_OACC_ATOMIC:
23191 c_parser_omp_atomic (loc, parser, true);
23193 case PRAGMA_OACC_CACHE:
23194 strcpy (p_name, "#pragma acc");
23195 stmt = c_parser_oacc_cache (loc, parser);
23197 case PRAGMA_OACC_DATA:
23198 stmt = c_parser_oacc_data (loc, parser, if_p);
23200 case PRAGMA_OACC_HOST_DATA:
23201 stmt = c_parser_oacc_host_data (loc, parser, if_p);
23203 case PRAGMA_OACC_KERNELS:
23204 case PRAGMA_OACC_PARALLEL:
23205 case PRAGMA_OACC_SERIAL:
23206 strcpy (p_name, "#pragma acc");
23207 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
23209 case PRAGMA_OACC_LOOP:
23210 strcpy (p_name, "#pragma acc");
23211 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
23213 case PRAGMA_OACC_WAIT:
23214 strcpy (p_name, "#pragma wait");
23215 stmt = c_parser_oacc_wait (loc, parser, p_name);
23217 case PRAGMA_OMP_ALLOCATE:
23218 c_parser_omp_allocate (loc, parser);
23220 case PRAGMA_OMP_ATOMIC:
23221 c_parser_omp_atomic (loc, parser, false);
23223 case PRAGMA_OMP_CRITICAL:
23224 stmt = c_parser_omp_critical (loc, parser, if_p);
23226 case PRAGMA_OMP_DISTRIBUTE:
23227 strcpy (p_name, "#pragma omp");
23228 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
23230 case PRAGMA_OMP_FOR:
23231 strcpy (p_name, "#pragma omp");
23232 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
23234 case PRAGMA_OMP_LOOP:
23235 strcpy (p_name, "#pragma omp");
23236 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
23238 case PRAGMA_OMP_MASKED:
23239 strcpy (p_name, "#pragma omp");
23240 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
23242 case PRAGMA_OMP_MASTER:
23243 strcpy (p_name, "#pragma omp");
23244 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
23246 case PRAGMA_OMP_PARALLEL:
23247 strcpy (p_name, "#pragma omp");
23248 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
23250 case PRAGMA_OMP_SCOPE:
23251 stmt = c_parser_omp_scope (loc, parser, if_p);
23253 case PRAGMA_OMP_SECTIONS:
23254 strcpy (p_name, "#pragma omp");
23255 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
23257 case PRAGMA_OMP_SIMD:
23258 strcpy (p_name, "#pragma omp");
23259 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
23261 case PRAGMA_OMP_SINGLE:
23262 stmt = c_parser_omp_single (loc, parser, if_p);
23264 case PRAGMA_OMP_TASK:
23265 stmt = c_parser_omp_task (loc, parser, if_p);
23267 case PRAGMA_OMP_TASKGROUP:
23268 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
23270 case PRAGMA_OMP_TASKLOOP:
23271 strcpy (p_name, "#pragma omp");
23272 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
23274 case PRAGMA_OMP_TEAMS:
23275 strcpy (p_name, "#pragma omp");
23276 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
23279 gcc_unreachable ();
23282 if (stmt && stmt != error_mark_node)
23283 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
23288 # pragma omp threadprivate (variable-list) */
23291 c_parser_omp_threadprivate (c_parser *parser)
23296 c_parser_consume_pragma (parser);
23297 loc = c_parser_peek_token (parser)->location;
23298 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
23300 /* Mark every variable in VARS to be assigned thread local storage. */
23301 for (t = vars; t; t = TREE_CHAIN (t))
23303 tree v = TREE_PURPOSE (t);
23305 /* FIXME diagnostics: Ideally we should keep individual
23306 locations for all the variables in the var list to make the
23307 following errors more precise. Perhaps
23308 c_parser_omp_var_list_parens() should construct a list of
23309 locations to go along with the var list. */
23311 /* If V had already been marked threadprivate, it doesn't matter
23312 whether it had been used prior to this point. */
23314 error_at (loc, "%qD is not a variable", v);
23315 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
23316 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
23317 else if (! is_global_var (v))
23318 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
23319 else if (TREE_TYPE (v) == error_mark_node)
23321 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
23322 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
23325 if (! DECL_THREAD_LOCAL_P (v))
23327 set_decl_tls_model (v, decl_default_tls_model (v));
23328 /* If rtl has been already set for this var, call
23329 make_decl_rtl once again, so that encode_section_info
23330 has a chance to look at the new decl flags. */
23331 if (DECL_RTL_SET_P (v))
23334 C_DECL_THREADPRIVATE_P (v) = 1;
23338 c_parser_skip_to_pragma_eol (parser);
23341 /* Parse a transaction attribute (GCC Extension).
23343 transaction-attribute:
23345 attribute-specifier
23349 c_parser_transaction_attributes (c_parser *parser)
23351 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
23352 return c_parser_gnu_attributes (parser);
23354 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
23356 return c_parser_std_attribute_specifier (parser, true);
23359 /* Parse a __transaction_atomic or __transaction_relaxed statement
23362 transaction-statement:
23363 __transaction_atomic transaction-attribute[opt] compound-statement
23364 __transaction_relaxed compound-statement
23366 Note that the only valid attribute is: "outer".
23370 c_parser_transaction (c_parser *parser, enum rid keyword)
23372 unsigned int old_in = parser->in_transaction;
23373 unsigned int this_in = 1, new_in;
23374 location_t loc = c_parser_peek_token (parser)->location;
23377 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23378 || keyword == RID_TRANSACTION_RELAXED)
23379 && c_parser_next_token_is_keyword (parser, keyword));
23380 c_parser_consume_token (parser);
23382 if (keyword == RID_TRANSACTION_RELAXED)
23383 this_in |= TM_STMT_ATTR_RELAXED;
23386 attrs = c_parser_transaction_attributes (parser);
23388 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
23391 /* Keep track if we're in the lexical scope of an outer transaction. */
23392 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
23394 parser->in_transaction = new_in;
23395 stmt = c_parser_compound_statement (parser);
23396 parser->in_transaction = old_in;
23399 stmt = c_finish_transaction (loc, stmt, this_in);
23401 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23402 "%<__transaction_atomic%> without transactional memory support enabled"
23403 : "%<__transaction_relaxed %> "
23404 "without transactional memory support enabled"));
23409 /* Parse a __transaction_atomic or __transaction_relaxed expression
23412 transaction-expression:
23413 __transaction_atomic ( expression )
23414 __transaction_relaxed ( expression )
23417 static struct c_expr
23418 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
23421 unsigned int old_in = parser->in_transaction;
23422 unsigned int this_in = 1;
23423 location_t loc = c_parser_peek_token (parser)->location;
23426 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23427 || keyword == RID_TRANSACTION_RELAXED)
23428 && c_parser_next_token_is_keyword (parser, keyword));
23429 c_parser_consume_token (parser);
23431 if (keyword == RID_TRANSACTION_RELAXED)
23432 this_in |= TM_STMT_ATTR_RELAXED;
23435 attrs = c_parser_transaction_attributes (parser);
23437 this_in |= parse_tm_stmt_attr (attrs, 0);
23440 parser->in_transaction = this_in;
23441 matching_parens parens;
23442 if (parens.require_open (parser))
23444 tree expr = c_parser_expression (parser).value;
23445 ret.original_type = TREE_TYPE (expr);
23446 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
23447 if (this_in & TM_STMT_ATTR_RELAXED)
23448 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
23449 SET_EXPR_LOCATION (ret.value, loc);
23450 ret.original_code = TRANSACTION_EXPR;
23451 if (!parens.require_close (parser))
23453 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
23461 ret.original_code = ERROR_MARK;
23462 ret.original_type = NULL;
23464 parser->in_transaction = old_in;
23467 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23468 "%<__transaction_atomic%> without transactional memory support enabled"
23469 : "%<__transaction_relaxed %> "
23470 "without transactional memory support enabled"));
23472 set_c_expr_source_range (&ret, loc, loc);
23477 /* Parse a __transaction_cancel statement (GCC Extension).
23479 transaction-cancel-statement:
23480 __transaction_cancel transaction-attribute[opt] ;
23482 Note that the only valid attribute is "outer".
23486 c_parser_transaction_cancel (c_parser *parser)
23488 location_t loc = c_parser_peek_token (parser)->location;
23490 bool is_outer = false;
23492 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
23493 c_parser_consume_token (parser);
23495 attrs = c_parser_transaction_attributes (parser);
23497 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
23501 error_at (loc, "%<__transaction_cancel%> without "
23502 "transactional memory support enabled");
23505 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
23507 error_at (loc, "%<__transaction_cancel%> within a "
23508 "%<__transaction_relaxed%>");
23513 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
23514 && !is_tm_may_cancel_outer (current_function_decl))
23516 error_at (loc, "outer %<__transaction_cancel%> not "
23517 "within outer %<__transaction_atomic%> or "
23518 "a %<transaction_may_cancel_outer%> function");
23522 else if (parser->in_transaction == 0)
23524 error_at (loc, "%<__transaction_cancel%> not within "
23525 "%<__transaction_atomic%>");
23529 return add_stmt (build_tm_abort_call (loc, is_outer));
23532 return build1 (NOP_EXPR, void_type_node, error_mark_node);
23535 /* Parse a single source file. */
23538 c_parse_file (void)
23540 /* Use local storage to begin. If the first token is a pragma, parse it.
23541 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23542 which will cause garbage collection. */
23545 memset (&tparser, 0, sizeof tparser);
23546 tparser.translate_strings_p = true;
23547 tparser.tokens = &tparser.tokens_buf[0];
23548 the_parser = &tparser;
23550 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
23551 c_parser_pragma_pch_preprocess (&tparser);
23553 c_common_no_more_pch ();
23555 the_parser = ggc_alloc<c_parser> ();
23556 *the_parser = tparser;
23557 if (tparser.tokens == &tparser.tokens_buf[0])
23558 the_parser->tokens = &the_parser->tokens_buf[0];
23560 /* Initialize EH, if we've been told to do so. */
23561 if (flag_exceptions)
23562 using_eh_for_cleanups ();
23564 c_parser_translation_unit (the_parser);
23568 /* Parse the body of a function declaration marked with "__RTL".
23570 The RTL parser works on the level of characters read from a
23571 FILE *, whereas c_parser works at the level of tokens.
23572 Square this circle by consuming all of the tokens up to and
23573 including the closing brace, recording the start/end of the RTL
23574 fragment, and reopening the file and re-reading the relevant
23575 lines within the RTL parser.
23577 This requires the opening and closing braces of the C function
23578 to be on separate lines from the RTL they wrap.
23580 Take ownership of START_WITH_PASS, if non-NULL. */
23583 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
23585 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23587 free (start_with_pass);
23588 return c_parser_peek_token (parser)->location;
23591 location_t start_loc = c_parser_peek_token (parser)->location;
23593 /* Consume all tokens, up to the closing brace, handling
23594 matching pairs of braces in the rtl dump. */
23595 int num_open_braces = 1;
23598 switch (c_parser_peek_token (parser)->type)
23600 case CPP_OPEN_BRACE:
23603 case CPP_CLOSE_BRACE:
23604 if (--num_open_braces == 0)
23605 goto found_closing_brace;
23608 error_at (start_loc, "no closing brace");
23609 free (start_with_pass);
23610 return c_parser_peek_token (parser)->location;
23614 c_parser_consume_token (parser);
23617 found_closing_brace:
23618 /* At the closing brace; record its location. */
23619 location_t end_loc = c_parser_peek_token (parser)->location;
23621 /* Consume the closing brace. */
23622 c_parser_consume_token (parser);
23624 /* Invoke the RTL parser. */
23625 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
23627 free (start_with_pass);
23631 /* Run the backend on the cfun created above, transferring ownership of
23632 START_WITH_PASS. */
23633 run_rtl_passes (start_with_pass);
23637 #include "gt-c-c-parser.h"