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);
126 mask |= D_ASM | D_EXT;
130 if (!c_dialect_objc ())
131 mask |= D_OBJC | D_CXX_OBJC;
133 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
134 for (i = 0; i < num_c_common_reswords; i++)
136 /* If a keyword is disabled, do not enter it into the table
137 and so create a canonical spelling that isn't a keyword. */
138 if (c_common_reswords[i].disable & mask)
141 && (c_common_reswords[i].disable & D_CXXWARN))
143 id = get_identifier (c_common_reswords[i].word);
144 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
145 C_IS_RESERVED_WORD (id) = 1;
150 id = get_identifier (c_common_reswords[i].word);
151 C_SET_RID_CODE (id, c_common_reswords[i].rid);
152 C_IS_RESERVED_WORD (id) = 1;
153 ridpointers [(int) c_common_reswords[i].rid] = id;
156 for (i = 0; i < NUM_INT_N_ENTS; i++)
158 /* We always create the symbols but they aren't always supported. */
160 sprintf (name, "__int%d", int_n_data[i].bitsize);
161 id = get_identifier (name);
162 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
163 C_IS_RESERVED_WORD (id) = 1;
165 sprintf (name, "__int%d__", int_n_data[i].bitsize);
166 id = get_identifier (name);
167 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
168 C_IS_RESERVED_WORD (id) = 1;
173 id = get_identifier ("omp_all_memory");
174 C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
175 C_IS_RESERVED_WORD (id) = 1;
176 ridpointers [RID_OMP_ALL_MEMORY] = id;
180 /* A parser structure recording information about the state and
181 context of parsing. Includes lexer information with up to two
182 tokens of look-ahead; more are not needed for C. */
183 struct GTY(()) c_parser {
184 /* The look-ahead tokens. */
185 c_token * GTY((skip)) tokens;
186 /* Buffer for look-ahead tokens. */
187 c_token tokens_buf[4];
188 /* How many look-ahead tokens are available (0 - 4, or
189 more if parsing from pre-lexed tokens). */
190 unsigned int tokens_avail;
191 /* Raw look-ahead tokens, used only for checking in Objective-C
192 whether '[[' starts attributes. */
193 vec<c_token, va_gc> *raw_tokens;
194 /* The number of raw look-ahead tokens that have since been fully
196 unsigned int raw_tokens_used;
197 /* True if a syntax error is being recovered from; false otherwise.
198 c_parser_error sets this flag. It should clear this flag when
199 enough tokens have been consumed to recover from the error. */
200 BOOL_BITFIELD error : 1;
201 /* True if we're processing a pragma, and shouldn't automatically
202 consume CPP_PRAGMA_EOL. */
203 BOOL_BITFIELD in_pragma : 1;
204 /* True if we're parsing the outermost block of an if statement. */
205 BOOL_BITFIELD in_if_block : 1;
206 /* True if we want to lex a translated, joined string (for an
207 initial #pragma pch_preprocess). Otherwise the parser is
208 responsible for concatenating strings and translating to the
209 execution character set as needed. */
210 BOOL_BITFIELD lex_joined_string : 1;
211 /* True if, when the parser is concatenating string literals, it
212 should translate them to the execution character set (false
213 inside attributes). */
214 BOOL_BITFIELD translate_strings_p : 1;
216 /* Objective-C specific parser/lexer information. */
218 /* True if we are in a context where the Objective-C "PQ" keywords
219 are considered keywords. */
220 BOOL_BITFIELD objc_pq_context : 1;
221 /* True if we are parsing a (potential) Objective-C foreach
222 statement. This is set to true after we parsed 'for (' and while
223 we wait for 'in' or ';' to decide if it's a standard C for loop or an
224 Objective-C foreach loop. */
225 BOOL_BITFIELD objc_could_be_foreach_context : 1;
226 /* The following flag is needed to contextualize Objective-C lexical
227 analysis. In some cases (e.g., 'int NSObject;'), it is
228 undesirable to bind an identifier to an Objective-C class, even
229 if a class with that name exists. */
230 BOOL_BITFIELD objc_need_raw_identifier : 1;
231 /* Nonzero if we're processing a __transaction statement. The value
232 is 1 | TM_STMT_ATTR_*. */
233 unsigned int in_transaction : 4;
234 /* True if we are in a context where the Objective-C "Property attribute"
235 keywords are valid. */
236 BOOL_BITFIELD objc_property_attr_context : 1;
238 /* Whether we have just seen/constructed a string-literal. Set when
239 returning a string-literal from c_parser_string_literal. Reset
240 in consume_token. Useful when we get a parse error and see an
241 unknown token, which could have been a string-literal constant
243 BOOL_BITFIELD seen_string_literal : 1;
245 /* Location of the last consumed token. */
246 location_t last_token_location;
249 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
252 c_parser_tokens_buf (c_parser *parser, unsigned n)
254 return &parser->tokens_buf[n];
257 /* Return the error state of PARSER. */
260 c_parser_error (c_parser *parser)
262 return parser->error;
265 /* Set the error state of PARSER to ERR. */
268 c_parser_set_error (c_parser *parser, bool err)
274 /* The actual parser and external interface. ??? Does this need to be
275 garbage-collected? */
277 static GTY (()) c_parser *the_parser;
279 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
280 context-sensitive postprocessing of the token is not done. */
283 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
285 timevar_push (TV_LEX);
287 if (raw || vec_safe_length (parser->raw_tokens) == 0)
289 token->type = c_lex_with_flags (&token->value, &token->location,
291 (parser->lex_joined_string
292 ? 0 : C_LEX_STRING_NO_JOIN));
293 token->id_kind = C_ID_NONE;
294 token->keyword = RID_MAX;
295 token->pragma_kind = PRAGMA_NONE;
299 /* Use a token previously lexed as a raw look-ahead token, and
300 complete the processing on it. */
301 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
302 ++parser->raw_tokens_used;
303 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
305 vec_free (parser->raw_tokens);
306 parser->raw_tokens_used = 0;
319 bool objc_force_identifier = parser->objc_need_raw_identifier;
320 if (c_dialect_objc ())
321 parser->objc_need_raw_identifier = false;
323 if (C_IS_RESERVED_WORD (token->value))
325 enum rid rid_code = C_RID_CODE (token->value);
327 if (rid_code == RID_CXX_COMPAT_WARN)
329 warning_at (token->location,
331 "identifier %qE conflicts with C++ keyword",
334 else if (rid_code >= RID_FIRST_ADDR_SPACE
335 && rid_code <= RID_LAST_ADDR_SPACE)
338 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
339 targetm.addr_space.diagnose_usage (as, token->location);
340 token->id_kind = C_ID_ADDRSPACE;
341 token->keyword = rid_code;
344 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
346 /* We found an Objective-C "pq" keyword (in, out,
347 inout, bycopy, byref, oneway). They need special
348 care because the interpretation depends on the
350 if (parser->objc_pq_context)
352 token->type = CPP_KEYWORD;
353 token->keyword = rid_code;
356 else if (parser->objc_could_be_foreach_context
357 && rid_code == RID_IN)
359 /* We are in Objective-C, inside a (potential)
360 foreach context (which means after having
361 parsed 'for (', but before having parsed ';'),
362 and we found 'in'. We consider it the keyword
363 which terminates the declaration at the
364 beginning of a foreach-statement. Note that
365 this means you can't use 'in' for anything else
366 in that context; in particular, in Objective-C
367 you can't use 'in' as the name of the running
368 variable in a C for loop. We could potentially
369 try to add code here to disambiguate, but it
370 seems a reasonable limitation. */
371 token->type = CPP_KEYWORD;
372 token->keyword = rid_code;
375 /* Else, "pq" keywords outside of the "pq" context are
376 not keywords, and we fall through to the code for
379 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
381 /* We found an Objective-C "property attribute"
382 keyword (getter, setter, readonly, etc). These are
383 only valid in the property context. */
384 if (parser->objc_property_attr_context)
386 token->type = CPP_KEYWORD;
387 token->keyword = rid_code;
390 /* Else they are not special keywords.
393 else if (c_dialect_objc ()
394 && (OBJC_IS_AT_KEYWORD (rid_code)
395 || OBJC_IS_CXX_KEYWORD (rid_code)))
397 /* We found one of the Objective-C "@" keywords (defs,
398 selector, synchronized, etc) or one of the
399 Objective-C "cxx" keywords (class, private,
400 protected, public, try, catch, throw) without a
401 preceding '@' sign. Do nothing and fall through to
402 the code for normal tokens (in C++ we would still
403 consider the CXX ones keywords, but not in C). */
408 token->type = CPP_KEYWORD;
409 token->keyword = rid_code;
414 decl = lookup_name (token->value);
417 if (TREE_CODE (decl) == TYPE_DECL)
419 token->id_kind = C_ID_TYPENAME;
423 else if (c_dialect_objc ())
425 tree objc_interface_decl = objc_is_class_name (token->value);
426 /* Objective-C class names are in the same namespace as
427 variables and typedefs, and hence are shadowed by local
429 if (objc_interface_decl
430 && (!objc_force_identifier || global_bindings_p ()))
432 token->value = objc_interface_decl;
433 token->id_kind = C_ID_CLASSNAME;
437 token->id_kind = C_ID_ID;
441 /* This only happens in Objective-C; it must be a keyword. */
442 token->type = CPP_KEYWORD;
443 switch (C_RID_CODE (token->value))
445 /* Replace 'class' with '@class', 'private' with '@private',
446 etc. This prevents confusion with the C++ keyword
447 'class', and makes the tokens consistent with other
448 Objective-C 'AT' keywords. For example '@class' is
449 reported as RID_AT_CLASS which is consistent with
450 '@synchronized', which is reported as
453 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
454 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
455 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
456 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
457 case RID_THROW: token->keyword = RID_AT_THROW; break;
458 case RID_TRY: token->keyword = RID_AT_TRY; break;
459 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
460 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
461 default: token->keyword = C_RID_CODE (token->value);
466 case CPP_CLOSE_PAREN:
468 /* These tokens may affect the interpretation of any identifiers
469 following, if doing Objective-C. */
470 if (c_dialect_objc ())
471 parser->objc_need_raw_identifier = false;
474 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
475 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
482 timevar_pop (TV_LEX);
485 /* Return a pointer to the next token from PARSER, reading it in if
489 c_parser_peek_token (c_parser *parser)
491 if (parser->tokens_avail == 0)
493 c_lex_one_token (parser, &parser->tokens[0]);
494 parser->tokens_avail = 1;
496 return &parser->tokens[0];
499 /* Return a pointer to the next-but-one token from PARSER, reading it
500 in if necessary. The next token is already read in. */
503 c_parser_peek_2nd_token (c_parser *parser)
505 if (parser->tokens_avail >= 2)
506 return &parser->tokens[1];
507 gcc_assert (parser->tokens_avail == 1);
508 gcc_assert (parser->tokens[0].type != CPP_EOF);
509 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
510 c_lex_one_token (parser, &parser->tokens[1]);
511 parser->tokens_avail = 2;
512 return &parser->tokens[1];
515 /* Return a pointer to the Nth token from PARSER, reading it
516 in if necessary. The N-1th token is already read in. */
519 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
521 /* N is 1-based, not zero-based. */
524 if (parser->tokens_avail >= n)
525 return &parser->tokens[n - 1];
526 gcc_assert (parser->tokens_avail == n - 1);
527 c_lex_one_token (parser, &parser->tokens[n - 1]);
528 parser->tokens_avail = n;
529 return &parser->tokens[n - 1];
532 /* Return a pointer to the Nth token from PARSER, reading it in as a
533 raw look-ahead token if necessary. The N-1th token is already read
534 in. Raw look-ahead tokens remain available for when the non-raw
535 functions above are called. */
538 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
540 /* N is 1-based, not zero-based. */
543 if (parser->tokens_avail >= n)
544 return &parser->tokens[n - 1];
545 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
546 unsigned int raw_avail
547 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
548 gcc_assert (raw_avail >= n - 1);
550 return &(*parser->raw_tokens)[parser->raw_tokens_used
551 + n - 1 - parser->tokens_avail];
552 vec_safe_reserve (parser->raw_tokens, 1);
553 parser->raw_tokens->quick_grow (raw_len + 1);
554 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
555 return &(*parser->raw_tokens)[raw_len];
559 c_keyword_starts_typename (enum rid keyword)
594 if (keyword >= RID_FIRST_INT_N
595 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
596 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
602 /* Return true if TOKEN can start a type name,
605 c_token_starts_typename (c_token *token)
610 switch (token->id_kind)
619 gcc_assert (c_dialect_objc ());
625 return c_keyword_starts_typename (token->keyword);
627 if (c_dialect_objc ())
635 /* Return true if the next token from PARSER can start a type name,
636 false otherwise. LA specifies how to do lookahead in order to
637 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
640 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
642 c_token *token = c_parser_peek_token (parser);
643 if (c_token_starts_typename (token))
646 /* Try a bit harder to detect an unknown typename. */
647 if (la != cla_prefer_id
648 && token->type == CPP_NAME
649 && token->id_kind == C_ID_ID
651 /* Do not try too hard when we could have "object in array". */
652 && !parser->objc_could_be_foreach_context
654 && (la == cla_prefer_type
655 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
656 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
658 /* Only unknown identifiers. */
659 && !lookup_name (token->value))
665 /* Return true if TOKEN is a type qualifier, false otherwise. */
667 c_token_is_qualifier (c_token *token)
672 switch (token->id_kind)
680 switch (token->keyword)
698 /* Return true if the next token from PARSER is a type qualifier,
701 c_parser_next_token_is_qualifier (c_parser *parser)
703 c_token *token = c_parser_peek_token (parser);
704 return c_token_is_qualifier (token);
707 /* Return true if TOKEN can start declaration specifiers (not
708 including standard attributes), false otherwise. */
710 c_token_starts_declspecs (c_token *token)
715 switch (token->id_kind)
724 gcc_assert (c_dialect_objc ());
730 switch (token->keyword)
771 if (token->keyword >= RID_FIRST_INT_N
772 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
773 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
778 if (c_dialect_objc ())
787 /* Return true if TOKEN can start declaration specifiers (not
788 including standard attributes) or a static assertion, false
791 c_token_starts_declaration (c_token *token)
793 if (c_token_starts_declspecs (token)
794 || token->keyword == RID_STATIC_ASSERT)
800 /* Return true if the next token from PARSER can start declaration
801 specifiers (not including standard attributes), false
804 c_parser_next_token_starts_declspecs (c_parser *parser)
806 c_token *token = c_parser_peek_token (parser);
808 /* In Objective-C, a classname normally starts a declspecs unless it
809 is immediately followed by a dot. In that case, it is the
810 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
811 setter/getter on the class. c_token_starts_declspecs() can't
812 differentiate between the two cases because it only checks the
813 current token, so we have a special check here. */
814 if (c_dialect_objc ()
815 && token->type == CPP_NAME
816 && token->id_kind == C_ID_CLASSNAME
817 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
820 return c_token_starts_declspecs (token);
823 /* Return true if the next tokens from PARSER can start declaration
824 specifiers (not including standard attributes) or a static
825 assertion, false otherwise. */
827 c_parser_next_tokens_start_declaration (c_parser *parser)
829 c_token *token = c_parser_peek_token (parser);
832 if (c_dialect_objc ()
833 && token->type == CPP_NAME
834 && token->id_kind == C_ID_CLASSNAME
835 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
838 /* Labels do not start declarations. */
839 if (token->type == CPP_NAME
840 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
843 if (c_token_starts_declaration (token))
846 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
852 /* Consume the next token from PARSER. */
855 c_parser_consume_token (c_parser *parser)
857 gcc_assert (parser->tokens_avail >= 1);
858 gcc_assert (parser->tokens[0].type != CPP_EOF);
859 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
860 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
861 parser->last_token_location = parser->tokens[0].location;
862 if (parser->tokens != &parser->tokens_buf[0])
864 else if (parser->tokens_avail >= 2)
866 parser->tokens[0] = parser->tokens[1];
867 if (parser->tokens_avail >= 3)
869 parser->tokens[1] = parser->tokens[2];
870 if (parser->tokens_avail >= 4)
871 parser->tokens[2] = parser->tokens[3];
874 parser->tokens_avail--;
875 parser->seen_string_literal = false;
878 /* Expect the current token to be a #pragma. Consume it and remember
879 that we've begun parsing a pragma. */
882 c_parser_consume_pragma (c_parser *parser)
884 gcc_assert (!parser->in_pragma);
885 gcc_assert (parser->tokens_avail >= 1);
886 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
887 if (parser->tokens != &parser->tokens_buf[0])
889 else if (parser->tokens_avail >= 2)
891 parser->tokens[0] = parser->tokens[1];
892 if (parser->tokens_avail >= 3)
893 parser->tokens[1] = parser->tokens[2];
895 parser->tokens_avail--;
896 parser->in_pragma = true;
899 /* Update the global input_location from TOKEN. */
901 c_parser_set_source_position_from_token (c_token *token)
903 if (token->type != CPP_EOF)
905 input_location = token->location;
909 /* Helper function for c_parser_error.
910 Having peeked a token of kind TOK1_KIND that might signify
911 a conflict marker, peek successor tokens to determine
912 if we actually do have a conflict marker.
913 Specifically, we consider a run of 7 '<', '=' or '>' characters
914 at the start of a line as a conflict marker.
915 These come through the lexer as three pairs and a single,
916 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
917 If it returns true, *OUT_LOC is written to with the location/range
921 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
924 c_token *token2 = c_parser_peek_2nd_token (parser);
925 if (token2->type != tok1_kind)
927 c_token *token3 = c_parser_peek_nth_token (parser, 3);
928 if (token3->type != tok1_kind)
930 c_token *token4 = c_parser_peek_nth_token (parser, 4);
931 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
934 /* It must be at the start of the line. */
935 location_t start_loc = c_parser_peek_token (parser)->location;
936 if (LOCATION_COLUMN (start_loc) != 1)
939 /* We have a conflict marker. Construct a location of the form:
942 with start == caret, finishing at the end of the marker. */
943 location_t finish_loc = get_finish (token4->location);
944 *out_loc = make_location (start_loc, start_loc, finish_loc);
949 /* Issue a diagnostic of the form
950 FILE:LINE: MESSAGE before TOKEN
951 where TOKEN is the next token in the input stream of PARSER.
952 MESSAGE (specified by the caller) is usually of the form "expected
955 Use RICHLOC as the location of the diagnostic.
957 Do not issue a diagnostic if still recovering from an error.
959 Return true iff an error was actually emitted.
961 ??? This is taken from the C++ parser, but building up messages in
962 this way is not i18n-friendly and some other approach should be
966 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
967 rich_location *richloc)
969 c_token *token = c_parser_peek_token (parser);
972 parser->error = true;
976 /* If this is actually a conflict marker, report it as such. */
977 if (token->type == CPP_LSHIFT
978 || token->type == CPP_RSHIFT
979 || token->type == CPP_EQ_EQ)
982 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
984 error_at (loc, "version control conflict marker in file");
989 /* If we were parsing a string-literal and there is an unknown name
990 token right after, then check to see if that could also have been
991 a literal string by checking the name against a list of known
992 standard string literal constants defined in header files. If
993 there is one, then add that as an hint to the error message. */
994 auto_diagnostic_group d;
996 if (parser->seen_string_literal && token->type == CPP_NAME)
998 tree name = token->value;
999 const char *token_name = IDENTIFIER_POINTER (name);
1000 const char *header_hint
1001 = get_c_stdlib_header_for_string_macro_name (token_name);
1002 if (header_hint != NULL)
1003 h = name_hint (NULL, new suggest_missing_header (token->location,
1008 c_parse_error (gmsgid,
1009 /* Because c_parse_error does not understand
1010 CPP_KEYWORD, keywords are treated like
1012 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1013 /* ??? The C parser does not save the cpp flags of a
1014 token, we need to pass 0 here and we will not get
1015 the source spelling of some tokens but rather the
1016 canonical spelling. */
1017 token->value, /*flags=*/0, richloc);
1021 /* As c_parser_error_richloc, but issue the message at the
1022 location of PARSER's next token, or at input_location
1023 if the next token is EOF. */
1026 c_parser_error (c_parser *parser, const char *gmsgid)
1028 c_token *token = c_parser_peek_token (parser);
1029 c_parser_set_source_position_from_token (token);
1030 rich_location richloc (line_table, input_location);
1031 return c_parser_error_richloc (parser, gmsgid, &richloc);
1034 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1035 This class is for tracking such a matching pair of symbols.
1036 In particular, it tracks the location of the first token,
1037 so that if the second token is missing, we can highlight the
1038 location of the first token when notifying the user about the
1041 template <typename traits_t>
1045 /* token_pair's ctor. */
1046 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1048 /* If the next token is the opening symbol for this pair, consume it and
1050 Otherwise, issue an error and return false.
1051 In either case, record the location of the opening token. */
1053 bool require_open (c_parser *parser)
1055 c_token *token = c_parser_peek_token (parser);
1057 m_open_loc = token->location;
1059 return c_parser_require (parser, traits_t::open_token_type,
1060 traits_t::open_gmsgid);
1063 /* Consume the next token from PARSER, recording its location as
1064 that of the opening token within the pair. */
1066 void consume_open (c_parser *parser)
1068 c_token *token = c_parser_peek_token (parser);
1069 gcc_assert (token->type == traits_t::open_token_type);
1070 m_open_loc = token->location;
1071 c_parser_consume_token (parser);
1074 /* If the next token is the closing symbol for this pair, consume it
1076 Otherwise, issue an error, highlighting the location of the
1077 corresponding opening token, and return false. */
1079 bool require_close (c_parser *parser) const
1081 return c_parser_require (parser, traits_t::close_token_type,
1082 traits_t::close_gmsgid, m_open_loc);
1085 /* Like token_pair::require_close, except that tokens will be skipped
1086 until the desired token is found. An error message is still produced
1087 if the next token is not as expected. */
1089 void skip_until_found_close (c_parser *parser) const
1091 c_parser_skip_until_found (parser, traits_t::close_token_type,
1092 traits_t::close_gmsgid, m_open_loc);
1096 location_t m_open_loc;
1099 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1101 struct matching_paren_traits
1103 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1104 static const char * const open_gmsgid;
1105 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1106 static const char * const close_gmsgid;
1109 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1110 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1112 /* "matching_parens" is a token_pair<T> class for tracking matching
1113 pairs of parentheses. */
1115 typedef token_pair<matching_paren_traits> matching_parens;
1117 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1119 struct matching_brace_traits
1121 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1122 static const char * const open_gmsgid;
1123 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1124 static const char * const close_gmsgid;
1127 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1128 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1130 /* "matching_braces" is a token_pair<T> class for tracking matching
1133 typedef token_pair<matching_brace_traits> matching_braces;
1135 /* Get a description of the matching symbol to TYPE e.g. "(" for
1139 get_matching_symbol (enum cpp_ttype type)
1145 case CPP_CLOSE_PAREN:
1147 case CPP_CLOSE_BRACE:
1152 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1153 issue the error MSGID. If MSGID is NULL then a message has already
1154 been produced and no message will be produced this time. Returns
1155 true if found, false otherwise.
1157 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1158 within any error as the location of an "opening" token matching
1159 the close token TYPE (e.g. the location of the '(' when TYPE is
1162 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1163 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1164 attempt to generate a fix-it hint for the problem.
1165 Otherwise msgid describes multiple token types (e.g.
1166 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1167 generate a fix-it hint. */
1170 c_parser_require (c_parser *parser,
1171 enum cpp_ttype type,
1173 location_t matching_location,
1174 bool type_is_unique)
1176 if (c_parser_next_token_is (parser, type))
1178 c_parser_consume_token (parser);
1183 location_t next_token_loc = c_parser_peek_token (parser)->location;
1184 gcc_rich_location richloc (next_token_loc);
1186 /* Potentially supply a fix-it hint, suggesting to add the
1187 missing token immediately after the *previous* token.
1188 This may move the primary location within richloc. */
1189 if (!parser->error && type_is_unique)
1190 maybe_suggest_missing_token_insertion (&richloc, type,
1191 parser->last_token_location);
1193 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1194 Attempt to consolidate diagnostics by printing it as a
1195 secondary range within the main diagnostic. */
1196 bool added_matching_location = false;
1197 if (matching_location != UNKNOWN_LOCATION)
1198 added_matching_location
1199 = richloc.add_location_if_nearby (matching_location);
1201 if (c_parser_error_richloc (parser, msgid, &richloc))
1202 /* If we weren't able to consolidate matching_location, then
1203 print it as a secondary diagnostic. */
1204 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1205 inform (matching_location, "to match this %qs",
1206 get_matching_symbol (type));
1212 /* If the next token is the indicated keyword, consume it. Otherwise,
1213 issue the error MSGID. Returns true if found, false otherwise. */
1216 c_parser_require_keyword (c_parser *parser,
1220 if (c_parser_next_token_is_keyword (parser, keyword))
1222 c_parser_consume_token (parser);
1227 c_parser_error (parser, msgid);
1232 /* Like c_parser_require, except that tokens will be skipped until the
1233 desired token is found. An error message is still produced if the
1234 next token is not as expected. If MSGID is NULL then a message has
1235 already been produced and no message will be produced this
1238 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1239 within any error as the location of an "opening" token matching
1240 the close token TYPE (e.g. the location of the '(' when TYPE is
1241 CPP_CLOSE_PAREN). */
1244 c_parser_skip_until_found (c_parser *parser,
1245 enum cpp_ttype type,
1247 location_t matching_location)
1249 unsigned nesting_depth = 0;
1251 if (c_parser_require (parser, type, msgid, matching_location))
1254 /* Skip tokens until the desired token is found. */
1257 /* Peek at the next token. */
1258 c_token *token = c_parser_peek_token (parser);
1259 /* If we've reached the token we want, consume it and stop. */
1260 if (token->type == type && !nesting_depth)
1262 c_parser_consume_token (parser);
1266 /* If we've run out of tokens, stop. */
1267 if (token->type == CPP_EOF)
1269 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1271 if (token->type == CPP_OPEN_BRACE
1272 || token->type == CPP_OPEN_PAREN
1273 || token->type == CPP_OPEN_SQUARE)
1275 else if (token->type == CPP_CLOSE_BRACE
1276 || token->type == CPP_CLOSE_PAREN
1277 || token->type == CPP_CLOSE_SQUARE)
1279 if (nesting_depth-- == 0)
1282 /* Consume this token. */
1283 c_parser_consume_token (parser);
1285 parser->error = false;
1288 /* Skip tokens until the end of a parameter is found, but do not
1289 consume the comma, semicolon or closing delimiter. */
1292 c_parser_skip_to_end_of_parameter (c_parser *parser)
1294 unsigned nesting_depth = 0;
1298 c_token *token = c_parser_peek_token (parser);
1299 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1302 /* If we've run out of tokens, stop. */
1303 if (token->type == CPP_EOF)
1305 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1307 if (token->type == CPP_OPEN_BRACE
1308 || token->type == CPP_OPEN_PAREN
1309 || token->type == CPP_OPEN_SQUARE)
1311 else if (token->type == CPP_CLOSE_BRACE
1312 || token->type == CPP_CLOSE_PAREN
1313 || token->type == CPP_CLOSE_SQUARE)
1315 if (nesting_depth-- == 0)
1318 /* Consume this token. */
1319 c_parser_consume_token (parser);
1321 parser->error = false;
1324 /* Expect to be at the end of the pragma directive and consume an
1325 end of line marker. */
1328 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1330 gcc_assert (parser->in_pragma);
1331 parser->in_pragma = false;
1333 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1334 c_parser_error (parser, "expected end of line");
1336 cpp_ttype token_type;
1339 c_token *token = c_parser_peek_token (parser);
1340 token_type = token->type;
1341 if (token_type == CPP_EOF)
1343 c_parser_consume_token (parser);
1345 while (token_type != CPP_PRAGMA_EOL);
1347 parser->error = false;
1350 /* Skip tokens until we have consumed an entire block, or until we
1351 have consumed a non-nested ';'. */
1354 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1356 unsigned nesting_depth = 0;
1357 bool save_error = parser->error;
1363 /* Peek at the next token. */
1364 token = c_parser_peek_token (parser);
1366 switch (token->type)
1371 case CPP_PRAGMA_EOL:
1372 if (parser->in_pragma)
1377 /* If the next token is a ';', we have reached the
1378 end of the statement. */
1381 /* Consume the ';'. */
1382 c_parser_consume_token (parser);
1387 case CPP_CLOSE_BRACE:
1388 /* If the next token is a non-nested '}', then we have
1389 reached the end of the current block. */
1390 if (nesting_depth == 0 || --nesting_depth == 0)
1392 c_parser_consume_token (parser);
1397 case CPP_OPEN_BRACE:
1398 /* If it the next token is a '{', then we are entering a new
1399 block. Consume the entire block. */
1404 /* If we see a pragma, consume the whole thing at once. We
1405 have some safeguards against consuming pragmas willy-nilly.
1406 Normally, we'd expect to be here with parser->error set,
1407 which disables these safeguards. But it's possible to get
1408 here for secondary error recovery, after parser->error has
1410 c_parser_consume_pragma (parser);
1411 c_parser_skip_to_pragma_eol (parser);
1412 parser->error = save_error;
1419 c_parser_consume_token (parser);
1423 parser->error = false;
1426 /* CPP's options (initialized by c-opts.cc). */
1427 extern cpp_options *cpp_opts;
1429 /* Save the warning flags which are controlled by __extension__. */
1432 disable_extension_diagnostics (void)
1435 | (warn_pointer_arith << 1)
1436 | (warn_traditional << 2)
1438 | (warn_long_long << 4)
1439 | (warn_cxx_compat << 5)
1440 | (warn_overlength_strings << 6)
1441 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1442 play tricks to properly restore it. */
1443 | ((warn_c90_c99_compat == 1) << 7)
1444 | ((warn_c90_c99_compat == -1) << 8)
1445 /* Similarly for warn_c99_c11_compat. */
1446 | ((warn_c99_c11_compat == 1) << 9)
1447 | ((warn_c99_c11_compat == -1) << 10)
1448 /* Similarly for warn_c11_c2x_compat. */
1449 | ((warn_c11_c2x_compat == 1) << 11)
1450 | ((warn_c11_c2x_compat == -1) << 12)
1452 cpp_opts->cpp_pedantic = pedantic = 0;
1453 warn_pointer_arith = 0;
1454 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1456 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1457 warn_cxx_compat = 0;
1458 warn_overlength_strings = 0;
1459 warn_c90_c99_compat = 0;
1460 warn_c99_c11_compat = 0;
1461 warn_c11_c2x_compat = 0;
1465 /* Restore the warning flags which are controlled by __extension__.
1466 FLAGS is the return value from disable_extension_diagnostics. */
1469 restore_extension_diagnostics (int flags)
1471 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1472 warn_pointer_arith = (flags >> 1) & 1;
1473 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1474 flag_iso = (flags >> 3) & 1;
1475 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1476 warn_cxx_compat = (flags >> 5) & 1;
1477 warn_overlength_strings = (flags >> 6) & 1;
1478 /* See above for why is this needed. */
1479 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1480 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1481 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1484 /* Helper data structure for parsing #pragma acc routine. */
1485 struct oacc_routine_data {
1486 bool error_seen; /* Set if error has been reported. */
1487 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1492 /* Used for parsing objc foreach statements. */
1493 static tree objc_foreach_break_label, objc_foreach_continue_label;
1495 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1497 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1498 static void c_parser_external_declaration (c_parser *);
1499 static void c_parser_asm_definition (c_parser *);
1500 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1501 bool, bool, tree * = NULL,
1502 vec<c_token> * = NULL,
1503 bool have_attrs = false,
1505 struct oacc_routine_data * = NULL,
1507 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1508 static void c_parser_static_assert_declaration (c_parser *);
1509 static struct c_typespec c_parser_enum_specifier (c_parser *);
1510 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1511 static tree c_parser_struct_declaration (c_parser *);
1512 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1513 static tree c_parser_alignas_specifier (c_parser *);
1514 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1516 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1518 struct c_declarator *);
1519 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1521 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1523 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1524 static tree c_parser_simple_asm_expr (c_parser *);
1525 static tree c_parser_gnu_attributes (c_parser *);
1526 static struct c_expr c_parser_initializer (c_parser *, tree);
1527 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1528 struct obstack *, tree);
1529 static void c_parser_initelt (c_parser *, struct obstack *);
1530 static void c_parser_initval (c_parser *, struct c_expr *,
1532 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1533 static location_t c_parser_compound_statement_nostart (c_parser *);
1534 static void c_parser_label (c_parser *, tree);
1535 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1536 static void c_parser_statement_after_labels (c_parser *, bool *,
1537 vec<tree> * = NULL);
1538 static tree c_parser_c99_block_statement (c_parser *, bool *,
1539 location_t * = NULL);
1540 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1541 static void c_parser_switch_statement (c_parser *, bool *);
1542 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1543 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1544 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1545 static tree c_parser_asm_statement (c_parser *);
1546 static tree c_parser_asm_operands (c_parser *);
1547 static tree c_parser_asm_goto_operands (c_parser *);
1548 static tree c_parser_asm_clobbers (c_parser *);
1549 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1551 static struct c_expr c_parser_conditional_expression (c_parser *,
1552 struct c_expr *, tree);
1553 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1555 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1556 static struct c_expr c_parser_unary_expression (c_parser *);
1557 static struct c_expr c_parser_sizeof_expression (c_parser *);
1558 static struct c_expr c_parser_alignof_expression (c_parser *);
1559 static struct c_expr c_parser_postfix_expression (c_parser *);
1560 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1561 struct c_type_name *,
1563 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1566 static tree c_parser_transaction (c_parser *, enum rid);
1567 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1568 static tree c_parser_transaction_cancel (c_parser *);
1569 static struct c_expr c_parser_expression (c_parser *);
1570 static struct c_expr c_parser_expression_conv (c_parser *);
1571 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1572 vec<tree, va_gc> **, location_t *,
1573 tree *, vec<location_t> *,
1574 unsigned int * = NULL);
1575 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1577 static void c_parser_oacc_declare (c_parser *);
1578 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1579 static void c_parser_oacc_update (c_parser *);
1580 static void c_parser_omp_construct (c_parser *, bool *);
1581 static void c_parser_omp_threadprivate (c_parser *);
1582 static void c_parser_omp_barrier (c_parser *);
1583 static void c_parser_omp_depobj (c_parser *);
1584 static void c_parser_omp_flush (c_parser *);
1585 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1586 tree, tree *, bool *);
1587 static void c_parser_omp_taskwait (c_parser *);
1588 static void c_parser_omp_taskyield (c_parser *);
1589 static void c_parser_omp_cancel (c_parser *);
1590 static void c_parser_omp_nothing (c_parser *);
1592 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1593 pragma_stmt, pragma_compound };
1594 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1595 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1596 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1597 static void c_parser_omp_end_declare_target (c_parser *);
1598 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1599 static void c_parser_omp_requires (c_parser *);
1600 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1601 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1602 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1604 /* These Objective-C parser functions are only ever called when
1605 compiling Objective-C. */
1606 static void c_parser_objc_class_definition (c_parser *, tree);
1607 static void c_parser_objc_class_instance_variables (c_parser *);
1608 static void c_parser_objc_class_declaration (c_parser *);
1609 static void c_parser_objc_alias_declaration (c_parser *);
1610 static void c_parser_objc_protocol_definition (c_parser *, tree);
1611 static bool c_parser_objc_method_type (c_parser *);
1612 static void c_parser_objc_method_definition (c_parser *);
1613 static void c_parser_objc_methodprotolist (c_parser *);
1614 static void c_parser_objc_methodproto (c_parser *);
1615 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1616 static tree c_parser_objc_type_name (c_parser *);
1617 static tree c_parser_objc_protocol_refs (c_parser *);
1618 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1619 static void c_parser_objc_synchronized_statement (c_parser *);
1620 static tree c_parser_objc_selector (c_parser *);
1621 static tree c_parser_objc_selector_arg (c_parser *);
1622 static tree c_parser_objc_receiver (c_parser *);
1623 static tree c_parser_objc_message_args (c_parser *);
1624 static tree c_parser_objc_keywordexpr (c_parser *);
1625 static void c_parser_objc_at_property_declaration (c_parser *);
1626 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1627 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1628 static bool c_parser_objc_diagnose_bad_element_prefix
1629 (c_parser *, struct c_declspecs *);
1630 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1632 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1635 external-declarations
1637 external-declarations:
1638 external-declaration
1639 external-declarations external-declaration
1648 c_parser_translation_unit (c_parser *parser)
1650 if (c_parser_next_token_is (parser, CPP_EOF))
1652 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1653 "ISO C forbids an empty translation unit");
1657 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1658 mark_valid_location_for_stdc_pragma (false);
1662 c_parser_external_declaration (parser);
1663 obstack_free (&parser_obstack, obstack_position);
1665 while (c_parser_next_token_is_not (parser, CPP_EOF));
1670 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1671 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1672 error ("storage size of %q+D isn%'t known", decl);
1674 if (current_omp_declare_target_attribute)
1677 error ("%<#pragma omp declare target%> without corresponding "
1678 "%<#pragma omp end declare target%>");
1679 current_omp_declare_target_attribute = 0;
1683 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1685 external-declaration:
1691 external-declaration:
1694 __extension__ external-declaration
1698 external-declaration:
1699 objc-class-definition
1700 objc-class-declaration
1701 objc-alias-declaration
1702 objc-protocol-definition
1703 objc-method-definition
1708 c_parser_external_declaration (c_parser *parser)
1711 switch (c_parser_peek_token (parser)->type)
1714 switch (c_parser_peek_token (parser)->keyword)
1717 ext = disable_extension_diagnostics ();
1718 c_parser_consume_token (parser);
1719 c_parser_external_declaration (parser);
1720 restore_extension_diagnostics (ext);
1723 c_parser_asm_definition (parser);
1725 case RID_AT_INTERFACE:
1726 case RID_AT_IMPLEMENTATION:
1727 gcc_assert (c_dialect_objc ());
1728 c_parser_objc_class_definition (parser, NULL_TREE);
1731 gcc_assert (c_dialect_objc ());
1732 c_parser_objc_class_declaration (parser);
1735 gcc_assert (c_dialect_objc ());
1736 c_parser_objc_alias_declaration (parser);
1738 case RID_AT_PROTOCOL:
1739 gcc_assert (c_dialect_objc ());
1740 c_parser_objc_protocol_definition (parser, NULL_TREE);
1742 case RID_AT_PROPERTY:
1743 gcc_assert (c_dialect_objc ());
1744 c_parser_objc_at_property_declaration (parser);
1746 case RID_AT_SYNTHESIZE:
1747 gcc_assert (c_dialect_objc ());
1748 c_parser_objc_at_synthesize_declaration (parser);
1750 case RID_AT_DYNAMIC:
1751 gcc_assert (c_dialect_objc ());
1752 c_parser_objc_at_dynamic_declaration (parser);
1755 gcc_assert (c_dialect_objc ());
1756 c_parser_consume_token (parser);
1757 objc_finish_implementation ();
1764 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1765 "ISO C does not allow extra %<;%> outside of a function");
1766 c_parser_consume_token (parser);
1769 mark_valid_location_for_stdc_pragma (true);
1770 c_parser_pragma (parser, pragma_external, NULL);
1771 mark_valid_location_for_stdc_pragma (false);
1775 if (c_dialect_objc ())
1777 c_parser_objc_method_definition (parser);
1780 /* Else fall through, and yield a syntax error trying to parse
1781 as a declaration or function definition. */
1785 /* A declaration or a function definition (or, in Objective-C,
1786 an @interface or @protocol with prefix attributes). We can
1787 only tell which after parsing the declaration specifiers, if
1788 any, and the first declarator. */
1789 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1794 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1795 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1797 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1800 add_debug_begin_stmt (location_t loc)
1802 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1803 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1806 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1807 SET_EXPR_LOCATION (stmt, loc);
1811 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1812 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1813 is accepted; otherwise (old-style parameter declarations) only other
1814 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1815 assertion is accepted; otherwise (old-style parameter declarations)
1816 it is not. If NESTED is true, we are inside a function or parsing
1817 old-style parameter declarations; any functions encountered are
1818 nested functions and declaration specifiers are required; otherwise
1819 we are at top level and functions are normal functions and
1820 declaration specifiers may be optional. If EMPTY_OK is true, empty
1821 declarations are OK (subject to all other constraints); otherwise
1822 (old-style parameter declarations) they are diagnosed. If
1823 START_ATTR_OK is true, the declaration specifiers may start with
1824 attributes (GNU or standard); otherwise they may not.
1825 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1826 declaration when parsing an Objective-C foreach statement.
1827 FALLTHRU_ATTR_P is used to signal whether this function parsed
1828 "__attribute__((fallthrough));". ATTRS are any standard attributes
1829 parsed in the caller (in contexts where such attributes had to be
1830 parsed to determine whether what follows is a declaration or a
1831 statement); HAVE_ATTRS says whether there were any such attributes
1835 declaration-specifiers init-declarator-list[opt] ;
1836 static_assert-declaration
1838 function-definition:
1839 declaration-specifiers[opt] declarator declaration-list[opt]
1844 declaration-list declaration
1846 init-declarator-list:
1848 init-declarator-list , init-declarator
1851 declarator simple-asm-expr[opt] gnu-attributes[opt]
1852 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1856 nested-function-definition:
1857 declaration-specifiers declarator declaration-list[opt]
1863 gnu-attributes objc-class-definition
1864 gnu-attributes objc-category-definition
1865 gnu-attributes objc-protocol-definition
1867 The simple-asm-expr and gnu-attributes are GNU extensions.
1869 This function does not handle __extension__; that is handled in its
1870 callers. ??? Following the old parser, __extension__ may start
1871 external declarations, declarations in functions and declarations
1872 at the start of "for" loops, but not old-style parameter
1875 C99 requires declaration specifiers in a function definition; the
1876 absence is diagnosed through the diagnosis of implicit int. In GNU
1877 C we also allow but diagnose declarations without declaration
1878 specifiers, but only at top level (elsewhere they conflict with
1881 In Objective-C, declarations of the looping variable in a foreach
1882 statement are exceptionally terminated by 'in' (for example, 'for
1883 (NSObject *object in array) { ... }').
1888 threadprivate-directive
1892 gimple-function-definition:
1893 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1894 declaration-list[opt] compound-statement
1896 rtl-function-definition:
1897 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1898 declaration-list[opt] compound-statement */
1901 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1902 bool static_assert_ok, bool empty_ok,
1903 bool nested, bool start_attr_ok,
1904 tree *objc_foreach_object_declaration
1906 vec<c_token> *omp_declare_simd_clauses
1908 bool have_attrs /* = false */,
1909 tree attrs /* = NULL_TREE */,
1910 struct oacc_routine_data *oacc_routine_data
1912 bool *fallthru_attr_p /* = NULL */)
1914 struct c_declspecs *specs;
1916 tree all_prefix_attrs;
1917 bool diagnosed_no_specs = false;
1918 location_t here = c_parser_peek_token (parser)->location;
1920 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1922 if (static_assert_ok
1923 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1925 c_parser_static_assert_declaration (parser);
1928 specs = build_null_declspecs ();
1930 /* Handle any standard attributes parsed in the caller. */
1933 declspecs_add_attrs (here, specs, attrs);
1934 specs->non_std_attrs_seen_p = false;
1937 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1938 if (c_parser_peek_token (parser)->type == CPP_NAME
1939 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1940 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1941 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1942 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1944 tree name = c_parser_peek_token (parser)->value;
1946 /* Issue a warning about NAME being an unknown type name, perhaps
1947 with some kind of hint.
1948 If the user forgot a "struct" etc, suggest inserting
1949 it. Otherwise, attempt to look for misspellings. */
1950 gcc_rich_location richloc (here);
1951 if (tag_exists_p (RECORD_TYPE, name))
1953 /* This is not C++ with its implicit typedef. */
1954 richloc.add_fixit_insert_before ("struct ");
1956 "unknown type name %qE;"
1957 " use %<struct%> keyword to refer to the type",
1960 else if (tag_exists_p (UNION_TYPE, name))
1962 richloc.add_fixit_insert_before ("union ");
1964 "unknown type name %qE;"
1965 " use %<union%> keyword to refer to the type",
1968 else if (tag_exists_p (ENUMERAL_TYPE, name))
1970 richloc.add_fixit_insert_before ("enum ");
1972 "unknown type name %qE;"
1973 " use %<enum%> keyword to refer to the type",
1978 auto_diagnostic_group d;
1979 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1981 if (const char *suggestion = hint.suggestion ())
1983 richloc.add_fixit_replace (suggestion);
1985 "unknown type name %qE; did you mean %qs?",
1989 error_at (here, "unknown type name %qE", name);
1992 /* Parse declspecs normally to get a correct pointer type, but avoid
1993 a further "fails to be a type name" error. Refuse nested functions
1994 since it is not how the user likely wants us to recover. */
1995 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1996 c_parser_peek_token (parser)->keyword = RID_VOID;
1997 c_parser_peek_token (parser)->value = error_mark_node;
2001 /* When there are standard attributes at the start of the
2002 declaration (to apply to the entity being declared), an
2003 init-declarator-list or function definition must be present. */
2004 if (c_parser_nth_token_starts_std_attributes (parser, 1))
2007 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2008 true, true, start_attr_ok, true, cla_nonabstract_decl);
2011 c_parser_skip_to_end_of_block_or_statement (parser);
2014 if (nested && !specs->declspecs_seen_p)
2016 c_parser_error (parser, "expected declaration specifiers");
2017 c_parser_skip_to_end_of_block_or_statement (parser);
2021 finish_declspecs (specs);
2022 bool auto_type_p = specs->typespec_word == cts_auto_type;
2023 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2026 error_at (here, "%<__auto_type%> in empty declaration");
2027 else if (specs->typespec_kind == ctsk_none
2028 && attribute_fallthrough_p (specs->attrs))
2030 if (fallthru_attr_p != NULL)
2031 *fallthru_attr_p = true;
2034 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2039 pedwarn (here, OPT_Wattributes,
2040 "%<fallthrough%> attribute at top level");
2042 else if (empty_ok && !(have_attrs
2043 && specs->non_std_attrs_seen_p))
2047 shadow_tag_warned (specs, 1);
2048 pedwarn (here, 0, "empty declaration");
2050 c_parser_consume_token (parser);
2051 if (oacc_routine_data)
2052 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2056 /* Provide better error recovery. Note that a type name here is usually
2057 better diagnosed as a redeclaration. */
2059 && specs->typespec_kind == ctsk_tagdef
2060 && c_parser_next_token_starts_declspecs (parser)
2061 && !c_parser_next_token_is (parser, CPP_NAME))
2063 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2064 parser->error = false;
2065 shadow_tag_warned (specs, 1);
2068 else if (c_dialect_objc () && !auto_type_p)
2070 /* Prefix attributes are an error on method decls. */
2071 switch (c_parser_peek_token (parser)->type)
2075 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2079 warning_at (c_parser_peek_token (parser)->location,
2081 "prefix attributes are ignored for methods");
2082 specs->attrs = NULL_TREE;
2085 c_parser_objc_method_definition (parser);
2087 c_parser_objc_methodproto (parser);
2093 /* This is where we parse 'attributes @interface ...',
2094 'attributes @implementation ...', 'attributes @protocol ...'
2095 (where attributes could be, for example, __attribute__
2098 switch (c_parser_peek_token (parser)->keyword)
2100 case RID_AT_INTERFACE:
2102 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2104 c_parser_objc_class_definition (parser, specs->attrs);
2108 case RID_AT_IMPLEMENTATION:
2110 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2114 warning_at (c_parser_peek_token (parser)->location,
2116 "prefix attributes are ignored for implementations");
2117 specs->attrs = NULL_TREE;
2119 c_parser_objc_class_definition (parser, NULL_TREE);
2123 case RID_AT_PROTOCOL:
2125 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2127 c_parser_objc_protocol_definition (parser, specs->attrs);
2134 case RID_AT_PROPERTY:
2137 c_parser_error (parser, "unexpected attribute");
2138 specs->attrs = NULL;
2145 else if (attribute_fallthrough_p (specs->attrs))
2146 warning_at (here, OPT_Wattributes,
2147 "%<fallthrough%> attribute not followed by %<;%>");
2149 pending_xref_error ();
2150 prefix_attrs = specs->attrs;
2151 all_prefix_attrs = prefix_attrs;
2152 specs->attrs = NULL_TREE;
2155 struct c_declarator *declarator;
2158 tree fnbody = NULL_TREE;
2159 /* Declaring either one or more declarators (in which case we
2160 should diagnose if there were no declaration specifiers) or a
2161 function definition (in which case the diagnostic for
2162 implicit int suffices). */
2163 declarator = c_parser_declarator (parser,
2164 specs->typespec_kind != ctsk_none,
2165 C_DTR_NORMAL, &dummy);
2166 if (declarator == NULL)
2168 if (omp_declare_simd_clauses)
2169 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2170 omp_declare_simd_clauses);
2171 if (oacc_routine_data)
2172 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2173 c_parser_skip_to_end_of_block_or_statement (parser);
2176 if (auto_type_p && declarator->kind != cdk_id)
2179 "%<__auto_type%> requires a plain identifier"
2181 c_parser_skip_to_end_of_block_or_statement (parser);
2184 if (c_parser_next_token_is (parser, CPP_EQ)
2185 || c_parser_next_token_is (parser, CPP_COMMA)
2186 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2187 || c_parser_next_token_is_keyword (parser, RID_ASM)
2188 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2189 || c_parser_next_token_is_keyword (parser, RID_IN))
2191 tree asm_name = NULL_TREE;
2192 tree postfix_attrs = NULL_TREE;
2193 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2195 diagnosed_no_specs = true;
2196 pedwarn (here, 0, "data definition has no type or storage class");
2198 /* Having seen a data definition, there cannot now be a
2199 function definition. */
2201 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2202 asm_name = c_parser_simple_asm_expr (parser);
2203 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2205 postfix_attrs = c_parser_gnu_attributes (parser);
2206 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2208 /* This means there is an attribute specifier after
2209 the declarator in a function definition. Provide
2210 some more information for the user. */
2211 error_at (here, "attributes should be specified before the "
2212 "declarator in a function definition");
2213 c_parser_skip_to_end_of_block_or_statement (parser);
2217 if (c_parser_next_token_is (parser, CPP_EQ))
2221 location_t init_loc;
2222 c_parser_consume_token (parser);
2225 init_loc = c_parser_peek_token (parser)->location;
2226 rich_location richloc (line_table, init_loc);
2227 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2228 /* A parameter is initialized, which is invalid. Don't
2229 attempt to instrument the initializer. */
2230 int flag_sanitize_save = flag_sanitize;
2231 if (nested && !empty_ok)
2233 init = c_parser_expr_no_commas (parser, NULL);
2234 flag_sanitize = flag_sanitize_save;
2235 if (TREE_CODE (init.value) == COMPONENT_REF
2236 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2238 "%<__auto_type%> used with a bit-field"
2240 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2241 tree init_type = TREE_TYPE (init.value);
2242 bool vm_type = variably_modified_type_p (init_type,
2245 init.value = save_expr (init.value);
2247 specs->typespec_kind = ctsk_typeof;
2248 specs->locations[cdw_typedef] = init_loc;
2249 specs->typedef_p = true;
2250 specs->type = init_type;
2253 bool maybe_const = true;
2254 tree type_expr = c_fully_fold (init.value, false,
2256 specs->expr_const_operands &= maybe_const;
2258 specs->expr = build2 (COMPOUND_EXPR,
2259 TREE_TYPE (type_expr),
2260 specs->expr, type_expr);
2262 specs->expr = type_expr;
2264 d = start_decl (declarator, specs, true,
2265 chainon (postfix_attrs, all_prefix_attrs));
2267 d = error_mark_node;
2268 if (omp_declare_simd_clauses)
2269 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2270 omp_declare_simd_clauses);
2274 /* The declaration of the variable is in effect while
2275 its initializer is parsed. */
2276 d = start_decl (declarator, specs, true,
2277 chainon (postfix_attrs, all_prefix_attrs));
2279 d = error_mark_node;
2280 if (omp_declare_simd_clauses)
2281 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2282 omp_declare_simd_clauses);
2283 init_loc = c_parser_peek_token (parser)->location;
2284 rich_location richloc (line_table, init_loc);
2285 start_init (d, asm_name, global_bindings_p (), &richloc);
2286 /* A parameter is initialized, which is invalid. Don't
2287 attempt to instrument the initializer. */
2288 int flag_sanitize_save = flag_sanitize;
2289 if (TREE_CODE (d) == PARM_DECL)
2291 init = c_parser_initializer (parser, d);
2292 flag_sanitize = flag_sanitize_save;
2295 if (oacc_routine_data)
2296 c_finish_oacc_routine (oacc_routine_data, d, false);
2297 if (d != error_mark_node)
2299 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2300 finish_decl (d, init_loc, init.value,
2301 init.original_type, asm_name);
2309 "%<__auto_type%> requires an initialized "
2310 "data declaration");
2311 c_parser_skip_to_end_of_block_or_statement (parser);
2315 location_t lastloc = UNKNOWN_LOCATION;
2316 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2317 tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2318 if (d && TREE_CODE (d) == FUNCTION_DECL)
2320 /* Find the innermost declarator that is neither cdk_id
2322 const struct c_declarator *decl = declarator;
2323 const struct c_declarator *last_non_id_attrs = NULL;
2331 last_non_id_attrs = decl;
2332 decl = decl->declarator;
2336 decl = decl->declarator;
2347 /* If it exists and is cdk_function declaration whose
2348 arguments have not been set yet, use its arguments. */
2349 if (last_non_id_attrs
2350 && last_non_id_attrs->kind == cdk_function)
2352 tree parms = last_non_id_attrs->u.arg_info->parms;
2353 if (DECL_ARGUMENTS (d) == NULL_TREE
2354 && DECL_INITIAL (d) == NULL_TREE)
2355 DECL_ARGUMENTS (d) = parms;
2357 warn_parm_array_mismatch (lastloc, d, parms);
2360 if (omp_declare_simd_clauses)
2362 tree parms = NULL_TREE;
2363 if (d && TREE_CODE (d) == FUNCTION_DECL)
2365 struct c_declarator *ce = declarator;
2367 if (ce->kind == cdk_function)
2369 parms = ce->u.arg_info->parms;
2373 ce = ce->declarator;
2376 temp_store_parm_decls (d, parms);
2377 c_finish_omp_declare_simd (parser, d, parms,
2378 omp_declare_simd_clauses);
2380 temp_pop_parm_decls ();
2382 if (oacc_routine_data)
2383 c_finish_oacc_routine (oacc_routine_data, d, false);
2385 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2386 NULL_TREE, asm_name);
2388 if (c_parser_next_token_is_keyword (parser, RID_IN))
2391 *objc_foreach_object_declaration = d;
2393 *objc_foreach_object_declaration = error_mark_node;
2396 if (c_parser_next_token_is (parser, CPP_COMMA))
2401 "%<__auto_type%> may only be used with"
2402 " a single declarator");
2403 c_parser_skip_to_end_of_block_or_statement (parser);
2406 c_parser_consume_token (parser);
2407 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2408 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2411 all_prefix_attrs = prefix_attrs;
2414 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2416 c_parser_consume_token (parser);
2419 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2421 /* This can only happen in Objective-C: we found the
2422 'in' that terminates the declaration inside an
2423 Objective-C foreach statement. Do not consume the
2424 token, so that the caller can use it to determine
2425 that this indeed is a foreach context. */
2430 c_parser_error (parser, "expected %<,%> or %<;%>");
2431 c_parser_skip_to_end_of_block_or_statement (parser);
2435 else if (auto_type_p)
2438 "%<__auto_type%> requires an initialized data declaration");
2439 c_parser_skip_to_end_of_block_or_statement (parser);
2444 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2445 "%<asm%> or %<__attribute__%>");
2446 c_parser_skip_to_end_of_block_or_statement (parser);
2449 /* Function definition (nested or otherwise). */
2452 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2453 c_push_function_context ();
2455 if (!start_function (specs, declarator, all_prefix_attrs))
2457 /* At this point we've consumed:
2458 declaration-specifiers declarator
2459 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2460 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2462 declaration-specifiers declarator
2463 aren't grokkable as a function definition, so we have
2465 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2466 if (c_parser_next_token_starts_declspecs (parser))
2469 declaration-specifiers declarator decl-specs
2470 then assume we have a missing semicolon, which would
2472 declaration-specifiers declarator decl-specs
2475 <~~~~~~~~~ declaration ~~~~~~~~~~>
2476 Use c_parser_require to get an error with a fix-it hint. */
2477 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2478 parser->error = false;
2482 /* This can appear in many cases looking nothing like a
2483 function definition, so we don't give a more specific
2484 error suggesting there was one. */
2485 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2486 "or %<__attribute__%>");
2489 c_pop_function_context ();
2493 if (DECL_DECLARED_INLINE_P (current_function_decl))
2494 tv = TV_PARSE_INLINE;
2497 auto_timevar at (g_timer, tv);
2499 /* Parse old-style parameter declarations. ??? Attributes are
2500 not allowed to start declaration specifiers here because of a
2501 syntax conflict between a function declaration with attribute
2502 suffix and a function definition with an attribute prefix on
2503 first old-style parameter declaration. Following the old
2504 parser, they are not accepted on subsequent old-style
2505 parameter declarations either. However, there is no
2506 ambiguity after the first declaration, nor indeed on the
2507 first as long as we don't allow postfix attributes after a
2508 declarator with a nonempty identifier list in a definition;
2509 and postfix attributes have never been accepted here in
2510 function definitions either. */
2511 while (c_parser_next_token_is_not (parser, CPP_EOF)
2512 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2513 c_parser_declaration_or_fndef (parser, false, false, false,
2515 store_parm_decls ();
2516 if (omp_declare_simd_clauses)
2517 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2518 omp_declare_simd_clauses);
2519 if (oacc_routine_data)
2520 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2521 location_t startloc = c_parser_peek_token (parser)->location;
2522 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2524 location_t endloc = startloc;
2526 /* If the definition was marked with __RTL, use the RTL parser now,
2527 consuming the function body. */
2528 if (specs->declspec_il == cdil_rtl)
2530 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2532 /* Normally, store_parm_decls sets next_is_function_body,
2533 anticipating a function body. We need a push_scope/pop_scope
2534 pair to flush out this state, or subsequent function parsing
2539 finish_function (endloc);
2542 /* If the definition was marked with __GIMPLE then parse the
2543 function body as GIMPLE. */
2544 else if (specs->declspec_il != cdil_none)
2546 bool saved = in_late_binary_op;
2547 in_late_binary_op = true;
2548 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2550 specs->entry_bb_count);
2551 in_late_binary_op = saved;
2554 fnbody = c_parser_compound_statement (parser, &endloc);
2555 tree fndecl = current_function_decl;
2558 tree decl = current_function_decl;
2559 /* Mark nested functions as needing static-chain initially.
2560 lower_nested_functions will recompute it but the
2561 DECL_STATIC_CHAIN flag is also used before that happens,
2562 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2563 DECL_STATIC_CHAIN (decl) = 1;
2565 finish_function (endloc);
2566 c_pop_function_context ();
2567 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2573 finish_function (endloc);
2575 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2576 if (specs->declspec_il != cdil_none)
2577 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2583 /* Parse an asm-definition (asm() outside a function body). This is a
2591 c_parser_asm_definition (c_parser *parser)
2593 tree asm_str = c_parser_simple_asm_expr (parser);
2595 symtab->finalize_toplevel_asm (asm_str);
2596 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2599 /* Parse a static assertion (C11 6.7.10).
2601 static_assert-declaration:
2602 static_assert-declaration-no-semi ;
2606 c_parser_static_assert_declaration (c_parser *parser)
2608 c_parser_static_assert_declaration_no_semi (parser);
2610 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2611 c_parser_skip_to_end_of_block_or_statement (parser);
2614 /* Parse a static assertion (C11 6.7.10), without the trailing
2617 static_assert-declaration-no-semi:
2618 _Static_assert ( constant-expression , string-literal )
2621 static_assert-declaration-no-semi:
2622 _Static_assert ( constant-expression )
2626 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2628 location_t assert_loc, value_loc;
2630 tree string = NULL_TREE;
2632 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2633 tree spelling = c_parser_peek_token (parser)->value;
2634 assert_loc = c_parser_peek_token (parser)->location;
2636 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2637 "ISO C99 does not support %qE", spelling);
2639 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2640 "ISO C90 does not support %qE", spelling);
2641 c_parser_consume_token (parser);
2642 matching_parens parens;
2643 if (!parens.require_open (parser))
2645 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2646 value = c_parser_expr_no_commas (parser, NULL).value;
2647 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2648 if (c_parser_next_token_is (parser, CPP_COMMA))
2650 c_parser_consume_token (parser);
2651 switch (c_parser_peek_token (parser)->type)
2657 case CPP_UTF8STRING:
2658 string = c_parser_string_literal (parser, false, true).value;
2661 c_parser_error (parser, "expected string literal");
2665 else if (flag_isoc11)
2666 /* If pedantic for pre-C11, the use of _Static_assert itself will
2667 have been diagnosed, so do not also diagnose the use of this
2668 new C2X feature of _Static_assert. */
2669 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2670 "ISO C11 does not support omitting the string in "
2672 parens.require_close (parser);
2674 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2676 error_at (value_loc, "expression in static assertion is not an integer");
2679 if (TREE_CODE (value) != INTEGER_CST)
2681 value = c_fully_fold (value, false, NULL);
2682 /* Strip no-op conversions. */
2683 STRIP_TYPE_NOPS (value);
2684 if (TREE_CODE (value) == INTEGER_CST)
2685 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2686 "is not an integer constant expression");
2688 if (TREE_CODE (value) != INTEGER_CST)
2690 error_at (value_loc, "expression in static assertion is not constant");
2693 constant_expression_warning (value);
2694 if (integer_zerop (value))
2697 error_at (assert_loc, "static assertion failed: %E", string);
2699 error_at (assert_loc, "static assertion failed");
2703 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2704 6.7, C11 6.7), adding them to SPECS (which may already include some).
2705 Storage class specifiers are accepted iff SCSPEC_OK; type
2706 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2707 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2708 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2709 addition to the syntax shown, standard attributes are accepted at
2710 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2711 unlike gnu-attributes, they are not accepted in the middle of the
2712 list. (This combines various different syntax productions in the C
2713 standard, and in some cases gnu-attributes and standard attributes
2714 at the start may already have been parsed before this function is
2717 declaration-specifiers:
2718 storage-class-specifier declaration-specifiers[opt]
2719 type-specifier declaration-specifiers[opt]
2720 type-qualifier declaration-specifiers[opt]
2721 function-specifier declaration-specifiers[opt]
2722 alignment-specifier declaration-specifiers[opt]
2724 Function specifiers (inline) are from C99, and are currently
2725 handled as storage class specifiers, as is __thread. Alignment
2726 specifiers are from C11.
2728 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2729 storage-class-specifier:
2737 (_Thread_local is new in C11.)
2739 C99 6.7.4, C11 6.7.4:
2744 (_Noreturn is new in C11.)
2746 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2759 [_Imaginary removed in C99 TC2]
2760 struct-or-union-specifier
2763 atomic-type-specifier
2765 (_Bool and _Complex are new in C99.)
2766 (atomic-type-specifier is new in C11.)
2768 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2774 address-space-qualifier
2777 (restrict is new in C99.)
2778 (_Atomic is new in C11.)
2782 declaration-specifiers:
2783 gnu-attributes declaration-specifiers[opt]
2789 identifier recognized by the target
2791 storage-class-specifier:
2805 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2806 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2808 atomic-type-specifier
2809 _Atomic ( type-name )
2814 class-name objc-protocol-refs[opt]
2815 typedef-name objc-protocol-refs
2820 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2821 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2822 bool alignspec_ok, bool auto_type_ok,
2823 bool start_std_attr_ok, bool end_std_attr_ok,
2824 enum c_lookahead_kind la)
2826 bool attrs_ok = start_attr_ok;
2827 bool seen_type = specs->typespec_kind != ctsk_none;
2830 gcc_assert (la == cla_prefer_id);
2832 if (start_std_attr_ok
2833 && c_parser_nth_token_starts_std_attributes (parser, 1))
2835 gcc_assert (!specs->non_std_attrs_seen_p);
2836 location_t loc = c_parser_peek_token (parser)->location;
2837 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2838 declspecs_add_attrs (loc, specs, attrs);
2839 specs->non_std_attrs_seen_p = false;
2842 while (c_parser_next_token_is (parser, CPP_NAME)
2843 || c_parser_next_token_is (parser, CPP_KEYWORD)
2844 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2846 struct c_typespec t;
2849 location_t loc = c_parser_peek_token (parser)->location;
2851 /* If we cannot accept a type, exit if the next token must start
2852 one. Also, if we already have seen a tagged definition,
2853 a typename would be an error anyway and likely the user
2854 has simply forgotten a semicolon, so we exit. */
2855 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2856 && c_parser_next_tokens_start_typename (parser, la)
2857 && !c_parser_next_token_is_qualifier (parser)
2858 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2861 if (c_parser_next_token_is (parser, CPP_NAME))
2863 c_token *name_token = c_parser_peek_token (parser);
2864 tree value = name_token->value;
2865 c_id_kind kind = name_token->id_kind;
2867 if (kind == C_ID_ADDRSPACE)
2870 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2871 declspecs_add_addrspace (name_token->location, specs, as);
2872 c_parser_consume_token (parser);
2877 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2879 /* If we cannot accept a type, and the next token must start one,
2880 exit. Do the same if we already have seen a tagged definition,
2881 since it would be an error anyway and likely the user has simply
2882 forgotten a semicolon. */
2883 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2886 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2887 a C_ID_CLASSNAME. */
2888 c_parser_consume_token (parser);
2891 if (kind == C_ID_ID)
2893 error_at (loc, "unknown type name %qE", value);
2894 t.kind = ctsk_typedef;
2895 t.spec = error_mark_node;
2897 else if (kind == C_ID_TYPENAME
2898 && (!c_dialect_objc ()
2899 || c_parser_next_token_is_not (parser, CPP_LESS)))
2901 t.kind = ctsk_typedef;
2902 /* For a typedef name, record the meaning, not the name.
2903 In case of 'foo foo, bar;'. */
2904 t.spec = lookup_name (value);
2908 tree proto = NULL_TREE;
2909 gcc_assert (c_dialect_objc ());
2911 if (c_parser_next_token_is (parser, CPP_LESS))
2912 proto = c_parser_objc_protocol_refs (parser);
2913 t.spec = objc_get_protocol_qualified_type (value, proto);
2916 t.expr_const_operands = true;
2917 declspecs_add_type (name_token->location, specs, t);
2920 if (c_parser_next_token_is (parser, CPP_LESS))
2922 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2923 nisse@lysator.liu.se. */
2925 gcc_assert (c_dialect_objc ());
2926 if (!typespec_ok || seen_type)
2928 proto = c_parser_objc_protocol_refs (parser);
2930 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2932 t.expr_const_operands = true;
2933 declspecs_add_type (loc, specs, t);
2936 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2937 switch (c_parser_peek_token (parser)->keyword)
2950 /* TODO: Distinguish between function specifiers (inline, noreturn)
2951 and storage class specifiers, either here or in
2952 declspecs_add_scspec. */
2953 declspecs_add_scspec (loc, specs,
2954 c_parser_peek_token (parser)->value);
2955 c_parser_consume_token (parser);
2987 if (c_dialect_objc ())
2988 parser->objc_need_raw_identifier = true;
2989 t.kind = ctsk_resword;
2990 t.spec = c_parser_peek_token (parser)->value;
2992 t.expr_const_operands = true;
2993 declspecs_add_type (loc, specs, t);
2994 c_parser_consume_token (parser);
3001 t = c_parser_enum_specifier (parser);
3002 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3003 declspecs_add_type (loc, specs, t);
3011 t = c_parser_struct_or_union_specifier (parser);
3012 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3013 declspecs_add_type (loc, specs, t);
3016 /* ??? The old parser rejected typeof after other type
3017 specifiers, but is a syntax error the best way of
3019 if (!typespec_ok || seen_type)
3023 t = c_parser_typeof_specifier (parser);
3024 declspecs_add_type (loc, specs, t);
3027 /* C parser handling of Objective-C constructs needs
3028 checking for correct lvalue-to-rvalue conversions, and
3029 the code in build_modify_expr handling various
3030 Objective-C cases, and that in build_unary_op handling
3031 Objective-C cases for increment / decrement, also needs
3032 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3033 and objc_types_are_equivalent may also need updates. */
3034 if (c_dialect_objc ())
3035 sorry ("%<_Atomic%> in Objective-C");
3037 pedwarn_c99 (loc, OPT_Wpedantic,
3038 "ISO C99 does not support the %<_Atomic%> qualifier");
3040 pedwarn_c99 (loc, OPT_Wpedantic,
3041 "ISO C90 does not support the %<_Atomic%> qualifier");
3044 value = c_parser_peek_token (parser)->value;
3045 c_parser_consume_token (parser);
3046 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3048 /* _Atomic ( type-name ). */
3050 c_parser_consume_token (parser);
3051 struct c_type_name *type = c_parser_type_name (parser);
3052 t.kind = ctsk_typeof;
3053 t.spec = error_mark_node;
3055 t.expr_const_operands = true;
3057 t.spec = groktypename (type, &t.expr,
3058 &t.expr_const_operands);
3059 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3061 if (t.spec != error_mark_node)
3063 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3064 error_at (loc, "%<_Atomic%>-qualified array type");
3065 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3066 error_at (loc, "%<_Atomic%>-qualified function type");
3067 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3068 error_at (loc, "%<_Atomic%> applied to a qualified type");
3070 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3072 declspecs_add_type (loc, specs, t);
3075 declspecs_add_qual (loc, specs, value);
3081 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3082 c_parser_consume_token (parser);
3087 attrs = c_parser_gnu_attributes (parser);
3088 declspecs_add_attrs (loc, specs, attrs);
3093 align = c_parser_alignas_specifier (parser);
3094 declspecs_add_alignas (loc, specs, align);
3098 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3099 c_parser_consume_token (parser);
3100 specs->declspec_il = cdil_gimple;
3101 specs->locations[cdw_gimple] = loc;
3102 c_parser_gimple_or_rtl_pass_list (parser, specs);
3105 c_parser_consume_token (parser);
3106 specs->declspec_il = cdil_rtl;
3107 specs->locations[cdw_rtl] = loc;
3108 c_parser_gimple_or_rtl_pass_list (parser, specs);
3116 && c_parser_nth_token_starts_std_attributes (parser, 1))
3117 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3120 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3123 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3125 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3127 enum gnu-attributes[opt] identifier
3129 The form with trailing comma is new in C99. The forms with
3130 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3131 without commas in the syntax (assignment expressions, not just
3132 conditional expressions); assignment expressions will be diagnosed
3137 enumerator-list , enumerator
3140 enumeration-constant attribute-specifier-sequence[opt]
3141 enumeration-constant attribute-specifier-sequence[opt]
3142 = constant-expression
3147 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3148 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3149 = constant-expression
3153 static struct c_typespec
3154 c_parser_enum_specifier (c_parser *parser)
3156 struct c_typespec ret;
3157 bool have_std_attrs;
3158 tree std_attrs = NULL_TREE;
3160 tree ident = NULL_TREE;
3161 location_t enum_loc;
3162 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3163 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3164 c_parser_consume_token (parser);
3165 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3167 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3168 attrs = c_parser_gnu_attributes (parser);
3169 enum_loc = c_parser_peek_token (parser)->location;
3170 /* Set the location in case we create a decl now. */
3171 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3172 if (c_parser_next_token_is (parser, CPP_NAME))
3174 ident = c_parser_peek_token (parser)->value;
3175 ident_loc = c_parser_peek_token (parser)->location;
3176 enum_loc = ident_loc;
3177 c_parser_consume_token (parser);
3179 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3181 /* Parse an enum definition. */
3182 struct c_enum_contents the_enum;
3185 /* We chain the enumerators in reverse order, then put them in
3186 forward order at the end. */
3188 timevar_push (TV_PARSE_ENUM);
3189 type = start_enum (enum_loc, &the_enum, ident);
3191 c_parser_consume_token (parser);
3199 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3200 location_t decl_loc, value_loc;
3201 if (c_parser_next_token_is_not (parser, CPP_NAME))
3203 /* Give a nicer error for "enum {}". */
3204 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3207 error_at (c_parser_peek_token (parser)->location,
3208 "empty enum is invalid");
3209 parser->error = true;
3212 c_parser_error (parser, "expected identifier");
3213 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3214 values = error_mark_node;
3217 token = c_parser_peek_token (parser);
3218 enum_id = token->value;
3219 /* Set the location in case we create a decl now. */
3220 c_parser_set_source_position_from_token (token);
3221 decl_loc = value_loc = token->location;
3222 c_parser_consume_token (parser);
3223 /* Parse any specified attributes. */
3224 tree std_attrs = NULL_TREE;
3225 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3226 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3227 tree enum_attrs = chainon (std_attrs,
3228 c_parser_gnu_attributes (parser));
3229 if (c_parser_next_token_is (parser, CPP_EQ))
3231 c_parser_consume_token (parser);
3232 value_loc = c_parser_peek_token (parser)->location;
3233 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3236 enum_value = NULL_TREE;
3237 enum_decl = build_enumerator (decl_loc, value_loc,
3238 &the_enum, enum_id, enum_value);
3240 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3241 TREE_CHAIN (enum_decl) = values;
3244 if (c_parser_next_token_is (parser, CPP_COMMA))
3246 comma_loc = c_parser_peek_token (parser)->location;
3248 c_parser_consume_token (parser);
3250 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3253 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3254 "comma at end of enumerator list");
3255 c_parser_consume_token (parser);
3260 c_parser_error (parser, "expected %<,%> or %<}%>");
3261 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3262 values = error_mark_node;
3266 postfix_attrs = c_parser_gnu_attributes (parser);
3267 ret.spec = finish_enum (type, nreverse (values),
3269 chainon (attrs, postfix_attrs)));
3270 ret.kind = ctsk_tagdef;
3271 ret.expr = NULL_TREE;
3272 ret.expr_const_operands = true;
3273 timevar_pop (TV_PARSE_ENUM);
3278 c_parser_error (parser, "expected %<{%>");
3279 ret.spec = error_mark_node;
3280 ret.kind = ctsk_tagref;
3281 ret.expr = NULL_TREE;
3282 ret.expr_const_operands = true;
3285 /* Attributes may only appear when the members are defined or in
3286 certain forward declarations (treat enum forward declarations in
3287 GNU C analogously to struct and union forward declarations in
3289 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3290 c_parser_error (parser, "expected %<;%>");
3291 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3293 /* In ISO C, enumerated types can be referred to only if already
3295 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3298 pedwarn (enum_loc, OPT_Wpedantic,
3299 "ISO C forbids forward references to %<enum%> types");
3304 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3306 struct-or-union-specifier:
3307 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3308 identifier[opt] { struct-contents } gnu-attributes[opt]
3309 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3313 struct-declaration-list
3315 struct-declaration-list:
3316 struct-declaration ;
3317 struct-declaration-list struct-declaration ;
3324 struct-declaration-list struct-declaration
3326 struct-declaration-list:
3327 struct-declaration-list ;
3330 (Note that in the syntax here, unlike that in ISO C, the semicolons
3331 are included here rather than in struct-declaration, in order to
3332 describe the syntax with extra semicolons and missing semicolon at
3337 struct-declaration-list:
3338 @defs ( class-name )
3340 (Note this does not include a trailing semicolon, but can be
3341 followed by further declarations, and gets a pedwarn-if-pedantic
3342 when followed by a semicolon.) */
3344 static struct c_typespec
3345 c_parser_struct_or_union_specifier (c_parser *parser)
3347 struct c_typespec ret;
3348 bool have_std_attrs;
3349 tree std_attrs = NULL_TREE;
3351 tree ident = NULL_TREE;
3352 location_t struct_loc;
3353 location_t ident_loc = UNKNOWN_LOCATION;
3354 enum tree_code code;
3355 switch (c_parser_peek_token (parser)->keyword)
3366 struct_loc = c_parser_peek_token (parser)->location;
3367 c_parser_consume_token (parser);
3368 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3370 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3371 attrs = c_parser_gnu_attributes (parser);
3373 /* Set the location in case we create a decl now. */
3374 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3376 if (c_parser_next_token_is (parser, CPP_NAME))
3378 ident = c_parser_peek_token (parser)->value;
3379 ident_loc = c_parser_peek_token (parser)->location;
3380 struct_loc = ident_loc;
3381 c_parser_consume_token (parser);
3383 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3385 /* Parse a struct or union definition. Start the scope of the
3386 tag before parsing components. */
3387 class c_struct_parse_info *struct_info;
3388 tree type = start_struct (struct_loc, code, ident, &struct_info);
3390 /* We chain the components in reverse order, then put them in
3391 forward order at the end. Each struct-declaration may
3392 declare multiple components (comma-separated), so we must use
3393 chainon to join them, although when parsing each
3394 struct-declaration we can use TREE_CHAIN directly.
3396 The theory behind all this is that there will be more
3397 semicolon separated fields than comma separated fields, and
3398 so we'll be minimizing the number of node traversals required
3401 timevar_push (TV_PARSE_STRUCT);
3402 contents = NULL_TREE;
3403 c_parser_consume_token (parser);
3404 /* Handle the Objective-C @defs construct,
3405 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3406 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3409 gcc_assert (c_dialect_objc ());
3410 c_parser_consume_token (parser);
3411 matching_parens parens;
3412 if (!parens.require_open (parser))
3414 if (c_parser_next_token_is (parser, CPP_NAME)
3415 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3417 name = c_parser_peek_token (parser)->value;
3418 c_parser_consume_token (parser);
3422 c_parser_error (parser, "expected class name");
3423 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3426 parens.skip_until_found_close (parser);
3427 contents = nreverse (objc_get_class_ivars (name));
3430 /* Parse the struct-declarations and semicolons. Problems with
3431 semicolons are diagnosed here; empty structures are diagnosed
3436 /* Parse any stray semicolon. */
3437 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3439 location_t semicolon_loc
3440 = c_parser_peek_token (parser)->location;
3441 gcc_rich_location richloc (semicolon_loc);
3442 richloc.add_fixit_remove ();
3443 pedwarn (&richloc, OPT_Wpedantic,
3444 "extra semicolon in struct or union specified");
3445 c_parser_consume_token (parser);
3448 /* Stop if at the end of the struct or union contents. */
3449 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3451 c_parser_consume_token (parser);
3454 /* Accept #pragmas at struct scope. */
3455 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3457 c_parser_pragma (parser, pragma_struct, NULL);
3460 /* Parse some comma-separated declarations, but not the
3461 trailing semicolon if any. */
3462 decls = c_parser_struct_declaration (parser);
3463 contents = chainon (decls, contents);
3464 /* If no semicolon follows, either we have a parse error or
3465 are at the end of the struct or union and should
3467 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3468 c_parser_consume_token (parser);
3471 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3472 pedwarn (c_parser_peek_token (parser)->location, 0,
3473 "no semicolon at end of struct or union");
3474 else if (parser->error
3475 || !c_parser_next_token_starts_declspecs (parser))
3477 c_parser_error (parser, "expected %<;%>");
3478 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3482 /* If we come here, we have already emitted an error
3483 for an expected `;', identifier or `(', and we also
3484 recovered already. Go on with the next field. */
3487 postfix_attrs = c_parser_gnu_attributes (parser);
3488 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3490 chainon (attrs, postfix_attrs)),
3492 ret.kind = ctsk_tagdef;
3493 ret.expr = NULL_TREE;
3494 ret.expr_const_operands = true;
3495 timevar_pop (TV_PARSE_STRUCT);
3500 c_parser_error (parser, "expected %<{%>");
3501 ret.spec = error_mark_node;
3502 ret.kind = ctsk_tagref;
3503 ret.expr = NULL_TREE;
3504 ret.expr_const_operands = true;
3507 /* Attributes may only appear when the members are defined or in
3508 certain forward declarations. */
3509 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3510 c_parser_error (parser, "expected %<;%>");
3511 /* ??? Existing practice is that GNU attributes are ignored after
3512 the struct or union keyword when not defining the members. */
3513 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3517 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3518 *without* the trailing semicolon.
3521 attribute-specifier-sequence[opt] specifier-qualifier-list
3522 attribute-specifier-sequence[opt] struct-declarator-list
3523 static_assert-declaration-no-semi
3525 specifier-qualifier-list:
3526 type-specifier specifier-qualifier-list[opt]
3527 type-qualifier specifier-qualifier-list[opt]
3528 alignment-specifier specifier-qualifier-list[opt]
3529 gnu-attributes specifier-qualifier-list[opt]
3531 struct-declarator-list:
3533 struct-declarator-list , gnu-attributes[opt] struct-declarator
3536 declarator gnu-attributes[opt]
3537 declarator[opt] : constant-expression gnu-attributes[opt]
3542 __extension__ struct-declaration
3543 specifier-qualifier-list
3545 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3546 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3547 any expression without commas in the syntax (assignment
3548 expressions, not just conditional expressions); assignment
3549 expressions will be diagnosed as non-constant. */
3552 c_parser_struct_declaration (c_parser *parser)
3554 struct c_declspecs *specs;
3556 tree all_prefix_attrs;
3558 location_t decl_loc;
3559 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3563 ext = disable_extension_diagnostics ();
3564 c_parser_consume_token (parser);
3565 decl = c_parser_struct_declaration (parser);
3566 restore_extension_diagnostics (ext);
3569 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3571 c_parser_static_assert_declaration_no_semi (parser);
3574 specs = build_null_declspecs ();
3575 decl_loc = c_parser_peek_token (parser)->location;
3576 /* Strictly by the standard, we shouldn't allow _Alignas here,
3577 but it appears to have been intended to allow it there, so
3578 we're keeping it as it is until WG14 reaches a conclusion
3580 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3581 c_parser_declspecs (parser, specs, false, true, true,
3582 true, false, true, true, cla_nonabstract_decl);
3585 if (!specs->declspecs_seen_p)
3587 c_parser_error (parser, "expected specifier-qualifier-list");
3590 finish_declspecs (specs);
3591 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3592 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3595 if (specs->typespec_kind == ctsk_none)
3597 pedwarn (decl_loc, OPT_Wpedantic,
3598 "ISO C forbids member declarations with no members");
3599 shadow_tag_warned (specs, pedantic);
3604 /* Support for unnamed structs or unions as members of
3605 structs or unions (which is [a] useful and [b] supports
3609 ret = grokfield (c_parser_peek_token (parser)->location,
3610 build_id_declarator (NULL_TREE), specs,
3613 decl_attributes (&ret, attrs, 0);
3618 /* Provide better error recovery. Note that a type name here is valid,
3619 and will be treated as a field name. */
3620 if (specs->typespec_kind == ctsk_tagdef
3621 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3622 && c_parser_next_token_starts_declspecs (parser)
3623 && !c_parser_next_token_is (parser, CPP_NAME))
3625 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3626 parser->error = false;
3630 pending_xref_error ();
3631 prefix_attrs = specs->attrs;
3632 all_prefix_attrs = prefix_attrs;
3633 specs->attrs = NULL_TREE;
3637 /* Declaring one or more declarators or un-named bit-fields. */
3638 struct c_declarator *declarator;
3640 if (c_parser_next_token_is (parser, CPP_COLON))
3641 declarator = build_id_declarator (NULL_TREE);
3643 declarator = c_parser_declarator (parser,
3644 specs->typespec_kind != ctsk_none,
3645 C_DTR_NORMAL, &dummy);
3646 if (declarator == NULL)
3648 c_parser_skip_to_end_of_block_or_statement (parser);
3651 if (c_parser_next_token_is (parser, CPP_COLON)
3652 || c_parser_next_token_is (parser, CPP_COMMA)
3653 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3654 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3655 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3657 tree postfix_attrs = NULL_TREE;
3658 tree width = NULL_TREE;
3660 if (c_parser_next_token_is (parser, CPP_COLON))
3662 c_parser_consume_token (parser);
3663 width = c_parser_expr_no_commas (parser, NULL).value;
3665 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3666 postfix_attrs = c_parser_gnu_attributes (parser);
3667 d = grokfield (c_parser_peek_token (parser)->location,
3668 declarator, specs, width, &all_prefix_attrs);
3669 decl_attributes (&d, chainon (postfix_attrs,
3670 all_prefix_attrs), 0);
3671 DECL_CHAIN (d) = decls;
3673 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3674 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3677 all_prefix_attrs = prefix_attrs;
3678 if (c_parser_next_token_is (parser, CPP_COMMA))
3679 c_parser_consume_token (parser);
3680 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3681 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3683 /* Semicolon consumed in caller. */
3688 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3694 c_parser_error (parser,
3695 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3696 "%<__attribute__%>");
3703 /* Parse a typeof specifier (a GNU extension).
3706 typeof ( expression )
3707 typeof ( type-name )
3710 static struct c_typespec
3711 c_parser_typeof_specifier (c_parser *parser)
3713 struct c_typespec ret;
3714 ret.kind = ctsk_typeof;
3715 ret.spec = error_mark_node;
3716 ret.expr = NULL_TREE;
3717 ret.expr_const_operands = true;
3718 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3719 c_parser_consume_token (parser);
3720 c_inhibit_evaluation_warnings++;
3722 matching_parens parens;
3723 if (!parens.require_open (parser))
3725 c_inhibit_evaluation_warnings--;
3729 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3731 struct c_type_name *type = c_parser_type_name (parser);
3732 c_inhibit_evaluation_warnings--;
3736 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3737 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3743 location_t here = c_parser_peek_token (parser)->location;
3744 struct c_expr expr = c_parser_expression (parser);
3745 c_inhibit_evaluation_warnings--;
3747 if (TREE_CODE (expr.value) == COMPONENT_REF
3748 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3749 error_at (here, "%<typeof%> applied to a bit-field");
3750 mark_exp_read (expr.value);
3751 ret.spec = TREE_TYPE (expr.value);
3752 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3753 /* This is returned with the type so that when the type is
3754 evaluated, this can be evaluated. */
3756 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3757 pop_maybe_used (was_vm);
3759 parens.skip_until_found_close (parser);
3763 /* Parse an alignment-specifier.
3767 alignment-specifier:
3768 _Alignas ( type-name )
3769 _Alignas ( constant-expression )
3773 c_parser_alignas_specifier (c_parser * parser)
3775 tree ret = error_mark_node;
3776 location_t loc = c_parser_peek_token (parser)->location;
3777 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3778 tree spelling = c_parser_peek_token (parser)->value;
3779 c_parser_consume_token (parser);
3781 pedwarn_c99 (loc, OPT_Wpedantic,
3782 "ISO C99 does not support %qE", spelling);
3784 pedwarn_c99 (loc, OPT_Wpedantic,
3785 "ISO C90 does not support %qE", spelling);
3786 matching_parens parens;
3787 if (!parens.require_open (parser))
3789 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3791 struct c_type_name *type = c_parser_type_name (parser);
3793 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3797 ret = c_parser_expr_no_commas (parser, NULL).value;
3798 parens.skip_until_found_close (parser);
3802 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3803 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3804 a typedef name may be redeclared; otherwise it may not. KIND
3805 indicates which kind of declarator is wanted. Returns a valid
3806 declarator except in the case of a syntax error in which case NULL is
3807 returned. *SEEN_ID is set to true if an identifier being declared is
3808 seen; this is used to diagnose bad forms of abstract array declarators
3809 and to determine whether an identifier list is syntactically permitted.
3812 pointer[opt] direct-declarator
3816 ( gnu-attributes[opt] declarator )
3817 direct-declarator array-declarator
3818 direct-declarator ( parameter-type-list )
3819 direct-declarator ( identifier-list[opt] )
3822 * type-qualifier-list[opt]
3823 * type-qualifier-list[opt] pointer
3825 type-qualifier-list:
3828 type-qualifier-list type-qualifier
3829 type-qualifier-list gnu-attributes
3832 [ type-qualifier-list[opt] assignment-expression[opt] ]
3833 [ static type-qualifier-list[opt] assignment-expression ]
3834 [ type-qualifier-list static assignment-expression ]
3835 [ type-qualifier-list[opt] * ]
3837 parameter-type-list:
3839 parameter-list , ...
3842 parameter-declaration
3843 parameter-list , parameter-declaration
3845 parameter-declaration:
3846 declaration-specifiers declarator gnu-attributes[opt]
3847 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3851 identifier-list , identifier
3853 abstract-declarator:
3855 pointer[opt] direct-abstract-declarator
3857 direct-abstract-declarator:
3858 ( gnu-attributes[opt] abstract-declarator )
3859 direct-abstract-declarator[opt] array-declarator
3860 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3865 direct-declarator ( parameter-forward-declarations
3866 parameter-type-list[opt] )
3868 direct-abstract-declarator:
3869 direct-abstract-declarator[opt] ( parameter-forward-declarations
3870 parameter-type-list[opt] )
3872 parameter-forward-declarations:
3874 parameter-forward-declarations parameter-list ;
3876 The uses of gnu-attributes shown above are GNU extensions.
3878 Some forms of array declarator are not included in C99 in the
3879 syntax for abstract declarators; these are disallowed elsewhere.
3880 This may be a defect (DR#289).
3882 This function also accepts an omitted abstract declarator as being
3883 an abstract declarator, although not part of the formal syntax. */
3885 struct c_declarator *
3886 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3889 /* Parse any initial pointer part. */
3890 if (c_parser_next_token_is (parser, CPP_MULT))
3892 struct c_declspecs *quals_attrs = build_null_declspecs ();
3893 struct c_declarator *inner;
3894 c_parser_consume_token (parser);
3895 c_parser_declspecs (parser, quals_attrs, false, false, true,
3896 false, false, true, false, cla_prefer_id);
3897 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3901 return make_pointer_declarator (quals_attrs, inner);
3903 /* Now we have a direct declarator, direct abstract declarator or
3904 nothing (which counts as a direct abstract declarator here). */
3905 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3908 /* Parse a direct declarator or direct abstract declarator; arguments
3909 as c_parser_declarator. */
3911 static struct c_declarator *
3912 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3915 /* The direct declarator must start with an identifier (possibly
3916 omitted) or a parenthesized declarator (possibly abstract). In
3917 an ordinary declarator, initial parentheses must start a
3918 parenthesized declarator. In an abstract declarator or parameter
3919 declarator, they could start a parenthesized declarator or a
3920 parameter list. To tell which, the open parenthesis and any
3921 following gnu-attributes must be read. If a declaration
3922 specifier or standard attributes follow, then it is a parameter
3923 list; if the specifier is a typedef name, there might be an
3924 ambiguity about redeclaring it, which is resolved in the
3925 direction of treating it as a typedef name. If a close
3926 parenthesis follows, it is also an empty parameter list, as the
3927 syntax does not permit empty abstract declarators. Otherwise, it
3928 is a parenthesized declarator (in which case the analysis may be
3929 repeated inside it, recursively).
3931 ??? There is an ambiguity in a parameter declaration "int
3932 (__attribute__((foo)) x)", where x is not a typedef name: it
3933 could be an abstract declarator for a function, or declare x with
3934 parentheses. The proper resolution of this ambiguity needs
3935 documenting. At present we follow an accident of the old
3936 parser's implementation, whereby the first parameter must have
3937 some declaration specifiers other than just gnu-attributes. Thus as
3938 a parameter declaration it is treated as a parenthesized
3939 parameter named x, and as an abstract declarator it is
3942 ??? Also following the old parser, gnu-attributes inside an empty
3943 parameter list are ignored, making it a list not yielding a
3944 prototype, rather than giving an error or making it have one
3945 parameter with implicit type int.
3947 ??? Also following the old parser, typedef names may be
3948 redeclared in declarators, but not Objective-C class names. */
3950 if (kind != C_DTR_ABSTRACT
3951 && c_parser_next_token_is (parser, CPP_NAME)
3953 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3954 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3955 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3957 struct c_declarator *inner
3958 = build_id_declarator (c_parser_peek_token (parser)->value);
3960 inner->id_loc = c_parser_peek_token (parser)->location;
3961 c_parser_consume_token (parser);
3962 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3963 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3964 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3967 if (kind != C_DTR_NORMAL
3968 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3969 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3971 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3972 inner->id_loc = c_parser_peek_token (parser)->location;
3973 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3976 /* Either we are at the end of an abstract declarator, or we have
3979 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3982 struct c_declarator *inner;
3983 c_parser_consume_token (parser);
3984 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3986 attrs = c_parser_gnu_attributes (parser);
3987 if (kind != C_DTR_NORMAL
3988 && (c_parser_next_token_starts_declspecs (parser)
3990 && c_parser_nth_token_starts_std_attributes (parser, 1))
3991 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3993 struct c_arg_info *args
3994 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3995 attrs, have_gnu_attrs);
4000 inner = build_id_declarator (NULL_TREE);
4002 && args->types != error_mark_node
4003 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4004 && c_parser_nth_token_starts_std_attributes (parser, 1))
4007 = c_parser_std_attribute_specifier_sequence (parser);
4009 inner = build_attrs_declarator (std_attrs, inner);
4011 inner = build_function_declarator (args, inner);
4012 return c_parser_direct_declarator_inner (parser, *seen_id,
4016 /* A parenthesized declarator. */
4017 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4018 if (inner != NULL && attrs != NULL)
4019 inner = build_attrs_declarator (attrs, inner);
4020 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4022 c_parser_consume_token (parser);
4026 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4030 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4037 if (kind == C_DTR_NORMAL)
4039 c_parser_error (parser, "expected identifier or %<(%>");
4043 return build_id_declarator (NULL_TREE);
4047 /* Parse part of a direct declarator or direct abstract declarator,
4048 given that some (in INNER) has already been parsed; ID_PRESENT is
4049 true if an identifier is present, false for an abstract
4052 static struct c_declarator *
4053 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4054 struct c_declarator *inner)
4056 /* Parse a sequence of array declarators and parameter lists. */
4057 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4058 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4060 location_t brace_loc = c_parser_peek_token (parser)->location;
4061 struct c_declarator *declarator;
4062 struct c_declspecs *quals_attrs = build_null_declspecs ();
4065 struct c_expr dimen;
4066 dimen.value = NULL_TREE;
4067 dimen.original_code = ERROR_MARK;
4068 dimen.original_type = NULL_TREE;
4069 c_parser_consume_token (parser);
4070 c_parser_declspecs (parser, quals_attrs, false, false, true,
4071 false, false, false, false, cla_prefer_id);
4072 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4074 c_parser_consume_token (parser);
4075 if (static_seen && !quals_attrs->declspecs_seen_p)
4076 c_parser_declspecs (parser, quals_attrs, false, false, true,
4077 false, false, false, false, cla_prefer_id);
4078 if (!quals_attrs->declspecs_seen_p)
4080 /* If "static" is present, there must be an array dimension.
4081 Otherwise, there may be a dimension, "*", or no
4086 dimen = c_parser_expr_no_commas (parser, NULL);
4090 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4092 dimen.value = NULL_TREE;
4095 else if (c_parser_next_token_is (parser, CPP_MULT))
4097 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4099 dimen.value = NULL_TREE;
4101 c_parser_consume_token (parser);
4106 dimen = c_parser_expr_no_commas (parser, NULL);
4112 dimen = c_parser_expr_no_commas (parser, NULL);
4115 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4116 c_parser_consume_token (parser);
4119 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4124 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4125 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4126 static_seen, star_seen);
4127 if (declarator == NULL)
4129 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4132 = c_parser_std_attribute_specifier_sequence (parser);
4134 inner = build_attrs_declarator (std_attrs, inner);
4136 inner = set_array_declarator_inner (declarator, inner);
4137 return c_parser_direct_declarator_inner (parser, id_present, inner);
4139 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4142 struct c_arg_info *args;
4143 c_parser_consume_token (parser);
4144 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4146 attrs = c_parser_gnu_attributes (parser);
4147 args = c_parser_parms_declarator (parser, id_present, attrs,
4154 && args->types != error_mark_node
4155 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4156 && c_parser_nth_token_starts_std_attributes (parser, 1))
4159 = c_parser_std_attribute_specifier_sequence (parser);
4161 inner = build_attrs_declarator (std_attrs, inner);
4163 inner = build_function_declarator (args, inner);
4164 return c_parser_direct_declarator_inner (parser, id_present, inner);
4170 /* Parse a parameter list or identifier list, including the closing
4171 parenthesis but not the opening one. ATTRS are the gnu-attributes
4172 at the start of the list. ID_LIST_OK is true if an identifier list
4173 is acceptable; such a list must not have attributes at the start.
4174 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4175 attributes) were present (in which case standard attributes cannot
4178 static struct c_arg_info *
4179 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4180 bool have_gnu_attrs)
4183 declare_parm_level ();
4184 /* If the list starts with an identifier, it is an identifier list.
4185 Otherwise, it is either a prototype list or an empty list. */
4188 && c_parser_next_token_is (parser, CPP_NAME)
4189 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4191 /* Look ahead to detect typos in type names. */
4192 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4193 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4194 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4195 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4196 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4198 tree list = NULL_TREE, *nextp = &list;
4199 while (c_parser_next_token_is (parser, CPP_NAME)
4200 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4202 *nextp = build_tree_list (NULL_TREE,
4203 c_parser_peek_token (parser)->value);
4204 nextp = & TREE_CHAIN (*nextp);
4205 c_parser_consume_token (parser);
4206 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4208 c_parser_consume_token (parser);
4209 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4211 c_parser_error (parser, "expected identifier");
4215 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4217 struct c_arg_info *ret = build_arg_info ();
4219 c_parser_consume_token (parser);
4225 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4233 struct c_arg_info *ret
4234 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4240 /* Parse a parameter list (possibly empty), including the closing
4241 parenthesis but not the opening one. ATTRS are the gnu-attributes
4242 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4243 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4244 which means standard attributes cannot start the list. EXPR is
4245 NULL or an expression that needs to be evaluated for the side
4246 effects of array size expressions in the parameters. */
4248 static struct c_arg_info *
4249 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4250 bool have_gnu_attrs)
4252 bool bad_parm = false;
4254 /* ??? Following the old parser, forward parameter declarations may
4255 use abstract declarators, and if no real parameter declarations
4256 follow the forward declarations then this is not diagnosed. Also
4257 note as above that gnu-attributes are ignored as the only contents of
4258 the parentheses, or as the only contents after forward
4260 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4262 struct c_arg_info *ret = build_arg_info ();
4263 c_parser_consume_token (parser);
4266 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4268 struct c_arg_info *ret = build_arg_info ();
4270 if (flag_allow_parameterless_variadic_functions)
4272 /* F (...) is allowed. */
4273 ret->types = NULL_TREE;
4277 /* Suppress -Wold-style-definition for this case. */
4278 ret->types = error_mark_node;
4279 error_at (c_parser_peek_token (parser)->location,
4280 "ISO C requires a named argument before %<...%>");
4282 c_parser_consume_token (parser);
4283 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4285 c_parser_consume_token (parser);
4290 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4295 /* Nonempty list of parameters, either terminated with semicolon
4296 (forward declarations; recurse) or with close parenthesis (normal
4297 function) or with ", ... )" (variadic function). */
4300 /* Parse a parameter. */
4301 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4304 have_gnu_attrs = false;
4308 push_parm_decl (parm, &expr);
4309 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4312 c_parser_consume_token (parser);
4313 mark_forward_parm_decls ();
4314 bool new_have_gnu_attrs
4315 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4316 new_attrs = c_parser_gnu_attributes (parser);
4317 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4318 new_have_gnu_attrs);
4320 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4322 c_parser_consume_token (parser);
4326 return get_parm_info (false, expr);
4328 if (!c_parser_require (parser, CPP_COMMA,
4329 "expected %<;%>, %<,%> or %<)%>",
4330 UNKNOWN_LOCATION, false))
4332 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4335 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4337 c_parser_consume_token (parser);
4338 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4340 c_parser_consume_token (parser);
4344 return get_parm_info (true, expr);
4348 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4356 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4357 start of the declaration if it is the first parameter;
4358 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4361 static struct c_parm *
4362 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4363 bool have_gnu_attrs)
4365 struct c_declspecs *specs;
4366 struct c_declarator *declarator;
4368 tree postfix_attrs = NULL_TREE;
4371 /* Accept #pragmas between parameter declarations. */
4372 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4373 c_parser_pragma (parser, pragma_param, NULL);
4375 if (!c_parser_next_token_starts_declspecs (parser)
4376 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4378 c_token *token = c_parser_peek_token (parser);
4381 c_parser_set_source_position_from_token (token);
4382 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4384 auto_diagnostic_group d;
4385 name_hint hint = lookup_name_fuzzy (token->value,
4386 FUZZY_LOOKUP_TYPENAME,
4388 if (const char *suggestion = hint.suggestion ())
4390 gcc_rich_location richloc (token->location);
4391 richloc.add_fixit_replace (suggestion);
4393 "unknown type name %qE; did you mean %qs?",
4394 token->value, suggestion);
4397 error_at (token->location, "unknown type name %qE", token->value);
4398 parser->error = true;
4400 /* ??? In some Objective-C cases '...' isn't applicable so there
4401 should be a different message. */
4403 c_parser_error (parser,
4404 "expected declaration specifiers or %<...%>");
4405 c_parser_skip_to_end_of_parameter (parser);
4409 location_t start_loc = c_parser_peek_token (parser)->location;
4411 specs = build_null_declspecs ();
4414 declspecs_add_attrs (input_location, specs, attrs);
4417 c_parser_declspecs (parser, specs, true, true, true, true, false,
4418 !have_gnu_attrs, true, cla_nonabstract_decl);
4419 finish_declspecs (specs);
4420 pending_xref_error ();
4421 prefix_attrs = specs->attrs;
4422 specs->attrs = NULL_TREE;
4423 declarator = c_parser_declarator (parser,
4424 specs->typespec_kind != ctsk_none,
4425 C_DTR_PARM, &dummy);
4426 if (declarator == NULL)
4428 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4431 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4432 postfix_attrs = c_parser_gnu_attributes (parser);
4434 /* Generate a location for the parameter, ranging from the start of the
4435 initial token to the end of the final token.
4437 If we have a identifier, then use it for the caret location, e.g.
4439 extern int callee (int one, int (*two)(int, int), float three);
4440 ~~~~~~^~~~~~~~~~~~~~
4442 otherwise, reuse the start location for the caret location e.g.:
4444 extern int callee (int one, int (*)(int, int), float three);
4447 location_t end_loc = parser->last_token_location;
4449 /* Find any cdk_id declarator; determine if we have an identifier. */
4450 c_declarator *id_declarator = declarator;
4451 while (id_declarator && id_declarator->kind != cdk_id)
4452 id_declarator = id_declarator->declarator;
4453 location_t caret_loc = (id_declarator->u.id.id
4454 ? id_declarator->id_loc
4456 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4458 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4459 declarator, param_loc);
4462 /* Parse a string literal in an asm expression. It should not be
4463 translated, and wide string literals are an error although
4464 permitted by the syntax. This is a GNU extension.
4471 c_parser_asm_string_literal (c_parser *parser)
4474 int save_flag = warn_overlength_strings;
4475 warn_overlength_strings = 0;
4476 str = c_parser_string_literal (parser, false, false).value;
4477 warn_overlength_strings = save_flag;
4481 /* Parse a simple asm expression. This is used in restricted
4482 contexts, where a full expression with inputs and outputs does not
4483 make sense. This is a GNU extension.
4486 asm ( asm-string-literal )
4490 c_parser_simple_asm_expr (c_parser *parser)
4493 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4494 c_parser_consume_token (parser);
4495 matching_parens parens;
4496 if (!parens.require_open (parser))
4498 str = c_parser_asm_string_literal (parser);
4499 if (!parens.require_close (parser))
4501 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4508 c_parser_gnu_attribute_any_word (c_parser *parser)
4510 tree attr_name = NULL_TREE;
4512 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4514 /* ??? See comment above about what keywords are accepted here. */
4516 switch (c_parser_peek_token (parser)->keyword)
4547 case RID_TRANSACTION_ATOMIC:
4548 case RID_TRANSACTION_CANCEL:
4564 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4565 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4567 else if (c_parser_next_token_is (parser, CPP_NAME))
4568 attr_name = c_parser_peek_token (parser)->value;
4573 /* Parse attribute arguments. This is a common form of syntax
4574 covering all currently valid GNU and standard attributes.
4576 gnu-attribute-arguments:
4578 identifier , nonempty-expr-list
4581 where the "identifier" must not be declared as a type. ??? Why not
4582 allow identifiers declared as types to start the arguments? */
4585 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4586 bool require_string, bool allow_empty_args)
4588 vec<tree, va_gc> *expr_list;
4590 /* Parse the attribute contents. If they start with an
4591 identifier which is followed by a comma or close
4592 parenthesis, then the arguments start with that
4593 identifier; otherwise they are an expression list.
4594 In objective-c the identifier may be a classname. */
4595 if (c_parser_next_token_is (parser, CPP_NAME)
4596 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4597 || (c_dialect_objc ()
4598 && c_parser_peek_token (parser)->id_kind
4600 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4601 || (c_parser_peek_2nd_token (parser)->type
4602 == CPP_CLOSE_PAREN))
4603 && (takes_identifier
4604 || (c_dialect_objc ()
4605 && c_parser_peek_token (parser)->id_kind
4606 == C_ID_CLASSNAME)))
4608 tree arg1 = c_parser_peek_token (parser)->value;
4609 c_parser_consume_token (parser);
4610 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4611 attr_args = build_tree_list (NULL_TREE, arg1);
4615 c_parser_consume_token (parser);
4616 expr_list = c_parser_expr_list (parser, false, true,
4617 NULL, NULL, NULL, NULL);
4618 tree_list = build_tree_list_vec (expr_list);
4619 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4620 release_tree_vector (expr_list);
4625 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4627 if (!allow_empty_args)
4628 error_at (c_parser_peek_token (parser)->location,
4629 "parentheses must be omitted if "
4630 "attribute argument list is empty");
4631 attr_args = NULL_TREE;
4633 else if (require_string)
4635 /* The only valid argument for this attribute is a string
4636 literal. Handle this specially here to avoid accepting
4637 string literals with excess parentheses. */
4638 tree string = c_parser_string_literal (parser, false, true).value;
4639 attr_args = build_tree_list (NULL_TREE, string);
4643 expr_list = c_parser_expr_list (parser, false, true,
4644 NULL, NULL, NULL, NULL);
4645 attr_args = build_tree_list_vec (expr_list);
4646 release_tree_vector (expr_list);
4652 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4656 gnu-attributes gnu-attribute
4659 __attribute__ ( ( gnu-attribute-list ) )
4663 gnu-attribute_list , gnu-attrib
4668 any-word ( gnu-attribute-arguments )
4670 where "any-word" may be any identifier (including one declared as a
4671 type), a reserved word storage class specifier, type specifier or
4672 type qualifier. ??? This still leaves out most reserved keywords
4673 (following the old parser), shouldn't we include them?
4674 When EXPECT_COMMA is true, expect the attribute to be preceded
4675 by a comma and fail if it isn't.
4676 When EMPTY_OK is true, allow and consume any number of consecutive
4677 commas with no attributes in between. */
4680 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4681 bool expect_comma = false, bool empty_ok = true)
4683 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4685 && !c_parser_next_token_is (parser, CPP_NAME)
4686 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4689 while (c_parser_next_token_is (parser, CPP_COMMA))
4691 c_parser_consume_token (parser);
4696 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4697 if (attr_name == NULL_TREE)
4700 attr_name = canonicalize_attr_name (attr_name);
4701 c_parser_consume_token (parser);
4704 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4706 if (expect_comma && !comma_first)
4708 /* A comma is missing between the last attribute on the chain
4710 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4712 return error_mark_node;
4714 attr = build_tree_list (attr_name, NULL_TREE);
4715 /* Add this attribute to the list. */
4716 attrs = chainon (attrs, attr);
4719 c_parser_consume_token (parser);
4722 = c_parser_attribute_arguments (parser,
4723 attribute_takes_identifier_p (attr_name),
4726 attr = build_tree_list (attr_name, attr_args);
4727 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4728 c_parser_consume_token (parser);
4731 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4733 return error_mark_node;
4736 if (expect_comma && !comma_first)
4738 /* A comma is missing between the last attribute on the chain
4740 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4742 return error_mark_node;
4745 /* Add this attribute to the list. */
4746 attrs = chainon (attrs, attr);
4751 c_parser_gnu_attributes (c_parser *parser)
4753 tree attrs = NULL_TREE;
4754 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4756 bool save_translate_strings_p = parser->translate_strings_p;
4757 parser->translate_strings_p = false;
4758 /* Consume the `__attribute__' keyword. */
4759 c_parser_consume_token (parser);
4760 /* Look for the two `(' tokens. */
4761 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4763 parser->translate_strings_p = save_translate_strings_p;
4766 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4768 parser->translate_strings_p = save_translate_strings_p;
4769 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4772 /* Parse the attribute list. Require a comma between successive
4773 (possibly empty) attributes. */
4774 for (bool expect_comma = false; ; expect_comma = true)
4776 /* Parse a single attribute. */
4777 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4778 if (attr == error_mark_node)
4785 /* Look for the two `)' tokens. */
4786 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4787 c_parser_consume_token (parser);
4790 parser->translate_strings_p = save_translate_strings_p;
4791 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4795 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4796 c_parser_consume_token (parser);
4799 parser->translate_strings_p = save_translate_strings_p;
4800 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4804 parser->translate_strings_p = save_translate_strings_p;
4810 /* Parse an optional balanced token sequence.
4812 balanced-token-sequence:
4814 balanced-token-sequence balanced-token
4817 ( balanced-token-sequence[opt] )
4818 [ balanced-token-sequence[opt] ]
4819 { balanced-token-sequence[opt] }
4820 any token other than ()[]{}
4824 c_parser_balanced_token_sequence (c_parser *parser)
4828 c_token *token = c_parser_peek_token (parser);
4829 switch (token->type)
4831 case CPP_OPEN_BRACE:
4833 matching_braces braces;
4834 braces.consume_open (parser);
4835 c_parser_balanced_token_sequence (parser);
4836 braces.require_close (parser);
4840 case CPP_OPEN_PAREN:
4842 matching_parens parens;
4843 parens.consume_open (parser);
4844 c_parser_balanced_token_sequence (parser);
4845 parens.require_close (parser);
4849 case CPP_OPEN_SQUARE:
4850 c_parser_consume_token (parser);
4851 c_parser_balanced_token_sequence (parser);
4852 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4855 case CPP_CLOSE_BRACE:
4856 case CPP_CLOSE_PAREN:
4857 case CPP_CLOSE_SQUARE:
4862 c_parser_consume_pragma (parser);
4863 c_parser_skip_to_pragma_eol (parser, false);
4867 c_parser_consume_token (parser);
4873 /* Parse standard (C2X) attributes (including GNU attributes in the
4876 attribute-specifier-sequence:
4877 attribute-specifier-sequence[opt] attribute-specifier
4879 attribute-specifier:
4880 [ [ attribute-list ] ]
4884 attribute-list, attribute[opt]
4887 attribute-token attribute-argument-clause[opt]
4891 attribute-prefixed-token
4896 attribute-prefixed-token:
4897 attribute-prefix :: identifier
4902 attribute-argument-clause:
4903 ( balanced-token-sequence[opt] )
4905 Keywords are accepted as identifiers for this purpose.
4909 c_parser_std_attribute (c_parser *parser, bool for_tm)
4911 c_token *token = c_parser_peek_token (parser);
4912 tree ns, name, attribute;
4914 /* Parse the attribute-token. */
4915 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4917 c_parser_error (parser, "expected identifier");
4918 return error_mark_node;
4920 name = canonicalize_attr_name (token->value);
4921 c_parser_consume_token (parser);
4922 if (c_parser_next_token_is (parser, CPP_SCOPE))
4925 c_parser_consume_token (parser);
4926 token = c_parser_peek_token (parser);
4927 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4929 c_parser_error (parser, "expected identifier");
4930 return error_mark_node;
4932 name = canonicalize_attr_name (token->value);
4933 c_parser_consume_token (parser);
4937 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4939 /* Parse the arguments, if any. */
4940 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4941 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4944 location_t open_loc = c_parser_peek_token (parser)->location;
4945 matching_parens parens;
4946 parens.consume_open (parser);
4947 if ((as && as->max_length == 0)
4948 /* Special-case the transactional-memory attribute "outer",
4949 which is specially handled but not registered as an
4950 attribute, to avoid allowing arbitrary balanced token
4951 sequences as arguments. */
4952 || is_attribute_p ("outer", name))
4954 error_at (open_loc, "%qE attribute does not take any arguments", name);
4955 parens.skip_until_found_close (parser);
4956 return error_mark_node;
4958 /* If this is a fake attribute created to handle -Wno-attributes,
4959 we must skip parsing the arguments. */
4960 if (as && !attribute_ignored_p (as))
4962 bool takes_identifier
4964 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4965 && attribute_takes_identifier_p (name));
4968 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4969 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4970 TREE_VALUE (attribute)
4971 = c_parser_attribute_arguments (parser, takes_identifier,
4972 require_string, false);
4975 c_parser_balanced_token_sequence (parser);
4976 parens.require_close (parser);
4979 if (ns == NULL_TREE && !for_tm && !as)
4981 /* An attribute with standard syntax and no namespace specified
4982 is a constraint violation if it is not one of the known
4983 standard attributes. Diagnose it here with a pedwarn and
4984 then discard it to prevent a duplicate warning later. */
4985 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4987 return error_mark_node;
4993 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4995 location_t loc = c_parser_peek_token (parser)->location;
4996 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4998 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5000 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5004 pedwarn_c11 (loc, OPT_Wpedantic,
5005 "ISO C does not support %<[[]]%> attributes before C2X");
5006 tree attributes = NULL_TREE;
5009 c_token *token = c_parser_peek_token (parser);
5010 if (token->type == CPP_CLOSE_SQUARE)
5012 if (token->type == CPP_COMMA)
5014 c_parser_consume_token (parser);
5017 tree attribute = c_parser_std_attribute (parser, for_tm);
5018 if (attribute != error_mark_node)
5020 TREE_CHAIN (attribute) = attributes;
5021 attributes = attribute;
5023 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5026 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5027 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5028 return nreverse (attributes);
5031 /* Look past an optional balanced token sequence of raw look-ahead
5032 tokens starting with the *Nth token. *N is updated to point to the
5033 following token. Return true if such a sequence was found, false
5034 if the tokens parsed were not balanced. */
5037 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5041 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5042 switch (token->type)
5044 case CPP_OPEN_BRACE:
5047 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5049 token = c_parser_peek_nth_token_raw (parser, *n);
5050 if (token->type == CPP_CLOSE_BRACE)
5060 case CPP_OPEN_PAREN:
5063 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5065 token = c_parser_peek_nth_token_raw (parser, *n);
5066 if (token->type == CPP_CLOSE_PAREN)
5076 case CPP_OPEN_SQUARE:
5079 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5081 token = c_parser_peek_nth_token_raw (parser, *n);
5082 if (token->type == CPP_CLOSE_SQUARE)
5092 case CPP_CLOSE_BRACE:
5093 case CPP_CLOSE_PAREN:
5094 case CPP_CLOSE_SQUARE:
5105 /* Return whether standard attributes start with the Nth token. */
5108 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5110 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5111 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5113 /* In C, '[[' must start attributes. In Objective-C, we need to
5114 check whether '[[' is matched by ']]'. */
5115 if (!c_dialect_objc ())
5118 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5120 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5121 if (token->type != CPP_CLOSE_SQUARE)
5123 token = c_parser_peek_nth_token_raw (parser, n + 1);
5124 return token->type == CPP_CLOSE_SQUARE;
5128 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5130 tree attributes = NULL_TREE;
5133 tree attrs = c_parser_std_attribute_specifier (parser, false);
5134 attributes = chainon (attributes, attrs);
5136 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5140 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5141 says whether alignment specifiers are OK (only in cases that might
5142 be the type name of a compound literal).
5145 specifier-qualifier-list abstract-declarator[opt]
5148 struct c_type_name *
5149 c_parser_type_name (c_parser *parser, bool alignas_ok)
5151 struct c_declspecs *specs = build_null_declspecs ();
5152 struct c_declarator *declarator;
5153 struct c_type_name *ret;
5155 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5156 false, true, cla_prefer_type);
5157 if (!specs->declspecs_seen_p)
5159 c_parser_error (parser, "expected specifier-qualifier-list");
5162 if (specs->type != error_mark_node)
5164 pending_xref_error ();
5165 finish_declspecs (specs);
5167 declarator = c_parser_declarator (parser,
5168 specs->typespec_kind != ctsk_none,
5169 C_DTR_ABSTRACT, &dummy);
5170 if (declarator == NULL)
5172 ret = XOBNEW (&parser_obstack, struct c_type_name);
5174 ret->declarator = declarator;
5178 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5181 assignment-expression
5182 { initializer-list }
5183 { initializer-list , }
5186 designation[opt] initializer
5187 initializer-list , designation[opt] initializer
5194 designator-list designator
5201 [ constant-expression ]
5213 [ constant-expression ... constant-expression ]
5215 Any expression without commas is accepted in the syntax for the
5216 constant-expressions, with non-constant expressions rejected later.
5218 DECL is the declaration we're parsing this initializer for.
5220 This function is only used for top-level initializers; for nested
5221 ones, see c_parser_initval. */
5223 static struct c_expr
5224 c_parser_initializer (c_parser *parser, tree decl)
5226 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5227 return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
5231 location_t loc = c_parser_peek_token (parser)->location;
5232 if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
5234 "variable-sized object may not be initialized except "
5235 "with an empty initializer");
5236 ret = c_parser_expr_no_commas (parser, NULL);
5237 /* This is handled mostly by gimplify.cc, but we have to deal with
5238 not warning about int x = x; as it is a GCC extension to turn off
5239 this warning but only if warn_init_self is zero. */
5241 && !DECL_EXTERNAL (decl)
5242 && !TREE_STATIC (decl)
5243 && ret.value == decl
5245 suppress_warning (decl, OPT_Winit_self);
5246 if (TREE_CODE (ret.value) != STRING_CST
5247 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5248 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5253 /* The location of the last comma within the current initializer list,
5254 or UNKNOWN_LOCATION if not within one. */
5256 location_t last_init_list_comma;
5258 /* Parse a braced initializer list. TYPE is the type specified for a
5259 compound literal, and NULL_TREE for other initializers and for
5260 nested braced lists. NESTED_P is true for nested braced lists,
5261 false for the list of a compound literal or the list that is the
5262 top-level initializer in a declaration. DECL is the declaration for
5263 the top-level initializer for a declaration, otherwise NULL_TREE. */
5265 static struct c_expr
5266 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5267 struct obstack *outer_obstack, tree decl)
5270 struct obstack braced_init_obstack;
5271 location_t brace_loc = c_parser_peek_token (parser)->location;
5272 gcc_obstack_init (&braced_init_obstack);
5273 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5274 matching_braces braces;
5275 braces.consume_open (parser);
5278 finish_implicit_inits (brace_loc, outer_obstack);
5279 push_init_level (brace_loc, 0, &braced_init_obstack);
5282 really_start_incremental_init (type);
5283 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5285 pedwarn_c11 (brace_loc, OPT_Wpedantic,
5286 "ISO C forbids empty initializer braces before C2X");
5290 if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
5291 error_at (brace_loc,
5292 "variable-sized object may not be initialized except "
5293 "with an empty initializer");
5294 /* Parse a non-empty initializer list, possibly with a trailing
5298 c_parser_initelt (parser, &braced_init_obstack);
5301 if (c_parser_next_token_is (parser, CPP_COMMA))
5303 last_init_list_comma = c_parser_peek_token (parser)->location;
5304 c_parser_consume_token (parser);
5308 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5312 c_token *next_tok = c_parser_peek_token (parser);
5313 if (next_tok->type != CPP_CLOSE_BRACE)
5316 ret.original_code = ERROR_MARK;
5317 ret.original_type = NULL;
5318 braces.skip_until_found_close (parser);
5319 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5320 obstack_free (&braced_init_obstack, NULL);
5323 location_t close_loc = next_tok->location;
5324 c_parser_consume_token (parser);
5325 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5326 obstack_free (&braced_init_obstack, NULL);
5327 set_c_expr_source_range (&ret, brace_loc, close_loc);
5331 /* Parse a nested initializer, including designators. */
5334 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5336 /* Parse any designator or designator list. A single array
5337 designator may have the subsequent "=" omitted in GNU C, but a
5338 longer list or a structure member designator may not. */
5339 if (c_parser_next_token_is (parser, CPP_NAME)
5340 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5342 /* Old-style structure member designator. */
5343 set_init_label (c_parser_peek_token (parser)->location,
5344 c_parser_peek_token (parser)->value,
5345 c_parser_peek_token (parser)->location,
5346 braced_init_obstack);
5347 /* Use the colon as the error location. */
5348 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5349 "obsolete use of designated initializer with %<:%>");
5350 c_parser_consume_token (parser);
5351 c_parser_consume_token (parser);
5355 /* des_seen is 0 if there have been no designators, 1 if there
5356 has been a single array designator and 2 otherwise. */
5358 /* Location of a designator. */
5359 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5360 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5361 || c_parser_next_token_is (parser, CPP_DOT))
5363 int des_prev = des_seen;
5365 des_loc = c_parser_peek_token (parser)->location;
5368 if (c_parser_next_token_is (parser, CPP_DOT))
5371 c_parser_consume_token (parser);
5372 if (c_parser_next_token_is (parser, CPP_NAME))
5374 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5375 c_parser_peek_token (parser)->location,
5376 braced_init_obstack);
5377 c_parser_consume_token (parser);
5383 init.original_code = ERROR_MARK;
5384 init.original_type = NULL;
5385 c_parser_error (parser, "expected identifier");
5386 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5387 process_init_element (input_location, init, false,
5388 braced_init_obstack);
5395 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5396 location_t array_index_loc = UNKNOWN_LOCATION;
5397 /* ??? Following the old parser, [ objc-receiver
5398 objc-message-args ] is accepted as an initializer,
5399 being distinguished from a designator by what follows
5400 the first assignment expression inside the square
5401 brackets, but after a first array designator a
5402 subsequent square bracket is for Objective-C taken to
5403 start an expression, using the obsolete form of
5404 designated initializer without '=', rather than
5405 possibly being a second level of designation: in LALR
5406 terms, the '[' is shifted rather than reducing
5407 designator to designator-list. */
5408 if (des_prev == 1 && c_dialect_objc ())
5410 des_seen = des_prev;
5413 if (des_prev == 0 && c_dialect_objc ())
5415 /* This might be an array designator or an
5416 Objective-C message expression. If the former,
5417 continue parsing here; if the latter, parse the
5418 remainder of the initializer given the starting
5419 primary-expression. ??? It might make sense to
5420 distinguish when des_prev == 1 as well; see
5421 previous comment. */
5423 struct c_expr mexpr;
5424 c_parser_consume_token (parser);
5425 if (c_parser_peek_token (parser)->type == CPP_NAME
5426 && ((c_parser_peek_token (parser)->id_kind
5428 || (c_parser_peek_token (parser)->id_kind
5429 == C_ID_CLASSNAME)))
5431 /* Type name receiver. */
5432 tree id = c_parser_peek_token (parser)->value;
5433 c_parser_consume_token (parser);
5434 rec = objc_get_class_reference (id);
5435 goto parse_message_args;
5437 first = c_parser_expr_no_commas (parser, NULL).value;
5438 mark_exp_read (first);
5439 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5440 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5441 goto array_desig_after_first;
5442 /* Expression receiver. So far only one part
5443 without commas has been parsed; there might be
5444 more of the expression. */
5446 while (c_parser_next_token_is (parser, CPP_COMMA))
5449 location_t comma_loc, exp_loc;
5450 comma_loc = c_parser_peek_token (parser)->location;
5451 c_parser_consume_token (parser);
5452 exp_loc = c_parser_peek_token (parser)->location;
5453 next = c_parser_expr_no_commas (parser, NULL);
5454 next = convert_lvalue_to_rvalue (exp_loc, next,
5456 rec = build_compound_expr (comma_loc, rec, next.value);
5459 /* Now parse the objc-message-args. */
5460 args = c_parser_objc_message_args (parser);
5461 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5464 = objc_build_message_expr (rec, args);
5465 mexpr.original_code = ERROR_MARK;
5466 mexpr.original_type = NULL;
5467 /* Now parse and process the remainder of the
5468 initializer, starting with this message
5469 expression as a primary-expression. */
5470 c_parser_initval (parser, &mexpr, braced_init_obstack);
5473 c_parser_consume_token (parser);
5474 array_index_loc = c_parser_peek_token (parser)->location;
5475 first = c_parser_expr_no_commas (parser, NULL).value;
5476 mark_exp_read (first);
5477 array_desig_after_first:
5478 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5480 ellipsis_loc = c_parser_peek_token (parser)->location;
5481 c_parser_consume_token (parser);
5482 second = c_parser_expr_no_commas (parser, NULL).value;
5483 mark_exp_read (second);
5487 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5489 c_parser_consume_token (parser);
5490 set_init_index (array_index_loc, first, second,
5491 braced_init_obstack);
5493 pedwarn (ellipsis_loc, OPT_Wpedantic,
5494 "ISO C forbids specifying range of elements to initialize");
5497 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5503 if (c_parser_next_token_is (parser, CPP_EQ))
5505 pedwarn_c90 (des_loc, OPT_Wpedantic,
5506 "ISO C90 forbids specifying subobject "
5508 c_parser_consume_token (parser);
5513 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5514 "obsolete use of designated initializer without %<=%>");
5519 init.original_code = ERROR_MARK;
5520 init.original_type = NULL;
5521 c_parser_error (parser, "expected %<=%>");
5522 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5523 process_init_element (input_location, init, false,
5524 braced_init_obstack);
5530 c_parser_initval (parser, NULL, braced_init_obstack);
5533 /* Parse a nested initializer; as c_parser_initializer but parses
5534 initializers within braced lists, after any designators have been
5535 applied. If AFTER is not NULL then it is an Objective-C message
5536 expression which is the primary-expression starting the
5540 c_parser_initval (c_parser *parser, struct c_expr *after,
5541 struct obstack * braced_init_obstack)
5544 gcc_assert (!after || c_dialect_objc ());
5545 location_t loc = c_parser_peek_token (parser)->location;
5547 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5548 init = c_parser_braced_init (parser, NULL_TREE, true,
5549 braced_init_obstack, NULL_TREE);
5552 init = c_parser_expr_no_commas (parser, after);
5553 if (init.value != NULL_TREE
5554 && TREE_CODE (init.value) != STRING_CST
5555 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5556 init = convert_lvalue_to_rvalue (loc, init, true, true);
5558 process_init_element (loc, init, false, braced_init_obstack);
5561 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5562 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5565 { block-item-list[opt] }
5566 { label-declarations block-item-list }
5570 block-item-list block-item
5583 { label-declarations block-item-list }
5586 __extension__ nested-declaration
5587 nested-function-definition
5591 label-declarations label-declaration
5594 __label__ identifier-list ;
5596 Allowing the mixing of declarations and code is new in C99. The
5597 GNU syntax also permits (not shown above) labels at the end of
5598 compound statements, which yield an error. We don't allow labels
5599 on declarations; this might seem like a natural extension, but
5600 there would be a conflict between gnu-attributes on the label and
5601 prefix gnu-attributes on the declaration. ??? The syntax follows the
5602 old parser in requiring something after label declarations.
5603 Although they are erroneous if the labels declared aren't defined,
5604 is it useful for the syntax to be this way?
5625 cancellation-point-directive */
5628 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5631 location_t brace_loc;
5632 brace_loc = c_parser_peek_token (parser)->location;
5633 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5635 /* Ensure a scope is entered and left anyway to avoid confusion
5636 if we have just prepared to enter a function body. */
5637 stmt = c_begin_compound_stmt (true);
5638 c_end_compound_stmt (brace_loc, stmt, true);
5639 return error_mark_node;
5641 stmt = c_begin_compound_stmt (true);
5642 location_t end_loc = c_parser_compound_statement_nostart (parser);
5646 return c_end_compound_stmt (brace_loc, stmt, true);
5649 /* Parse a compound statement except for the opening brace. This is
5650 used for parsing both compound statements and statement expressions
5651 (which follow different paths to handling the opening). */
5654 c_parser_compound_statement_nostart (c_parser *parser)
5656 bool last_stmt = false;
5657 bool last_label = false;
5658 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5659 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5660 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5662 location_t endloc = c_parser_peek_token (parser)->location;
5663 add_debug_begin_stmt (endloc);
5664 c_parser_consume_token (parser);
5667 mark_valid_location_for_stdc_pragma (true);
5668 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5670 /* Read zero or more forward-declarations for labels that nested
5671 functions can jump to. */
5672 mark_valid_location_for_stdc_pragma (false);
5673 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5675 label_loc = c_parser_peek_token (parser)->location;
5676 c_parser_consume_token (parser);
5677 /* Any identifiers, including those declared as type names,
5682 if (c_parser_next_token_is_not (parser, CPP_NAME))
5684 c_parser_error (parser, "expected identifier");
5688 = declare_label (c_parser_peek_token (parser)->value);
5689 C_DECLARED_LABEL_FLAG (label) = 1;
5690 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5691 c_parser_consume_token (parser);
5692 if (c_parser_next_token_is (parser, CPP_COMMA))
5693 c_parser_consume_token (parser);
5697 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5699 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5701 /* We must now have at least one statement, label or declaration. */
5702 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5704 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5705 c_parser_error (parser, "expected declaration or statement");
5706 location_t endloc = c_parser_peek_token (parser)->location;
5707 c_parser_consume_token (parser);
5710 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5712 location_t loc = c_parser_peek_token (parser)->location;
5713 loc = expansion_point_location_if_in_system_header (loc);
5714 /* Standard attributes may start a label, statement or declaration. */
5716 = c_parser_nth_token_starts_std_attributes (parser, 1);
5717 tree std_attrs = NULL_TREE;
5719 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5720 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5721 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5722 || (c_parser_next_token_is (parser, CPP_NAME)
5723 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5725 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5726 label_loc = c_parser_peek_2nd_token (parser)->location;
5728 label_loc = c_parser_peek_token (parser)->location;
5731 mark_valid_location_for_stdc_pragma (false);
5732 c_parser_label (parser, std_attrs);
5734 else if (c_parser_next_tokens_start_declaration (parser)
5736 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5739 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5740 "a label can only be part of a statement and "
5741 "a declaration is not a statement");
5743 mark_valid_location_for_stdc_pragma (false);
5744 bool fallthru_attr_p = false;
5745 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5746 true, true, true, NULL,
5747 NULL, have_std_attrs, std_attrs,
5748 NULL, &fallthru_attr_p);
5750 if (last_stmt && !fallthru_attr_p)
5751 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5752 "ISO C90 forbids mixed declarations and code");
5753 last_stmt = fallthru_attr_p;
5756 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5758 /* __extension__ can start a declaration, but is also an
5759 unary operator that can start an expression. Consume all
5760 but the last of a possible series of __extension__ to
5761 determine which. If standard attributes have already
5762 been seen, it must start a statement, not a declaration,
5763 but standard attributes starting a declaration may appear
5764 after __extension__. */
5765 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5766 && (c_parser_peek_2nd_token (parser)->keyword
5768 c_parser_consume_token (parser);
5770 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5771 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5774 ext = disable_extension_diagnostics ();
5775 c_parser_consume_token (parser);
5777 mark_valid_location_for_stdc_pragma (false);
5778 c_parser_declaration_or_fndef (parser, true, true, true, true,
5780 /* Following the old parser, __extension__ does not
5781 disable this diagnostic. */
5782 restore_extension_diagnostics (ext);
5784 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5785 "ISO C90 forbids mixed declarations and code");
5791 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5794 c_parser_error (parser, "expected declaration or statement");
5795 /* External pragmas, and some omp pragmas, are not associated
5796 with regular c code, and so are not to be considered statements
5797 syntactically. This ensures that the user doesn't put them
5798 places that would turn into syntax errors if the directive
5800 if (c_parser_pragma (parser,
5801 last_label ? pragma_stmt : pragma_compound,
5803 last_label = false, last_stmt = true;
5805 else if (c_parser_next_token_is (parser, CPP_EOF))
5807 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5808 c_parser_error (parser, "expected declaration or statement");
5809 return c_parser_peek_token (parser)->location;
5811 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5813 if (parser->in_if_block)
5815 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5816 error_at (loc, "expected %<}%> before %<else%>");
5817 return c_parser_peek_token (parser)->location;
5821 error_at (loc, "%<else%> without a previous %<if%>");
5822 c_parser_consume_token (parser);
5829 c_warn_unused_attributes (std_attrs);
5832 mark_valid_location_for_stdc_pragma (false);
5833 c_parser_statement_after_labels (parser, NULL);
5836 parser->error = false;
5839 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5840 location_t endloc = c_parser_peek_token (parser)->location;
5841 c_parser_consume_token (parser);
5842 /* Restore the value we started with. */
5843 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5847 /* Parse all consecutive labels, possibly preceded by standard
5848 attributes. In this context, a statement is required, not a
5849 declaration, so attributes must be followed by a statement that is
5850 not just a semicolon. */
5853 c_parser_all_labels (c_parser *parser)
5855 tree std_attrs = NULL;
5856 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5858 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5859 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5860 c_parser_error (parser, "expected statement");
5862 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5863 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5864 || (c_parser_next_token_is (parser, CPP_NAME)
5865 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5867 c_parser_label (parser, std_attrs);
5869 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5871 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5872 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5873 c_parser_error (parser, "expected statement");
5877 c_warn_unused_attributes (std_attrs);
5880 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5883 identifier : gnu-attributes[opt]
5884 case constant-expression :
5890 case constant-expression ... constant-expression :
5892 The use of gnu-attributes on labels is a GNU extension. The syntax in
5893 GNU C accepts any expressions without commas, non-constant
5894 expressions being rejected later. Any standard
5895 attribute-specifier-sequence before the first label has been parsed
5896 in the caller, to distinguish statements from declarations. Any
5897 attribute-specifier-sequence after the label is parsed in this
5900 c_parser_label (c_parser *parser, tree std_attrs)
5902 location_t loc1 = c_parser_peek_token (parser)->location;
5903 tree label = NULL_TREE;
5905 /* Remember whether this case or a user-defined label is allowed to fall
5907 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5909 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5912 c_parser_consume_token (parser);
5913 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5914 if (c_parser_next_token_is (parser, CPP_COLON))
5916 c_parser_consume_token (parser);
5917 label = do_case (loc1, exp1, NULL_TREE, std_attrs);
5919 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5921 c_parser_consume_token (parser);
5922 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5923 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5924 label = do_case (loc1, exp1, exp2, std_attrs);
5927 c_parser_error (parser, "expected %<:%> or %<...%>");
5929 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5931 c_parser_consume_token (parser);
5932 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5933 label = do_case (loc1, NULL_TREE, NULL_TREE, std_attrs);
5937 tree name = c_parser_peek_token (parser)->value;
5940 location_t loc2 = c_parser_peek_token (parser)->location;
5941 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5942 c_parser_consume_token (parser);
5943 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5944 c_parser_consume_token (parser);
5945 attrs = c_parser_gnu_attributes (parser);
5946 tlab = define_label (loc2, name);
5949 decl_attributes (&tlab, attrs, 0);
5950 decl_attributes (&tlab, std_attrs, 0);
5951 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5954 && c_parser_next_tokens_start_declaration (parser))
5955 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5956 " label and declaration appertains to the label");
5960 if (TREE_CODE (label) == LABEL_EXPR)
5961 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5963 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5967 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5971 attribute-specifier-sequence[opt] compound-statement
5972 expression-statement
5973 attribute-specifier-sequence[opt] selection-statement
5974 attribute-specifier-sequence[opt] iteration-statement
5975 attribute-specifier-sequence[opt] jump-statement
5978 attribute-specifier-sequence[opt] label statement
5980 expression-statement:
5982 attribute-specifier-sequence expression ;
5984 selection-statement:
5988 iteration-statement:
5997 return expression[opt] ;
6002 attribute-specifier-sequence[opt] asm-statement
6007 expression-statement:
6013 attribute-specifier-sequence[opt] objc-throw-statement
6014 attribute-specifier-sequence[opt] objc-try-catch-statement
6015 attribute-specifier-sequence[opt] objc-synchronized-statement
6017 objc-throw-statement:
6024 attribute-specifier-sequence[opt] openacc-construct
6033 parallel-directive structured-block
6036 kernels-directive structured-block
6039 data-directive structured-block
6042 loop-directive structured-block
6047 attribute-specifier-sequence[opt] openmp-construct
6056 parallel-for-construct
6057 parallel-for-simd-construct
6058 parallel-sections-construct
6065 parallel-directive structured-block
6068 for-directive iteration-statement
6071 simd-directive iteration-statements
6074 for-simd-directive iteration-statements
6077 sections-directive section-scope
6080 single-directive structured-block
6082 parallel-for-construct:
6083 parallel-for-directive iteration-statement
6085 parallel-for-simd-construct:
6086 parallel-for-simd-directive iteration-statement
6088 parallel-sections-construct:
6089 parallel-sections-directive section-scope
6092 master-directive structured-block
6095 critical-directive structured-block
6098 atomic-directive expression-statement
6101 ordered-directive structured-block
6103 Transactional Memory:
6106 attribute-specifier-sequence[opt] transaction-statement
6107 attribute-specifier-sequence[opt] transaction-cancel-statement
6109 IF_P is used to track whether there's a (possibly labeled) if statement
6110 which is not enclosed in braces and has an else clause. This is used to
6111 implement -Wparentheses. */
6114 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6116 c_parser_all_labels (parser);
6117 if (loc_after_labels)
6118 *loc_after_labels = c_parser_peek_token (parser)->location;
6119 c_parser_statement_after_labels (parser, if_p, NULL);
6122 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6123 of if-else-if conditions. All labels and standard attributes have
6124 been parsed in the caller.
6126 IF_P is used to track whether there's a (possibly labeled) if statement
6127 which is not enclosed in braces and has an else clause. This is used to
6128 implement -Wparentheses. */
6131 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6134 location_t loc = c_parser_peek_token (parser)->location;
6135 tree stmt = NULL_TREE;
6136 bool in_if_block = parser->in_if_block;
6137 parser->in_if_block = false;
6141 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6142 add_debug_begin_stmt (loc);
6145 switch (c_parser_peek_token (parser)->type)
6147 case CPP_OPEN_BRACE:
6148 add_stmt (c_parser_compound_statement (parser));
6151 switch (c_parser_peek_token (parser)->keyword)
6154 c_parser_if_statement (parser, if_p, chain);
6157 c_parser_switch_statement (parser, if_p);
6160 c_parser_while_statement (parser, false, 0, if_p);
6163 c_parser_do_statement (parser, false, 0);
6166 c_parser_for_statement (parser, false, 0, if_p);
6169 c_parser_consume_token (parser);
6170 if (c_parser_next_token_is (parser, CPP_NAME))
6172 stmt = c_finish_goto_label (loc,
6173 c_parser_peek_token (parser)->value);
6174 c_parser_consume_token (parser);
6176 else if (c_parser_next_token_is (parser, CPP_MULT))
6180 c_parser_consume_token (parser);
6181 val = c_parser_expression (parser);
6182 val = convert_lvalue_to_rvalue (loc, val, false, true);
6183 stmt = c_finish_goto_ptr (loc, val);
6186 c_parser_error (parser, "expected identifier or %<*%>");
6187 goto expect_semicolon;
6189 c_parser_consume_token (parser);
6190 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6191 goto expect_semicolon;
6193 c_parser_consume_token (parser);
6194 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6195 goto expect_semicolon;
6197 c_parser_consume_token (parser);
6198 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6200 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6201 c_parser_consume_token (parser);
6205 location_t xloc = c_parser_peek_token (parser)->location;
6206 struct c_expr expr = c_parser_expression_conv (parser);
6207 mark_exp_read (expr.value);
6208 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6209 expr.value, expr.original_type);
6210 goto expect_semicolon;
6214 stmt = c_parser_asm_statement (parser);
6216 case RID_TRANSACTION_ATOMIC:
6217 case RID_TRANSACTION_RELAXED:
6218 stmt = c_parser_transaction (parser,
6219 c_parser_peek_token (parser)->keyword);
6221 case RID_TRANSACTION_CANCEL:
6222 stmt = c_parser_transaction_cancel (parser);
6223 goto expect_semicolon;
6225 gcc_assert (c_dialect_objc ());
6226 c_parser_consume_token (parser);
6227 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6229 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6230 c_parser_consume_token (parser);
6234 struct c_expr expr = c_parser_expression (parser);
6235 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6236 expr.value = c_fully_fold (expr.value, false, NULL);
6237 stmt = objc_build_throw_stmt (loc, expr.value);
6238 goto expect_semicolon;
6242 gcc_assert (c_dialect_objc ());
6243 c_parser_objc_try_catch_finally_statement (parser);
6245 case RID_AT_SYNCHRONIZED:
6246 gcc_assert (c_dialect_objc ());
6247 c_parser_objc_synchronized_statement (parser);
6251 /* Allow '__attribute__((fallthrough));'. */
6252 tree attrs = c_parser_gnu_attributes (parser);
6253 if (attribute_fallthrough_p (attrs))
6255 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6257 tree fn = build_call_expr_internal_loc (loc,
6262 c_parser_consume_token (parser);
6265 warning_at (loc, OPT_Wattributes,
6266 "%<fallthrough%> attribute not followed "
6269 else if (attrs != NULL_TREE)
6270 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6271 " can be applied to a null statement");
6279 c_parser_consume_token (parser);
6281 case CPP_CLOSE_PAREN:
6282 case CPP_CLOSE_SQUARE:
6283 /* Avoid infinite loop in error recovery:
6284 c_parser_skip_until_found stops at a closing nesting
6285 delimiter without consuming it, but here we need to consume
6286 it to proceed further. */
6287 c_parser_error (parser, "expected statement");
6288 c_parser_consume_token (parser);
6291 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6296 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6298 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6301 /* Two cases cannot and do not have line numbers associated: If stmt
6302 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6303 cannot hold line numbers. But that's OK because the statement
6304 will either be changed to a MODIFY_EXPR during gimplification of
6305 the statement expr, or discarded. If stmt was compound, but
6306 without new variables, we will have skipped the creation of a
6307 BIND and will have a bare STATEMENT_LIST. But that's OK because
6308 (recursively) all of the component statements should already have
6309 line numbers assigned. ??? Can we discard no-op statements
6311 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6312 protected_set_expr_location (stmt, loc);
6314 parser->in_if_block = in_if_block;
6317 /* Parse the condition from an if, do, while or for statements. */
6320 c_parser_condition (c_parser *parser)
6322 location_t loc = c_parser_peek_token (parser)->location;
6324 cond = c_parser_expression_conv (parser).value;
6325 cond = c_objc_common_truthvalue_conversion (loc, cond);
6326 cond = c_fully_fold (cond, false, NULL);
6327 if (warn_sequence_point)
6328 verify_sequence_points (cond);
6332 /* Parse a parenthesized condition from an if, do or while statement.
6338 c_parser_paren_condition (c_parser *parser)
6341 matching_parens parens;
6342 if (!parens.require_open (parser))
6343 return error_mark_node;
6344 cond = c_parser_condition (parser);
6345 parens.skip_until_found_close (parser);
6349 /* Parse a statement which is a block in C99.
6351 IF_P is used to track whether there's a (possibly labeled) if statement
6352 which is not enclosed in braces and has an else clause. This is used to
6353 implement -Wparentheses. */
6356 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6357 location_t *loc_after_labels)
6359 tree block = c_begin_compound_stmt (flag_isoc99);
6360 location_t loc = c_parser_peek_token (parser)->location;
6361 c_parser_statement (parser, if_p, loc_after_labels);
6362 return c_end_compound_stmt (loc, block, flag_isoc99);
6365 /* Parse the body of an if statement. This is just parsing a
6366 statement but (a) it is a block in C99, (b) we track whether the
6367 body is an if statement for the sake of -Wparentheses warnings, (c)
6368 we handle an empty body specially for the sake of -Wempty-body
6369 warnings, and (d) we call parser_compound_statement directly
6370 because c_parser_statement_after_labels resets
6371 parser->in_if_block.
6373 IF_P is used to track whether there's a (possibly labeled) if statement
6374 which is not enclosed in braces and has an else clause. This is used to
6375 implement -Wparentheses. */
6378 c_parser_if_body (c_parser *parser, bool *if_p,
6379 const token_indent_info &if_tinfo)
6381 tree block = c_begin_compound_stmt (flag_isoc99);
6382 location_t body_loc = c_parser_peek_token (parser)->location;
6383 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6384 token_indent_info body_tinfo
6385 = get_token_indent_info (c_parser_peek_token (parser));
6387 c_parser_all_labels (parser);
6388 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6390 location_t loc = c_parser_peek_token (parser)->location;
6391 add_stmt (build_empty_stmt (loc));
6392 c_parser_consume_token (parser);
6393 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6394 warning_at (loc, OPT_Wempty_body,
6395 "suggest braces around empty body in an %<if%> statement");
6397 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6398 add_stmt (c_parser_compound_statement (parser));
6401 body_loc_after_labels = c_parser_peek_token (parser)->location;
6402 c_parser_statement_after_labels (parser, if_p);
6405 token_indent_info next_tinfo
6406 = get_token_indent_info (c_parser_peek_token (parser));
6407 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6408 if (body_loc_after_labels != UNKNOWN_LOCATION
6409 && next_tinfo.type != CPP_SEMICOLON)
6410 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6411 if_tinfo.location, RID_IF);
6413 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6416 /* Parse the else body of an if statement. This is just parsing a
6417 statement but (a) it is a block in C99, (b) we handle an empty body
6418 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6419 of if-else-if conditions. */
6422 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6425 location_t body_loc = c_parser_peek_token (parser)->location;
6426 tree block = c_begin_compound_stmt (flag_isoc99);
6427 token_indent_info body_tinfo
6428 = get_token_indent_info (c_parser_peek_token (parser));
6429 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6431 c_parser_all_labels (parser);
6432 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6434 location_t loc = c_parser_peek_token (parser)->location;
6437 "suggest braces around empty body in an %<else%> statement");
6438 add_stmt (build_empty_stmt (loc));
6439 c_parser_consume_token (parser);
6443 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6444 body_loc_after_labels = c_parser_peek_token (parser)->location;
6445 c_parser_statement_after_labels (parser, NULL, chain);
6448 token_indent_info next_tinfo
6449 = get_token_indent_info (c_parser_peek_token (parser));
6450 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6451 if (body_loc_after_labels != UNKNOWN_LOCATION
6452 && next_tinfo.type != CPP_SEMICOLON)
6453 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6454 else_tinfo.location, RID_ELSE);
6456 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6459 /* We might need to reclassify any previously-lexed identifier, e.g.
6460 when we've left a for loop with an if-statement without else in the
6461 body - we might have used a wrong scope for the token. See PR67784. */
6464 c_parser_maybe_reclassify_token (c_parser *parser)
6466 if (c_parser_next_token_is (parser, CPP_NAME))
6468 c_token *token = c_parser_peek_token (parser);
6470 if (token->id_kind != C_ID_CLASSNAME)
6472 tree decl = lookup_name (token->value);
6474 token->id_kind = C_ID_ID;
6477 if (TREE_CODE (decl) == TYPE_DECL)
6478 token->id_kind = C_ID_TYPENAME;
6480 else if (c_dialect_objc ())
6482 tree objc_interface_decl = objc_is_class_name (token->value);
6483 /* Objective-C class names are in the same namespace as
6484 variables and typedefs, and hence are shadowed by local
6486 if (objc_interface_decl)
6488 token->value = objc_interface_decl;
6489 token->id_kind = C_ID_CLASSNAME;
6496 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6499 if ( expression ) statement
6500 if ( expression ) statement else statement
6502 CHAIN is a vector of if-else-if conditions.
6503 IF_P is used to track whether there's a (possibly labeled) if statement
6504 which is not enclosed in braces and has an else clause. This is used to
6505 implement -Wparentheses. */
6508 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6513 bool nested_if = false;
6514 tree first_body, second_body;
6517 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6518 token_indent_info if_tinfo
6519 = get_token_indent_info (c_parser_peek_token (parser));
6520 c_parser_consume_token (parser);
6521 block = c_begin_compound_stmt (flag_isoc99);
6522 loc = c_parser_peek_token (parser)->location;
6523 cond = c_parser_paren_condition (parser);
6524 in_if_block = parser->in_if_block;
6525 parser->in_if_block = true;
6526 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6527 parser->in_if_block = in_if_block;
6529 if (warn_duplicated_cond)
6530 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6532 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6534 token_indent_info else_tinfo
6535 = get_token_indent_info (c_parser_peek_token (parser));
6536 c_parser_consume_token (parser);
6537 if (warn_duplicated_cond)
6539 if (c_parser_next_token_is_keyword (parser, RID_IF)
6542 /* We've got "if (COND) else if (COND2)". Start the
6543 condition chain and add COND as the first element. */
6544 chain = new vec<tree> ();
6545 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6546 chain->safe_push (cond);
6548 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6549 /* This is if-else without subsequent if. Zap the condition
6550 chain; we would have already warned at this point. */
6553 second_body = c_parser_else_body (parser, else_tinfo, chain);
6554 /* Set IF_P to true to indicate that this if statement has an
6555 else clause. This may trigger the Wparentheses warning
6556 below when we get back up to the parent if statement. */
6562 second_body = NULL_TREE;
6564 /* Diagnose an ambiguous else if if-then-else is nested inside
6567 warning_at (loc, OPT_Wdangling_else,
6568 "suggest explicit braces to avoid ambiguous %<else%>");
6570 if (warn_duplicated_cond)
6571 /* This if statement does not have an else clause. We don't
6572 need the condition chain anymore. */
6575 c_finish_if_stmt (loc, cond, first_body, second_body);
6576 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6578 c_parser_maybe_reclassify_token (parser);
6581 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6584 switch (expression) statement
6588 c_parser_switch_statement (c_parser *parser, bool *if_p)
6591 tree block, expr, body;
6592 unsigned char save_in_statement;
6593 location_t switch_loc = c_parser_peek_token (parser)->location;
6594 location_t switch_cond_loc;
6595 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6596 c_parser_consume_token (parser);
6597 block = c_begin_compound_stmt (flag_isoc99);
6598 bool explicit_cast_p = false;
6599 matching_parens parens;
6600 if (parens.require_open (parser))
6602 switch_cond_loc = c_parser_peek_token (parser)->location;
6603 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6604 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6605 explicit_cast_p = true;
6606 ce = c_parser_expression (parser);
6607 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6609 /* ??? expr has no valid location? */
6610 parens.skip_until_found_close (parser);
6614 switch_cond_loc = UNKNOWN_LOCATION;
6615 expr = error_mark_node;
6616 ce.original_type = error_mark_node;
6618 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6619 save_in_statement = in_statement;
6620 in_statement |= IN_SWITCH_STMT;
6621 location_t loc_after_labels;
6622 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6623 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6624 location_t next_loc = c_parser_peek_token (parser)->location;
6625 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6626 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6628 c_finish_switch (body, ce.original_type);
6629 in_statement = save_in_statement;
6630 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6631 c_parser_maybe_reclassify_token (parser);
6634 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6637 while (expression) statement
6639 IF_P is used to track whether there's a (possibly labeled) if statement
6640 which is not enclosed in braces and has an else clause. This is used to
6641 implement -Wparentheses. */
6644 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6647 tree block, cond, body;
6648 unsigned char save_in_statement;
6650 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6651 token_indent_info while_tinfo
6652 = get_token_indent_info (c_parser_peek_token (parser));
6653 c_parser_consume_token (parser);
6654 block = c_begin_compound_stmt (flag_isoc99);
6655 loc = c_parser_peek_token (parser)->location;
6656 cond = c_parser_paren_condition (parser);
6657 if (ivdep && cond != error_mark_node)
6658 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6659 build_int_cst (integer_type_node,
6660 annot_expr_ivdep_kind),
6662 if (unroll && cond != error_mark_node)
6663 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6664 build_int_cst (integer_type_node,
6665 annot_expr_unroll_kind),
6666 build_int_cst (integer_type_node, unroll));
6667 save_in_statement = in_statement;
6668 in_statement = IN_ITERATION_STMT;
6670 token_indent_info body_tinfo
6671 = get_token_indent_info (c_parser_peek_token (parser));
6673 location_t loc_after_labels;
6674 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6675 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6676 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6677 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6678 c_parser_maybe_reclassify_token (parser);
6680 token_indent_info next_tinfo
6681 = get_token_indent_info (c_parser_peek_token (parser));
6682 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6684 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6685 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6686 while_tinfo.location, RID_WHILE);
6688 in_statement = save_in_statement;
6691 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6694 do statement while ( expression ) ;
6698 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6700 tree block, cond, body;
6701 unsigned char save_in_statement;
6703 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6704 c_parser_consume_token (parser);
6705 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6706 warning_at (c_parser_peek_token (parser)->location,
6708 "suggest braces around empty body in %<do%> statement");
6709 block = c_begin_compound_stmt (flag_isoc99);
6710 loc = c_parser_peek_token (parser)->location;
6711 save_in_statement = in_statement;
6712 in_statement = IN_ITERATION_STMT;
6713 body = c_parser_c99_block_statement (parser, NULL);
6714 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6715 in_statement = save_in_statement;
6716 cond = c_parser_paren_condition (parser);
6717 if (ivdep && cond != error_mark_node)
6718 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6719 build_int_cst (integer_type_node,
6720 annot_expr_ivdep_kind),
6722 if (unroll && cond != error_mark_node)
6723 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6724 build_int_cst (integer_type_node,
6725 annot_expr_unroll_kind),
6726 build_int_cst (integer_type_node, unroll));
6727 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6728 c_parser_skip_to_end_of_block_or_statement (parser);
6730 add_stmt (build_stmt (loc, DO_STMT, cond, body));
6731 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6734 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6737 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6738 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6740 The form with a declaration is new in C99.
6742 ??? In accordance with the old parser, the declaration may be a
6743 nested function, which is then rejected in check_for_loop_decls,
6744 but does it make any sense for this to be included in the grammar?
6745 Note in particular that the nested function does not include a
6746 trailing ';', whereas the "declaration" production includes one.
6747 Also, can we reject bad declarations earlier and cheaper than
6748 check_for_loop_decls?
6750 In Objective-C, there are two additional variants:
6753 for ( expression in expresssion ) statement
6754 for ( declaration in expression ) statement
6756 This is inconsistent with C, because the second variant is allowed
6757 even if c99 is not enabled.
6759 The rest of the comment documents these Objective-C foreach-statement.
6761 Here is the canonical example of the first variant:
6762 for (object in array) { do something with object }
6763 we call the first expression ("object") the "object_expression" and
6764 the second expression ("array") the "collection_expression".
6765 object_expression must be an lvalue of type "id" (a generic Objective-C
6766 object) because the loop works by assigning to object_expression the
6767 various objects from the collection_expression. collection_expression
6768 must evaluate to something of type "id" which responds to the method
6769 countByEnumeratingWithState:objects:count:.
6771 The canonical example of the second variant is:
6772 for (id object in array) { do something with object }
6773 which is completely equivalent to
6776 for (object in array) { do something with object }
6778 Note that initizializing 'object' in some way (eg, "for ((object =
6779 xxx) in array) { do something with object }") is possibly
6780 technically valid, but completely pointless as 'object' will be
6781 assigned to something else as soon as the loop starts. We should
6782 most likely reject it (TODO).
6784 The beginning of the Objective-C foreach-statement looks exactly
6785 like the beginning of the for-statement, and we can tell it is a
6786 foreach-statement only because the initial declaration or
6787 expression is terminated by 'in' instead of ';'.
6789 IF_P is used to track whether there's a (possibly labeled) if statement
6790 which is not enclosed in braces and has an else clause. This is used to
6791 implement -Wparentheses. */
6794 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6797 tree block, cond, incr, body;
6798 unsigned char save_in_statement;
6799 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6800 /* The following are only used when parsing an ObjC foreach statement. */
6801 tree object_expression;
6802 /* Silence the bogus uninitialized warning. */
6803 tree collection_expression = NULL;
6804 location_t loc = c_parser_peek_token (parser)->location;
6805 location_t for_loc = loc;
6806 bool is_foreach_statement = false;
6807 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6808 token_indent_info for_tinfo
6809 = get_token_indent_info (c_parser_peek_token (parser));
6810 c_parser_consume_token (parser);
6811 /* Open a compound statement in Objective-C as well, just in case this is
6812 as foreach expression. */
6813 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6814 cond = error_mark_node;
6815 incr = error_mark_node;
6816 matching_parens parens;
6817 if (parens.require_open (parser))
6819 /* Parse the initialization declaration or expression. */
6820 object_expression = error_mark_node;
6821 parser->objc_could_be_foreach_context = c_dialect_objc ();
6822 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6824 parser->objc_could_be_foreach_context = false;
6825 c_parser_consume_token (parser);
6826 c_finish_expr_stmt (loc, NULL_TREE);
6828 else if (c_parser_next_tokens_start_declaration (parser)
6829 || c_parser_nth_token_starts_std_attributes (parser, 1))
6831 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6832 &object_expression);
6833 parser->objc_could_be_foreach_context = false;
6835 if (c_parser_next_token_is_keyword (parser, RID_IN))
6837 c_parser_consume_token (parser);
6838 is_foreach_statement = true;
6839 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6840 c_parser_error (parser, "multiple iterating variables in "
6841 "fast enumeration");
6844 check_for_loop_decls (for_loc, flag_isoc99);
6846 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6848 /* __extension__ can start a declaration, but is also an
6849 unary operator that can start an expression. Consume all
6850 but the last of a possible series of __extension__ to
6852 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6853 && (c_parser_peek_2nd_token (parser)->keyword
6855 c_parser_consume_token (parser);
6856 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6857 || c_parser_nth_token_starts_std_attributes (parser, 2))
6860 ext = disable_extension_diagnostics ();
6861 c_parser_consume_token (parser);
6862 c_parser_declaration_or_fndef (parser, true, true, true, true,
6863 true, &object_expression);
6864 parser->objc_could_be_foreach_context = false;
6866 restore_extension_diagnostics (ext);
6867 if (c_parser_next_token_is_keyword (parser, RID_IN))
6869 c_parser_consume_token (parser);
6870 is_foreach_statement = true;
6871 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6872 c_parser_error (parser, "multiple iterating variables in "
6873 "fast enumeration");
6876 check_for_loop_decls (for_loc, flag_isoc99);
6886 tree init_expression;
6887 ce = c_parser_expression (parser);
6888 init_expression = ce.value;
6889 parser->objc_could_be_foreach_context = false;
6890 if (c_parser_next_token_is_keyword (parser, RID_IN))
6892 c_parser_consume_token (parser);
6893 is_foreach_statement = true;
6894 if (! lvalue_p (init_expression))
6895 c_parser_error (parser, "invalid iterating variable in "
6896 "fast enumeration");
6898 = c_fully_fold (init_expression, false, NULL);
6902 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6903 init_expression = ce.value;
6904 c_finish_expr_stmt (loc, init_expression);
6905 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6910 /* Parse the loop condition. In the case of a foreach
6911 statement, there is no loop condition. */
6912 gcc_assert (!parser->objc_could_be_foreach_context);
6913 if (!is_foreach_statement)
6915 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6919 c_parser_error (parser, "missing loop condition in loop "
6920 "with %<GCC ivdep%> pragma");
6921 cond = error_mark_node;
6925 c_parser_error (parser, "missing loop condition in loop "
6926 "with %<GCC unroll%> pragma");
6927 cond = error_mark_node;
6931 c_parser_consume_token (parser);
6937 cond = c_parser_condition (parser);
6938 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6941 if (ivdep && cond != error_mark_node)
6942 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6943 build_int_cst (integer_type_node,
6944 annot_expr_ivdep_kind),
6946 if (unroll && cond != error_mark_node)
6947 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6948 build_int_cst (integer_type_node,
6949 annot_expr_unroll_kind),
6950 build_int_cst (integer_type_node, unroll));
6952 /* Parse the increment expression (the third expression in a
6953 for-statement). In the case of a foreach-statement, this is
6954 the expression that follows the 'in'. */
6955 loc = c_parser_peek_token (parser)->location;
6956 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6958 if (is_foreach_statement)
6960 c_parser_error (parser,
6961 "missing collection in fast enumeration");
6962 collection_expression = error_mark_node;
6965 incr = c_process_expr_stmt (loc, NULL_TREE);
6969 if (is_foreach_statement)
6970 collection_expression
6971 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6974 struct c_expr ce = c_parser_expression (parser);
6975 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6976 incr = c_process_expr_stmt (loc, ce.value);
6979 parens.skip_until_found_close (parser);
6981 save_in_statement = in_statement;
6982 if (is_foreach_statement)
6984 in_statement = IN_OBJC_FOREACH;
6985 save_objc_foreach_break_label = objc_foreach_break_label;
6986 save_objc_foreach_continue_label = objc_foreach_continue_label;
6987 objc_foreach_break_label = create_artificial_label (loc);
6988 objc_foreach_continue_label = create_artificial_label (loc);
6991 in_statement = IN_ITERATION_STMT;
6993 token_indent_info body_tinfo
6994 = get_token_indent_info (c_parser_peek_token (parser));
6996 location_t loc_after_labels;
6997 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6998 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
7000 if (is_foreach_statement)
7001 objc_finish_foreach_loop (for_loc, object_expression,
7002 collection_expression, body,
7003 objc_foreach_break_label,
7004 objc_foreach_continue_label);
7006 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
7008 add_stmt (c_end_compound_stmt (for_loc, block,
7009 flag_isoc99 || c_dialect_objc ()));
7010 c_parser_maybe_reclassify_token (parser);
7012 token_indent_info next_tinfo
7013 = get_token_indent_info (c_parser_peek_token (parser));
7014 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
7016 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
7017 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7018 for_tinfo.location, RID_FOR);
7020 in_statement = save_in_statement;
7021 if (is_foreach_statement)
7023 objc_foreach_break_label = save_objc_foreach_break_label;
7024 objc_foreach_continue_label = save_objc_foreach_continue_label;
7028 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7029 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7038 asm-qualifier-list asm-qualifier
7042 asm asm-qualifier-list[opt] ( asm-argument ) ;
7046 asm-string-literal : asm-operands[opt]
7047 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7048 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7050 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7053 The form with asm-goto-operands is valid if and only if the
7054 asm-qualifier-list contains goto, and is the only allowed form in that case.
7055 Duplicate asm-qualifiers are not allowed.
7057 The :: token is considered equivalent to two consecutive : tokens. */
7060 c_parser_asm_statement (c_parser *parser)
7062 tree str, outputs, inputs, clobbers, labels, ret;
7064 location_t asm_loc = c_parser_peek_token (parser)->location;
7065 int section, nsections;
7067 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7068 c_parser_consume_token (parser);
7070 /* Handle the asm-qualifier-list. */
7071 location_t volatile_loc = UNKNOWN_LOCATION;
7072 location_t inline_loc = UNKNOWN_LOCATION;
7073 location_t goto_loc = UNKNOWN_LOCATION;
7076 c_token *token = c_parser_peek_token (parser);
7077 location_t loc = token->location;
7078 switch (token->keyword)
7083 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7084 inform (volatile_loc, "first seen here");
7088 c_parser_consume_token (parser);
7094 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7095 inform (inline_loc, "first seen here");
7099 c_parser_consume_token (parser);
7105 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7106 inform (goto_loc, "first seen here");
7110 c_parser_consume_token (parser);
7115 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7116 c_parser_consume_token (parser);
7125 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7126 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7127 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7131 matching_parens parens;
7132 if (!parens.require_open (parser))
7135 str = c_parser_asm_string_literal (parser);
7136 if (str == NULL_TREE)
7137 goto error_close_paren;
7140 outputs = NULL_TREE;
7142 clobbers = NULL_TREE;
7145 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7148 /* Parse each colon-delimited section of operands. */
7149 nsections = 3 + is_goto;
7150 for (section = 0; section < nsections; ++section)
7152 if (c_parser_next_token_is (parser, CPP_SCOPE))
7155 if (section == nsections)
7157 c_parser_error (parser, "expected %<)%>");
7158 goto error_close_paren;
7160 c_parser_consume_token (parser);
7162 else if (!c_parser_require (parser, CPP_COLON,
7164 ? G_("expected %<:%>")
7165 : G_("expected %<:%> or %<)%>"),
7166 UNKNOWN_LOCATION, is_goto))
7167 goto error_close_paren;
7169 /* Once past any colon, we're no longer a simple asm. */
7172 if ((!c_parser_next_token_is (parser, CPP_COLON)
7173 && !c_parser_next_token_is (parser, CPP_SCOPE)
7174 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7179 outputs = c_parser_asm_operands (parser);
7182 inputs = c_parser_asm_operands (parser);
7185 clobbers = c_parser_asm_clobbers (parser);
7188 labels = c_parser_asm_goto_operands (parser);
7194 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7199 if (!parens.require_close (parser))
7201 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7205 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7206 c_parser_skip_to_end_of_block_or_statement (parser);
7208 ret = build_asm_stmt (is_volatile,
7209 build_asm_expr (asm_loc, str, outputs, inputs,
7210 clobbers, labels, simple, is_inline));
7216 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7220 /* Parse asm operands, a GNU extension.
7224 asm-operands , asm-operand
7227 asm-string-literal ( expression )
7228 [ identifier ] asm-string-literal ( expression )
7232 c_parser_asm_operands (c_parser *parser)
7234 tree list = NULL_TREE;
7239 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7241 c_parser_consume_token (parser);
7242 if (c_parser_next_token_is (parser, CPP_NAME))
7244 tree id = c_parser_peek_token (parser)->value;
7245 c_parser_consume_token (parser);
7246 name = build_string (IDENTIFIER_LENGTH (id),
7247 IDENTIFIER_POINTER (id));
7251 c_parser_error (parser, "expected identifier");
7252 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7255 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7260 str = c_parser_asm_string_literal (parser);
7261 if (str == NULL_TREE)
7263 matching_parens parens;
7264 if (!parens.require_open (parser))
7266 expr = c_parser_expression (parser);
7267 mark_exp_read (expr.value);
7268 if (!parens.require_close (parser))
7270 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7273 list = chainon (list, build_tree_list (build_tree_list (name, str),
7275 if (c_parser_next_token_is (parser, CPP_COMMA))
7276 c_parser_consume_token (parser);
7283 /* Parse asm clobbers, a GNU extension.
7287 asm-clobbers , asm-string-literal
7291 c_parser_asm_clobbers (c_parser *parser)
7293 tree list = NULL_TREE;
7296 tree str = c_parser_asm_string_literal (parser);
7298 list = tree_cons (NULL_TREE, str, list);
7301 if (c_parser_next_token_is (parser, CPP_COMMA))
7302 c_parser_consume_token (parser);
7309 /* Parse asm goto labels, a GNU extension.
7313 asm-goto-operands , identifier
7317 c_parser_asm_goto_operands (c_parser *parser)
7319 tree list = NULL_TREE;
7324 if (c_parser_next_token_is (parser, CPP_NAME))
7326 c_token *tok = c_parser_peek_token (parser);
7328 label = lookup_label_for_goto (tok->location, name);
7329 c_parser_consume_token (parser);
7330 TREE_USED (label) = 1;
7334 c_parser_error (parser, "expected identifier");
7338 name = build_string (IDENTIFIER_LENGTH (name),
7339 IDENTIFIER_POINTER (name));
7340 list = tree_cons (name, label, list);
7341 if (c_parser_next_token_is (parser, CPP_COMMA))
7342 c_parser_consume_token (parser);
7344 return nreverse (list);
7348 /* Parse a possibly concatenated sequence of string literals.
7349 TRANSLATE says whether to translate them to the execution character
7350 set; WIDE_OK says whether any kind of prefixed string literal is
7351 permitted in this context. This code is based on that in
7355 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7359 struct obstack str_ob;
7360 struct obstack loc_ob;
7361 cpp_string str, istr, *strs;
7363 location_t loc, last_tok_loc;
7364 enum cpp_ttype type;
7365 tree value, string_tree;
7367 tok = c_parser_peek_token (parser);
7368 loc = tok->location;
7369 last_tok_loc = linemap_resolve_location (line_table, loc,
7370 LRK_MACRO_DEFINITION_LOCATION,
7379 case CPP_UTF8STRING:
7380 string_tree = tok->value;
7384 c_parser_error (parser, "expected string literal");
7386 ret.value = NULL_TREE;
7387 ret.original_code = ERROR_MARK;
7388 ret.original_type = NULL_TREE;
7392 /* Try to avoid the overhead of creating and destroying an obstack
7393 for the common case of just one string. */
7394 switch (c_parser_peek_2nd_token (parser)->type)
7397 c_parser_consume_token (parser);
7398 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7399 str.len = TREE_STRING_LENGTH (string_tree);
7408 case CPP_UTF8STRING:
7409 gcc_obstack_init (&str_ob);
7410 gcc_obstack_init (&loc_ob);
7414 c_parser_consume_token (parser);
7416 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7417 str.len = TREE_STRING_LENGTH (string_tree);
7418 if (type != tok->type)
7420 if (type == CPP_STRING)
7422 else if (tok->type != CPP_STRING)
7423 error ("unsupported non-standard concatenation "
7424 "of string literals");
7426 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7427 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7428 tok = c_parser_peek_token (parser);
7429 string_tree = tok->value;
7431 = linemap_resolve_location (line_table, tok->location,
7432 LRK_MACRO_DEFINITION_LOCATION, NULL);
7434 while (tok->type == CPP_STRING
7435 || tok->type == CPP_WSTRING
7436 || tok->type == CPP_STRING16
7437 || tok->type == CPP_STRING32
7438 || tok->type == CPP_UTF8STRING);
7439 strs = (cpp_string *) obstack_finish (&str_ob);
7442 if (count > 1 && !in_system_header_at (input_location))
7443 warning (OPT_Wtraditional,
7444 "traditional C rejects string constant concatenation");
7446 if ((type == CPP_STRING || wide_ok)
7448 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7449 (parse_in, strs, count, &istr, type)))
7451 value = build_string (istr.len, (const char *) istr.text);
7452 free (CONST_CAST (unsigned char *, istr.text));
7455 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7456 gcc_assert (g_string_concat_db);
7457 g_string_concat_db->record_string_concatenation (count, locs);
7462 if (type != CPP_STRING && !wide_ok)
7464 error_at (loc, "a wide string is invalid in this context");
7467 /* Callers cannot generally handle error_mark_node in this
7468 context, so return the empty string instead. An error has
7469 been issued, either above or from cpp_interpret_string. */
7474 case CPP_UTF8STRING:
7475 if (type == CPP_UTF8STRING && flag_char8_t)
7477 value = build_string (TYPE_PRECISION (char8_type_node)
7478 / TYPE_PRECISION (char_type_node),
7479 ""); /* char8_t is 8 bits */
7482 value = build_string (1, "");
7485 value = build_string (TYPE_PRECISION (char16_type_node)
7486 / TYPE_PRECISION (char_type_node),
7487 "\0"); /* char16_t is 16 bits */
7490 value = build_string (TYPE_PRECISION (char32_type_node)
7491 / TYPE_PRECISION (char_type_node),
7492 "\0\0\0"); /* char32_t is 32 bits */
7495 value = build_string (TYPE_PRECISION (wchar_type_node)
7496 / TYPE_PRECISION (char_type_node),
7497 "\0\0\0"); /* widest supported wchar_t
7507 TREE_TYPE (value) = char_array_type_node;
7509 case CPP_UTF8STRING:
7511 TREE_TYPE (value) = char8_array_type_node;
7513 TREE_TYPE (value) = char_array_type_node;
7516 TREE_TYPE (value) = char16_array_type_node;
7519 TREE_TYPE (value) = char32_array_type_node;
7522 TREE_TYPE (value) = wchar_array_type_node;
7524 value = fix_string_type (value);
7528 obstack_free (&str_ob, 0);
7529 obstack_free (&loc_ob, 0);
7533 ret.original_code = STRING_CST;
7534 ret.original_type = NULL_TREE;
7535 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7537 parser->seen_string_literal = true;
7541 /* Parse an expression other than a compound expression; that is, an
7542 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7543 AFTER is not NULL then it is an Objective-C message expression which
7544 is the primary-expression starting the expression as an initializer.
7546 assignment-expression:
7547 conditional-expression
7548 unary-expression assignment-operator assignment-expression
7550 assignment-operator: one of
7551 = *= /= %= += -= <<= >>= &= ^= |=
7553 In GNU C we accept any conditional expression on the LHS and
7554 diagnose the invalid lvalue rather than producing a syntax
7557 static struct c_expr
7558 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7559 tree omp_atomic_lhs)
7561 struct c_expr lhs, rhs, ret;
7562 enum tree_code code;
7563 location_t op_location, exp_location;
7564 bool save_in_omp_for = c_in_omp_for;
7565 c_in_omp_for = false;
7566 gcc_assert (!after || c_dialect_objc ());
7567 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7568 op_location = c_parser_peek_token (parser)->location;
7569 switch (c_parser_peek_token (parser)->type)
7578 code = TRUNC_DIV_EXPR;
7581 code = TRUNC_MOD_EXPR;
7596 code = BIT_AND_EXPR;
7599 code = BIT_XOR_EXPR;
7602 code = BIT_IOR_EXPR;
7605 c_in_omp_for = save_in_omp_for;
7608 c_parser_consume_token (parser);
7609 exp_location = c_parser_peek_token (parser)->location;
7610 rhs = c_parser_expr_no_commas (parser, NULL);
7611 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7613 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7614 code, exp_location, rhs.value,
7617 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7618 if (code == NOP_EXPR)
7619 ret.original_code = MODIFY_EXPR;
7622 suppress_warning (ret.value, OPT_Wparentheses);
7623 ret.original_code = ERROR_MARK;
7625 ret.original_type = NULL;
7626 c_in_omp_for = save_in_omp_for;
7630 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7631 AFTER is not NULL then it is an Objective-C message expression which is
7632 the primary-expression starting the expression as an initializer.
7634 conditional-expression:
7635 logical-OR-expression
7636 logical-OR-expression ? expression : conditional-expression
7640 conditional-expression:
7641 logical-OR-expression ? : conditional-expression
7644 static struct c_expr
7645 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7646 tree omp_atomic_lhs)
7648 struct c_expr cond, exp1, exp2, ret;
7649 location_t start, cond_loc, colon_loc;
7651 gcc_assert (!after || c_dialect_objc ());
7653 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7655 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7657 if (cond.value != error_mark_node)
7658 start = cond.get_start ();
7660 start = UNKNOWN_LOCATION;
7661 cond_loc = c_parser_peek_token (parser)->location;
7662 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7663 c_parser_consume_token (parser);
7664 if (c_parser_next_token_is (parser, CPP_COLON))
7666 tree eptype = NULL_TREE;
7668 location_t middle_loc = c_parser_peek_token (parser)->location;
7669 pedwarn (middle_loc, OPT_Wpedantic,
7670 "ISO C forbids omitting the middle term of a %<?:%> expression");
7671 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7673 eptype = TREE_TYPE (cond.value);
7674 cond.value = TREE_OPERAND (cond.value, 0);
7676 tree e = cond.value;
7677 while (TREE_CODE (e) == COMPOUND_EXPR)
7678 e = TREE_OPERAND (e, 1);
7679 warn_for_omitted_condop (middle_loc, e);
7680 /* Make sure first operand is calculated only once. */
7681 exp1.value = save_expr (default_conversion (cond.value));
7683 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7684 exp1.original_type = NULL;
7685 exp1.src_range = cond.src_range;
7686 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7687 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7692 = c_objc_common_truthvalue_conversion
7693 (cond_loc, default_conversion (cond.value));
7694 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7695 exp1 = c_parser_expression_conv (parser);
7696 mark_exp_read (exp1.value);
7697 c_inhibit_evaluation_warnings +=
7698 ((cond.value == truthvalue_true_node)
7699 - (cond.value == truthvalue_false_node));
7702 colon_loc = c_parser_peek_token (parser)->location;
7703 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7705 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7707 ret.original_code = ERROR_MARK;
7708 ret.original_type = NULL;
7712 location_t exp2_loc = c_parser_peek_token (parser)->location;
7713 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7714 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7716 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7717 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7718 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7719 if (UNLIKELY (omp_atomic_lhs != NULL)
7720 && (TREE_CODE (cond.value) == GT_EXPR
7721 || TREE_CODE (cond.value) == LT_EXPR
7722 || TREE_CODE (cond.value) == EQ_EXPR)
7723 && c_tree_equal (exp2.value, omp_atomic_lhs)
7724 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
7725 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
7726 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
7727 cond.value, exp1.value, exp2.value);
7730 = build_conditional_expr (colon_loc, cond.value,
7731 cond.original_code == C_MAYBE_CONST_EXPR,
7732 exp1.value, exp1.original_type, loc1,
7733 exp2.value, exp2.original_type, loc2);
7734 ret.original_code = ERROR_MARK;
7735 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7736 ret.original_type = NULL;
7741 /* If both sides are enum type, the default conversion will have
7742 made the type of the result be an integer type. We want to
7743 remember the enum types we started with. */
7744 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7745 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7746 ret.original_type = ((t1 != error_mark_node
7747 && t2 != error_mark_node
7748 && (TYPE_MAIN_VARIANT (t1)
7749 == TYPE_MAIN_VARIANT (t2)))
7753 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7758 /* Parse a binary expression; that is, a logical-OR-expression (C90
7759 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7760 NULL then it is an Objective-C message expression which is the
7761 primary-expression starting the expression as an initializer.
7763 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7764 when it should be the unfolded lhs. In a valid OpenMP source,
7765 one of the operands of the toplevel binary expression must be equal
7766 to it. In that case, just return a build2 created binary operation
7767 rather than result of parser_build_binary_op.
7769 multiplicative-expression:
7771 multiplicative-expression * cast-expression
7772 multiplicative-expression / cast-expression
7773 multiplicative-expression % cast-expression
7775 additive-expression:
7776 multiplicative-expression
7777 additive-expression + multiplicative-expression
7778 additive-expression - multiplicative-expression
7782 shift-expression << additive-expression
7783 shift-expression >> additive-expression
7785 relational-expression:
7787 relational-expression < shift-expression
7788 relational-expression > shift-expression
7789 relational-expression <= shift-expression
7790 relational-expression >= shift-expression
7792 equality-expression:
7793 relational-expression
7794 equality-expression == relational-expression
7795 equality-expression != relational-expression
7799 AND-expression & equality-expression
7801 exclusive-OR-expression:
7803 exclusive-OR-expression ^ AND-expression
7805 inclusive-OR-expression:
7806 exclusive-OR-expression
7807 inclusive-OR-expression | exclusive-OR-expression
7809 logical-AND-expression:
7810 inclusive-OR-expression
7811 logical-AND-expression && inclusive-OR-expression
7813 logical-OR-expression:
7814 logical-AND-expression
7815 logical-OR-expression || logical-AND-expression
7818 static struct c_expr
7819 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7820 tree omp_atomic_lhs)
7822 /* A binary expression is parsed using operator-precedence parsing,
7823 with the operands being cast expressions. All the binary
7824 operators are left-associative. Thus a binary expression is of
7827 E0 op1 E1 op2 E2 ...
7829 which we represent on a stack. On the stack, the precedence
7830 levels are strictly increasing. When a new operator is
7831 encountered of higher precedence than that at the top of the
7832 stack, it is pushed; its LHS is the top expression, and its RHS
7833 is everything parsed until it is popped. When a new operator is
7834 encountered with precedence less than or equal to that at the top
7835 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7836 by the result of the operation until the operator at the top of
7837 the stack has lower precedence than the new operator or there is
7838 only one element on the stack; then the top expression is the LHS
7839 of the new operator. In the case of logical AND and OR
7840 expressions, we also need to adjust c_inhibit_evaluation_warnings
7841 as appropriate when the operators are pushed and popped. */
7844 /* The expression at this stack level. */
7846 /* The precedence of the operator on its left, PREC_NONE at the
7847 bottom of the stack. */
7848 enum c_parser_prec prec;
7849 /* The operation on its left. */
7851 /* The source location of this operation. */
7853 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7857 /* Location of the binary operator. */
7858 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7861 switch (stack[sp].op) \
7863 case TRUTH_ANDIF_EXPR: \
7864 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7865 == truthvalue_false_node); \
7867 case TRUTH_ORIF_EXPR: \
7868 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7869 == truthvalue_true_node); \
7871 case TRUNC_DIV_EXPR: \
7872 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7873 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7874 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7875 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7877 tree type0 = stack[sp - 1].sizeof_arg; \
7878 tree type1 = stack[sp].sizeof_arg; \
7879 tree first_arg = type0; \
7880 if (!TYPE_P (type0)) \
7881 type0 = TREE_TYPE (type0); \
7882 if (!TYPE_P (type1)) \
7883 type1 = TREE_TYPE (type1); \
7884 if (POINTER_TYPE_P (type0) \
7885 && comptypes (TREE_TYPE (type0), type1) \
7886 && !(TREE_CODE (first_arg) == PARM_DECL \
7887 && C_ARRAY_PARAMETER (first_arg) \
7888 && warn_sizeof_array_argument)) \
7890 auto_diagnostic_group d; \
7891 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7892 "division %<sizeof (%T) / sizeof (%T)%> " \
7893 "does not compute the number of array " \
7896 if (DECL_P (first_arg)) \
7897 inform (DECL_SOURCE_LOCATION (first_arg), \
7898 "first %<sizeof%> operand was declared here"); \
7900 else if (TREE_CODE (type0) == ARRAY_TYPE \
7901 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7902 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7903 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7904 stack[sp].sizeof_arg, type1); \
7910 stack[sp - 1].expr \
7911 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7912 stack[sp - 1].expr, true, true); \
7914 = convert_lvalue_to_rvalue (stack[sp].loc, \
7915 stack[sp].expr, true, true); \
7916 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
7917 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
7918 && ((1 << stack[sp].prec) \
7919 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
7920 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
7921 | (1 << PREC_ADD) | (1 << PREC_MULT) \
7922 | (1 << PREC_EQ)))) \
7923 || ((c_parser_next_token_is (parser, CPP_QUERY) \
7924 || (omp_atomic_lhs == void_list_node \
7925 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
7926 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7927 && stack[sp].op != TRUNC_MOD_EXPR \
7928 && stack[sp].op != GE_EXPR \
7929 && stack[sp].op != LE_EXPR \
7930 && stack[sp].op != NE_EXPR \
7931 && stack[0].expr.value != error_mark_node \
7932 && stack[1].expr.value != error_mark_node \
7933 && (omp_atomic_lhs == void_list_node \
7934 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7935 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
7936 || (stack[sp].op == EQ_EXPR \
7937 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
7939 tree t = make_node (stack[1].op); \
7940 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7941 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7942 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7943 stack[0].expr.value = t; \
7944 stack[0].expr.m_decimal = 0; \
7947 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7949 stack[sp - 1].expr, \
7953 gcc_assert (!after || c_dialect_objc ());
7954 stack[0].loc = c_parser_peek_token (parser)->location;
7955 stack[0].expr = c_parser_cast_expression (parser, after);
7956 stack[0].prec = PREC_NONE;
7957 stack[0].sizeof_arg = c_last_sizeof_arg;
7961 enum c_parser_prec oprec;
7962 enum tree_code ocode;
7963 source_range src_range;
7966 switch (c_parser_peek_token (parser)->type)
7974 ocode = TRUNC_DIV_EXPR;
7978 ocode = TRUNC_MOD_EXPR;
7990 ocode = LSHIFT_EXPR;
7994 ocode = RSHIFT_EXPR;
8008 case CPP_GREATER_EQ:
8021 oprec = PREC_BITAND;
8022 ocode = BIT_AND_EXPR;
8025 oprec = PREC_BITXOR;
8026 ocode = BIT_XOR_EXPR;
8030 ocode = BIT_IOR_EXPR;
8033 oprec = PREC_LOGAND;
8034 ocode = TRUTH_ANDIF_EXPR;
8038 ocode = TRUTH_ORIF_EXPR;
8041 /* Not a binary operator, so end of the binary
8045 binary_loc = c_parser_peek_token (parser)->location;
8046 while (oprec <= stack[sp].prec)
8048 c_parser_consume_token (parser);
8051 case TRUTH_ANDIF_EXPR:
8052 src_range = stack[sp].expr.src_range;
8054 = convert_lvalue_to_rvalue (stack[sp].loc,
8055 stack[sp].expr, true, true);
8056 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8057 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8058 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8059 == truthvalue_false_node);
8060 set_c_expr_source_range (&stack[sp].expr, src_range);
8062 case TRUTH_ORIF_EXPR:
8063 src_range = stack[sp].expr.src_range;
8065 = convert_lvalue_to_rvalue (stack[sp].loc,
8066 stack[sp].expr, true, true);
8067 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8068 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8069 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8070 == truthvalue_true_node);
8071 set_c_expr_source_range (&stack[sp].expr, src_range);
8077 stack[sp].loc = binary_loc;
8078 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8079 stack[sp].prec = oprec;
8080 stack[sp].op = ocode;
8081 stack[sp].sizeof_arg = c_last_sizeof_arg;
8086 return stack[0].expr;
8090 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8091 is not NULL then it is an Objective-C message expression which is the
8092 primary-expression starting the expression as an initializer.
8096 ( type-name ) unary-expression
8099 static struct c_expr
8100 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8102 location_t cast_loc = c_parser_peek_token (parser)->location;
8103 gcc_assert (!after || c_dialect_objc ());
8105 return c_parser_postfix_expression_after_primary (parser,
8107 /* If the expression begins with a parenthesized type name, it may
8108 be either a cast or a compound literal; we need to see whether
8109 the next character is '{' to tell the difference. If not, it is
8110 an unary expression. Full detection of unknown typenames here
8111 would require a 3-token lookahead. */
8112 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8113 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8115 struct c_type_name *type_name;
8118 matching_parens parens;
8119 parens.consume_open (parser);
8120 type_name = c_parser_type_name (parser, true);
8121 parens.skip_until_found_close (parser);
8122 if (type_name == NULL)
8125 ret.original_code = ERROR_MARK;
8126 ret.original_type = NULL;
8130 /* Save casted types in the function's used types hash table. */
8131 used_types_insert (type_name->specs->type);
8133 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8134 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8136 if (type_name->specs->alignas_p)
8137 error_at (type_name->specs->locations[cdw_alignas],
8138 "alignment specified for type name in cast");
8140 location_t expr_loc = c_parser_peek_token (parser)->location;
8141 expr = c_parser_cast_expression (parser, NULL);
8142 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8144 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8145 if (ret.value && expr.value)
8146 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8147 ret.original_code = ERROR_MARK;
8148 ret.original_type = NULL;
8152 return c_parser_unary_expression (parser);
8155 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8161 unary-operator cast-expression
8162 sizeof unary-expression
8163 sizeof ( type-name )
8165 unary-operator: one of
8171 __alignof__ unary-expression
8172 __alignof__ ( type-name )
8175 (C11 permits _Alignof with type names only.)
8177 unary-operator: one of
8178 __extension__ __real__ __imag__
8180 Transactional Memory:
8183 transaction-expression
8185 In addition, the GNU syntax treats ++ and -- as unary operators, so
8186 they may be applied to cast expressions with errors for non-lvalues
8189 static struct c_expr
8190 c_parser_unary_expression (c_parser *parser)
8193 struct c_expr ret, op;
8194 location_t op_loc = c_parser_peek_token (parser)->location;
8197 ret.original_code = ERROR_MARK;
8198 ret.original_type = NULL;
8199 switch (c_parser_peek_token (parser)->type)
8202 c_parser_consume_token (parser);
8203 exp_loc = c_parser_peek_token (parser)->location;
8204 op = c_parser_cast_expression (parser, NULL);
8206 op = default_function_array_read_conversion (exp_loc, op);
8207 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8208 case CPP_MINUS_MINUS:
8209 c_parser_consume_token (parser);
8210 exp_loc = c_parser_peek_token (parser)->location;
8211 op = c_parser_cast_expression (parser, NULL);
8213 op = default_function_array_read_conversion (exp_loc, op);
8214 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8216 c_parser_consume_token (parser);
8217 op = c_parser_cast_expression (parser, NULL);
8218 mark_exp_read (op.value);
8219 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8222 c_parser_consume_token (parser);
8223 exp_loc = c_parser_peek_token (parser)->location;
8224 op = c_parser_cast_expression (parser, NULL);
8225 finish = op.get_finish ();
8226 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8227 location_t combined_loc = make_location (op_loc, op_loc, finish);
8228 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8229 ret.src_range.m_start = op_loc;
8230 ret.src_range.m_finish = finish;
8235 if (!c_dialect_objc () && !in_system_header_at (input_location))
8238 "traditional C rejects the unary plus operator");
8239 c_parser_consume_token (parser);
8240 exp_loc = c_parser_peek_token (parser)->location;
8241 op = c_parser_cast_expression (parser, NULL);
8242 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8243 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8245 c_parser_consume_token (parser);
8246 exp_loc = c_parser_peek_token (parser)->location;
8247 op = c_parser_cast_expression (parser, NULL);
8248 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8249 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8251 c_parser_consume_token (parser);
8252 exp_loc = c_parser_peek_token (parser)->location;
8253 op = c_parser_cast_expression (parser, NULL);
8254 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8255 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8257 c_parser_consume_token (parser);
8258 exp_loc = c_parser_peek_token (parser)->location;
8259 op = c_parser_cast_expression (parser, NULL);
8260 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8261 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8263 /* Refer to the address of a label as a pointer. */
8264 c_parser_consume_token (parser);
8265 if (c_parser_next_token_is (parser, CPP_NAME))
8267 ret.value = finish_label_address_expr
8268 (c_parser_peek_token (parser)->value, op_loc);
8269 set_c_expr_source_range (&ret, op_loc,
8270 c_parser_peek_token (parser)->get_finish ());
8271 c_parser_consume_token (parser);
8275 c_parser_error (parser, "expected identifier");
8280 switch (c_parser_peek_token (parser)->keyword)
8283 return c_parser_sizeof_expression (parser);
8285 return c_parser_alignof_expression (parser);
8286 case RID_BUILTIN_HAS_ATTRIBUTE:
8287 return c_parser_has_attribute_expression (parser);
8289 c_parser_consume_token (parser);
8290 ext = disable_extension_diagnostics ();
8291 ret = c_parser_cast_expression (parser, NULL);
8292 restore_extension_diagnostics (ext);
8295 c_parser_consume_token (parser);
8296 exp_loc = c_parser_peek_token (parser)->location;
8297 op = c_parser_cast_expression (parser, NULL);
8298 op = default_function_array_conversion (exp_loc, op);
8299 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8301 c_parser_consume_token (parser);
8302 exp_loc = c_parser_peek_token (parser)->location;
8303 op = c_parser_cast_expression (parser, NULL);
8304 op = default_function_array_conversion (exp_loc, op);
8305 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8306 case RID_TRANSACTION_ATOMIC:
8307 case RID_TRANSACTION_RELAXED:
8308 return c_parser_transaction_expression (parser,
8309 c_parser_peek_token (parser)->keyword);
8311 return c_parser_postfix_expression (parser);
8314 return c_parser_postfix_expression (parser);
8318 /* Parse a sizeof expression. */
8320 static struct c_expr
8321 c_parser_sizeof_expression (c_parser *parser)
8324 struct c_expr result;
8325 location_t expr_loc;
8326 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8329 location_t finish = UNKNOWN_LOCATION;
8331 start = c_parser_peek_token (parser)->location;
8333 c_parser_consume_token (parser);
8334 c_inhibit_evaluation_warnings++;
8336 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8337 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8339 /* Either sizeof ( type-name ) or sizeof unary-expression
8340 starting with a compound literal. */
8341 struct c_type_name *type_name;
8342 matching_parens parens;
8343 parens.consume_open (parser);
8344 expr_loc = c_parser_peek_token (parser)->location;
8345 type_name = c_parser_type_name (parser, true);
8346 parens.skip_until_found_close (parser);
8347 finish = parser->tokens_buf[0].location;
8348 if (type_name == NULL)
8351 c_inhibit_evaluation_warnings--;
8354 ret.original_code = ERROR_MARK;
8355 ret.original_type = NULL;
8358 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8360 expr = c_parser_postfix_expression_after_paren_type (parser,
8363 finish = expr.get_finish ();
8366 /* sizeof ( type-name ). */
8367 if (type_name->specs->alignas_p)
8368 error_at (type_name->specs->locations[cdw_alignas],
8369 "alignment specified for type name in %<sizeof%>");
8370 c_inhibit_evaluation_warnings--;
8372 result = c_expr_sizeof_type (expr_loc, type_name);
8376 expr_loc = c_parser_peek_token (parser)->location;
8377 expr = c_parser_unary_expression (parser);
8378 finish = expr.get_finish ();
8380 c_inhibit_evaluation_warnings--;
8382 mark_exp_read (expr.value);
8383 if (TREE_CODE (expr.value) == COMPONENT_REF
8384 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8385 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8386 result = c_expr_sizeof_expr (expr_loc, expr);
8388 if (finish == UNKNOWN_LOCATION)
8390 set_c_expr_source_range (&result, start, finish);
8394 /* Parse an alignof expression. */
8396 static struct c_expr
8397 c_parser_alignof_expression (c_parser *parser)
8400 location_t start_loc = c_parser_peek_token (parser)->location;
8402 tree alignof_spelling = c_parser_peek_token (parser)->value;
8403 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8404 bool is_c11_alignof = (strcmp (IDENTIFIER_POINTER (alignof_spelling),
8406 || strcmp (IDENTIFIER_POINTER (alignof_spelling),
8408 /* A diagnostic is not required for the use of this identifier in
8409 the implementation namespace; only diagnose it for the C11 or C2X
8410 spelling because of existing code using the other spellings. */
8414 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8417 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8420 c_parser_consume_token (parser);
8421 c_inhibit_evaluation_warnings++;
8423 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8424 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8426 /* Either __alignof__ ( type-name ) or __alignof__
8427 unary-expression starting with a compound literal. */
8429 struct c_type_name *type_name;
8431 matching_parens parens;
8432 parens.consume_open (parser);
8433 loc = c_parser_peek_token (parser)->location;
8434 type_name = c_parser_type_name (parser, true);
8435 end_loc = c_parser_peek_token (parser)->location;
8436 parens.skip_until_found_close (parser);
8437 if (type_name == NULL)
8440 c_inhibit_evaluation_warnings--;
8443 ret.original_code = ERROR_MARK;
8444 ret.original_type = NULL;
8447 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8449 expr = c_parser_postfix_expression_after_paren_type (parser,
8454 /* alignof ( type-name ). */
8455 if (type_name->specs->alignas_p)
8456 error_at (type_name->specs->locations[cdw_alignas],
8457 "alignment specified for type name in %qE",
8459 c_inhibit_evaluation_warnings--;
8461 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8463 false, is_c11_alignof, 1);
8464 ret.original_code = ERROR_MARK;
8465 ret.original_type = NULL;
8466 set_c_expr_source_range (&ret, start_loc, end_loc);
8472 expr = c_parser_unary_expression (parser);
8473 end_loc = expr.src_range.m_finish;
8475 mark_exp_read (expr.value);
8476 c_inhibit_evaluation_warnings--;
8480 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8482 ret.value = c_alignof_expr (start_loc, expr.value);
8483 ret.original_code = ERROR_MARK;
8484 ret.original_type = NULL;
8485 set_c_expr_source_range (&ret, start_loc, end_loc);
8490 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8493 static struct c_expr
8494 c_parser_has_attribute_expression (c_parser *parser)
8496 gcc_assert (c_parser_next_token_is_keyword (parser,
8497 RID_BUILTIN_HAS_ATTRIBUTE));
8498 location_t start = c_parser_peek_token (parser)->location;
8499 c_parser_consume_token (parser);
8501 c_inhibit_evaluation_warnings++;
8503 matching_parens parens;
8504 if (!parens.require_open (parser))
8506 c_inhibit_evaluation_warnings--;
8509 struct c_expr result;
8510 result.set_error ();
8511 result.original_code = ERROR_MARK;
8512 result.original_type = NULL;
8516 /* Treat the type argument the same way as in typeof for the purposes
8517 of warnings. FIXME: Generalize this so the warning refers to
8518 __builtin_has_attribute rather than typeof. */
8521 /* The first operand: one of DECL, EXPR, or TYPE. */
8522 tree oper = NULL_TREE;
8523 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8525 struct c_type_name *tname = c_parser_type_name (parser);
8529 oper = groktypename (tname, NULL, NULL);
8530 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8535 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8536 c_inhibit_evaluation_warnings--;
8538 if (cexpr.value != error_mark_node)
8540 mark_exp_read (cexpr.value);
8542 tree etype = TREE_TYPE (oper);
8543 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8544 /* This is returned with the type so that when the type is
8545 evaluated, this can be evaluated. */
8547 oper = c_fully_fold (oper, false, NULL);
8548 pop_maybe_used (was_vm);
8552 struct c_expr result;
8553 result.original_code = ERROR_MARK;
8554 result.original_type = NULL;
8556 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8558 /* Consume the closing parenthesis if that's the next token
8559 in the likely case the built-in was invoked with fewer
8560 than two arguments. */
8561 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8562 c_parser_consume_token (parser);
8563 c_inhibit_evaluation_warnings--;
8564 result.set_error ();
8568 bool save_translate_strings_p = parser->translate_strings_p;
8570 location_t atloc = c_parser_peek_token (parser)->location;
8571 /* Parse a single attribute. Require no leading comma and do not
8572 allow empty attributes. */
8573 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8575 parser->translate_strings_p = save_translate_strings_p;
8577 location_t finish = c_parser_peek_token (parser)->location;
8578 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8579 c_parser_consume_token (parser);
8582 c_parser_error (parser, "expected identifier");
8583 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8585 result.set_error ();
8591 error_at (atloc, "expected identifier");
8592 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8594 result.set_error ();
8598 result.original_code = INTEGER_CST;
8599 result.original_type = boolean_type_node;
8601 if (has_attribute (atloc, oper, attr, default_conversion))
8602 result.value = boolean_true_node;
8604 result.value = boolean_false_node;
8606 set_c_expr_source_range (&result, start, finish);
8607 result.m_decimal = 0;
8611 /* Helper function to read arguments of builtins which are interfaces
8612 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8613 others. The name of the builtin is passed using BNAME parameter.
8614 Function returns true if there were no errors while parsing and
8615 stores the arguments in CEXPR_LIST. If it returns true,
8616 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8619 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8620 vec<c_expr_t, va_gc> **ret_cexpr_list,
8622 location_t *out_close_paren_loc)
8624 location_t loc = c_parser_peek_token (parser)->location;
8625 vec<c_expr_t, va_gc> *cexpr_list;
8627 bool saved_force_folding_builtin_constant_p;
8629 *ret_cexpr_list = NULL;
8630 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8632 error_at (loc, "cannot take address of %qs", bname);
8636 c_parser_consume_token (parser);
8638 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8640 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8641 c_parser_consume_token (parser);
8645 saved_force_folding_builtin_constant_p
8646 = force_folding_builtin_constant_p;
8647 force_folding_builtin_constant_p |= choose_expr_p;
8648 expr = c_parser_expr_no_commas (parser, NULL);
8649 force_folding_builtin_constant_p
8650 = saved_force_folding_builtin_constant_p;
8651 vec_alloc (cexpr_list, 1);
8652 vec_safe_push (cexpr_list, expr);
8653 while (c_parser_next_token_is (parser, CPP_COMMA))
8655 c_parser_consume_token (parser);
8656 expr = c_parser_expr_no_commas (parser, NULL);
8657 vec_safe_push (cexpr_list, expr);
8660 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8661 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8664 *ret_cexpr_list = cexpr_list;
8668 /* This represents a single generic-association. */
8670 struct c_generic_association
8672 /* The location of the starting token of the type. */
8673 location_t type_location;
8674 /* The association's type, or NULL_TREE for 'default'. */
8676 /* The association's expression. */
8677 struct c_expr expression;
8680 /* Parse a generic-selection. (C11 6.5.1.1).
8683 _Generic ( assignment-expression , generic-assoc-list )
8687 generic-assoc-list , generic-association
8689 generic-association:
8690 type-name : assignment-expression
8691 default : assignment-expression
8694 static struct c_expr
8695 c_parser_generic_selection (c_parser *parser)
8697 struct c_expr selector, error_expr;
8699 struct c_generic_association matched_assoc;
8700 int match_found = -1;
8701 location_t generic_loc, selector_loc;
8703 error_expr.original_code = ERROR_MARK;
8704 error_expr.original_type = NULL;
8705 error_expr.set_error ();
8706 matched_assoc.type_location = UNKNOWN_LOCATION;
8707 matched_assoc.type = NULL_TREE;
8708 matched_assoc.expression = error_expr;
8710 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8711 generic_loc = c_parser_peek_token (parser)->location;
8712 c_parser_consume_token (parser);
8714 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8715 "ISO C99 does not support %<_Generic%>");
8717 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8718 "ISO C90 does not support %<_Generic%>");
8720 matching_parens parens;
8721 if (!parens.require_open (parser))
8724 c_inhibit_evaluation_warnings++;
8725 selector_loc = c_parser_peek_token (parser)->location;
8726 selector = c_parser_expr_no_commas (parser, NULL);
8727 selector = default_function_array_conversion (selector_loc, selector);
8728 c_inhibit_evaluation_warnings--;
8730 if (selector.value == error_mark_node)
8732 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8735 mark_exp_read (selector.value);
8736 selector_type = TREE_TYPE (selector.value);
8737 /* In ISO C terms, rvalues (including the controlling expression of
8738 _Generic) do not have qualified types. */
8739 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8740 selector_type = TYPE_MAIN_VARIANT (selector_type);
8741 /* In ISO C terms, _Noreturn is not part of the type of expressions
8742 such as &abort, but in GCC it is represented internally as a type
8744 if (FUNCTION_POINTER_TYPE_P (selector_type)
8745 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8747 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8749 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8751 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8755 auto_vec<c_generic_association> associations;
8758 struct c_generic_association assoc, *iter;
8760 c_token *token = c_parser_peek_token (parser);
8762 assoc.type_location = token->location;
8763 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8765 c_parser_consume_token (parser);
8766 assoc.type = NULL_TREE;
8770 struct c_type_name *type_name;
8772 type_name = c_parser_type_name (parser);
8773 if (type_name == NULL)
8775 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8778 assoc.type = groktypename (type_name, NULL, NULL);
8779 if (assoc.type == error_mark_node)
8781 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8785 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8786 error_at (assoc.type_location,
8787 "%<_Generic%> association has function type");
8788 else if (!COMPLETE_TYPE_P (assoc.type))
8789 error_at (assoc.type_location,
8790 "%<_Generic%> association has incomplete type");
8792 if (variably_modified_type_p (assoc.type, NULL_TREE))
8793 error_at (assoc.type_location,
8794 "%<_Generic%> association has "
8795 "variable length type");
8798 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8800 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8804 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8805 if (assoc.expression.value == error_mark_node)
8807 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8811 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8813 if (assoc.type == NULL_TREE)
8815 if (iter->type == NULL_TREE)
8817 error_at (assoc.type_location,
8818 "duplicate %<default%> case in %<_Generic%>");
8819 inform (iter->type_location, "original %<default%> is here");
8822 else if (iter->type != NULL_TREE)
8824 if (comptypes (assoc.type, iter->type))
8826 error_at (assoc.type_location,
8827 "%<_Generic%> specifies two compatible types");
8828 inform (iter->type_location, "compatible type is here");
8833 if (assoc.type == NULL_TREE)
8835 if (match_found < 0)
8837 matched_assoc = assoc;
8838 match_found = associations.length ();
8841 else if (comptypes (assoc.type, selector_type))
8843 if (match_found < 0 || matched_assoc.type == NULL_TREE)
8845 matched_assoc = assoc;
8846 match_found = associations.length ();
8850 error_at (assoc.type_location,
8851 "%<_Generic%> selector matches multiple associations");
8852 inform (matched_assoc.type_location,
8853 "other match is here");
8857 associations.safe_push (assoc);
8859 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8861 c_parser_consume_token (parser);
8865 struct c_generic_association *iter;
8866 FOR_EACH_VEC_ELT (associations, ix, iter)
8867 if (ix != (unsigned) match_found)
8868 mark_exp_read (iter->expression.value);
8870 if (!parens.require_close (parser))
8872 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8876 if (match_found < 0)
8878 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8879 "compatible with any association",
8884 return matched_assoc.expression;
8887 /* Check the validity of a function pointer argument *EXPR (argument
8888 position POS) to __builtin_tgmath. Return the number of function
8889 arguments if possibly valid; return 0 having reported an error if
8893 check_tgmath_function (c_expr *expr, unsigned int pos)
8895 tree type = TREE_TYPE (expr->value);
8896 if (!FUNCTION_POINTER_TYPE_P (type))
8898 error_at (expr->get_location (),
8899 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8903 type = TREE_TYPE (type);
8904 if (!prototype_p (type))
8906 error_at (expr->get_location (),
8907 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8910 if (stdarg_p (type))
8912 error_at (expr->get_location (),
8913 "argument %u of %<__builtin_tgmath%> has variable arguments",
8917 unsigned int nargs = 0;
8918 function_args_iterator iter;
8920 FOREACH_FUNCTION_ARGS (type, t, iter)
8922 if (t == void_type_node)
8928 error_at (expr->get_location (),
8929 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8935 /* Ways in which a parameter or return value of a type-generic macro
8936 may vary between the different functions the macro may call. */
8937 enum tgmath_parm_kind
8939 tgmath_fixed, tgmath_real, tgmath_complex
8942 /* Helper function for c_parser_postfix_expression. Parse predefined
8945 static struct c_expr
8946 c_parser_predefined_identifier (c_parser *parser)
8948 location_t loc = c_parser_peek_token (parser)->location;
8949 switch (c_parser_peek_token (parser)->keyword)
8951 case RID_FUNCTION_NAME:
8952 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8953 "identifier", "__FUNCTION__");
8955 case RID_PRETTY_FUNCTION_NAME:
8956 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8957 "identifier", "__PRETTY_FUNCTION__");
8959 case RID_C99_FUNCTION_NAME:
8960 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8961 "%<__func__%> predefined identifier");
8968 expr.original_code = ERROR_MARK;
8969 expr.original_type = NULL;
8970 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8971 c_parser_peek_token (parser)->value);
8972 set_c_expr_source_range (&expr, loc, loc);
8974 c_parser_consume_token (parser);
8978 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8979 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8980 call c_parser_postfix_expression_after_paren_type on encountering them.
8984 postfix-expression [ expression ]
8985 postfix-expression ( argument-expression-list[opt] )
8986 postfix-expression . identifier
8987 postfix-expression -> identifier
8988 postfix-expression ++
8989 postfix-expression --
8990 ( type-name ) { initializer-list }
8991 ( type-name ) { initializer-list , }
8993 argument-expression-list:
8995 argument-expression-list , argument-expression
9008 (treated as a keyword in GNU C)
9011 ( compound-statement )
9012 __builtin_va_arg ( assignment-expression , type-name )
9013 __builtin_offsetof ( type-name , offsetof-member-designator )
9014 __builtin_choose_expr ( assignment-expression ,
9015 assignment-expression ,
9016 assignment-expression )
9017 __builtin_types_compatible_p ( type-name , type-name )
9018 __builtin_tgmath ( expr-list )
9019 __builtin_complex ( assignment-expression , assignment-expression )
9020 __builtin_shuffle ( assignment-expression , assignment-expression )
9021 __builtin_shuffle ( assignment-expression ,
9022 assignment-expression ,
9023 assignment-expression, )
9024 __builtin_convertvector ( assignment-expression , type-name )
9025 __builtin_assoc_barrier ( assignment-expression )
9027 offsetof-member-designator:
9029 offsetof-member-designator . identifier
9030 offsetof-member-designator [ expression ]
9035 [ objc-receiver objc-message-args ]
9036 @selector ( objc-selector-arg )
9037 @protocol ( identifier )
9038 @encode ( type-name )
9040 Classname . identifier
9043 static struct c_expr
9044 c_parser_postfix_expression (c_parser *parser)
9046 struct c_expr expr, e1;
9047 struct c_type_name *t1, *t2;
9048 location_t loc = c_parser_peek_token (parser)->location;
9049 source_range tok_range = c_parser_peek_token (parser)->get_range ();
9050 expr.original_code = ERROR_MARK;
9051 expr.original_type = NULL;
9053 switch (c_parser_peek_token (parser)->type)
9056 expr.value = c_parser_peek_token (parser)->value;
9057 set_c_expr_source_range (&expr, tok_range);
9058 loc = c_parser_peek_token (parser)->location;
9059 expr.m_decimal = c_parser_peek_token (parser)->flags & DECIMAL_INT;
9060 c_parser_consume_token (parser);
9061 if (TREE_CODE (expr.value) == FIXED_CST
9062 && !targetm.fixed_point_supported_p ())
9064 error_at (loc, "fixed-point types not supported for this target");
9073 expr.value = c_parser_peek_token (parser)->value;
9074 /* For the purpose of warning when a pointer is compared with
9075 a zero character constant. */
9076 expr.original_type = char_type_node;
9077 set_c_expr_source_range (&expr, tok_range);
9078 c_parser_consume_token (parser);
9084 case CPP_UTF8STRING:
9085 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9088 case CPP_OBJC_STRING:
9089 gcc_assert (c_dialect_objc ());
9091 = objc_build_string_object (c_parser_peek_token (parser)->value);
9092 set_c_expr_source_range (&expr, tok_range);
9093 c_parser_consume_token (parser);
9096 switch (c_parser_peek_token (parser)->id_kind)
9100 tree id = c_parser_peek_token (parser)->value;
9101 c_parser_consume_token (parser);
9102 expr.value = build_external_ref (loc, id,
9103 (c_parser_peek_token (parser)->type
9105 &expr.original_type);
9106 set_c_expr_source_range (&expr, tok_range);
9109 case C_ID_CLASSNAME:
9111 /* Here we parse the Objective-C 2.0 Class.name dot
9113 tree class_name = c_parser_peek_token (parser)->value;
9115 c_parser_consume_token (parser);
9116 gcc_assert (c_dialect_objc ());
9117 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9122 if (c_parser_next_token_is_not (parser, CPP_NAME))
9124 c_parser_error (parser, "expected identifier");
9128 c_token *component_tok = c_parser_peek_token (parser);
9129 component = component_tok->value;
9130 location_t end_loc = component_tok->get_finish ();
9131 c_parser_consume_token (parser);
9132 expr.value = objc_build_class_component_ref (class_name,
9134 set_c_expr_source_range (&expr, loc, end_loc);
9138 c_parser_error (parser, "expected expression");
9143 case CPP_OPEN_PAREN:
9144 /* A parenthesized expression, statement expression or compound
9146 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9148 /* A statement expression. */
9150 location_t brace_loc;
9151 c_parser_consume_token (parser);
9152 brace_loc = c_parser_peek_token (parser)->location;
9153 c_parser_consume_token (parser);
9154 /* If we've not yet started the current function's statement list,
9155 or we're in the parameter scope of an old-style function
9156 declaration, statement expressions are not allowed. */
9157 if (!building_stmt_list_p () || old_style_parameter_scope ())
9159 error_at (loc, "braced-group within expression allowed "
9160 "only inside a function");
9161 parser->error = true;
9162 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9163 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9167 stmt = c_begin_stmt_expr ();
9168 c_parser_compound_statement_nostart (parser);
9169 location_t close_loc = c_parser_peek_token (parser)->location;
9170 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9172 pedwarn (loc, OPT_Wpedantic,
9173 "ISO C forbids braced-groups within expressions");
9174 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9175 set_c_expr_source_range (&expr, loc, close_loc);
9176 mark_exp_read (expr.value);
9180 /* A parenthesized expression. */
9181 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9182 c_parser_consume_token (parser);
9183 expr = c_parser_expression (parser);
9184 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9185 suppress_warning (expr.value, OPT_Wparentheses);
9186 if (expr.original_code != C_MAYBE_CONST_EXPR
9187 && expr.original_code != SIZEOF_EXPR)
9188 expr.original_code = ERROR_MARK;
9189 /* Remember that we saw ( ) around the sizeof. */
9190 if (expr.original_code == SIZEOF_EXPR)
9191 expr.original_code = PAREN_SIZEOF_EXPR;
9192 /* Don't change EXPR.ORIGINAL_TYPE. */
9193 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9194 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9195 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9196 "expected %<)%>", loc_open_paren);
9200 switch (c_parser_peek_token (parser)->keyword)
9202 case RID_FUNCTION_NAME:
9203 case RID_PRETTY_FUNCTION_NAME:
9204 case RID_C99_FUNCTION_NAME:
9205 expr = c_parser_predefined_identifier (parser);
9209 location_t start_loc = loc;
9210 c_parser_consume_token (parser);
9211 matching_parens parens;
9212 if (!parens.require_open (parser))
9217 e1 = c_parser_expr_no_commas (parser, NULL);
9218 mark_exp_read (e1.value);
9219 e1.value = c_fully_fold (e1.value, false, NULL);
9220 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9222 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9226 loc = c_parser_peek_token (parser)->location;
9227 t1 = c_parser_type_name (parser);
9228 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9229 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9237 tree type_expr = NULL_TREE;
9238 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9239 groktypename (t1, &type_expr, NULL));
9242 expr.value = build2 (C_MAYBE_CONST_EXPR,
9243 TREE_TYPE (expr.value), type_expr,
9245 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9247 set_c_expr_source_range (&expr, start_loc, end_loc);
9253 c_parser_consume_token (parser);
9254 matching_parens parens;
9255 if (!parens.require_open (parser))
9260 t1 = c_parser_type_name (parser);
9262 parser->error = true;
9263 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9264 gcc_assert (parser->error);
9267 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9271 tree type = groktypename (t1, NULL, NULL);
9273 if (type == error_mark_node)
9274 offsetof_ref = error_mark_node;
9277 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9278 SET_EXPR_LOCATION (offsetof_ref, loc);
9280 /* Parse the second argument to __builtin_offsetof. We
9281 must have one identifier, and beyond that we want to
9282 accept sub structure and sub array references. */
9283 if (c_parser_next_token_is (parser, CPP_NAME))
9285 c_token *comp_tok = c_parser_peek_token (parser);
9287 = build_component_ref (loc, offsetof_ref, comp_tok->value,
9288 comp_tok->location, UNKNOWN_LOCATION);
9289 c_parser_consume_token (parser);
9290 while (c_parser_next_token_is (parser, CPP_DOT)
9291 || c_parser_next_token_is (parser,
9293 || c_parser_next_token_is (parser,
9296 if (c_parser_next_token_is (parser, CPP_DEREF))
9298 loc = c_parser_peek_token (parser)->location;
9299 offsetof_ref = build_array_ref (loc,
9304 else if (c_parser_next_token_is (parser, CPP_DOT))
9307 c_parser_consume_token (parser);
9308 if (c_parser_next_token_is_not (parser,
9311 c_parser_error (parser, "expected identifier");
9314 c_token *comp_tok = c_parser_peek_token (parser);
9316 = build_component_ref (loc, offsetof_ref,
9320 c_parser_consume_token (parser);
9326 loc = c_parser_peek_token (parser)->location;
9327 c_parser_consume_token (parser);
9328 ce = c_parser_expression (parser);
9329 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9331 idx = c_fully_fold (idx, false, NULL);
9332 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9334 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9339 c_parser_error (parser, "expected identifier");
9340 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9341 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9343 expr.value = fold_offsetof (offsetof_ref);
9344 set_c_expr_source_range (&expr, loc, end_loc);
9347 case RID_CHOOSE_EXPR:
9349 vec<c_expr_t, va_gc> *cexpr_list;
9350 c_expr_t *e1_p, *e2_p, *e3_p;
9352 location_t close_paren_loc;
9354 c_parser_consume_token (parser);
9355 if (!c_parser_get_builtin_args (parser,
9356 "__builtin_choose_expr",
9364 if (vec_safe_length (cexpr_list) != 3)
9366 error_at (loc, "wrong number of arguments to "
9367 "%<__builtin_choose_expr%>");
9372 e1_p = &(*cexpr_list)[0];
9373 e2_p = &(*cexpr_list)[1];
9374 e3_p = &(*cexpr_list)[2];
9377 mark_exp_read (e2_p->value);
9378 mark_exp_read (e3_p->value);
9379 if (TREE_CODE (c) != INTEGER_CST
9380 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9382 "first argument to %<__builtin_choose_expr%> not"
9384 constant_expression_warning (c);
9385 expr = integer_zerop (c) ? *e3_p : *e2_p;
9386 set_c_expr_source_range (&expr, loc, close_paren_loc);
9389 case RID_TYPES_COMPATIBLE_P:
9391 c_parser_consume_token (parser);
9392 matching_parens parens;
9393 if (!parens.require_open (parser))
9398 t1 = c_parser_type_name (parser);
9404 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9406 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9410 t2 = c_parser_type_name (parser);
9416 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9417 parens.skip_until_found_close (parser);
9419 e1 = groktypename (t1, NULL, NULL);
9420 e2 = groktypename (t2, NULL, NULL);
9421 if (e1 == error_mark_node || e2 == error_mark_node)
9427 e1 = TYPE_MAIN_VARIANT (e1);
9428 e2 = TYPE_MAIN_VARIANT (e2);
9431 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9432 set_c_expr_source_range (&expr, loc, close_paren_loc);
9435 case RID_BUILTIN_TGMATH:
9437 vec<c_expr_t, va_gc> *cexpr_list;
9438 location_t close_paren_loc;
9440 c_parser_consume_token (parser);
9441 if (!c_parser_get_builtin_args (parser,
9450 if (vec_safe_length (cexpr_list) < 3)
9452 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9459 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9460 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9461 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9467 if (vec_safe_length (cexpr_list) < nargs)
9469 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9473 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9474 if (num_functions < 2)
9476 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9481 /* The first NUM_FUNCTIONS expressions are the function
9482 pointers. The remaining NARGS expressions are the
9483 arguments that are to be passed to one of those
9484 functions, chosen following <tgmath.h> rules. */
9485 for (unsigned int j = 1; j < num_functions; j++)
9487 unsigned int this_nargs
9488 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9489 if (this_nargs == 0)
9494 if (this_nargs != nargs)
9496 error_at ((*cexpr_list)[j].get_location (),
9497 "argument %u of %<__builtin_tgmath%> has "
9498 "wrong number of arguments", j + 1);
9504 /* The functions all have the same number of arguments.
9505 Determine whether arguments and return types vary in
9506 ways permitted for <tgmath.h> functions. */
9507 /* The first entry in each of these vectors is for the
9508 return type, subsequent entries for parameter
9510 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9511 auto_vec<tree> parm_first (nargs + 1);
9512 auto_vec<bool> parm_complex (nargs + 1);
9513 auto_vec<bool> parm_varies (nargs + 1);
9514 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9515 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9516 parm_first.quick_push (first_ret);
9517 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9518 parm_varies.quick_push (false);
9519 function_args_iterator iter;
9521 unsigned int argpos;
9522 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9524 if (t == void_type_node)
9526 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9527 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9528 parm_varies.quick_push (false);
9530 for (unsigned int j = 1; j < num_functions; j++)
9532 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9533 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9534 if (ret != parm_first[0])
9536 parm_varies[0] = true;
9537 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9538 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9540 error_at ((*cexpr_list)[0].get_location (),
9541 "invalid type-generic return type for "
9542 "argument %u of %<__builtin_tgmath%>",
9547 if (!SCALAR_FLOAT_TYPE_P (ret)
9548 && !COMPLEX_FLOAT_TYPE_P (ret))
9550 error_at ((*cexpr_list)[j].get_location (),
9551 "invalid type-generic return type for "
9552 "argument %u of %<__builtin_tgmath%>",
9558 if (TREE_CODE (ret) == COMPLEX_TYPE)
9559 parm_complex[0] = true;
9561 FOREACH_FUNCTION_ARGS (type, t, iter)
9563 if (t == void_type_node)
9565 t = TYPE_MAIN_VARIANT (t);
9566 if (t != parm_first[argpos])
9568 parm_varies[argpos] = true;
9569 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9570 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9572 error_at ((*cexpr_list)[0].get_location (),
9573 "invalid type-generic type for "
9574 "argument %u of argument %u of "
9575 "%<__builtin_tgmath%>", argpos, 1);
9579 if (!SCALAR_FLOAT_TYPE_P (t)
9580 && !COMPLEX_FLOAT_TYPE_P (t))
9582 error_at ((*cexpr_list)[j].get_location (),
9583 "invalid type-generic type for "
9584 "argument %u of argument %u of "
9585 "%<__builtin_tgmath%>", argpos, j + 1);
9590 if (TREE_CODE (t) == COMPLEX_TYPE)
9591 parm_complex[argpos] = true;
9595 enum tgmath_parm_kind max_variation = tgmath_fixed;
9596 for (unsigned int j = 0; j <= nargs; j++)
9598 enum tgmath_parm_kind this_kind;
9601 if (parm_complex[j])
9602 max_variation = this_kind = tgmath_complex;
9605 this_kind = tgmath_real;
9606 if (max_variation != tgmath_complex)
9607 max_variation = tgmath_real;
9611 this_kind = tgmath_fixed;
9612 parm_kind.quick_push (this_kind);
9614 if (max_variation == tgmath_fixed)
9616 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9617 "all have the same type");
9622 /* Identify a parameter (not the return type) that varies,
9623 including with complex types if any variation includes
9624 complex types; there must be at least one such
9626 unsigned int tgarg = 0;
9627 for (unsigned int j = 1; j <= nargs; j++)
9628 if (parm_kind[j] == max_variation)
9635 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9636 "lack type-generic parameter");
9641 /* Determine the type of the relevant parameter for each
9643 auto_vec<tree> tg_type (num_functions);
9644 for (unsigned int j = 0; j < num_functions; j++)
9646 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9648 FOREACH_FUNCTION_ARGS (type, t, iter)
9650 if (argpos == tgarg)
9652 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9659 /* Verify that the corresponding types are different for
9660 all the listed functions. Also determine whether all
9661 the types are complex, whether all the types are
9662 standard or binary, and whether all the types are
9664 bool all_complex = true;
9665 bool all_binary = true;
9666 bool all_decimal = true;
9667 hash_set<tree> tg_types;
9668 FOR_EACH_VEC_ELT (tg_type, i, t)
9670 if (TREE_CODE (t) == COMPLEX_TYPE)
9671 all_decimal = false;
9674 all_complex = false;
9675 if (DECIMAL_FLOAT_TYPE_P (t))
9678 all_decimal = false;
9680 if (tg_types.add (t))
9682 error_at ((*cexpr_list)[i].get_location (),
9683 "duplicate type-generic parameter type for "
9684 "function argument %u of %<__builtin_tgmath%>",
9691 /* Verify that other parameters and the return type whose
9692 types vary have their types varying in the correct
9694 for (unsigned int j = 0; j < num_functions; j++)
9696 tree exp_type = tg_type[j];
9697 tree exp_real_type = exp_type;
9698 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9699 exp_real_type = TREE_TYPE (exp_type);
9700 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9701 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9702 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9703 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9705 error_at ((*cexpr_list)[j].get_location (),
9706 "bad return type for function argument %u "
9707 "of %<__builtin_tgmath%>", j + 1);
9712 FOREACH_FUNCTION_ARGS (type, t, iter)
9714 if (t == void_type_node)
9716 t = TYPE_MAIN_VARIANT (t);
9717 if ((parm_kind[argpos] == tgmath_complex
9719 || (parm_kind[argpos] == tgmath_real
9720 && t != exp_real_type))
9722 error_at ((*cexpr_list)[j].get_location (),
9723 "bad type for argument %u of "
9724 "function argument %u of "
9725 "%<__builtin_tgmath%>", argpos, j + 1);
9733 /* The functions listed are a valid set of functions for a
9734 <tgmath.h> macro to select between. Identify the
9735 matching function, if any. First, the argument types
9736 must be combined following <tgmath.h> rules. Integer
9737 types are treated as _Decimal64 if any type-generic
9738 argument is decimal, or if the only alternatives for
9739 type-generic arguments are of decimal types, and are
9740 otherwise treated as double (or _Complex double for
9741 complex integer types, or _Float64 or _Complex _Float64
9742 if all the return types are the same _FloatN or
9743 _FloatNx type). After that adjustment, types are
9744 combined following the usual arithmetic conversions.
9745 If the function only accepts complex arguments, a
9746 complex type is produced. */
9747 bool arg_complex = all_complex;
9748 bool arg_binary = all_binary;
9749 bool arg_int_decimal = all_decimal;
9750 for (unsigned int j = 1; j <= nargs; j++)
9752 if (parm_kind[j] == tgmath_fixed)
9754 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9755 tree type = TREE_TYPE (ce->value);
9756 if (!INTEGRAL_TYPE_P (type)
9757 && !SCALAR_FLOAT_TYPE_P (type)
9758 && TREE_CODE (type) != COMPLEX_TYPE)
9760 error_at (ce->get_location (),
9761 "invalid type of argument %u of type-generic "
9766 if (DECIMAL_FLOAT_TYPE_P (type))
9768 arg_int_decimal = true;
9771 error_at (ce->get_location (),
9772 "decimal floating-point argument %u to "
9773 "complex-only type-generic function", j);
9777 else if (all_binary)
9779 error_at (ce->get_location (),
9780 "decimal floating-point argument %u to "
9781 "binary-only type-generic function", j);
9785 else if (arg_complex)
9787 error_at (ce->get_location (),
9788 "both complex and decimal floating-point "
9789 "arguments to type-generic function");
9793 else if (arg_binary)
9795 error_at (ce->get_location (),
9796 "both binary and decimal floating-point "
9797 "arguments to type-generic function");
9802 else if (TREE_CODE (type) == COMPLEX_TYPE)
9805 if (COMPLEX_FLOAT_TYPE_P (type))
9809 error_at (ce->get_location (),
9810 "complex argument %u to "
9811 "decimal-only type-generic function", j);
9815 else if (arg_int_decimal)
9817 error_at (ce->get_location (),
9818 "both complex and decimal floating-point "
9819 "arguments to type-generic function");
9824 else if (SCALAR_FLOAT_TYPE_P (type))
9829 error_at (ce->get_location (),
9830 "binary argument %u to "
9831 "decimal-only type-generic function", j);
9835 else if (arg_int_decimal)
9837 error_at (ce->get_location (),
9838 "both binary and decimal floating-point "
9839 "arguments to type-generic function");
9845 /* For a macro rounding its result to a narrower type, map
9846 integer types to _Float64 not double if the return type
9847 is a _FloatN or _FloatNx type. */
9848 bool arg_int_float64 = false;
9849 if (parm_kind[0] == tgmath_fixed
9850 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9851 && float64_type_node != NULL_TREE)
9852 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9853 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9855 arg_int_float64 = true;
9858 tree arg_real = NULL_TREE;
9859 for (unsigned int j = 1; j <= nargs; j++)
9861 if (parm_kind[j] == tgmath_fixed)
9863 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9864 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9865 if (TREE_CODE (type) == COMPLEX_TYPE)
9866 type = TREE_TYPE (type);
9867 if (INTEGRAL_TYPE_P (type))
9868 type = (arg_int_decimal
9869 ? dfloat64_type_node
9872 : double_type_node);
9873 if (arg_real == NULL_TREE)
9876 arg_real = common_type (arg_real, type);
9877 if (arg_real == error_mark_node)
9883 tree arg_type = (arg_complex
9884 ? build_complex_type (arg_real)
9887 /* Look for a function to call with type-generic parameter
9889 c_expr_t *fn = NULL;
9890 for (unsigned int j = 0; j < num_functions; j++)
9892 if (tg_type[j] == arg_type)
9894 fn = &(*cexpr_list)[j];
9899 && parm_kind[0] == tgmath_fixed
9900 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9902 /* Presume this is a macro that rounds its result to a
9903 narrower type, and look for the first function with
9904 at least the range and precision of the argument
9906 for (unsigned int j = 0; j < num_functions; j++)
9909 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9911 tree real_tg_type = (arg_complex
9912 ? TREE_TYPE (tg_type[j])
9914 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9915 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9917 scalar_float_mode arg_mode
9918 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9919 scalar_float_mode tg_mode
9920 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9921 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9922 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9923 if (arg_fmt->b == tg_fmt->b
9924 && arg_fmt->p <= tg_fmt->p
9925 && arg_fmt->emax <= tg_fmt->emax
9926 && (arg_fmt->emin - arg_fmt->p
9927 >= tg_fmt->emin - tg_fmt->p))
9929 fn = &(*cexpr_list)[j];
9936 error_at (loc, "no matching function for type-generic call");
9941 /* Construct a call to FN. */
9942 vec<tree, va_gc> *args;
9943 vec_alloc (args, nargs);
9944 vec<tree, va_gc> *origtypes;
9945 vec_alloc (origtypes, nargs);
9946 auto_vec<location_t> arg_loc (nargs);
9947 for (unsigned int j = 0; j < nargs; j++)
9949 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9950 args->quick_push (ce->value);
9951 arg_loc.quick_push (ce->get_location ());
9952 origtypes->quick_push (ce->original_type);
9954 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9956 set_c_expr_source_range (&expr, loc, close_paren_loc);
9959 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9961 vec<c_expr_t, va_gc> *cexpr_list;
9964 location_t close_paren_loc;
9966 c_parser_consume_token (parser);
9967 if (!c_parser_get_builtin_args (parser,
9968 "__builtin_call_with_static_chain",
9975 if (vec_safe_length (cexpr_list) != 2)
9977 error_at (loc, "wrong number of arguments to "
9978 "%<__builtin_call_with_static_chain%>");
9983 expr = (*cexpr_list)[0];
9984 e2_p = &(*cexpr_list)[1];
9985 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9986 chain_value = e2_p->value;
9987 mark_exp_read (chain_value);
9989 if (TREE_CODE (expr.value) != CALL_EXPR)
9990 error_at (loc, "first argument to "
9991 "%<__builtin_call_with_static_chain%> "
9992 "must be a call expression");
9993 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9994 error_at (loc, "second argument to "
9995 "%<__builtin_call_with_static_chain%> "
9996 "must be a pointer type");
9998 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9999 set_c_expr_source_range (&expr, loc, close_paren_loc);
10002 case RID_BUILTIN_COMPLEX:
10004 vec<c_expr_t, va_gc> *cexpr_list;
10005 c_expr_t *e1_p, *e2_p;
10006 location_t close_paren_loc;
10008 c_parser_consume_token (parser);
10009 if (!c_parser_get_builtin_args (parser,
10010 "__builtin_complex",
10011 &cexpr_list, false,
10018 if (vec_safe_length (cexpr_list) != 2)
10020 error_at (loc, "wrong number of arguments to "
10021 "%<__builtin_complex%>");
10026 e1_p = &(*cexpr_list)[0];
10027 e2_p = &(*cexpr_list)[1];
10029 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
10030 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
10031 e1_p->value = convert (TREE_TYPE (e1_p->value),
10032 TREE_OPERAND (e1_p->value, 0));
10033 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
10034 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
10035 e2_p->value = convert (TREE_TYPE (e2_p->value),
10036 TREE_OPERAND (e2_p->value, 0));
10037 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10038 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10039 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
10040 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
10042 error_at (loc, "%<__builtin_complex%> operand "
10043 "not of real binary floating-point type");
10047 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10048 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10051 "%<__builtin_complex%> operands of different types");
10055 pedwarn_c90 (loc, OPT_Wpedantic,
10056 "ISO C90 does not support complex types");
10057 expr.value = build2_loc (loc, COMPLEX_EXPR,
10060 (TREE_TYPE (e1_p->value))),
10061 e1_p->value, e2_p->value);
10062 set_c_expr_source_range (&expr, loc, close_paren_loc);
10065 case RID_BUILTIN_SHUFFLE:
10067 vec<c_expr_t, va_gc> *cexpr_list;
10070 location_t close_paren_loc;
10072 c_parser_consume_token (parser);
10073 if (!c_parser_get_builtin_args (parser,
10074 "__builtin_shuffle",
10075 &cexpr_list, false,
10082 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10083 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10085 if (vec_safe_length (cexpr_list) == 2)
10086 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10088 (*cexpr_list)[1].value);
10090 else if (vec_safe_length (cexpr_list) == 3)
10091 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10092 (*cexpr_list)[1].value,
10093 (*cexpr_list)[2].value);
10096 error_at (loc, "wrong number of arguments to "
10097 "%<__builtin_shuffle%>");
10100 set_c_expr_source_range (&expr, loc, close_paren_loc);
10103 case RID_BUILTIN_SHUFFLEVECTOR:
10105 vec<c_expr_t, va_gc> *cexpr_list;
10108 location_t close_paren_loc;
10110 c_parser_consume_token (parser);
10111 if (!c_parser_get_builtin_args (parser,
10112 "__builtin_shufflevector",
10113 &cexpr_list, false,
10120 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10121 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10123 if (vec_safe_length (cexpr_list) < 3)
10125 error_at (loc, "wrong number of arguments to "
10126 "%<__builtin_shuffle%>");
10131 auto_vec<tree, 16> mask;
10132 for (i = 2; i < cexpr_list->length (); ++i)
10133 mask.safe_push ((*cexpr_list)[i].value);
10134 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10135 (*cexpr_list)[1].value,
10138 set_c_expr_source_range (&expr, loc, close_paren_loc);
10141 case RID_BUILTIN_CONVERTVECTOR:
10143 location_t start_loc = loc;
10144 c_parser_consume_token (parser);
10145 matching_parens parens;
10146 if (!parens.require_open (parser))
10151 e1 = c_parser_expr_no_commas (parser, NULL);
10152 mark_exp_read (e1.value);
10153 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10155 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10159 loc = c_parser_peek_token (parser)->location;
10160 t1 = c_parser_type_name (parser);
10161 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10162 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10168 tree type_expr = NULL_TREE;
10169 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10170 groktypename (t1, &type_expr,
10172 set_c_expr_source_range (&expr, start_loc, end_loc);
10176 case RID_BUILTIN_ASSOC_BARRIER:
10178 location_t start_loc = loc;
10179 c_parser_consume_token (parser);
10180 matching_parens parens;
10181 if (!parens.require_open (parser))
10186 e1 = c_parser_expr_no_commas (parser, NULL);
10187 mark_exp_read (e1.value);
10188 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10189 parens.skip_until_found_close (parser);
10190 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10191 set_c_expr_source_range (&expr, start_loc, end_loc);
10194 case RID_AT_SELECTOR:
10196 gcc_assert (c_dialect_objc ());
10197 c_parser_consume_token (parser);
10198 matching_parens parens;
10199 if (!parens.require_open (parser))
10204 tree sel = c_parser_objc_selector_arg (parser);
10205 location_t close_loc = c_parser_peek_token (parser)->location;
10206 parens.skip_until_found_close (parser);
10207 expr.value = objc_build_selector_expr (loc, sel);
10208 set_c_expr_source_range (&expr, loc, close_loc);
10211 case RID_AT_PROTOCOL:
10213 gcc_assert (c_dialect_objc ());
10214 c_parser_consume_token (parser);
10215 matching_parens parens;
10216 if (!parens.require_open (parser))
10221 if (c_parser_next_token_is_not (parser, CPP_NAME))
10223 c_parser_error (parser, "expected identifier");
10224 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10228 tree id = c_parser_peek_token (parser)->value;
10229 c_parser_consume_token (parser);
10230 location_t close_loc = c_parser_peek_token (parser)->location;
10231 parens.skip_until_found_close (parser);
10232 expr.value = objc_build_protocol_expr (id);
10233 set_c_expr_source_range (&expr, loc, close_loc);
10236 case RID_AT_ENCODE:
10238 /* Extension to support C-structures in the archiver. */
10239 gcc_assert (c_dialect_objc ());
10240 c_parser_consume_token (parser);
10241 matching_parens parens;
10242 if (!parens.require_open (parser))
10247 t1 = c_parser_type_name (parser);
10251 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10254 location_t close_loc = c_parser_peek_token (parser)->location;
10255 parens.skip_until_found_close (parser);
10256 tree type = groktypename (t1, NULL, NULL);
10257 expr.value = objc_build_encode_expr (type);
10258 set_c_expr_source_range (&expr, loc, close_loc);
10262 expr = c_parser_generic_selection (parser);
10264 case RID_OMP_ALL_MEMORY:
10265 gcc_assert (flag_openmp);
10266 c_parser_consume_token (parser);
10267 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
10268 "%<depend%> clause");
10271 /* C23 'nullptr' literal. */
10273 c_parser_consume_token (parser);
10274 expr.value = nullptr_node;
10275 set_c_expr_source_range (&expr, tok_range);
10276 pedwarn_c11 (loc, OPT_Wpedantic,
10277 "ISO C does not support %qs before C2X", "nullptr");
10280 c_parser_consume_token (parser);
10281 expr.value = boolean_true_node;
10282 set_c_expr_source_range (&expr, tok_range);
10285 c_parser_consume_token (parser);
10286 expr.value = boolean_false_node;
10287 set_c_expr_source_range (&expr, tok_range);
10290 c_parser_error (parser, "expected expression");
10295 case CPP_OPEN_SQUARE:
10296 if (c_dialect_objc ())
10298 tree receiver, args;
10299 c_parser_consume_token (parser);
10300 receiver = c_parser_objc_receiver (parser);
10301 args = c_parser_objc_message_args (parser);
10302 location_t close_loc = c_parser_peek_token (parser)->location;
10303 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10305 expr.value = objc_build_message_expr (receiver, args);
10306 set_c_expr_source_range (&expr, loc, close_loc);
10309 /* Else fall through to report error. */
10312 c_parser_error (parser, "expected expression");
10317 return c_parser_postfix_expression_after_primary
10318 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10321 /* Parse a postfix expression after a parenthesized type name: the
10322 brace-enclosed initializer of a compound literal, possibly followed
10323 by some postfix operators. This is separate because it is not
10324 possible to tell until after the type name whether a cast
10325 expression has a cast or a compound literal, or whether the operand
10326 of sizeof is a parenthesized type name or starts with a compound
10327 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10328 location of the first token after the parentheses around the type
10331 static struct c_expr
10332 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10333 struct c_type_name *type_name,
10334 location_t type_loc)
10337 struct c_expr init;
10339 struct c_expr expr;
10340 location_t start_loc;
10341 tree type_expr = NULL_TREE;
10342 bool type_expr_const = true;
10343 check_compound_literal_type (type_loc, type_name);
10344 rich_location richloc (line_table, type_loc);
10345 start_init (NULL_TREE, NULL, 0, &richloc);
10346 type = groktypename (type_name, &type_expr, &type_expr_const);
10347 start_loc = c_parser_peek_token (parser)->location;
10348 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10350 error_at (type_loc, "compound literal has variable size");
10351 type = error_mark_node;
10353 init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
10355 maybe_warn_string_init (type_loc, type, init);
10357 if (type != error_mark_node
10358 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10359 && current_function_decl)
10361 error ("compound literal qualified by address-space qualifier");
10362 type = error_mark_node;
10365 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10366 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10367 ? CONSTRUCTOR_NON_CONST (init.value)
10368 : init.original_code == C_MAYBE_CONST_EXPR);
10369 non_const |= !type_expr_const;
10370 unsigned int alignas_align = 0;
10371 if (type != error_mark_node
10372 && type_name->specs->align_log != -1)
10374 alignas_align = 1U << type_name->specs->align_log;
10375 if (alignas_align < min_align_of_type (type))
10377 error_at (type_name->specs->locations[cdw_alignas],
10378 "%<_Alignas%> specifiers cannot reduce "
10379 "alignment of compound literal");
10383 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10385 set_c_expr_source_range (&expr, init.src_range);
10386 expr.original_code = ERROR_MARK;
10387 expr.original_type = NULL;
10388 if (type != error_mark_node
10389 && expr.value != error_mark_node
10392 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10394 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10395 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10399 gcc_assert (!non_const);
10400 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10401 type_expr, expr.value);
10404 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10407 /* Callback function for sizeof_pointer_memaccess_warning to compare
10411 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10413 return comptypes (type1, type2) == 1;
10416 /* Warn for patterns where abs-like function appears to be used incorrectly,
10417 gracefully ignore any non-abs-like function. The warning location should
10418 be LOC. FNDECL is the declaration of called function, it must be a
10419 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10423 warn_for_abs (location_t loc, tree fndecl, tree arg)
10425 /* Avoid warning in unreachable subexpressions. */
10426 if (c_inhibit_evaluation_warnings)
10429 tree atype = TREE_TYPE (arg);
10431 /* Casts from pointers (and thus arrays and fndecls) will generate
10432 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10433 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10434 types and possibly other exotic types. */
10435 if (!INTEGRAL_TYPE_P (atype)
10436 && !SCALAR_FLOAT_TYPE_P (atype)
10437 && TREE_CODE (atype) != COMPLEX_TYPE)
10440 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10445 case BUILT_IN_LABS:
10446 case BUILT_IN_LLABS:
10447 case BUILT_IN_IMAXABS:
10448 if (!INTEGRAL_TYPE_P (atype))
10450 if (SCALAR_FLOAT_TYPE_P (atype))
10451 warning_at (loc, OPT_Wabsolute_value,
10452 "using integer absolute value function %qD when "
10453 "argument is of floating-point type %qT",
10455 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10456 warning_at (loc, OPT_Wabsolute_value,
10457 "using integer absolute value function %qD when "
10458 "argument is of complex type %qT", fndecl, atype);
10460 gcc_unreachable ();
10463 if (TYPE_UNSIGNED (atype))
10464 warning_at (loc, OPT_Wabsolute_value,
10465 "taking the absolute value of unsigned type %qT "
10466 "has no effect", atype);
10469 CASE_FLT_FN (BUILT_IN_FABS):
10470 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10471 if (!SCALAR_FLOAT_TYPE_P (atype)
10472 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10474 if (INTEGRAL_TYPE_P (atype))
10475 warning_at (loc, OPT_Wabsolute_value,
10476 "using floating-point absolute value function %qD "
10477 "when argument is of integer type %qT", fndecl, atype);
10478 else if (DECIMAL_FLOAT_TYPE_P (atype))
10479 warning_at (loc, OPT_Wabsolute_value,
10480 "using floating-point absolute value function %qD "
10481 "when argument is of decimal floating-point type %qT",
10483 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10484 warning_at (loc, OPT_Wabsolute_value,
10485 "using floating-point absolute value function %qD when "
10486 "argument is of complex type %qT", fndecl, atype);
10488 gcc_unreachable ();
10493 CASE_FLT_FN (BUILT_IN_CABS):
10494 if (TREE_CODE (atype) != COMPLEX_TYPE)
10496 if (INTEGRAL_TYPE_P (atype))
10497 warning_at (loc, OPT_Wabsolute_value,
10498 "using complex absolute value function %qD when "
10499 "argument is of integer type %qT", fndecl, atype);
10500 else if (SCALAR_FLOAT_TYPE_P (atype))
10501 warning_at (loc, OPT_Wabsolute_value,
10502 "using complex absolute value function %qD when "
10503 "argument is of floating-point type %qT",
10506 gcc_unreachable ();
10512 case BUILT_IN_FABSD32:
10513 case BUILT_IN_FABSD64:
10514 case BUILT_IN_FABSD128:
10515 if (!DECIMAL_FLOAT_TYPE_P (atype))
10517 if (INTEGRAL_TYPE_P (atype))
10518 warning_at (loc, OPT_Wabsolute_value,
10519 "using decimal floating-point absolute value "
10520 "function %qD when argument is of integer type %qT",
10522 else if (SCALAR_FLOAT_TYPE_P (atype))
10523 warning_at (loc, OPT_Wabsolute_value,
10524 "using decimal floating-point absolute value "
10525 "function %qD when argument is of floating-point "
10526 "type %qT", fndecl, atype);
10527 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10528 warning_at (loc, OPT_Wabsolute_value,
10529 "using decimal floating-point absolute value "
10530 "function %qD when argument is of complex type %qT",
10533 gcc_unreachable ();
10542 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10545 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10546 if (TREE_CODE (atype) == COMPLEX_TYPE)
10548 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10549 atype = TREE_TYPE (atype);
10550 ftype = TREE_TYPE (ftype);
10553 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10554 warning_at (loc, OPT_Wabsolute_value,
10555 "absolute value function %qD given an argument of type %qT "
10556 "but has parameter of type %qT which may cause truncation "
10557 "of value", fndecl, atype, ftype);
10561 /* Parse a postfix expression after the initial primary or compound
10562 literal; that is, parse a series of postfix operators.
10564 EXPR_LOC is the location of the primary expression. */
10566 static struct c_expr
10567 c_parser_postfix_expression_after_primary (c_parser *parser,
10568 location_t expr_loc,
10569 struct c_expr expr)
10571 struct c_expr orig_expr;
10573 location_t sizeof_arg_loc[3], comp_loc;
10574 tree sizeof_arg[3];
10575 unsigned int literal_zero_mask;
10577 vec<tree, va_gc> *exprlist;
10578 vec<tree, va_gc> *origtypes = NULL;
10579 vec<location_t> arg_loc = vNULL;
10585 location_t op_loc = c_parser_peek_token (parser)->location;
10586 switch (c_parser_peek_token (parser)->type)
10588 case CPP_OPEN_SQUARE:
10589 /* Array reference. */
10590 c_parser_consume_token (parser);
10591 idx = c_parser_expression (parser).value;
10592 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10594 start = expr.get_start ();
10595 finish = parser->tokens_buf[0].location;
10596 expr.value = build_array_ref (op_loc, expr.value, idx);
10597 set_c_expr_source_range (&expr, start, finish);
10598 expr.original_code = ERROR_MARK;
10599 expr.original_type = NULL;
10601 case CPP_OPEN_PAREN:
10602 /* Function call. */
10604 matching_parens parens;
10605 parens.consume_open (parser);
10606 for (i = 0; i < 3; i++)
10608 sizeof_arg[i] = NULL_TREE;
10609 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10611 literal_zero_mask = 0;
10612 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10615 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10616 sizeof_arg_loc, sizeof_arg,
10617 &arg_loc, &literal_zero_mask);
10618 parens.skip_until_found_close (parser);
10621 mark_exp_read (expr.value);
10622 if (warn_sizeof_pointer_memaccess)
10623 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10624 expr.value, exprlist,
10626 sizeof_ptr_memacc_comptypes);
10627 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10629 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10630 && vec_safe_length (exprlist) == 3)
10632 tree arg0 = (*exprlist)[0];
10633 tree arg2 = (*exprlist)[2];
10634 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10636 if (warn_absolute_value
10637 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10638 && vec_safe_length (exprlist) == 1)
10639 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10642 start = expr.get_start ();
10643 finish = parser->tokens_buf[0].get_finish ();
10645 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10646 exprlist, origtypes);
10647 set_c_expr_source_range (&expr, start, finish);
10649 expr.original_code = ERROR_MARK;
10650 if (TREE_CODE (expr.value) == INTEGER_CST
10651 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10652 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10653 expr.original_code = C_MAYBE_CONST_EXPR;
10654 expr.original_type = NULL;
10657 release_tree_vector (exprlist);
10658 release_tree_vector (origtypes);
10660 arg_loc.release ();
10663 /* Structure element reference. */
10664 c_parser_consume_token (parser);
10665 expr = default_function_array_conversion (expr_loc, expr);
10666 if (c_parser_next_token_is (parser, CPP_NAME))
10668 c_token *comp_tok = c_parser_peek_token (parser);
10669 ident = comp_tok->value;
10670 comp_loc = comp_tok->location;
10674 c_parser_error (parser, "expected identifier");
10676 expr.original_code = ERROR_MARK;
10677 expr.original_type = NULL;
10680 start = expr.get_start ();
10681 finish = c_parser_peek_token (parser)->get_finish ();
10682 c_parser_consume_token (parser);
10683 expr.value = build_component_ref (op_loc, expr.value, ident,
10684 comp_loc, UNKNOWN_LOCATION);
10685 set_c_expr_source_range (&expr, start, finish);
10686 expr.original_code = ERROR_MARK;
10687 if (TREE_CODE (expr.value) != COMPONENT_REF)
10688 expr.original_type = NULL;
10691 /* Remember the original type of a bitfield. */
10692 tree field = TREE_OPERAND (expr.value, 1);
10693 if (TREE_CODE (field) != FIELD_DECL)
10694 expr.original_type = NULL;
10696 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10700 /* Structure element reference. */
10701 c_parser_consume_token (parser);
10702 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10703 if (c_parser_next_token_is (parser, CPP_NAME))
10705 c_token *comp_tok = c_parser_peek_token (parser);
10706 ident = comp_tok->value;
10707 comp_loc = comp_tok->location;
10711 c_parser_error (parser, "expected identifier");
10713 expr.original_code = ERROR_MARK;
10714 expr.original_type = NULL;
10717 start = expr.get_start ();
10718 finish = c_parser_peek_token (parser)->get_finish ();
10719 c_parser_consume_token (parser);
10720 expr.value = build_component_ref (op_loc,
10721 build_indirect_ref (op_loc,
10725 expr.get_location ());
10726 set_c_expr_source_range (&expr, start, finish);
10727 expr.original_code = ERROR_MARK;
10728 if (TREE_CODE (expr.value) != COMPONENT_REF)
10729 expr.original_type = NULL;
10732 /* Remember the original type of a bitfield. */
10733 tree field = TREE_OPERAND (expr.value, 1);
10734 if (TREE_CODE (field) != FIELD_DECL)
10735 expr.original_type = NULL;
10737 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10740 case CPP_PLUS_PLUS:
10741 /* Postincrement. */
10742 start = expr.get_start ();
10743 finish = c_parser_peek_token (parser)->get_finish ();
10744 c_parser_consume_token (parser);
10745 expr = default_function_array_read_conversion (expr_loc, expr);
10746 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10747 expr.value, false);
10748 set_c_expr_source_range (&expr, start, finish);
10749 expr.original_code = ERROR_MARK;
10750 expr.original_type = NULL;
10752 case CPP_MINUS_MINUS:
10753 /* Postdecrement. */
10754 start = expr.get_start ();
10755 finish = c_parser_peek_token (parser)->get_finish ();
10756 c_parser_consume_token (parser);
10757 expr = default_function_array_read_conversion (expr_loc, expr);
10758 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10759 expr.value, false);
10760 set_c_expr_source_range (&expr, start, finish);
10761 expr.original_code = ERROR_MARK;
10762 expr.original_type = NULL;
10770 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10773 assignment-expression
10774 expression , assignment-expression
10777 static struct c_expr
10778 c_parser_expression (c_parser *parser)
10780 location_t tloc = c_parser_peek_token (parser)->location;
10781 struct c_expr expr;
10782 expr = c_parser_expr_no_commas (parser, NULL);
10783 if (c_parser_next_token_is (parser, CPP_COMMA))
10784 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10785 while (c_parser_next_token_is (parser, CPP_COMMA))
10787 struct c_expr next;
10789 location_t loc = c_parser_peek_token (parser)->location;
10790 location_t expr_loc;
10791 c_parser_consume_token (parser);
10792 expr_loc = c_parser_peek_token (parser)->location;
10793 lhsval = expr.value;
10794 while (TREE_CODE (lhsval) == COMPOUND_EXPR
10795 || TREE_CODE (lhsval) == NOP_EXPR)
10797 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10798 lhsval = TREE_OPERAND (lhsval, 1);
10800 lhsval = TREE_OPERAND (lhsval, 0);
10802 if (DECL_P (lhsval) || handled_component_p (lhsval))
10803 mark_exp_read (lhsval);
10804 next = c_parser_expr_no_commas (parser, NULL);
10805 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10806 expr.value = build_compound_expr (loc, expr.value, next.value);
10807 expr.original_code = COMPOUND_EXPR;
10808 expr.original_type = next.original_type;
10813 /* Parse an expression and convert functions or arrays to pointers and
10814 lvalues to rvalues. */
10816 static struct c_expr
10817 c_parser_expression_conv (c_parser *parser)
10819 struct c_expr expr;
10820 location_t loc = c_parser_peek_token (parser)->location;
10821 expr = c_parser_expression (parser);
10822 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10826 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10827 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10830 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10833 if (idx >= HOST_BITS_PER_INT)
10836 c_token *tok = c_parser_peek_token (parser);
10845 /* If a parameter is literal zero alone, remember it
10846 for -Wmemset-transposed-args warning. */
10847 if (integer_zerop (tok->value)
10848 && !TREE_OVERFLOW (tok->value)
10849 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10850 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10851 *literal_zero_mask |= 1U << idx;
10857 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10858 functions and arrays to pointers and lvalues to rvalues. If
10859 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10860 locations of function arguments into this vector.
10862 nonempty-expr-list:
10863 assignment-expression
10864 nonempty-expr-list , assignment-expression
10867 static vec<tree, va_gc> *
10868 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10869 vec<tree, va_gc> **p_orig_types,
10870 location_t *sizeof_arg_loc, tree *sizeof_arg,
10871 vec<location_t> *locations,
10872 unsigned int *literal_zero_mask)
10874 vec<tree, va_gc> *ret;
10875 vec<tree, va_gc> *orig_types;
10876 struct c_expr expr;
10877 unsigned int idx = 0;
10879 ret = make_tree_vector ();
10880 if (p_orig_types == NULL)
10883 orig_types = make_tree_vector ();
10885 if (literal_zero_mask)
10886 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10887 expr = c_parser_expr_no_commas (parser, NULL);
10889 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10891 expr.value = c_fully_fold (expr.value, false, NULL);
10892 ret->quick_push (expr.value);
10894 orig_types->quick_push (expr.original_type);
10896 locations->safe_push (expr.get_location ());
10897 if (sizeof_arg != NULL
10898 && (expr.original_code == SIZEOF_EXPR
10899 || expr.original_code == PAREN_SIZEOF_EXPR))
10901 sizeof_arg[0] = c_last_sizeof_arg;
10902 sizeof_arg_loc[0] = c_last_sizeof_loc;
10904 while (c_parser_next_token_is (parser, CPP_COMMA))
10906 c_parser_consume_token (parser);
10907 if (literal_zero_mask)
10908 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10909 expr = c_parser_expr_no_commas (parser, NULL);
10911 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10914 expr.value = c_fully_fold (expr.value, false, NULL);
10915 vec_safe_push (ret, expr.value);
10917 vec_safe_push (orig_types, expr.original_type);
10919 locations->safe_push (expr.get_location ());
10921 && sizeof_arg != NULL
10922 && (expr.original_code == SIZEOF_EXPR
10923 || expr.original_code == PAREN_SIZEOF_EXPR))
10925 sizeof_arg[idx] = c_last_sizeof_arg;
10926 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10930 *p_orig_types = orig_types;
10934 /* Parse Objective-C-specific constructs. */
10936 /* Parse an objc-class-definition.
10938 objc-class-definition:
10939 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10940 objc-class-instance-variables[opt] objc-methodprotolist @end
10941 @implementation identifier objc-superclass[opt]
10942 objc-class-instance-variables[opt]
10943 @interface identifier ( identifier ) objc-protocol-refs[opt]
10944 objc-methodprotolist @end
10945 @interface identifier ( ) objc-protocol-refs[opt]
10946 objc-methodprotolist @end
10947 @implementation identifier ( identifier )
10952 "@interface identifier (" must start "@interface identifier (
10953 identifier ) ...": objc-methodprotolist in the first production may
10954 not start with a parenthesized identifier as a declarator of a data
10955 definition with no declaration specifiers if the objc-superclass,
10956 objc-protocol-refs and objc-class-instance-variables are omitted. */
10959 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10964 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10966 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10969 gcc_unreachable ();
10971 c_parser_consume_token (parser);
10972 if (c_parser_next_token_is_not (parser, CPP_NAME))
10974 c_parser_error (parser, "expected identifier");
10977 id1 = c_parser_peek_token (parser)->value;
10978 location_t loc1 = c_parser_peek_token (parser)->location;
10979 c_parser_consume_token (parser);
10980 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10982 /* We have a category or class extension. */
10984 tree proto = NULL_TREE;
10985 matching_parens parens;
10986 parens.consume_open (parser);
10987 if (c_parser_next_token_is_not (parser, CPP_NAME))
10989 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10991 /* We have a class extension. */
10996 c_parser_error (parser, "expected identifier or %<)%>");
10997 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
11003 id2 = c_parser_peek_token (parser)->value;
11004 c_parser_consume_token (parser);
11006 parens.skip_until_found_close (parser);
11009 objc_start_category_implementation (id1, id2);
11012 if (c_parser_next_token_is (parser, CPP_LESS))
11013 proto = c_parser_objc_protocol_refs (parser);
11014 objc_start_category_interface (id1, id2, proto, attributes);
11015 c_parser_objc_methodprotolist (parser);
11016 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11017 objc_finish_interface ();
11020 if (c_parser_next_token_is (parser, CPP_COLON))
11022 c_parser_consume_token (parser);
11023 if (c_parser_next_token_is_not (parser, CPP_NAME))
11025 c_parser_error (parser, "expected identifier");
11028 superclass = c_parser_peek_token (parser)->value;
11029 c_parser_consume_token (parser);
11032 superclass = NULL_TREE;
11035 tree proto = NULL_TREE;
11036 if (c_parser_next_token_is (parser, CPP_LESS))
11037 proto = c_parser_objc_protocol_refs (parser);
11038 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
11041 objc_start_class_implementation (id1, superclass);
11042 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11043 c_parser_objc_class_instance_variables (parser);
11046 objc_continue_interface ();
11047 c_parser_objc_methodprotolist (parser);
11048 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11049 objc_finish_interface ();
11053 objc_continue_implementation ();
11058 /* Parse objc-class-instance-variables.
11060 objc-class-instance-variables:
11061 { objc-instance-variable-decl-list[opt] }
11063 objc-instance-variable-decl-list:
11064 objc-visibility-spec
11065 objc-instance-variable-decl ;
11067 objc-instance-variable-decl-list objc-visibility-spec
11068 objc-instance-variable-decl-list objc-instance-variable-decl ;
11069 objc-instance-variable-decl-list ;
11071 objc-visibility-spec:
11076 objc-instance-variable-decl:
11081 c_parser_objc_class_instance_variables (c_parser *parser)
11083 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
11084 c_parser_consume_token (parser);
11085 while (c_parser_next_token_is_not (parser, CPP_EOF))
11088 /* Parse any stray semicolon. */
11089 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11091 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11092 "extra semicolon");
11093 c_parser_consume_token (parser);
11096 /* Stop if at the end of the instance variables. */
11097 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11099 c_parser_consume_token (parser);
11102 /* Parse any objc-visibility-spec. */
11103 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11105 c_parser_consume_token (parser);
11106 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11109 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11111 c_parser_consume_token (parser);
11112 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11115 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11117 c_parser_consume_token (parser);
11118 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11121 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11123 c_parser_consume_token (parser);
11124 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11127 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11129 c_parser_pragma (parser, pragma_external, NULL);
11133 /* Parse some comma-separated declarations. */
11134 decls = c_parser_struct_declaration (parser);
11137 /* There is a syntax error. We want to skip the offending
11138 tokens up to the next ';' (included) or '}'
11141 /* First, skip manually a ')' or ']'. This is because they
11142 reduce the nesting level, so c_parser_skip_until_found()
11143 wouldn't be able to skip past them. */
11144 c_token *token = c_parser_peek_token (parser);
11145 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11146 c_parser_consume_token (parser);
11148 /* Then, do the standard skipping. */
11149 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11151 /* We hopefully recovered. Start normal parsing again. */
11152 parser->error = false;
11157 /* Comma-separated instance variables are chained together
11158 in reverse order; add them one by one. */
11159 tree ivar = nreverse (decls);
11160 for (; ivar; ivar = DECL_CHAIN (ivar))
11161 objc_add_instance_variable (copy_node (ivar));
11163 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11167 /* Parse an objc-class-declaration.
11169 objc-class-declaration:
11170 @class identifier-list ;
11174 c_parser_objc_class_declaration (c_parser *parser)
11176 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11177 c_parser_consume_token (parser);
11178 /* Any identifiers, including those declared as type names, are OK
11183 if (c_parser_next_token_is_not (parser, CPP_NAME))
11185 c_parser_error (parser, "expected identifier");
11186 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11187 parser->error = false;
11190 id = c_parser_peek_token (parser)->value;
11191 objc_declare_class (id);
11192 c_parser_consume_token (parser);
11193 if (c_parser_next_token_is (parser, CPP_COMMA))
11194 c_parser_consume_token (parser);
11198 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11201 /* Parse an objc-alias-declaration.
11203 objc-alias-declaration:
11204 @compatibility_alias identifier identifier ;
11208 c_parser_objc_alias_declaration (c_parser *parser)
11211 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11212 c_parser_consume_token (parser);
11213 if (c_parser_next_token_is_not (parser, CPP_NAME))
11215 c_parser_error (parser, "expected identifier");
11216 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11219 id1 = c_parser_peek_token (parser)->value;
11220 c_parser_consume_token (parser);
11221 if (c_parser_next_token_is_not (parser, CPP_NAME))
11223 c_parser_error (parser, "expected identifier");
11224 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11227 id2 = c_parser_peek_token (parser)->value;
11228 c_parser_consume_token (parser);
11229 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11230 objc_declare_alias (id1, id2);
11233 /* Parse an objc-protocol-definition.
11235 objc-protocol-definition:
11236 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11237 @protocol identifier-list ;
11239 "@protocol identifier ;" should be resolved as "@protocol
11240 identifier-list ;": objc-methodprotolist may not start with a
11241 semicolon in the first alternative if objc-protocol-refs are
11245 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11247 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11249 c_parser_consume_token (parser);
11250 if (c_parser_next_token_is_not (parser, CPP_NAME))
11252 c_parser_error (parser, "expected identifier");
11255 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11256 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11258 /* Any identifiers, including those declared as type names, are
11263 if (c_parser_next_token_is_not (parser, CPP_NAME))
11265 c_parser_error (parser, "expected identifier");
11268 id = c_parser_peek_token (parser)->value;
11269 objc_declare_protocol (id, attributes);
11270 c_parser_consume_token (parser);
11271 if (c_parser_next_token_is (parser, CPP_COMMA))
11272 c_parser_consume_token (parser);
11276 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11280 tree id = c_parser_peek_token (parser)->value;
11281 tree proto = NULL_TREE;
11282 c_parser_consume_token (parser);
11283 if (c_parser_next_token_is (parser, CPP_LESS))
11284 proto = c_parser_objc_protocol_refs (parser);
11285 parser->objc_pq_context = true;
11286 objc_start_protocol (id, proto, attributes);
11287 c_parser_objc_methodprotolist (parser);
11288 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11289 parser->objc_pq_context = false;
11290 objc_finish_interface ();
11294 /* Parse an objc-method-type.
11300 Return true if it is a class method (+) and false if it is
11301 an instance method (-).
11304 c_parser_objc_method_type (c_parser *parser)
11306 switch (c_parser_peek_token (parser)->type)
11309 c_parser_consume_token (parser);
11312 c_parser_consume_token (parser);
11315 gcc_unreachable ();
11319 /* Parse an objc-method-definition.
11321 objc-method-definition:
11322 objc-method-type objc-method-decl ;[opt] compound-statement
11326 c_parser_objc_method_definition (c_parser *parser)
11328 bool is_class_method = c_parser_objc_method_type (parser);
11329 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11330 parser->objc_pq_context = true;
11331 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11333 if (decl == error_mark_node)
11334 return; /* Bail here. */
11336 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11338 c_parser_consume_token (parser);
11339 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11340 "extra semicolon in method definition specified");
11343 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11345 c_parser_error (parser, "expected %<{%>");
11349 parser->objc_pq_context = false;
11350 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11352 add_stmt (c_parser_compound_statement (parser));
11353 objc_finish_method_definition (current_function_decl);
11357 /* This code is executed when we find a method definition
11358 outside of an @implementation context (or invalid for other
11359 reasons). Parse the method (to keep going) but do not emit
11362 c_parser_compound_statement (parser);
11366 /* Parse an objc-methodprotolist.
11368 objc-methodprotolist:
11370 objc-methodprotolist objc-methodproto
11371 objc-methodprotolist declaration
11372 objc-methodprotolist ;
11376 The declaration is a data definition, which may be missing
11377 declaration specifiers under the same rules and diagnostics as
11378 other data definitions outside functions, and the stray semicolon
11379 is diagnosed the same way as a stray semicolon outside a
11383 c_parser_objc_methodprotolist (c_parser *parser)
11387 /* The list is terminated by @end. */
11388 switch (c_parser_peek_token (parser)->type)
11390 case CPP_SEMICOLON:
11391 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11392 "ISO C does not allow extra %<;%> outside of a function");
11393 c_parser_consume_token (parser);
11397 c_parser_objc_methodproto (parser);
11400 c_parser_pragma (parser, pragma_external, NULL);
11405 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11407 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11408 c_parser_objc_at_property_declaration (parser);
11409 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11411 objc_set_method_opt (true);
11412 c_parser_consume_token (parser);
11414 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11416 objc_set_method_opt (false);
11417 c_parser_consume_token (parser);
11420 c_parser_declaration_or_fndef (parser, false, false, true,
11427 /* Parse an objc-methodproto.
11430 objc-method-type objc-method-decl ;
11434 c_parser_objc_methodproto (c_parser *parser)
11436 bool is_class_method = c_parser_objc_method_type (parser);
11437 tree decl, attributes = NULL_TREE;
11439 /* Remember protocol qualifiers in prototypes. */
11440 parser->objc_pq_context = true;
11441 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11443 /* Forget protocol qualifiers now. */
11444 parser->objc_pq_context = false;
11446 /* Do not allow the presence of attributes to hide an erroneous
11447 method implementation in the interface section. */
11448 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11450 c_parser_error (parser, "expected %<;%>");
11454 if (decl != error_mark_node)
11455 objc_add_method_declaration (is_class_method, decl, attributes);
11457 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11460 /* If we are at a position that method attributes may be present, check that
11461 there are not any parsed already (a syntax error) and then collect any
11462 specified at the current location. Finally, if new attributes were present,
11463 check that the next token is legal ( ';' for decls and '{' for defs). */
11466 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11471 c_parser_error (parser,
11472 "method attributes must be specified at the end only");
11473 *attributes = NULL_TREE;
11477 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11478 *attributes = c_parser_gnu_attributes (parser);
11480 /* If there were no attributes here, just report any earlier error. */
11481 if (*attributes == NULL_TREE || bad)
11484 /* If the attributes are followed by a ; or {, then just report any earlier
11486 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11487 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11490 /* We've got attributes, but not at the end. */
11491 c_parser_error (parser,
11492 "expected %<;%> or %<{%> after method attribute definition");
11496 /* Parse an objc-method-decl.
11499 ( objc-type-name ) objc-selector
11501 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11502 objc-keyword-selector objc-optparmlist
11505 objc-keyword-selector:
11507 objc-keyword-selector objc-keyword-decl
11510 objc-selector : ( objc-type-name ) identifier
11511 objc-selector : identifier
11512 : ( objc-type-name ) identifier
11516 objc-optparms objc-optellipsis
11520 objc-opt-parms , parameter-declaration
11528 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11529 tree *attributes, tree *expr)
11531 tree type = NULL_TREE;
11533 tree parms = NULL_TREE;
11534 bool ellipsis = false;
11535 bool attr_err = false;
11537 *attributes = NULL_TREE;
11538 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11540 matching_parens parens;
11541 parens.consume_open (parser);
11542 type = c_parser_objc_type_name (parser);
11543 parens.skip_until_found_close (parser);
11545 sel = c_parser_objc_selector (parser);
11546 /* If there is no selector, or a colon follows, we have an
11547 objc-keyword-selector. If there is a selector, and a colon does
11548 not follow, that selector ends the objc-method-decl. */
11549 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11552 tree list = NULL_TREE;
11555 tree atype = NULL_TREE, id, keyworddecl;
11556 tree param_attr = NULL_TREE;
11557 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11559 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11561 c_parser_consume_token (parser);
11562 atype = c_parser_objc_type_name (parser);
11563 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11566 /* New ObjC allows attributes on method parameters. */
11567 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11568 param_attr = c_parser_gnu_attributes (parser);
11569 if (c_parser_next_token_is_not (parser, CPP_NAME))
11571 c_parser_error (parser, "expected identifier");
11572 return error_mark_node;
11574 id = c_parser_peek_token (parser)->value;
11575 c_parser_consume_token (parser);
11576 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11577 list = chainon (list, keyworddecl);
11578 tsel = c_parser_objc_selector (parser);
11579 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11583 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11585 /* Parse the optional parameter list. Optional Objective-C
11586 method parameters follow the C syntax, and may include '...'
11587 to denote a variable number of arguments. */
11588 parms = make_node (TREE_LIST);
11589 while (c_parser_next_token_is (parser, CPP_COMMA))
11591 struct c_parm *parm;
11592 c_parser_consume_token (parser);
11593 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11596 c_parser_consume_token (parser);
11597 attr_err |= c_parser_objc_maybe_method_attributes
11598 (parser, attributes) ;
11601 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11604 parms = chainon (parms,
11605 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11610 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11614 c_parser_error (parser, "objective-c method declaration is expected");
11615 return error_mark_node;
11619 return error_mark_node;
11621 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11624 /* Parse an objc-type-name.
11627 objc-type-qualifiers[opt] type-name
11628 objc-type-qualifiers[opt]
11630 objc-type-qualifiers:
11631 objc-type-qualifier
11632 objc-type-qualifiers objc-type-qualifier
11634 objc-type-qualifier: one of
11635 in out inout bycopy byref oneway
11639 c_parser_objc_type_name (c_parser *parser)
11641 tree quals = NULL_TREE;
11642 struct c_type_name *type_name = NULL;
11643 tree type = NULL_TREE;
11646 c_token *token = c_parser_peek_token (parser);
11647 if (token->type == CPP_KEYWORD
11648 && (token->keyword == RID_IN
11649 || token->keyword == RID_OUT
11650 || token->keyword == RID_INOUT
11651 || token->keyword == RID_BYCOPY
11652 || token->keyword == RID_BYREF
11653 || token->keyword == RID_ONEWAY))
11655 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11656 c_parser_consume_token (parser);
11661 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11662 type_name = c_parser_type_name (parser);
11664 type = groktypename (type_name, NULL, NULL);
11666 /* If the type is unknown, and error has already been produced and
11667 we need to recover from the error. In that case, use NULL_TREE
11668 for the type, as if no type had been specified; this will use the
11669 default type ('id') which is good for error recovery. */
11670 if (type == error_mark_node)
11673 return build_tree_list (quals, type);
11676 /* Parse objc-protocol-refs.
11678 objc-protocol-refs:
11679 < identifier-list >
11683 c_parser_objc_protocol_refs (c_parser *parser)
11685 tree list = NULL_TREE;
11686 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11687 c_parser_consume_token (parser);
11688 /* Any identifiers, including those declared as type names, are OK
11693 if (c_parser_next_token_is_not (parser, CPP_NAME))
11695 c_parser_error (parser, "expected identifier");
11698 id = c_parser_peek_token (parser)->value;
11699 list = chainon (list, build_tree_list (NULL_TREE, id));
11700 c_parser_consume_token (parser);
11701 if (c_parser_next_token_is (parser, CPP_COMMA))
11702 c_parser_consume_token (parser);
11706 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11710 /* Parse an objc-try-catch-finally-statement.
11712 objc-try-catch-finally-statement:
11713 @try compound-statement objc-catch-list[opt]
11714 @try compound-statement objc-catch-list[opt] @finally compound-statement
11717 @catch ( objc-catch-parameter-declaration ) compound-statement
11718 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11720 objc-catch-parameter-declaration:
11721 parameter-declaration
11724 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11726 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11727 for C++. Keep them in sync. */
11730 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11732 location_t location;
11735 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11736 c_parser_consume_token (parser);
11737 location = c_parser_peek_token (parser)->location;
11738 objc_maybe_warn_exceptions (location);
11739 stmt = c_parser_compound_statement (parser);
11740 objc_begin_try_stmt (location, stmt);
11742 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11744 struct c_parm *parm;
11745 tree parameter_declaration = error_mark_node;
11746 bool seen_open_paren = false;
11748 c_parser_consume_token (parser);
11749 matching_parens parens;
11750 if (!parens.require_open (parser))
11751 seen_open_paren = true;
11752 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11754 /* We have "@catch (...)" (where the '...' are literally
11755 what is in the code). Skip the '...'.
11756 parameter_declaration is set to NULL_TREE, and
11757 objc_being_catch_clauses() knows that that means
11759 c_parser_consume_token (parser);
11760 parameter_declaration = NULL_TREE;
11764 /* We have "@catch (NSException *exception)" or something
11765 like that. Parse the parameter declaration. */
11766 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11768 parameter_declaration = error_mark_node;
11770 parameter_declaration = grokparm (parm, NULL);
11772 if (seen_open_paren)
11773 parens.require_close (parser);
11776 /* If there was no open parenthesis, we are recovering from
11777 an error, and we are trying to figure out what mistake
11778 the user has made. */
11780 /* If there is an immediate closing parenthesis, the user
11781 probably forgot the opening one (ie, they typed "@catch
11782 NSException *e)". Parse the closing parenthesis and keep
11784 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11785 c_parser_consume_token (parser);
11787 /* If these is no immediate closing parenthesis, the user
11788 probably doesn't know that parenthesis are required at
11789 all (ie, they typed "@catch NSException *e"). So, just
11790 forget about the closing parenthesis and keep going. */
11792 objc_begin_catch_clause (parameter_declaration);
11793 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11794 c_parser_compound_statement_nostart (parser);
11795 objc_finish_catch_clause ();
11797 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11799 c_parser_consume_token (parser);
11800 location = c_parser_peek_token (parser)->location;
11801 stmt = c_parser_compound_statement (parser);
11802 objc_build_finally_clause (location, stmt);
11804 objc_finish_try_stmt ();
11807 /* Parse an objc-synchronized-statement.
11809 objc-synchronized-statement:
11810 @synchronized ( expression ) compound-statement
11814 c_parser_objc_synchronized_statement (c_parser *parser)
11818 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11819 c_parser_consume_token (parser);
11820 loc = c_parser_peek_token (parser)->location;
11821 objc_maybe_warn_exceptions (loc);
11822 matching_parens parens;
11823 if (parens.require_open (parser))
11825 struct c_expr ce = c_parser_expression (parser);
11826 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11828 expr = c_fully_fold (expr, false, NULL);
11829 parens.skip_until_found_close (parser);
11832 expr = error_mark_node;
11833 stmt = c_parser_compound_statement (parser);
11834 objc_build_synchronized (loc, expr, stmt);
11837 /* Parse an objc-selector; return NULL_TREE without an error if the
11838 next token is not an objc-selector.
11843 enum struct union if else while do for switch case default
11844 break continue return goto asm sizeof typeof __alignof
11845 unsigned long const short volatile signed restrict _Complex
11846 in out inout bycopy byref oneway int char float double void _Bool
11849 ??? Why this selection of keywords but not, for example, storage
11850 class specifiers? */
11853 c_parser_objc_selector (c_parser *parser)
11855 c_token *token = c_parser_peek_token (parser);
11856 tree value = token->value;
11857 if (token->type == CPP_NAME)
11859 c_parser_consume_token (parser);
11862 if (token->type != CPP_KEYWORD)
11864 switch (token->keyword)
11903 CASE_RID_FLOATN_NX:
11907 case RID_AUTO_TYPE:
11912 c_parser_consume_token (parser);
11919 /* Parse an objc-selector-arg.
11923 objc-keywordname-list
11925 objc-keywordname-list:
11927 objc-keywordname-list objc-keywordname
11935 c_parser_objc_selector_arg (c_parser *parser)
11937 tree sel = c_parser_objc_selector (parser);
11938 tree list = NULL_TREE;
11940 && c_parser_next_token_is_not (parser, CPP_COLON)
11941 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11945 if (c_parser_next_token_is (parser, CPP_SCOPE))
11947 c_parser_consume_token (parser);
11948 list = chainon (list, build_tree_list (sel, NULL_TREE));
11949 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11953 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11955 list = chainon (list, build_tree_list (sel, NULL_TREE));
11957 sel = c_parser_objc_selector (parser);
11959 && c_parser_next_token_is_not (parser, CPP_COLON)
11960 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11966 /* Parse an objc-receiver.
11975 c_parser_objc_receiver (c_parser *parser)
11977 location_t loc = c_parser_peek_token (parser)->location;
11979 if (c_parser_peek_token (parser)->type == CPP_NAME
11980 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11981 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11983 tree id = c_parser_peek_token (parser)->value;
11984 c_parser_consume_token (parser);
11985 return objc_get_class_reference (id);
11987 struct c_expr ce = c_parser_expression (parser);
11988 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11989 return c_fully_fold (ce.value, false, NULL);
11992 /* Parse objc-message-args.
11996 objc-keywordarg-list
11998 objc-keywordarg-list:
12000 objc-keywordarg-list objc-keywordarg
12003 objc-selector : objc-keywordexpr
12008 c_parser_objc_message_args (c_parser *parser)
12010 tree sel = c_parser_objc_selector (parser);
12011 tree list = NULL_TREE;
12012 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
12017 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
12018 return error_mark_node;
12019 keywordexpr = c_parser_objc_keywordexpr (parser);
12020 list = chainon (list, build_tree_list (sel, keywordexpr));
12021 sel = c_parser_objc_selector (parser);
12022 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
12028 /* Parse an objc-keywordexpr.
12035 c_parser_objc_keywordexpr (c_parser *parser)
12038 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
12039 NULL, NULL, NULL, NULL);
12040 if (vec_safe_length (expr_list) == 1)
12042 /* Just return the expression, remove a level of
12044 ret = (*expr_list)[0];
12048 /* We have a comma expression, we will collapse later. */
12049 ret = build_tree_list_vec (expr_list);
12051 release_tree_vector (expr_list);
12055 /* A check, needed in several places, that ObjC interface, implementation or
12056 method definitions are not prefixed by incorrect items. */
12058 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
12059 struct c_declspecs *specs)
12061 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
12062 || specs->typespec_kind != ctsk_none)
12064 c_parser_error (parser,
12065 "no type or storage class may be specified here,");
12066 c_parser_skip_to_end_of_block_or_statement (parser);
12072 /* Parse an Objective-C @property declaration. The syntax is:
12074 objc-property-declaration:
12075 '@property' objc-property-attributes[opt] struct-declaration ;
12077 objc-property-attributes:
12078 '(' objc-property-attribute-list ')'
12080 objc-property-attribute-list:
12081 objc-property-attribute
12082 objc-property-attribute-list, objc-property-attribute
12084 objc-property-attribute
12085 'getter' = identifier
12086 'setter' = identifier
12095 @property NSString *name;
12096 @property (readonly) id object;
12097 @property (retain, nonatomic, getter=getTheName) id name;
12098 @property int a, b, c;
12100 PS: This function is identical to cp_parser_objc_at_propery_declaration
12101 for C++. Keep them in sync. */
12103 c_parser_objc_at_property_declaration (c_parser *parser)
12105 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12106 location_t loc = c_parser_peek_token (parser)->location;
12107 c_parser_consume_token (parser); /* Eat '@property'. */
12109 /* Parse the optional attribute list.
12111 A list of parsed, but not verified, attributes. */
12112 vec<property_attribute_info *> prop_attr_list = vNULL;
12114 bool syntax_error = false;
12115 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12117 matching_parens parens;
12119 location_t attr_start = c_parser_peek_token (parser)->location;
12121 parens.consume_open (parser);
12123 /* Property attribute keywords are valid now. */
12124 parser->objc_property_attr_context = true;
12126 /* Allow @property (), with a warning. */
12127 location_t attr_end = c_parser_peek_token (parser)->location;
12129 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12131 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12132 warning_at (attr_comb, OPT_Wattributes,
12133 "empty property attribute list");
12138 c_token *token = c_parser_peek_token (parser);
12139 attr_start = token->location;
12140 attr_end = get_finish (token->location);
12141 location_t attr_comb = make_location (attr_start, attr_start,
12144 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12146 warning_at (attr_comb, OPT_Wattributes,
12147 "missing property attribute");
12148 if (token->type == CPP_CLOSE_PAREN)
12150 c_parser_consume_token (parser);
12154 tree attr_name = NULL_TREE;
12155 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12156 bool add_at = false;
12157 if (token->type == CPP_KEYWORD)
12159 keyword = token->keyword;
12160 if (OBJC_IS_AT_KEYWORD (keyword))
12162 /* For '@' keywords the token value has the keyword,
12163 prepend the '@' for diagnostics. */
12164 attr_name = token->value;
12168 attr_name = ridpointers[(int)keyword];
12170 else if (token->type == CPP_NAME)
12171 attr_name = token->value;
12172 c_parser_consume_token (parser);
12174 enum objc_property_attribute_kind prop_kind
12175 = objc_prop_attr_kind_for_rid (keyword);
12176 property_attribute_info *prop
12177 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12178 prop_attr_list.safe_push (prop);
12181 switch (prop->prop_kind)
12184 case OBJC_PROPERTY_ATTR_UNKNOWN:
12186 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12187 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12189 error_at (attr_comb, "unknown property attribute");
12190 prop->parse_error = syntax_error = true;
12193 case OBJC_PROPERTY_ATTR_GETTER:
12194 case OBJC_PROPERTY_ATTR_SETTER:
12195 if (c_parser_next_token_is_not (parser, CPP_EQ))
12197 attr_comb = make_location (attr_end, attr_start, attr_end);
12198 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12200 prop->parse_error = syntax_error = true;
12203 token = c_parser_peek_token (parser);
12204 attr_end = token->location;
12205 c_parser_consume_token (parser); /* eat the = */
12206 if (c_parser_next_token_is_not (parser, CPP_NAME))
12208 attr_comb = make_location (attr_end, attr_start, attr_end);
12209 error_at (attr_comb, "expected %qE selector name",
12211 prop->parse_error = syntax_error = true;
12214 /* Get the end of the method name, and consume the name. */
12215 token = c_parser_peek_token (parser);
12216 attr_end = get_finish (token->location);
12217 meth_name = token->value;
12218 c_parser_consume_token (parser);
12219 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12221 if (c_parser_next_token_is_not (parser, CPP_COLON))
12223 attr_comb = make_location (attr_end, attr_start,
12225 error_at (attr_comb, "setter method names must"
12226 " terminate with %<:%>");
12227 prop->parse_error = syntax_error = true;
12231 attr_end = get_finish (c_parser_peek_token
12232 (parser)->location);
12233 c_parser_consume_token (parser);
12235 attr_comb = make_location (attr_start, attr_start,
12239 attr_comb = make_location (attr_start, attr_start,
12241 prop->ident = meth_name;
12242 /* Updated location including all that was successfully
12244 prop->prop_loc = attr_comb;
12248 /* If we see a comma here, then keep going - even if we already
12249 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12250 this makes a more useful output and avoid spurious warnings about
12251 missing attributes that are, in fact, specified after the one with
12252 the syntax error. */
12253 if (c_parser_next_token_is (parser, CPP_COMMA))
12254 c_parser_consume_token (parser);
12258 parser->objc_property_attr_context = false;
12260 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12261 /* We don't really want to chew the whole of the file looking for a
12262 matching closing parenthesis, so we will try to read the decl and
12263 let the error handling for that close out the statement. */
12266 syntax_error = false, parens.skip_until_found_close (parser);
12269 /* 'properties' is the list of properties that we read. Usually a
12270 single one, but maybe more (eg, in "@property int a, b, c;" there
12272 tree properties = c_parser_struct_declaration (parser);
12274 if (properties == error_mark_node)
12275 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12278 if (properties == NULL_TREE)
12279 c_parser_error (parser, "expected identifier");
12282 /* Comma-separated properties are chained together in reverse order;
12283 add them one by one. */
12284 properties = nreverse (properties);
12285 for (; properties; properties = TREE_CHAIN (properties))
12286 objc_add_property_declaration (loc, copy_node (properties),
12289 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12292 while (!prop_attr_list.is_empty())
12293 delete prop_attr_list.pop ();
12294 prop_attr_list.release ();
12295 parser->error = false;
12298 /* Parse an Objective-C @synthesize declaration. The syntax is:
12300 objc-synthesize-declaration:
12301 @synthesize objc-synthesize-identifier-list ;
12303 objc-synthesize-identifier-list:
12304 objc-synthesize-identifier
12305 objc-synthesize-identifier-list, objc-synthesize-identifier
12307 objc-synthesize-identifier
12309 identifier = identifier
12312 @synthesize MyProperty;
12313 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12315 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12316 for C++. Keep them in sync.
12319 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12321 tree list = NULL_TREE;
12323 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12324 loc = c_parser_peek_token (parser)->location;
12326 c_parser_consume_token (parser);
12329 tree property, ivar;
12330 if (c_parser_next_token_is_not (parser, CPP_NAME))
12332 c_parser_error (parser, "expected identifier");
12333 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12334 /* Once we find the semicolon, we can resume normal parsing.
12335 We have to reset parser->error manually because
12336 c_parser_skip_until_found() won't reset it for us if the
12337 next token is precisely a semicolon. */
12338 parser->error = false;
12341 property = c_parser_peek_token (parser)->value;
12342 c_parser_consume_token (parser);
12343 if (c_parser_next_token_is (parser, CPP_EQ))
12345 c_parser_consume_token (parser);
12346 if (c_parser_next_token_is_not (parser, CPP_NAME))
12348 c_parser_error (parser, "expected identifier");
12349 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12350 parser->error = false;
12353 ivar = c_parser_peek_token (parser)->value;
12354 c_parser_consume_token (parser);
12358 list = chainon (list, build_tree_list (ivar, property));
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_synthesize_declaration (loc, list);
12368 /* Parse an Objective-C @dynamic declaration. The syntax is:
12370 objc-dynamic-declaration:
12371 @dynamic identifier-list ;
12374 @dynamic MyProperty;
12375 @dynamic MyProperty, AnotherProperty;
12377 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12378 for C++. Keep them in sync.
12381 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12383 tree list = NULL_TREE;
12385 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12386 loc = c_parser_peek_token (parser)->location;
12388 c_parser_consume_token (parser);
12392 if (c_parser_next_token_is_not (parser, CPP_NAME))
12394 c_parser_error (parser, "expected identifier");
12395 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12396 parser->error = false;
12399 property = c_parser_peek_token (parser)->value;
12400 list = chainon (list, build_tree_list (NULL_TREE, property));
12401 c_parser_consume_token (parser);
12402 if (c_parser_next_token_is (parser, CPP_COMMA))
12403 c_parser_consume_token (parser);
12407 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12408 objc_add_dynamic_declaration (loc, list);
12412 /* Parse a pragma GCC ivdep. */
12415 c_parse_pragma_ivdep (c_parser *parser)
12417 c_parser_consume_pragma (parser);
12418 c_parser_skip_to_pragma_eol (parser);
12422 /* Parse a pragma GCC unroll. */
12424 static unsigned short
12425 c_parser_pragma_unroll (c_parser *parser)
12427 unsigned short unroll;
12428 c_parser_consume_pragma (parser);
12429 location_t location = c_parser_peek_token (parser)->location;
12430 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12431 mark_exp_read (expr);
12432 expr = c_fully_fold (expr, false, NULL);
12433 HOST_WIDE_INT lunroll = 0;
12434 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12435 || TREE_CODE (expr) != INTEGER_CST
12436 || (lunroll = tree_to_shwi (expr)) < 0
12437 || lunroll >= USHRT_MAX)
12439 error_at (location, "%<#pragma GCC unroll%> requires an"
12440 " assignment-expression that evaluates to a non-negative"
12441 " integral constant less than %u", USHRT_MAX);
12446 unroll = (unsigned short)lunroll;
12451 c_parser_skip_to_pragma_eol (parser);
12455 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12456 should be considered, statements. ALLOW_STMT is true if we're within
12457 the context of a function and such pragmas are to be allowed. Returns
12458 true if we actually parsed such a pragma. */
12461 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12464 const char *construct = NULL;
12466 input_location = c_parser_peek_token (parser)->location;
12467 id = c_parser_peek_token (parser)->pragma_kind;
12468 gcc_assert (id != PRAGMA_NONE);
12472 case PRAGMA_OACC_DECLARE:
12473 c_parser_oacc_declare (parser);
12476 case PRAGMA_OACC_ENTER_DATA:
12477 if (context != pragma_compound)
12479 construct = "acc enter data";
12481 if (context == pragma_stmt)
12483 error_at (c_parser_peek_token (parser)->location,
12484 "%<#pragma %s%> may only be used in compound "
12485 "statements", construct);
12486 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12491 c_parser_oacc_enter_exit_data (parser, true);
12494 case PRAGMA_OACC_EXIT_DATA:
12495 if (context != pragma_compound)
12497 construct = "acc exit data";
12500 c_parser_oacc_enter_exit_data (parser, false);
12503 case PRAGMA_OACC_ROUTINE:
12504 if (context != pragma_external)
12506 error_at (c_parser_peek_token (parser)->location,
12507 "%<#pragma acc routine%> must be at file scope");
12508 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12511 c_parser_oacc_routine (parser, context);
12514 case PRAGMA_OACC_UPDATE:
12515 if (context != pragma_compound)
12517 construct = "acc update";
12520 c_parser_oacc_update (parser);
12523 case PRAGMA_OMP_BARRIER:
12524 if (context != pragma_compound)
12526 construct = "omp barrier";
12529 c_parser_omp_barrier (parser);
12532 case PRAGMA_OMP_DEPOBJ:
12533 if (context != pragma_compound)
12535 construct = "omp depobj";
12538 c_parser_omp_depobj (parser);
12541 case PRAGMA_OMP_FLUSH:
12542 if (context != pragma_compound)
12544 construct = "omp flush";
12547 c_parser_omp_flush (parser);
12550 case PRAGMA_OMP_TASKWAIT:
12551 if (context != pragma_compound)
12553 construct = "omp taskwait";
12556 c_parser_omp_taskwait (parser);
12559 case PRAGMA_OMP_TASKYIELD:
12560 if (context != pragma_compound)
12562 construct = "omp taskyield";
12565 c_parser_omp_taskyield (parser);
12568 case PRAGMA_OMP_CANCEL:
12569 if (context != pragma_compound)
12571 construct = "omp cancel";
12574 c_parser_omp_cancel (parser);
12577 case PRAGMA_OMP_CANCELLATION_POINT:
12578 return c_parser_omp_cancellation_point (parser, context);
12580 case PRAGMA_OMP_THREADPRIVATE:
12581 c_parser_omp_threadprivate (parser);
12584 case PRAGMA_OMP_TARGET:
12585 return c_parser_omp_target (parser, context, if_p);
12587 case PRAGMA_OMP_END_DECLARE_TARGET:
12588 c_parser_omp_end_declare_target (parser);
12591 case PRAGMA_OMP_SCAN:
12592 error_at (c_parser_peek_token (parser)->location,
12593 "%<#pragma omp scan%> may only be used in "
12594 "a loop construct with %<inscan%> %<reduction%> clause");
12595 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12598 case PRAGMA_OMP_SECTION:
12599 error_at (c_parser_peek_token (parser)->location,
12600 "%<#pragma omp section%> may only be used in "
12601 "%<#pragma omp sections%> construct");
12602 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12605 case PRAGMA_OMP_DECLARE:
12606 return c_parser_omp_declare (parser, context);
12608 case PRAGMA_OMP_REQUIRES:
12609 if (context != pragma_external)
12611 error_at (c_parser_peek_token (parser)->location,
12612 "%<#pragma omp requires%> may only be used at file scope");
12613 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12616 c_parser_omp_requires (parser);
12619 case PRAGMA_OMP_NOTHING:
12620 c_parser_omp_nothing (parser);
12623 case PRAGMA_OMP_ERROR:
12624 return c_parser_omp_error (parser, context);
12626 case PRAGMA_OMP_ORDERED:
12627 return c_parser_omp_ordered (parser, context, if_p);
12631 const bool ivdep = c_parse_pragma_ivdep (parser);
12632 unsigned short unroll;
12633 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12634 unroll = c_parser_pragma_unroll (parser);
12637 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12638 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12639 && !c_parser_next_token_is_keyword (parser, RID_DO))
12641 c_parser_error (parser, "for, while or do statement expected");
12644 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12645 c_parser_for_statement (parser, ivdep, unroll, if_p);
12646 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12647 c_parser_while_statement (parser, ivdep, unroll, if_p);
12649 c_parser_do_statement (parser, ivdep, unroll);
12653 case PRAGMA_UNROLL:
12655 unsigned short unroll = c_parser_pragma_unroll (parser);
12657 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12658 ivdep = c_parse_pragma_ivdep (parser);
12661 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12662 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12663 && !c_parser_next_token_is_keyword (parser, RID_DO))
12665 c_parser_error (parser, "for, while or do statement expected");
12668 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12669 c_parser_for_statement (parser, ivdep, unroll, if_p);
12670 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12671 c_parser_while_statement (parser, ivdep, unroll, if_p);
12673 c_parser_do_statement (parser, ivdep, unroll);
12677 case PRAGMA_GCC_PCH_PREPROCESS:
12678 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12679 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12682 case PRAGMA_OACC_WAIT:
12683 if (context != pragma_compound)
12685 construct = "acc wait";
12688 /* FALL THROUGH. */
12691 if (id < PRAGMA_FIRST_EXTERNAL)
12693 if (context != pragma_stmt && context != pragma_compound)
12696 c_parser_error (parser, "expected declaration specifiers");
12697 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12700 c_parser_omp_construct (parser, if_p);
12706 c_parser_consume_pragma (parser);
12707 c_invoke_pragma_handler (id);
12709 /* Skip to EOL, but suppress any error message. Those will have been
12710 generated by the handler routine through calling error, as opposed
12711 to calling c_parser_error. */
12712 parser->error = true;
12713 c_parser_skip_to_pragma_eol (parser);
12718 /* The interface the pragma parsers have to the lexer. */
12721 pragma_lex (tree *value, location_t *loc)
12723 c_token *tok = c_parser_peek_token (the_parser);
12724 enum cpp_ttype ret = tok->type;
12726 *value = tok->value;
12728 *loc = tok->location;
12730 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12732 else if (ret == CPP_STRING)
12733 *value = c_parser_string_literal (the_parser, false, false).value;
12736 if (ret == CPP_KEYWORD)
12738 c_parser_consume_token (the_parser);
12745 c_parser_pragma_pch_preprocess (c_parser *parser)
12749 parser->lex_joined_string = true;
12750 c_parser_consume_pragma (parser);
12751 if (c_parser_next_token_is (parser, CPP_STRING))
12753 name = c_parser_peek_token (parser)->value;
12754 c_parser_consume_token (parser);
12757 c_parser_error (parser, "expected string literal");
12758 c_parser_skip_to_pragma_eol (parser);
12759 parser->lex_joined_string = false;
12762 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12765 /* OpenACC and OpenMP parsing routines. */
12767 /* Returns name of the next clause.
12768 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12769 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12770 returned and the token is consumed. */
12772 static pragma_omp_clause
12773 c_parser_omp_clause_name (c_parser *parser)
12775 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12777 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12778 result = PRAGMA_OACC_CLAUSE_AUTO;
12779 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12780 result = PRAGMA_OMP_CLAUSE_IF;
12781 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12782 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12783 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12784 result = PRAGMA_OMP_CLAUSE_FOR;
12785 else if (c_parser_next_token_is (parser, CPP_NAME))
12787 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12792 if (!strcmp ("affinity", p))
12793 result = PRAGMA_OMP_CLAUSE_AFFINITY;
12794 else if (!strcmp ("aligned", p))
12795 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12796 else if (!strcmp ("allocate", p))
12797 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12798 else if (!strcmp ("async", p))
12799 result = PRAGMA_OACC_CLAUSE_ASYNC;
12800 else if (!strcmp ("attach", p))
12801 result = PRAGMA_OACC_CLAUSE_ATTACH;
12804 if (!strcmp ("bind", p))
12805 result = PRAGMA_OMP_CLAUSE_BIND;
12808 if (!strcmp ("collapse", p))
12809 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12810 else if (!strcmp ("copy", p))
12811 result = PRAGMA_OACC_CLAUSE_COPY;
12812 else if (!strcmp ("copyin", p))
12813 result = PRAGMA_OMP_CLAUSE_COPYIN;
12814 else if (!strcmp ("copyout", p))
12815 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12816 else if (!strcmp ("copyprivate", p))
12817 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12818 else if (!strcmp ("create", p))
12819 result = PRAGMA_OACC_CLAUSE_CREATE;
12822 if (!strcmp ("defaultmap", p))
12823 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12824 else if (!strcmp ("delete", p))
12825 result = PRAGMA_OACC_CLAUSE_DELETE;
12826 else if (!strcmp ("depend", p))
12827 result = PRAGMA_OMP_CLAUSE_DEPEND;
12828 else if (!strcmp ("detach", p))
12829 result = PRAGMA_OACC_CLAUSE_DETACH;
12830 else if (!strcmp ("device", p))
12831 result = PRAGMA_OMP_CLAUSE_DEVICE;
12832 else if (!strcmp ("deviceptr", p))
12833 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12834 else if (!strcmp ("device_resident", p))
12835 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12836 else if (!strcmp ("device_type", p))
12837 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12838 else if (!strcmp ("dist_schedule", p))
12839 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12840 else if (!strcmp ("doacross", p))
12841 result = PRAGMA_OMP_CLAUSE_DOACROSS;
12844 if (!strcmp ("enter", p))
12845 result = PRAGMA_OMP_CLAUSE_ENTER;
12848 if (!strcmp ("filter", p))
12849 result = PRAGMA_OMP_CLAUSE_FILTER;
12850 else if (!strcmp ("final", p))
12851 result = PRAGMA_OMP_CLAUSE_FINAL;
12852 else if (!strcmp ("finalize", p))
12853 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12854 else if (!strcmp ("firstprivate", p))
12855 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12856 else if (!strcmp ("from", p))
12857 result = PRAGMA_OMP_CLAUSE_FROM;
12860 if (!strcmp ("gang", p))
12861 result = PRAGMA_OACC_CLAUSE_GANG;
12862 else if (!strcmp ("grainsize", p))
12863 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12866 if (!strcmp ("has_device_addr", p))
12867 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
12868 else if (!strcmp ("hint", p))
12869 result = PRAGMA_OMP_CLAUSE_HINT;
12870 else if (!strcmp ("host", p))
12871 result = PRAGMA_OACC_CLAUSE_HOST;
12874 if (!strcmp ("if_present", p))
12875 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12876 else if (!strcmp ("in_reduction", p))
12877 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12878 else if (!strcmp ("inbranch", p))
12879 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12880 else if (!strcmp ("independent", p))
12881 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12882 else if (!strcmp ("is_device_ptr", p))
12883 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12886 if (!strcmp ("lastprivate", p))
12887 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12888 else if (!strcmp ("linear", p))
12889 result = PRAGMA_OMP_CLAUSE_LINEAR;
12890 else if (!strcmp ("link", p))
12891 result = PRAGMA_OMP_CLAUSE_LINK;
12894 if (!strcmp ("map", p))
12895 result = PRAGMA_OMP_CLAUSE_MAP;
12896 else if (!strcmp ("mergeable", p))
12897 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12900 if (!strcmp ("no_create", p))
12901 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12902 else if (!strcmp ("nogroup", p))
12903 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12904 else if (!strcmp ("nohost", p))
12905 result = PRAGMA_OACC_CLAUSE_NOHOST;
12906 else if (!strcmp ("nontemporal", p))
12907 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12908 else if (!strcmp ("notinbranch", p))
12909 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12910 else if (!strcmp ("nowait", p))
12911 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12912 else if (!strcmp ("num_gangs", p))
12913 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12914 else if (!strcmp ("num_tasks", p))
12915 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12916 else if (!strcmp ("num_teams", p))
12917 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12918 else if (!strcmp ("num_threads", p))
12919 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12920 else if (!strcmp ("num_workers", p))
12921 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12924 if (!strcmp ("ordered", p))
12925 result = PRAGMA_OMP_CLAUSE_ORDERED;
12926 else if (!strcmp ("order", p))
12927 result = PRAGMA_OMP_CLAUSE_ORDER;
12930 if (!strcmp ("parallel", p))
12931 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12932 else if (!strcmp ("present", p))
12933 result = PRAGMA_OACC_CLAUSE_PRESENT;
12934 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12936 else if (!strcmp ("present_or_copy", p)
12937 || !strcmp ("pcopy", p))
12938 result = PRAGMA_OACC_CLAUSE_COPY;
12939 else if (!strcmp ("present_or_copyin", p)
12940 || !strcmp ("pcopyin", p))
12941 result = PRAGMA_OACC_CLAUSE_COPYIN;
12942 else if (!strcmp ("present_or_copyout", p)
12943 || !strcmp ("pcopyout", p))
12944 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12945 else if (!strcmp ("present_or_create", p)
12946 || !strcmp ("pcreate", p))
12947 result = PRAGMA_OACC_CLAUSE_CREATE;
12948 else if (!strcmp ("priority", p))
12949 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12950 else if (!strcmp ("private", p))
12951 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12952 else if (!strcmp ("proc_bind", p))
12953 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12956 if (!strcmp ("reduction", p))
12957 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12960 if (!strcmp ("safelen", p))
12961 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12962 else if (!strcmp ("schedule", p))
12963 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12964 else if (!strcmp ("sections", p))
12965 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12966 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12967 result = PRAGMA_OACC_CLAUSE_HOST;
12968 else if (!strcmp ("seq", p))
12969 result = PRAGMA_OACC_CLAUSE_SEQ;
12970 else if (!strcmp ("shared", p))
12971 result = PRAGMA_OMP_CLAUSE_SHARED;
12972 else if (!strcmp ("simd", p))
12973 result = PRAGMA_OMP_CLAUSE_SIMD;
12974 else if (!strcmp ("simdlen", p))
12975 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12978 if (!strcmp ("task_reduction", p))
12979 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12980 else if (!strcmp ("taskgroup", p))
12981 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12982 else if (!strcmp ("thread_limit", p))
12983 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12984 else if (!strcmp ("threads", p))
12985 result = PRAGMA_OMP_CLAUSE_THREADS;
12986 else if (!strcmp ("tile", p))
12987 result = PRAGMA_OACC_CLAUSE_TILE;
12988 else if (!strcmp ("to", p))
12989 result = PRAGMA_OMP_CLAUSE_TO;
12992 if (!strcmp ("uniform", p))
12993 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12994 else if (!strcmp ("untied", p))
12995 result = PRAGMA_OMP_CLAUSE_UNTIED;
12996 else if (!strcmp ("use_device", p))
12997 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12998 else if (!strcmp ("use_device_addr", p))
12999 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
13000 else if (!strcmp ("use_device_ptr", p))
13001 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
13004 if (!strcmp ("vector", p))
13005 result = PRAGMA_OACC_CLAUSE_VECTOR;
13006 else if (!strcmp ("vector_length", p))
13007 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
13010 if (!strcmp ("wait", p))
13011 result = PRAGMA_OACC_CLAUSE_WAIT;
13012 else if (!strcmp ("worker", p))
13013 result = PRAGMA_OACC_CLAUSE_WORKER;
13018 if (result != PRAGMA_OMP_CLAUSE_NONE)
13019 c_parser_consume_token (parser);
13024 /* Validate that a clause of the given type does not already exist. */
13027 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
13030 if (tree c = omp_find_clause (clauses, code))
13031 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
13035 Parse wait clause or wait directive parameters. */
13038 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
13040 vec<tree, va_gc> *args;
13043 matching_parens parens;
13044 if (!parens.require_open (parser))
13047 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
13048 args_tree = build_tree_list_vec (args);
13050 for (t = args_tree; t; t = TREE_CHAIN (t))
13052 tree targ = TREE_VALUE (t);
13054 if (targ != error_mark_node)
13056 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
13058 c_parser_error (parser, "expression must be integral");
13059 targ = error_mark_node;
13063 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
13065 OMP_CLAUSE_DECL (c) = targ;
13066 OMP_CLAUSE_CHAIN (c) = list;
13072 release_tree_vector (args);
13073 parens.require_close (parser);
13077 /* OpenACC 2.0, OpenMP 2.5:
13080 variable-list , identifier
13082 If KIND is nonzero, create the appropriate node and install the
13083 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13084 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13086 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13087 return the list created.
13089 The optional ALLOW_DEREF argument is true if list items can use the deref
13094 tree low_bound, length;
13097 omp_dim (tree lb, tree len, location_t lo, bool nc)
13098 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13102 c_parser_omp_variable_list (c_parser *parser,
13103 location_t clause_loc,
13104 enum omp_clause_code kind, tree list,
13105 bool allow_deref = false)
13107 auto_vec<omp_dim> dims;
13108 bool array_section_p;
13109 auto_vec<c_token> tokens;
13110 unsigned int tokens_avail = 0;
13115 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13117 if (c_parser_next_token_is_not (parser, CPP_NAME)
13118 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13120 struct c_expr expr;
13121 if (kind == OMP_CLAUSE_DEPEND
13122 && c_parser_next_token_is_keyword (parser,
13123 RID_OMP_ALL_MEMORY)
13124 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13125 || (c_parser_peek_2nd_token (parser)->type
13126 == CPP_CLOSE_PAREN)))
13128 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
13129 c_parser_consume_token (parser);
13132 expr = c_parser_expr_no_commas (parser, NULL);
13133 if (expr.value != error_mark_node)
13135 tree u = build_omp_clause (clause_loc, kind);
13136 OMP_CLAUSE_DECL (u) = expr.value;
13137 OMP_CLAUSE_CHAIN (u) = list;
13141 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13144 c_parser_consume_token (parser);
13149 tokens.truncate (0);
13150 unsigned int nesting_depth = 0;
13153 c_token *token = c_parser_peek_token (parser);
13154 switch (token->type)
13157 case CPP_PRAGMA_EOL:
13159 case CPP_OPEN_BRACE:
13160 case CPP_OPEN_PAREN:
13161 case CPP_OPEN_SQUARE:
13164 case CPP_CLOSE_BRACE:
13165 case CPP_CLOSE_PAREN:
13166 case CPP_CLOSE_SQUARE:
13167 if (nesting_depth-- == 0)
13171 if (nesting_depth == 0)
13176 tokens.safe_push (*token);
13177 c_parser_consume_token (parser);
13183 /* Make sure nothing tries to read past the end of the tokens. */
13185 memset (&eof_token, 0, sizeof (eof_token));
13186 eof_token.type = CPP_EOF;
13187 tokens.safe_push (eof_token);
13188 tokens.safe_push (eof_token);
13190 tokens_avail = parser->tokens_avail;
13191 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13192 parser->tokens = tokens.address ();
13193 parser->tokens_avail = tokens.length ();
13196 tree t = NULL_TREE;
13198 if (c_parser_next_token_is (parser, CPP_NAME)
13199 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13201 t = lookup_name (c_parser_peek_token (parser)->value);
13203 if (t == NULL_TREE)
13205 undeclared_variable (c_parser_peek_token (parser)->location,
13206 c_parser_peek_token (parser)->value);
13207 t = error_mark_node;
13210 c_parser_consume_token (parser);
13212 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13213 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13214 || (c_parser_peek_token (parser)->keyword
13215 == RID_PRETTY_FUNCTION_NAME)
13216 || (c_parser_peek_token (parser)->keyword
13217 == RID_C99_FUNCTION_NAME)))
13218 t = c_parser_predefined_identifier (parser).value;
13222 c_parser_error (parser, "expected identifier");
13226 if (t == error_mark_node)
13228 else if (kind != 0)
13232 case OMP_CLAUSE__CACHE_:
13233 /* The OpenACC cache directive explicitly only allows "array
13234 elements or subarrays". */
13235 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13237 c_parser_error (parser, "expected %<[%>");
13238 t = error_mark_node;
13242 case OMP_CLAUSE_MAP:
13243 case OMP_CLAUSE_FROM:
13244 case OMP_CLAUSE_TO:
13245 start_component_ref:
13246 while (c_parser_next_token_is (parser, CPP_DOT)
13248 && c_parser_next_token_is (parser, CPP_DEREF)))
13250 location_t op_loc = c_parser_peek_token (parser)->location;
13251 location_t arrow_loc = UNKNOWN_LOCATION;
13252 if (c_parser_next_token_is (parser, CPP_DEREF))
13256 t_expr.original_code = ERROR_MARK;
13257 t_expr.original_type = NULL;
13258 set_c_expr_source_range (&t_expr, op_loc, op_loc);
13259 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13261 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13262 arrow_loc = t_expr.get_location ();
13264 c_parser_consume_token (parser);
13265 if (!c_parser_next_token_is (parser, CPP_NAME))
13267 c_parser_error (parser, "expected identifier");
13268 t = error_mark_node;
13272 c_token *comp_tok = c_parser_peek_token (parser);
13273 tree ident = comp_tok->value;
13274 location_t comp_loc = comp_tok->location;
13275 c_parser_consume_token (parser);
13276 t = build_component_ref (op_loc, t, ident, comp_loc,
13280 case OMP_CLAUSE_AFFINITY:
13281 case OMP_CLAUSE_DEPEND:
13282 case OMP_CLAUSE_REDUCTION:
13283 case OMP_CLAUSE_IN_REDUCTION:
13284 case OMP_CLAUSE_TASK_REDUCTION:
13285 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13286 array_section_p = false;
13288 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13290 location_t loc = UNKNOWN_LOCATION;
13291 tree low_bound = NULL_TREE, length = NULL_TREE;
13292 bool no_colon = false;
13294 c_parser_consume_token (parser);
13295 if (!c_parser_next_token_is (parser, CPP_COLON))
13297 location_t expr_loc
13298 = c_parser_peek_token (parser)->location;
13299 c_expr expr = c_parser_expression (parser);
13300 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13302 low_bound = expr.value;
13305 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13307 length = integer_one_node;
13312 /* Look for `:'. */
13313 if (!c_parser_require (parser, CPP_COLON,
13316 t = error_mark_node;
13319 array_section_p = true;
13320 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13322 location_t expr_loc
13323 = c_parser_peek_token (parser)->location;
13324 c_expr expr = c_parser_expression (parser);
13325 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13327 length = expr.value;
13330 /* Look for the closing `]'. */
13331 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13334 t = error_mark_node;
13338 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13341 if (t != error_mark_node)
13343 if ((kind == OMP_CLAUSE_MAP
13344 || kind == OMP_CLAUSE_FROM
13345 || kind == OMP_CLAUSE_TO)
13346 && !array_section_p
13347 && (c_parser_next_token_is (parser, CPP_DOT)
13349 && c_parser_next_token_is (parser,
13352 for (unsigned i = 0; i < dims.length (); i++)
13354 gcc_assert (dims[i].length == integer_one_node);
13355 t = build_array_ref (dims[i].loc,
13356 t, dims[i].low_bound);
13358 goto start_component_ref;
13361 for (unsigned i = 0; i < dims.length (); i++)
13362 t = tree_cons (dims[i].low_bound, dims[i].length, t);
13365 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13366 && t != error_mark_node
13367 && parser->tokens_avail != 2)
13369 if (array_section_p)
13371 error_at (c_parser_peek_token (parser)->location,
13372 "expected %<)%> or %<,%>");
13373 t = error_mark_node;
13377 parser->tokens = tokens.address ();
13378 parser->tokens_avail = tokens.length ();
13380 t = c_parser_expr_no_commas (parser, NULL).value;
13381 if (t != error_mark_node && parser->tokens_avail != 2)
13383 error_at (c_parser_peek_token (parser)->location,
13384 "expected %<)%> or %<,%>");
13385 t = error_mark_node;
13394 if (t != error_mark_node)
13396 tree u = build_omp_clause (clause_loc, kind);
13397 OMP_CLAUSE_DECL (u) = t;
13398 OMP_CLAUSE_CHAIN (u) = list;
13403 list = tree_cons (t, NULL_TREE, list);
13405 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13407 parser->tokens = &parser->tokens_buf[0];
13408 parser->tokens_avail = tokens_avail;
13410 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13413 c_parser_consume_token (parser);
13420 /* Similarly, but expect leading and trailing parenthesis. This is a very
13421 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13422 argument is true if list items can use the deref (->) operator. */
13425 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13426 tree list, bool allow_deref = false)
13428 /* The clauses location. */
13429 location_t loc = c_parser_peek_token (parser)->location;
13431 matching_parens parens;
13432 if (parens.require_open (parser))
13434 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13435 parens.skip_until_found_close (parser);
13441 copy ( variable-list )
13442 copyin ( variable-list )
13443 copyout ( variable-list )
13444 create ( variable-list )
13445 delete ( variable-list )
13446 present ( variable-list )
13449 no_create ( variable-list )
13450 attach ( variable-list )
13451 detach ( variable-list ) */
13454 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13457 enum gomp_map_kind kind;
13460 case PRAGMA_OACC_CLAUSE_ATTACH:
13461 kind = GOMP_MAP_ATTACH;
13463 case PRAGMA_OACC_CLAUSE_COPY:
13464 kind = GOMP_MAP_TOFROM;
13466 case PRAGMA_OACC_CLAUSE_COPYIN:
13467 kind = GOMP_MAP_TO;
13469 case PRAGMA_OACC_CLAUSE_COPYOUT:
13470 kind = GOMP_MAP_FROM;
13472 case PRAGMA_OACC_CLAUSE_CREATE:
13473 kind = GOMP_MAP_ALLOC;
13475 case PRAGMA_OACC_CLAUSE_DELETE:
13476 kind = GOMP_MAP_RELEASE;
13478 case PRAGMA_OACC_CLAUSE_DETACH:
13479 kind = GOMP_MAP_DETACH;
13481 case PRAGMA_OACC_CLAUSE_DEVICE:
13482 kind = GOMP_MAP_FORCE_TO;
13484 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13485 kind = GOMP_MAP_DEVICE_RESIDENT;
13487 case PRAGMA_OACC_CLAUSE_HOST:
13488 kind = GOMP_MAP_FORCE_FROM;
13490 case PRAGMA_OACC_CLAUSE_LINK:
13491 kind = GOMP_MAP_LINK;
13493 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13494 kind = GOMP_MAP_IF_PRESENT;
13496 case PRAGMA_OACC_CLAUSE_PRESENT:
13497 kind = GOMP_MAP_FORCE_PRESENT;
13500 gcc_unreachable ();
13503 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13505 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13506 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13512 deviceptr ( variable-list ) */
13515 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13517 location_t loc = c_parser_peek_token (parser)->location;
13520 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13521 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13522 variable-list must only allow for pointer variables. */
13523 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13524 for (t = vars; t && t; t = TREE_CHAIN (t))
13526 tree v = TREE_PURPOSE (t);
13528 /* FIXME diagnostics: Ideally we should keep individual
13529 locations for all the variables in the var list to make the
13530 following errors more precise. Perhaps
13531 c_parser_omp_var_list_parens() should construct a list of
13532 locations to go along with the var list. */
13534 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13535 error_at (loc, "%qD is not a variable", v);
13536 else if (TREE_TYPE (v) == error_mark_node)
13538 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13539 error_at (loc, "%qD is not a pointer variable", v);
13541 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13542 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13543 OMP_CLAUSE_DECL (u) = v;
13544 OMP_CLAUSE_CHAIN (u) = list;
13551 /* OpenACC 2.0, OpenMP 3.0:
13552 collapse ( constant-expression ) */
13555 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13557 tree c, num = error_mark_node;
13561 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13562 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13564 loc = c_parser_peek_token (parser)->location;
13565 matching_parens parens;
13566 if (parens.require_open (parser))
13568 num = c_parser_expr_no_commas (parser, NULL).value;
13569 parens.skip_until_found_close (parser);
13571 if (num == error_mark_node)
13573 mark_exp_read (num);
13574 num = c_fully_fold (num, false, NULL);
13575 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13576 || !tree_fits_shwi_p (num)
13577 || (n = tree_to_shwi (num)) <= 0
13581 "collapse argument needs positive constant integer expression");
13584 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13585 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13586 OMP_CLAUSE_CHAIN (c) = list;
13591 copyin ( variable-list ) */
13594 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13596 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13600 copyprivate ( variable-list ) */
13603 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13605 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13609 default ( none | shared )
13612 default ( private | firstprivate )
13615 default ( none | present ) */
13618 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13620 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13621 location_t loc = c_parser_peek_token (parser)->location;
13624 matching_parens parens;
13625 if (!parens.require_open (parser))
13627 if (c_parser_next_token_is (parser, CPP_NAME))
13629 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13634 if (strcmp ("none", p) != 0)
13636 kind = OMP_CLAUSE_DEFAULT_NONE;
13642 if (strcmp ("present", p) != 0)
13644 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13648 if (strcmp ("private", p) != 0)
13650 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
13655 if (strcmp ("firstprivate", p) != 0 || is_oacc)
13657 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13661 if (strcmp ("shared", p) != 0 || is_oacc)
13663 kind = OMP_CLAUSE_DEFAULT_SHARED;
13670 c_parser_consume_token (parser);
13676 c_parser_error (parser, "expected %<none%> or %<present%>");
13678 c_parser_error (parser, "expected %<none%>, %<shared%>, "
13679 "%<private%> or %<firstprivate%>");
13681 parens.skip_until_found_close (parser);
13683 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13686 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13687 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13688 OMP_CLAUSE_CHAIN (c) = list;
13689 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13695 firstprivate ( variable-list ) */
13698 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13700 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13704 final ( expression ) */
13707 c_parser_omp_clause_final (c_parser *parser, tree list)
13709 location_t loc = c_parser_peek_token (parser)->location;
13710 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13712 matching_parens parens;
13714 if (!parens.require_open (parser))
13715 t = error_mark_node;
13718 location_t eloc = c_parser_peek_token (parser)->location;
13719 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13720 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13721 t = c_objc_common_truthvalue_conversion (eloc, t);
13722 t = c_fully_fold (t, false, NULL);
13723 parens.skip_until_found_close (parser);
13726 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13728 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13729 OMP_CLAUSE_FINAL_EXPR (c) = t;
13730 OMP_CLAUSE_CHAIN (c) = list;
13734 c_parser_error (parser, "expected %<(%>");
13739 /* OpenACC, OpenMP 2.5:
13743 if ( directive-name-modifier : expression )
13745 directive-name-modifier:
13746 parallel | task | taskloop | target data | target | target update
13747 | target enter data | target exit data
13750 directive-name-modifier:
13751 ... | simd | cancel */
13754 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13756 location_t location = c_parser_peek_token (parser)->location;
13757 enum tree_code if_modifier = ERROR_MARK;
13759 matching_parens parens;
13760 if (!parens.require_open (parser))
13763 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13765 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13767 if (strcmp (p, "cancel") == 0)
13768 if_modifier = VOID_CST;
13769 else if (strcmp (p, "parallel") == 0)
13770 if_modifier = OMP_PARALLEL;
13771 else if (strcmp (p, "simd") == 0)
13772 if_modifier = OMP_SIMD;
13773 else if (strcmp (p, "task") == 0)
13774 if_modifier = OMP_TASK;
13775 else if (strcmp (p, "taskloop") == 0)
13776 if_modifier = OMP_TASKLOOP;
13777 else if (strcmp (p, "target") == 0)
13779 if_modifier = OMP_TARGET;
13780 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13782 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13783 if (strcmp ("data", p) == 0)
13784 if_modifier = OMP_TARGET_DATA;
13785 else if (strcmp ("update", p) == 0)
13786 if_modifier = OMP_TARGET_UPDATE;
13787 else if (strcmp ("enter", p) == 0)
13788 if_modifier = OMP_TARGET_ENTER_DATA;
13789 else if (strcmp ("exit", p) == 0)
13790 if_modifier = OMP_TARGET_EXIT_DATA;
13791 if (if_modifier != OMP_TARGET)
13794 c_parser_consume_token (parser);
13798 location_t loc = c_parser_peek_2nd_token (parser)->location;
13799 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13801 if_modifier = ERROR_MARK;
13803 if (if_modifier == OMP_TARGET_ENTER_DATA
13804 || if_modifier == OMP_TARGET_EXIT_DATA)
13806 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13808 p = IDENTIFIER_POINTER
13809 (c_parser_peek_2nd_token (parser)->value);
13810 if (strcmp ("data", p) == 0)
13814 c_parser_consume_token (parser);
13818 = c_parser_peek_2nd_token (parser)->location;
13819 error_at (loc, "expected %<data%>");
13820 if_modifier = ERROR_MARK;
13825 if (if_modifier != ERROR_MARK)
13827 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13829 c_parser_consume_token (parser);
13830 c_parser_consume_token (parser);
13836 location_t loc = c_parser_peek_2nd_token (parser)->location;
13837 error_at (loc, "expected %<:%>");
13839 if_modifier = ERROR_MARK;
13844 location_t loc = c_parser_peek_token (parser)->location;
13845 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13846 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13847 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13848 t = c_fully_fold (t, false, NULL);
13849 parens.skip_until_found_close (parser);
13851 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13852 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13854 if (if_modifier != ERROR_MARK
13855 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13857 const char *p = NULL;
13858 switch (if_modifier)
13860 case VOID_CST: p = "cancel"; break;
13861 case OMP_PARALLEL: p = "parallel"; break;
13862 case OMP_SIMD: p = "simd"; break;
13863 case OMP_TASK: p = "task"; break;
13864 case OMP_TASKLOOP: p = "taskloop"; break;
13865 case OMP_TARGET_DATA: p = "target data"; break;
13866 case OMP_TARGET: p = "target"; break;
13867 case OMP_TARGET_UPDATE: p = "target update"; break;
13868 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13869 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13870 default: gcc_unreachable ();
13872 error_at (location, "too many %<if%> clauses with %qs modifier",
13876 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13879 error_at (location, "too many %<if%> clauses");
13881 error_at (location, "too many %<if%> clauses without modifier");
13884 else if (if_modifier == ERROR_MARK
13885 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13887 error_at (location, "if any %<if%> clause has modifier, then all "
13888 "%<if%> clauses have to use modifier");
13893 c = build_omp_clause (location, OMP_CLAUSE_IF);
13894 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13895 OMP_CLAUSE_IF_EXPR (c) = t;
13896 OMP_CLAUSE_CHAIN (c) = list;
13901 lastprivate ( variable-list )
13904 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13907 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13909 /* The clauses location. */
13910 location_t loc = c_parser_peek_token (parser)->location;
13912 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13914 bool conditional = false;
13915 if (c_parser_next_token_is (parser, CPP_NAME)
13916 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13919 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13920 if (strcmp (p, "conditional") == 0)
13922 conditional = true;
13923 c_parser_consume_token (parser);
13924 c_parser_consume_token (parser);
13927 tree nlist = c_parser_omp_variable_list (parser, loc,
13928 OMP_CLAUSE_LASTPRIVATE, list);
13929 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13931 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13932 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13942 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13946 /* FIXME: Should we allow duplicates? */
13947 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13949 c = build_omp_clause (c_parser_peek_token (parser)->location,
13950 OMP_CLAUSE_MERGEABLE);
13951 OMP_CLAUSE_CHAIN (c) = list;
13960 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13963 location_t loc = c_parser_peek_token (parser)->location;
13965 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13967 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13968 OMP_CLAUSE_CHAIN (c) = list;
13973 num_threads ( expression ) */
13976 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13978 location_t num_threads_loc = c_parser_peek_token (parser)->location;
13979 matching_parens parens;
13980 if (parens.require_open (parser))
13982 location_t expr_loc = c_parser_peek_token (parser)->location;
13983 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13984 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13985 tree c, t = expr.value;
13986 t = c_fully_fold (t, false, NULL);
13988 parens.skip_until_found_close (parser);
13990 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13992 c_parser_error (parser, "expected integer expression");
13996 /* Attempt to statically determine when the number isn't positive. */
13997 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13998 build_int_cst (TREE_TYPE (t), 0));
13999 protected_set_expr_location (c, expr_loc);
14000 if (c == boolean_true_node)
14002 warning_at (expr_loc, 0,
14003 "%<num_threads%> value must be positive");
14004 t = integer_one_node;
14007 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
14009 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
14010 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
14011 OMP_CLAUSE_CHAIN (c) = list;
14019 num_tasks ( expression )
14022 num_tasks ( strict : expression ) */
14025 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
14027 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
14028 matching_parens parens;
14029 if (parens.require_open (parser))
14031 bool strict = false;
14032 if (c_parser_next_token_is (parser, CPP_NAME)
14033 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14034 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14038 c_parser_consume_token (parser);
14039 c_parser_consume_token (parser);
14042 location_t expr_loc = c_parser_peek_token (parser)->location;
14043 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14044 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14045 tree c, t = expr.value;
14046 t = c_fully_fold (t, false, NULL);
14048 parens.skip_until_found_close (parser);
14050 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14052 c_parser_error (parser, "expected integer expression");
14056 /* Attempt to statically determine when the number isn't positive. */
14057 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14058 build_int_cst (TREE_TYPE (t), 0));
14059 if (CAN_HAVE_LOCATION_P (c))
14060 SET_EXPR_LOCATION (c, expr_loc);
14061 if (c == boolean_true_node)
14063 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
14064 t = integer_one_node;
14067 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
14069 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
14070 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
14071 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
14072 OMP_CLAUSE_CHAIN (c) = list;
14080 grainsize ( expression )
14083 grainsize ( strict : expression ) */
14086 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
14088 location_t grainsize_loc = c_parser_peek_token (parser)->location;
14089 matching_parens parens;
14090 if (parens.require_open (parser))
14092 bool strict = false;
14093 if (c_parser_next_token_is (parser, CPP_NAME)
14094 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14095 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14099 c_parser_consume_token (parser);
14100 c_parser_consume_token (parser);
14103 location_t expr_loc = c_parser_peek_token (parser)->location;
14104 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14105 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14106 tree c, t = expr.value;
14107 t = c_fully_fold (t, false, NULL);
14109 parens.skip_until_found_close (parser);
14111 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14113 c_parser_error (parser, "expected integer expression");
14117 /* Attempt to statically determine when the number isn't positive. */
14118 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14119 build_int_cst (TREE_TYPE (t), 0));
14120 if (CAN_HAVE_LOCATION_P (c))
14121 SET_EXPR_LOCATION (c, expr_loc);
14122 if (c == boolean_true_node)
14124 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14125 t = integer_one_node;
14128 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14130 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14131 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14132 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14133 OMP_CLAUSE_CHAIN (c) = list;
14141 priority ( expression ) */
14144 c_parser_omp_clause_priority (c_parser *parser, tree list)
14146 location_t priority_loc = c_parser_peek_token (parser)->location;
14147 matching_parens parens;
14148 if (parens.require_open (parser))
14150 location_t expr_loc = c_parser_peek_token (parser)->location;
14151 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14152 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14153 tree c, t = expr.value;
14154 t = c_fully_fold (t, false, NULL);
14156 parens.skip_until_found_close (parser);
14158 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14160 c_parser_error (parser, "expected integer expression");
14164 /* Attempt to statically determine when the number isn't
14166 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14167 build_int_cst (TREE_TYPE (t), 0));
14168 if (CAN_HAVE_LOCATION_P (c))
14169 SET_EXPR_LOCATION (c, expr_loc);
14170 if (c == boolean_true_node)
14172 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14173 t = integer_one_node;
14176 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14178 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14179 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14180 OMP_CLAUSE_CHAIN (c) = list;
14188 hint ( expression ) */
14191 c_parser_omp_clause_hint (c_parser *parser, tree list)
14193 location_t hint_loc = c_parser_peek_token (parser)->location;
14194 matching_parens parens;
14195 if (parens.require_open (parser))
14197 location_t expr_loc = c_parser_peek_token (parser)->location;
14198 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14199 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14200 tree c, t = expr.value;
14201 t = c_fully_fold (t, false, NULL);
14202 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14203 || TREE_CODE (t) != INTEGER_CST
14204 || tree_int_cst_sgn (t) == -1)
14206 c_parser_error (parser, "expected constant integer expression "
14207 "with valid sync-hint value");
14210 parens.skip_until_found_close (parser);
14211 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14213 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14214 OMP_CLAUSE_HINT_EXPR (c) = t;
14215 OMP_CLAUSE_CHAIN (c) = list;
14223 filter ( integer-expression ) */
14226 c_parser_omp_clause_filter (c_parser *parser, tree list)
14228 location_t hint_loc = c_parser_peek_token (parser)->location;
14229 matching_parens parens;
14230 if (parens.require_open (parser))
14232 location_t expr_loc = c_parser_peek_token (parser)->location;
14233 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14234 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14235 tree c, t = expr.value;
14236 t = c_fully_fold (t, false, NULL);
14237 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14239 c_parser_error (parser, "expected integer expression");
14242 parens.skip_until_found_close (parser);
14243 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14245 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14246 OMP_CLAUSE_FILTER_EXPR (c) = t;
14247 OMP_CLAUSE_CHAIN (c) = list;
14255 defaultmap ( tofrom : scalar )
14258 defaultmap ( implicit-behavior [ : variable-category ] ) */
14261 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14263 location_t loc = c_parser_peek_token (parser)->location;
14266 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14267 enum omp_clause_defaultmap_kind category
14268 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14270 matching_parens parens;
14271 if (!parens.require_open (parser))
14273 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14275 else if (!c_parser_next_token_is (parser, CPP_NAME))
14278 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14279 "%<tofrom%>, %<firstprivate%>, %<none%> "
14284 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14289 if (strcmp ("alloc", p) == 0)
14290 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14292 goto invalid_behavior;
14296 if (strcmp ("default", p) == 0)
14297 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14299 goto invalid_behavior;
14303 if (strcmp ("firstprivate", p) == 0)
14304 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14305 else if (strcmp ("from", p) == 0)
14306 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14308 goto invalid_behavior;
14312 if (strcmp ("none", p) == 0)
14313 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14315 goto invalid_behavior;
14319 if (strcmp ("tofrom", p) == 0)
14320 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14321 else if (strcmp ("to", p) == 0)
14322 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14324 goto invalid_behavior;
14328 goto invalid_behavior;
14330 c_parser_consume_token (parser);
14332 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14334 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14336 if (!c_parser_next_token_is (parser, CPP_NAME))
14339 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14343 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14347 if (strcmp ("aggregate", p) == 0)
14348 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14350 goto invalid_category;
14354 if (strcmp ("pointer", p) == 0)
14355 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14357 goto invalid_category;
14361 if (strcmp ("scalar", p) == 0)
14362 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14364 goto invalid_category;
14368 goto invalid_category;
14371 c_parser_consume_token (parser);
14373 parens.skip_until_found_close (parser);
14375 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14376 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14377 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14378 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14379 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14380 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14382 enum omp_clause_defaultmap_kind cat = category;
14383 location_t loc = OMP_CLAUSE_LOCATION (c);
14384 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14385 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14389 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14392 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14395 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14398 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14402 gcc_unreachable ();
14405 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14408 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14413 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14414 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14415 OMP_CLAUSE_CHAIN (c) = list;
14419 parens.skip_until_found_close (parser);
14424 use_device ( variable-list )
14427 use_device_ptr ( variable-list ) */
14430 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14432 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14437 use_device_addr ( variable-list ) */
14440 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14442 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14447 has_device_addr ( variable-list ) */
14450 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
14452 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
14457 is_device_ptr ( variable-list ) */
14460 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14462 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14466 num_gangs ( expression )
14467 num_workers ( expression )
14468 vector_length ( expression ) */
14471 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14474 location_t loc = c_parser_peek_token (parser)->location;
14476 matching_parens parens;
14477 if (!parens.require_open (parser))
14480 location_t expr_loc = c_parser_peek_token (parser)->location;
14481 c_expr expr = c_parser_expression (parser);
14482 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14483 tree c, t = expr.value;
14484 t = c_fully_fold (t, false, NULL);
14486 parens.skip_until_found_close (parser);
14488 if (t == error_mark_node)
14490 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14492 error_at (expr_loc, "%qs expression must be integral",
14493 omp_clause_code_name[code]);
14497 /* Attempt to statically determine when the number isn't positive. */
14498 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14499 build_int_cst (TREE_TYPE (t), 0));
14500 protected_set_expr_location (c, expr_loc);
14501 if (c == boolean_true_node)
14503 warning_at (expr_loc, 0,
14504 "%qs value must be positive",
14505 omp_clause_code_name[code]);
14506 t = integer_one_node;
14509 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14511 c = build_omp_clause (loc, code);
14512 OMP_CLAUSE_OPERAND (c, 0) = t;
14513 OMP_CLAUSE_CHAIN (c) = list;
14519 gang [( gang-arg-list )]
14520 worker [( [num:] int-expr )]
14521 vector [( [length:] int-expr )]
14523 where gang-arg is one of:
14528 and size-expr may be:
14535 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14536 omp_clause_code kind,
14537 const char *str, tree list)
14539 const char *id = "num";
14540 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14542 if (kind == OMP_CLAUSE_VECTOR)
14545 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14547 c_parser_consume_token (parser);
14551 c_token *next = c_parser_peek_token (parser);
14554 /* Gang static argument. */
14555 if (kind == OMP_CLAUSE_GANG
14556 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14558 c_parser_consume_token (parser);
14560 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14561 goto cleanup_error;
14564 if (ops[idx] != NULL_TREE)
14566 c_parser_error (parser, "too many %<static%> arguments");
14567 goto cleanup_error;
14570 /* Check for the '*' argument. */
14571 if (c_parser_next_token_is (parser, CPP_MULT)
14572 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14573 || c_parser_peek_2nd_token (parser)->type
14574 == CPP_CLOSE_PAREN))
14576 c_parser_consume_token (parser);
14577 ops[idx] = integer_minus_one_node;
14579 if (c_parser_next_token_is (parser, CPP_COMMA))
14581 c_parser_consume_token (parser);
14588 /* Worker num: argument and vector length: arguments. */
14589 else if (c_parser_next_token_is (parser, CPP_NAME)
14590 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14591 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14593 c_parser_consume_token (parser); /* id */
14594 c_parser_consume_token (parser); /* ':' */
14597 /* Now collect the actual argument. */
14598 if (ops[idx] != NULL_TREE)
14600 c_parser_error (parser, "unexpected argument");
14601 goto cleanup_error;
14604 location_t expr_loc = c_parser_peek_token (parser)->location;
14605 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14606 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14607 tree expr = cexpr.value;
14608 if (expr == error_mark_node)
14609 goto cleanup_error;
14611 expr = c_fully_fold (expr, false, NULL);
14613 /* Attempt to statically determine when the number isn't a
14614 positive integer. */
14616 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14618 c_parser_error (parser, "expected integer expression");
14622 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14623 build_int_cst (TREE_TYPE (expr), 0));
14624 if (c == boolean_true_node)
14626 warning_at (loc, 0,
14627 "%qs value must be positive", str);
14628 expr = integer_one_node;
14633 if (kind == OMP_CLAUSE_GANG
14634 && c_parser_next_token_is (parser, CPP_COMMA))
14636 c_parser_consume_token (parser);
14643 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14644 goto cleanup_error;
14647 check_no_duplicate_clause (list, kind, str);
14649 c = build_omp_clause (loc, kind);
14652 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14654 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14655 OMP_CLAUSE_CHAIN (c) = list;
14660 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14672 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14675 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14677 tree c = build_omp_clause (loc, code);
14678 OMP_CLAUSE_CHAIN (c) = list;
14684 async [( int-expr )] */
14687 c_parser_oacc_clause_async (c_parser *parser, tree list)
14690 location_t loc = c_parser_peek_token (parser)->location;
14692 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14694 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14696 c_parser_consume_token (parser);
14698 t = c_parser_expr_no_commas (parser, NULL).value;
14699 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14700 c_parser_error (parser, "expected integer expression");
14701 else if (t == error_mark_node
14702 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14706 t = c_fully_fold (t, false, NULL);
14708 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14710 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14711 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14712 OMP_CLAUSE_CHAIN (c) = list;
14719 tile ( size-expr-list ) */
14722 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14724 tree c, expr = error_mark_node;
14726 tree tile = NULL_TREE;
14728 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14729 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14731 loc = c_parser_peek_token (parser)->location;
14732 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14737 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14740 if (c_parser_next_token_is (parser, CPP_MULT)
14741 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14742 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14744 c_parser_consume_token (parser);
14745 expr = integer_zero_node;
14749 location_t expr_loc = c_parser_peek_token (parser)->location;
14750 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14751 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14752 expr = cexpr.value;
14754 if (expr == error_mark_node)
14756 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14761 expr = c_fully_fold (expr, false, NULL);
14763 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14764 || !tree_fits_shwi_p (expr)
14765 || tree_to_shwi (expr) <= 0)
14767 error_at (expr_loc, "%<tile%> argument needs positive"
14768 " integral constant");
14769 expr = integer_zero_node;
14773 tile = tree_cons (NULL_TREE, expr, tile);
14775 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14777 /* Consume the trailing ')'. */
14778 c_parser_consume_token (parser);
14780 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14781 tile = nreverse (tile);
14782 OMP_CLAUSE_TILE_LIST (c) = tile;
14783 OMP_CLAUSE_CHAIN (c) = list;
14788 wait [( int-expr-list )] */
14791 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14793 location_t clause_loc = c_parser_peek_token (parser)->location;
14795 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14796 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14799 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14801 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14802 OMP_CLAUSE_CHAIN (c) = list;
14811 order ( concurrent )
14814 order ( order-modifier : concurrent )
14821 c_parser_omp_clause_order (c_parser *parser, tree list)
14823 location_t loc = c_parser_peek_token (parser)->location;
14826 bool unconstrained = false;
14827 bool reproducible = false;
14829 matching_parens parens;
14830 if (!parens.require_open (parser))
14832 if (c_parser_next_token_is (parser, CPP_NAME)
14833 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14835 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14836 if (strcmp (p, "unconstrained") == 0)
14837 unconstrained = true;
14838 else if (strcmp (p, "reproducible") == 0)
14839 reproducible = true;
14842 c_parser_error (parser, "expected %<reproducible%> or "
14843 "%<unconstrained%>");
14846 c_parser_consume_token (parser);
14847 c_parser_consume_token (parser);
14849 if (!c_parser_next_token_is (parser, CPP_NAME))
14851 c_parser_error (parser, "expected %<concurrent%>");
14854 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14855 if (strcmp (p, "concurrent") != 0)
14857 c_parser_error (parser, "expected %<concurrent%>");
14860 c_parser_consume_token (parser);
14861 parens.skip_until_found_close (parser);
14862 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
14863 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14864 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
14865 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
14866 OMP_CLAUSE_CHAIN (c) = list;
14870 parens.skip_until_found_close (parser);
14876 bind ( teams | parallel | thread ) */
14879 c_parser_omp_clause_bind (c_parser *parser, tree list)
14881 location_t loc = c_parser_peek_token (parser)->location;
14884 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14886 matching_parens parens;
14887 if (!parens.require_open (parser))
14889 if (!c_parser_next_token_is (parser, CPP_NAME))
14892 c_parser_error (parser,
14893 "expected %<teams%>, %<parallel%> or %<thread%>");
14894 parens.skip_until_found_close (parser);
14897 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14898 if (strcmp (p, "teams") == 0)
14899 kind = OMP_CLAUSE_BIND_TEAMS;
14900 else if (strcmp (p, "parallel") == 0)
14901 kind = OMP_CLAUSE_BIND_PARALLEL;
14902 else if (strcmp (p, "thread") != 0)
14904 c_parser_consume_token (parser);
14905 parens.skip_until_found_close (parser);
14906 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14907 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14908 OMP_CLAUSE_BIND_KIND (c) = kind;
14909 OMP_CLAUSE_CHAIN (c) = list;
14918 ordered ( constant-expression ) */
14921 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14923 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14925 tree c, num = NULL_TREE;
14927 location_t loc = c_parser_peek_token (parser)->location;
14928 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14930 matching_parens parens;
14931 parens.consume_open (parser);
14932 num = c_parser_expr_no_commas (parser, NULL).value;
14933 parens.skip_until_found_close (parser);
14935 if (num == error_mark_node)
14939 mark_exp_read (num);
14940 num = c_fully_fold (num, false, NULL);
14941 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14942 || !tree_fits_shwi_p (num)
14943 || (n = tree_to_shwi (num)) <= 0
14946 error_at (loc, "ordered argument needs positive "
14947 "constant integer expression");
14951 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14952 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14953 OMP_CLAUSE_CHAIN (c) = list;
14958 private ( variable-list ) */
14961 c_parser_omp_clause_private (c_parser *parser, tree list)
14963 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14967 reduction ( reduction-operator : variable-list )
14969 reduction-operator:
14970 One of: + * - & ^ | && ||
14974 reduction-operator:
14975 One of: + * - & ^ | && || max min
14979 reduction-operator:
14980 One of: + * - & ^ | && ||
14984 reduction ( reduction-modifier, reduction-operator : variable-list )
14985 in_reduction ( reduction-operator : variable-list )
14986 task_reduction ( reduction-operator : variable-list ) */
14989 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14990 bool is_omp, tree list)
14992 location_t clause_loc = c_parser_peek_token (parser)->location;
14993 matching_parens parens;
14994 if (parens.require_open (parser))
14997 bool inscan = false;
14998 enum tree_code code = ERROR_MARK;
14999 tree reduc_id = NULL_TREE;
15001 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
15003 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
15004 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
15006 c_parser_consume_token (parser);
15007 c_parser_consume_token (parser);
15009 else if (c_parser_next_token_is (parser, CPP_NAME)
15010 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
15013 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15014 if (strcmp (p, "task") == 0)
15016 else if (strcmp (p, "inscan") == 0)
15018 if (task || inscan)
15020 c_parser_consume_token (parser);
15021 c_parser_consume_token (parser);
15026 switch (c_parser_peek_token (parser)->type)
15038 code = BIT_AND_EXPR;
15041 code = BIT_XOR_EXPR;
15044 code = BIT_IOR_EXPR;
15047 code = TRUTH_ANDIF_EXPR;
15050 code = TRUTH_ORIF_EXPR;
15055 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15056 if (strcmp (p, "min") == 0)
15061 if (strcmp (p, "max") == 0)
15066 reduc_id = c_parser_peek_token (parser)->value;
15070 c_parser_error (parser,
15071 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15072 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15073 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15076 c_parser_consume_token (parser);
15077 reduc_id = c_omp_reduction_id (code, reduc_id);
15078 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15082 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
15083 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15085 tree d = OMP_CLAUSE_DECL (c), type;
15086 if (TREE_CODE (d) != TREE_LIST)
15087 type = TREE_TYPE (d);
15092 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
15094 type = TREE_TYPE (t);
15097 if (TREE_CODE (type) != POINTER_TYPE
15098 && TREE_CODE (type) != ARRAY_TYPE)
15100 type = TREE_TYPE (type);
15104 while (TREE_CODE (type) == ARRAY_TYPE)
15105 type = TREE_TYPE (type);
15106 OMP_CLAUSE_REDUCTION_CODE (c) = code;
15108 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15110 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15111 if (code == ERROR_MARK
15112 || !(INTEGRAL_TYPE_P (type)
15113 || TREE_CODE (type) == REAL_TYPE
15114 || TREE_CODE (type) == COMPLEX_TYPE))
15115 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15116 = c_omp_reduction_lookup (reduc_id,
15117 TYPE_MAIN_VARIANT (type));
15122 parens.skip_until_found_close (parser);
15128 schedule ( schedule-kind )
15129 schedule ( schedule-kind , expression )
15132 static | dynamic | guided | runtime | auto
15135 schedule ( schedule-modifier : schedule-kind )
15136 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15144 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15147 location_t loc = c_parser_peek_token (parser)->location;
15148 int modifiers = 0, nmodifiers = 0;
15150 matching_parens parens;
15151 if (!parens.require_open (parser))
15154 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15156 location_t comma = UNKNOWN_LOCATION;
15157 while (c_parser_next_token_is (parser, CPP_NAME))
15159 tree kind = c_parser_peek_token (parser)->value;
15160 const char *p = IDENTIFIER_POINTER (kind);
15161 if (strcmp ("simd", p) == 0)
15162 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15163 else if (strcmp ("monotonic", p) == 0)
15164 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15165 else if (strcmp ("nonmonotonic", p) == 0)
15166 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15169 comma = UNKNOWN_LOCATION;
15170 c_parser_consume_token (parser);
15171 if (nmodifiers++ == 0
15172 && c_parser_next_token_is (parser, CPP_COMMA))
15174 comma = c_parser_peek_token (parser)->location;
15175 c_parser_consume_token (parser);
15179 c_parser_require (parser, CPP_COLON, "expected %<:%>");
15183 if (comma != UNKNOWN_LOCATION)
15184 error_at (comma, "expected %<:%>");
15186 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15187 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15188 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15189 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15191 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15196 if (c_parser_next_token_is (parser, CPP_NAME))
15198 tree kind = c_parser_peek_token (parser)->value;
15199 const char *p = IDENTIFIER_POINTER (kind);
15204 if (strcmp ("dynamic", p) != 0)
15206 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15210 if (strcmp ("guided", p) != 0)
15212 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15216 if (strcmp ("runtime", p) != 0)
15218 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15225 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15226 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15227 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15228 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15232 c_parser_consume_token (parser);
15233 if (c_parser_next_token_is (parser, CPP_COMMA))
15236 c_parser_consume_token (parser);
15238 here = c_parser_peek_token (parser)->location;
15239 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15240 expr = convert_lvalue_to_rvalue (here, expr, false, true);
15242 t = c_fully_fold (t, false, NULL);
15244 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15245 error_at (here, "schedule %<runtime%> does not take "
15246 "a %<chunk_size%> parameter");
15247 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15249 "schedule %<auto%> does not take "
15250 "a %<chunk_size%> parameter");
15251 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15253 /* Attempt to statically determine when the number isn't
15255 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15256 build_int_cst (TREE_TYPE (t), 0));
15257 protected_set_expr_location (s, loc);
15258 if (s == boolean_true_node)
15260 warning_at (loc, 0,
15261 "chunk size value must be positive");
15262 t = integer_one_node;
15264 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15267 c_parser_error (parser, "expected integer expression");
15269 parens.skip_until_found_close (parser);
15272 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15273 "expected %<,%> or %<)%>");
15275 OMP_CLAUSE_SCHEDULE_KIND (c)
15276 = (enum omp_clause_schedule_kind)
15277 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15279 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15280 OMP_CLAUSE_CHAIN (c) = list;
15284 c_parser_error (parser, "invalid schedule kind");
15285 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15290 shared ( variable-list ) */
15293 c_parser_omp_clause_shared (c_parser *parser, tree list)
15295 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15302 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15306 /* FIXME: Should we allow duplicates? */
15307 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15309 c = build_omp_clause (c_parser_peek_token (parser)->location,
15310 OMP_CLAUSE_UNTIED);
15311 OMP_CLAUSE_CHAIN (c) = list;
15321 c_parser_omp_clause_branch (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]);
15326 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15327 OMP_CLAUSE_CHAIN (c) = list;
15339 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15340 enum omp_clause_code code, tree list)
15342 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15343 OMP_CLAUSE_CHAIN (c) = list;
15352 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15354 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15355 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15356 OMP_CLAUSE_NOGROUP);
15357 OMP_CLAUSE_CHAIN (c) = list;
15366 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15367 enum omp_clause_code code, tree list)
15369 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15370 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15371 OMP_CLAUSE_CHAIN (c) = list;
15376 num_teams ( expression )
15379 num_teams ( expression : expression ) */
15382 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15384 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15385 matching_parens parens;
15386 if (parens.require_open (parser))
15388 location_t upper_loc = c_parser_peek_token (parser)->location;
15389 location_t lower_loc = UNKNOWN_LOCATION;
15390 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15391 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15392 tree c, upper = expr.value, lower = NULL_TREE;
15393 upper = c_fully_fold (upper, false, NULL);
15395 if (c_parser_next_token_is (parser, CPP_COLON))
15397 c_parser_consume_token (parser);
15398 lower_loc = upper_loc;
15400 upper_loc = c_parser_peek_token (parser)->location;
15401 expr = c_parser_expr_no_commas (parser, NULL);
15402 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15403 upper = expr.value;
15404 upper = c_fully_fold (upper, false, NULL);
15407 parens.skip_until_found_close (parser);
15409 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
15410 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
15412 c_parser_error (parser, "expected integer expression");
15416 /* Attempt to statically determine when the number isn't positive. */
15417 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
15418 build_int_cst (TREE_TYPE (upper), 0));
15419 protected_set_expr_location (c, upper_loc);
15420 if (c == boolean_true_node)
15422 warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
15423 upper = integer_one_node;
15427 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
15428 build_int_cst (TREE_TYPE (lower), 0));
15429 protected_set_expr_location (c, lower_loc);
15430 if (c == boolean_true_node)
15432 warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
15435 else if (TREE_CODE (lower) == INTEGER_CST
15436 && TREE_CODE (upper) == INTEGER_CST
15437 && tree_int_cst_lt (upper, lower))
15439 warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
15440 "than upper bound %qE", lower, upper);
15445 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15447 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15448 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
15449 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
15450 OMP_CLAUSE_CHAIN (c) = list;
15458 thread_limit ( expression ) */
15461 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15463 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15464 matching_parens parens;
15465 if (parens.require_open (parser))
15467 location_t expr_loc = c_parser_peek_token (parser)->location;
15468 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15469 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15470 tree c, t = expr.value;
15471 t = c_fully_fold (t, false, NULL);
15473 parens.skip_until_found_close (parser);
15475 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15477 c_parser_error (parser, "expected integer expression");
15481 /* Attempt to statically determine when the number isn't positive. */
15482 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15483 build_int_cst (TREE_TYPE (t), 0));
15484 protected_set_expr_location (c, expr_loc);
15485 if (c == boolean_true_node)
15487 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15488 t = integer_one_node;
15491 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15494 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15495 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15496 OMP_CLAUSE_CHAIN (c) = list;
15504 aligned ( variable-list )
15505 aligned ( variable-list : constant-expression ) */
15508 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15510 location_t clause_loc = c_parser_peek_token (parser)->location;
15513 matching_parens parens;
15514 if (!parens.require_open (parser))
15517 nl = c_parser_omp_variable_list (parser, clause_loc,
15518 OMP_CLAUSE_ALIGNED, list);
15520 if (c_parser_next_token_is (parser, CPP_COLON))
15522 c_parser_consume_token (parser);
15523 location_t expr_loc = c_parser_peek_token (parser)->location;
15524 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15525 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15526 tree alignment = expr.value;
15527 alignment = c_fully_fold (alignment, false, NULL);
15528 if (TREE_CODE (alignment) != INTEGER_CST
15529 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15530 || tree_int_cst_sgn (alignment) != 1)
15532 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15533 "be positive constant integer expression");
15534 alignment = NULL_TREE;
15537 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15538 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15541 parens.skip_until_found_close (parser);
15546 allocate ( variable-list )
15547 allocate ( expression : variable-list )
15550 allocate ( allocator-modifier : variable-list )
15551 allocate ( allocator-modifier , allocator-modifier : variable-list )
15553 allocator-modifier:
15554 allocator ( expression )
15555 align ( expression ) */
15558 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15560 location_t clause_loc = c_parser_peek_token (parser)->location;
15562 tree allocator = NULL_TREE;
15563 tree align = NULL_TREE;
15565 matching_parens parens;
15566 if (!parens.require_open (parser))
15569 if ((c_parser_next_token_is_not (parser, CPP_NAME)
15570 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15571 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15572 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15574 bool has_modifiers = false;
15575 tree orig_type = NULL_TREE;
15576 if (c_parser_next_token_is (parser, CPP_NAME)
15577 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15579 unsigned int n = 3;
15581 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15582 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
15583 && c_parser_check_balanced_raw_token_sequence (parser, &n)
15584 && (c_parser_peek_nth_token_raw (parser, n)->type
15585 == CPP_CLOSE_PAREN))
15587 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15589 has_modifiers = true;
15590 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15592 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
15594 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
15595 == CPP_OPEN_PAREN))
15597 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
15598 const char *q = IDENTIFIER_POINTER (tok->value);
15600 if ((strcmp (q, "allocator") == 0
15601 || strcmp (q, "align") == 0)
15602 && c_parser_check_balanced_raw_token_sequence (parser,
15604 && (c_parser_peek_nth_token_raw (parser, n)->type
15605 == CPP_CLOSE_PAREN)
15606 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15608 has_modifiers = true;
15613 c_parser_consume_token (parser);
15614 matching_parens parens2;;
15615 parens2.require_open (parser);
15616 location_t expr_loc = c_parser_peek_token (parser)->location;
15617 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15618 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15619 if (strcmp (p, "allocator") == 0)
15621 allocator = expr.value;
15622 allocator = c_fully_fold (allocator, false, NULL);
15623 orig_type = expr.original_type
15624 ? expr.original_type : TREE_TYPE (allocator);
15625 orig_type = TYPE_MAIN_VARIANT (orig_type);
15629 align = expr.value;
15630 align = c_fully_fold (align, false, NULL);
15632 parens2.skip_until_found_close (parser);
15633 if (c_parser_next_token_is (parser, CPP_COMMA))
15635 c_parser_consume_token (parser);
15636 c_token *tok = c_parser_peek_token (parser);
15637 const char *q = "";
15638 if (c_parser_next_token_is (parser, CPP_NAME))
15639 q = IDENTIFIER_POINTER (tok->value);
15640 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
15642 c_parser_error (parser, "expected %<allocator%> or "
15644 parens.skip_until_found_close (parser);
15647 else if (strcmp (p, q) == 0)
15649 error_at (tok->location, "duplicate %qs modifier", p);
15650 parens.skip_until_found_close (parser);
15653 c_parser_consume_token (parser);
15654 if (!parens2.require_open (parser))
15656 parens.skip_until_found_close (parser);
15659 expr_loc = c_parser_peek_token (parser)->location;
15660 expr = c_parser_expr_no_commas (parser, NULL);
15661 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15663 if (strcmp (q, "allocator") == 0)
15665 allocator = expr.value;
15666 allocator = c_fully_fold (allocator, false, NULL);
15667 orig_type = expr.original_type
15668 ? expr.original_type : TREE_TYPE (allocator);
15669 orig_type = TYPE_MAIN_VARIANT (orig_type);
15673 align = expr.value;
15674 align = c_fully_fold (align, false, NULL);
15676 parens2.skip_until_found_close (parser);
15680 if (!has_modifiers)
15682 location_t expr_loc = c_parser_peek_token (parser)->location;
15683 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15684 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15685 allocator = expr.value;
15686 allocator = c_fully_fold (allocator, false, NULL);
15687 orig_type = expr.original_type
15688 ? expr.original_type : TREE_TYPE (allocator);
15689 orig_type = TYPE_MAIN_VARIANT (orig_type);
15692 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15693 || TREE_CODE (orig_type) != ENUMERAL_TYPE
15694 || (TYPE_NAME (orig_type)
15695 != get_identifier ("omp_allocator_handle_t"))))
15697 error_at (clause_loc, "%<allocate%> clause allocator expression "
15698 "has type %qT rather than "
15699 "%<omp_allocator_handle_t%>",
15700 TREE_TYPE (allocator));
15701 allocator = NULL_TREE;
15704 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
15705 || !tree_fits_uhwi_p (align)
15706 || !integer_pow2p (align)))
15708 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
15709 "argument needs to be positive constant "
15710 "power of two integer expression");
15713 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15715 parens.skip_until_found_close (parser);
15720 nl = c_parser_omp_variable_list (parser, clause_loc,
15721 OMP_CLAUSE_ALLOCATE, list);
15723 if (allocator || align)
15724 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15726 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15727 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
15730 parens.skip_until_found_close (parser);
15735 linear ( variable-list )
15736 linear ( variable-list : expression )
15739 linear ( modifier ( variable-list ) )
15740 linear ( modifier ( variable-list ) : expression )
15746 linear ( variable-list : modifiers-list )
15750 step ( expression ) */
15753 c_parser_omp_clause_linear (c_parser *parser, tree list)
15755 location_t clause_loc = c_parser_peek_token (parser)->location;
15757 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15758 bool old_linear_modifier = false;
15760 matching_parens parens;
15761 if (!parens.require_open (parser))
15764 if (c_parser_next_token_is (parser, CPP_NAME))
15766 c_token *tok = c_parser_peek_token (parser);
15767 const char *p = IDENTIFIER_POINTER (tok->value);
15768 if (strcmp ("val", p) == 0)
15769 kind = OMP_CLAUSE_LINEAR_VAL;
15770 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15771 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15772 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15774 old_linear_modifier = true;
15775 c_parser_consume_token (parser);
15776 c_parser_consume_token (parser);
15780 nl = c_parser_omp_variable_list (parser, clause_loc,
15781 OMP_CLAUSE_LINEAR, list);
15783 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15784 parens.skip_until_found_close (parser);
15786 if (c_parser_next_token_is (parser, CPP_COLON))
15788 c_parser_consume_token (parser);
15789 location_t expr_loc = c_parser_peek_token (parser)->location;
15790 bool has_modifiers = false;
15791 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
15792 && c_parser_next_token_is (parser, CPP_NAME))
15794 c_token *tok = c_parser_peek_token (parser);
15795 const char *p = IDENTIFIER_POINTER (tok->value);
15796 unsigned int pos = 0;
15797 if (strcmp ("val", p) == 0)
15799 else if (strcmp ("step", p) == 0
15800 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15803 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
15804 && (c_parser_peek_nth_token_raw (parser, pos)->type
15805 == CPP_CLOSE_PAREN))
15812 tok = c_parser_peek_nth_token_raw (parser, pos);
15813 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
15814 has_modifiers = true;
15820 while (c_parser_next_token_is (parser, CPP_NAME))
15822 c_token *tok = c_parser_peek_token (parser);
15823 const char *p = IDENTIFIER_POINTER (tok->value);
15824 if (strcmp ("val", p) == 0)
15826 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15827 error_at (tok->location, "multiple linear modifiers");
15828 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15829 c_parser_consume_token (parser);
15831 else if (strcmp ("step", p) == 0)
15833 c_parser_consume_token (parser);
15834 matching_parens parens2;
15835 if (parens2.require_open (parser))
15838 error_at (tok->location,
15839 "multiple %<step%> modifiers");
15840 expr_loc = c_parser_peek_token (parser)->location;
15841 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15842 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15844 step = c_fully_fold (expr.value, false, NULL);
15845 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15847 error_at (clause_loc, "%<linear%> clause step "
15848 "expression must be integral");
15849 step = integer_one_node;
15851 parens2.skip_until_found_close (parser);
15858 if (c_parser_next_token_is (parser, CPP_COMMA))
15860 c_parser_consume_token (parser);
15866 step = integer_one_node;
15870 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15871 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15872 step = c_fully_fold (expr.value, false, NULL);
15873 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15875 error_at (clause_loc, "%<linear%> clause step expression must "
15877 step = integer_one_node;
15883 step = integer_one_node;
15885 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15887 OMP_CLAUSE_LINEAR_STEP (c) = step;
15888 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15889 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
15892 parens.skip_until_found_close (parser);
15897 nontemporal ( variable-list ) */
15900 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15902 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15906 safelen ( constant-expression ) */
15909 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15911 location_t clause_loc = c_parser_peek_token (parser)->location;
15914 matching_parens parens;
15915 if (!parens.require_open (parser))
15918 location_t expr_loc = c_parser_peek_token (parser)->location;
15919 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15920 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15922 t = c_fully_fold (t, false, NULL);
15923 if (TREE_CODE (t) != INTEGER_CST
15924 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15925 || tree_int_cst_sgn (t) != 1)
15927 error_at (clause_loc, "%<safelen%> clause expression must "
15928 "be positive constant integer expression");
15932 parens.skip_until_found_close (parser);
15933 if (t == NULL_TREE || t == error_mark_node)
15936 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15938 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15939 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15940 OMP_CLAUSE_CHAIN (c) = list;
15945 simdlen ( constant-expression ) */
15948 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15950 location_t clause_loc = c_parser_peek_token (parser)->location;
15953 matching_parens parens;
15954 if (!parens.require_open (parser))
15957 location_t expr_loc = c_parser_peek_token (parser)->location;
15958 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15959 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15961 t = c_fully_fold (t, false, NULL);
15962 if (TREE_CODE (t) != INTEGER_CST
15963 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15964 || tree_int_cst_sgn (t) != 1)
15966 error_at (clause_loc, "%<simdlen%> clause expression must "
15967 "be positive constant integer expression");
15971 parens.skip_until_found_close (parser);
15972 if (t == NULL_TREE || t == error_mark_node)
15975 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15977 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15978 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15979 OMP_CLAUSE_CHAIN (c) = list;
15985 identifier [+/- integer]
15986 vec , identifier [+/- integer]
15990 c_parser_omp_clause_doacross_sink (c_parser *parser, location_t clause_loc,
15991 tree list, bool depend_p)
15994 if (c_parser_next_token_is_not (parser, CPP_NAME)
15995 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15997 c_parser_error (parser, "expected identifier");
16003 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16004 if (strcmp (p, "omp_cur_iteration") == 0
16005 && c_parser_peek_2nd_token (parser)->type == CPP_MINUS
16006 && c_parser_peek_nth_token (parser, 3)->type == CPP_NUMBER
16007 && c_parser_peek_nth_token (parser, 4)->type == CPP_CLOSE_PAREN)
16009 tree val = c_parser_peek_nth_token (parser, 3)->value;
16010 if (integer_onep (val))
16012 c_parser_consume_token (parser);
16013 c_parser_consume_token (parser);
16014 c_parser_consume_token (parser);
16015 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16016 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
16017 OMP_CLAUSE_CHAIN (u) = list;
16025 while (c_parser_next_token_is (parser, CPP_NAME)
16026 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
16028 tree t = lookup_name (c_parser_peek_token (parser)->value);
16029 tree addend = NULL;
16031 if (t == NULL_TREE)
16033 undeclared_variable (c_parser_peek_token (parser)->location,
16034 c_parser_peek_token (parser)->value);
16035 t = error_mark_node;
16038 c_parser_consume_token (parser);
16041 if (c_parser_next_token_is (parser, CPP_MINUS))
16043 else if (!c_parser_next_token_is (parser, CPP_PLUS))
16045 addend = integer_zero_node;
16047 goto add_to_vector;
16049 c_parser_consume_token (parser);
16051 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
16053 c_parser_error (parser, "expected integer");
16057 addend = c_parser_peek_token (parser)->value;
16058 if (TREE_CODE (addend) != INTEGER_CST)
16060 c_parser_error (parser, "expected integer");
16063 c_parser_consume_token (parser);
16066 if (t != error_mark_node)
16068 vec = tree_cons (addend, t, vec);
16070 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
16073 if (c_parser_next_token_is_not (parser, CPP_COMMA)
16074 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
16075 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
16078 c_parser_consume_token (parser);
16081 if (vec == NULL_TREE)
16084 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16085 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
16086 OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
16087 OMP_CLAUSE_DECL (u) = nreverse (vec);
16088 OMP_CLAUSE_CHAIN (u) = list;
16093 iterators ( iterators-definition )
16095 iterators-definition:
16097 iterator-specifier , iterators-definition
16099 iterator-specifier:
16100 identifier = range-specification
16101 iterator-type identifier = range-specification
16103 range-specification:
16105 begin : end : step */
16108 c_parser_omp_iterators (c_parser *parser)
16110 tree ret = NULL_TREE, *last = &ret;
16111 c_parser_consume_token (parser);
16115 matching_parens parens;
16116 if (!parens.require_open (parser))
16117 return error_mark_node;
16121 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
16122 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
16124 struct c_type_name *type = c_parser_type_name (parser);
16126 iter_type = groktypename (type, &type_expr, NULL);
16128 if (iter_type == NULL_TREE)
16129 iter_type = integer_type_node;
16131 location_t loc = c_parser_peek_token (parser)->location;
16132 if (!c_parser_next_token_is (parser, CPP_NAME))
16134 c_parser_error (parser, "expected identifier");
16138 tree id = c_parser_peek_token (parser)->value;
16139 c_parser_consume_token (parser);
16141 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16144 location_t eloc = c_parser_peek_token (parser)->location;
16145 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16146 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16147 tree begin = expr.value;
16149 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16152 eloc = c_parser_peek_token (parser)->location;
16153 expr = c_parser_expr_no_commas (parser, NULL);
16154 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16155 tree end = expr.value;
16157 tree step = integer_one_node;
16158 if (c_parser_next_token_is (parser, CPP_COLON))
16160 c_parser_consume_token (parser);
16161 eloc = c_parser_peek_token (parser)->location;
16162 expr = c_parser_expr_no_commas (parser, NULL);
16163 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16167 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
16168 DECL_ARTIFICIAL (iter_var) = 1;
16169 DECL_CONTEXT (iter_var) = current_function_decl;
16170 pushdecl (iter_var);
16172 *last = make_tree_vec (6);
16173 TREE_VEC_ELT (*last, 0) = iter_var;
16174 TREE_VEC_ELT (*last, 1) = begin;
16175 TREE_VEC_ELT (*last, 2) = end;
16176 TREE_VEC_ELT (*last, 3) = step;
16177 last = &TREE_CHAIN (*last);
16179 if (c_parser_next_token_is (parser, CPP_COMMA))
16181 c_parser_consume_token (parser);
16188 parens.skip_until_found_close (parser);
16189 return ret ? ret : error_mark_node;
16193 affinity ( [aff-modifier :] variable-list )
16195 iterator ( iterators-definition ) */
16198 c_parser_omp_clause_affinity (c_parser *parser, tree list)
16200 location_t clause_loc = c_parser_peek_token (parser)->location;
16201 tree nl, iterators = NULL_TREE;
16203 matching_parens parens;
16204 if (!parens.require_open (parser))
16207 if (c_parser_next_token_is (parser, CPP_NAME))
16209 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16210 bool parse_iter = ((strcmp ("iterator", p) == 0)
16211 && (c_parser_peek_2nd_token (parser)->type
16212 == CPP_OPEN_PAREN));
16216 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
16217 && (c_parser_peek_nth_token_raw (parser, n)->type
16218 == CPP_CLOSE_PAREN)
16219 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
16224 iterators = c_parser_omp_iterators (parser);
16225 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16229 parens.skip_until_found_close (parser);
16234 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16238 tree block = pop_scope ();
16239 if (iterators != error_mark_node)
16241 TREE_VEC_ELT (iterators, 5) = block;
16242 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16243 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16244 OMP_CLAUSE_DECL (c));
16248 parens.skip_until_found_close (parser);
16254 depend ( depend-kind: variable-list )
16262 depend ( sink : vec )
16265 depend ( depend-modifier , depend-kind: variable-list )
16268 in | out | inout | mutexinoutset | depobj | inoutset
16271 iterator ( iterators-definition ) */
16274 c_parser_omp_clause_depend (c_parser *parser, tree list)
16276 location_t clause_loc = c_parser_peek_token (parser)->location;
16277 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16278 enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
16279 tree nl, c, iterators = NULL_TREE;
16281 matching_parens parens;
16282 if (!parens.require_open (parser))
16287 if (c_parser_next_token_is_not (parser, CPP_NAME))
16290 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16291 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16293 iterators = c_parser_omp_iterators (parser);
16294 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16297 if (strcmp ("in", p) == 0)
16298 kind = OMP_CLAUSE_DEPEND_IN;
16299 else if (strcmp ("inout", p) == 0)
16300 kind = OMP_CLAUSE_DEPEND_INOUT;
16301 else if (strcmp ("inoutset", p) == 0)
16302 kind = OMP_CLAUSE_DEPEND_INOUTSET;
16303 else if (strcmp ("mutexinoutset", p) == 0)
16304 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16305 else if (strcmp ("out", p) == 0)
16306 kind = OMP_CLAUSE_DEPEND_OUT;
16307 else if (strcmp ("depobj", p) == 0)
16308 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16309 else if (strcmp ("sink", p) == 0)
16310 dkind = OMP_CLAUSE_DOACROSS_SINK;
16311 else if (strcmp ("source", p) == 0)
16312 dkind = OMP_CLAUSE_DOACROSS_SOURCE;
16319 c_parser_consume_token (parser);
16322 && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
16323 || dkind == OMP_CLAUSE_DOACROSS_SINK))
16326 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16327 dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
16328 iterators = NULL_TREE;
16331 if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
16333 c = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16334 OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
16335 OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
16336 OMP_CLAUSE_DECL (c) = NULL_TREE;
16337 OMP_CLAUSE_CHAIN (c) = list;
16338 parens.skip_until_found_close (parser);
16342 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16345 if (dkind == OMP_CLAUSE_DOACROSS_SINK)
16346 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, true);
16349 nl = c_parser_omp_variable_list (parser, clause_loc,
16350 OMP_CLAUSE_DEPEND, list);
16354 tree block = pop_scope ();
16355 if (iterators == error_mark_node)
16356 iterators = NULL_TREE;
16358 TREE_VEC_ELT (iterators, 5) = block;
16361 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16363 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16365 OMP_CLAUSE_DECL (c)
16366 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16370 parens.skip_until_found_close (parser);
16374 c_parser_error (parser, "invalid depend kind");
16376 parens.skip_until_found_close (parser);
16383 doacross ( source : )
16384 doacross ( source : omp_cur_iteration )
16386 doacross ( sink : vec )
16387 doacross ( sink : omp_cur_iteration - logical_iteration ) */
16390 c_parser_omp_clause_doacross (c_parser *parser, tree list)
16392 location_t clause_loc = c_parser_peek_token (parser)->location;
16393 enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
16397 matching_parens parens;
16398 if (!parens.require_open (parser))
16401 if (c_parser_next_token_is_not (parser, CPP_NAME))
16404 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16405 if (strcmp ("sink", p) == 0)
16406 kind = OMP_CLAUSE_DOACROSS_SINK;
16407 else if (strcmp ("source", p) == 0)
16408 kind = OMP_CLAUSE_DOACROSS_SOURCE;
16412 c_parser_consume_token (parser);
16414 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16417 if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
16419 if (c_parser_next_token_is (parser, CPP_NAME)
16420 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16421 "omp_cur_iteration") == 0)
16422 c_parser_consume_token (parser);
16423 nl = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16424 OMP_CLAUSE_DOACROSS_KIND (nl) = OMP_CLAUSE_DOACROSS_SOURCE;
16425 OMP_CLAUSE_DECL (nl) = NULL_TREE;
16426 OMP_CLAUSE_CHAIN (nl) = list;
16429 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, false);
16431 parens.skip_until_found_close (parser);
16435 c_parser_error (parser, "invalid doacross kind");
16437 parens.skip_until_found_close (parser);
16442 map ( map-kind: variable-list )
16443 map ( variable-list )
16446 alloc | to | from | tofrom
16450 alloc | to | from | tofrom | release | delete
16452 map ( always [,] map-kind: variable-list )
16455 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16461 c_parser_omp_clause_map (c_parser *parser, tree list)
16463 location_t clause_loc = c_parser_peek_token (parser)->location;
16464 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
16467 matching_parens parens;
16468 if (!parens.require_open (parser))
16472 int map_kind_pos = 0;
16473 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
16475 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
16477 map_kind_pos = pos;
16481 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
16486 int always_modifier = 0;
16487 int close_modifier = 0;
16488 for (int pos = 1; pos < map_kind_pos; ++pos)
16490 c_token *tok = c_parser_peek_token (parser);
16492 if (tok->type == CPP_COMMA)
16494 c_parser_consume_token (parser);
16498 const char *p = IDENTIFIER_POINTER (tok->value);
16499 if (strcmp ("always", p) == 0)
16501 if (always_modifier)
16503 c_parser_error (parser, "too many %<always%> modifiers");
16504 parens.skip_until_found_close (parser);
16509 else if (strcmp ("close", p) == 0)
16511 if (close_modifier)
16513 c_parser_error (parser, "too many %<close%> modifiers");
16514 parens.skip_until_found_close (parser);
16521 c_parser_error (parser, "%<#pragma omp target%> with "
16522 "modifier other than %<always%> or "
16523 "%<close%> on %<map%> clause");
16524 parens.skip_until_found_close (parser);
16528 c_parser_consume_token (parser);
16531 if (c_parser_next_token_is (parser, CPP_NAME)
16532 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16534 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16535 if (strcmp ("alloc", p) == 0)
16536 kind = GOMP_MAP_ALLOC;
16537 else if (strcmp ("to", p) == 0)
16538 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
16539 else if (strcmp ("from", p) == 0)
16540 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
16541 else if (strcmp ("tofrom", p) == 0)
16542 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
16543 else if (strcmp ("release", p) == 0)
16544 kind = GOMP_MAP_RELEASE;
16545 else if (strcmp ("delete", p) == 0)
16546 kind = GOMP_MAP_DELETE;
16549 c_parser_error (parser, "invalid map kind");
16550 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16554 c_parser_consume_token (parser);
16555 c_parser_consume_token (parser);
16558 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
16561 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16562 OMP_CLAUSE_SET_MAP_KIND (c, kind);
16564 parens.skip_until_found_close (parser);
16569 device ( expression )
16572 device ( [device-modifier :] integer-expression )
16575 ancestor | device_num */
16578 c_parser_omp_clause_device (c_parser *parser, tree list)
16580 location_t clause_loc = c_parser_peek_token (parser)->location;
16581 location_t expr_loc;
16584 bool ancestor = false;
16586 matching_parens parens;
16587 if (!parens.require_open (parser))
16590 if (c_parser_next_token_is (parser, CPP_NAME)
16591 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16593 c_token *tok = c_parser_peek_token (parser);
16594 const char *p = IDENTIFIER_POINTER (tok->value);
16595 if (strcmp ("ancestor", p) == 0)
16597 /* A requires directive with the reverse_offload clause must be
16599 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
16601 error_at (tok->location, "%<ancestor%> device modifier not "
16602 "preceded by %<requires%> directive "
16603 "with %<reverse_offload%> clause");
16604 parens.skip_until_found_close (parser);
16609 else if (strcmp ("device_num", p) == 0)
16613 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
16614 parens.skip_until_found_close (parser);
16617 c_parser_consume_token (parser);
16618 c_parser_consume_token (parser);
16621 expr_loc = c_parser_peek_token (parser)->location;
16622 expr = c_parser_expr_no_commas (parser, NULL);
16623 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16625 t = c_fully_fold (t, false, NULL);
16627 parens.skip_until_found_close (parser);
16629 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16631 c_parser_error (parser, "expected integer expression");
16634 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
16636 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
16641 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
16643 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
16645 OMP_CLAUSE_DEVICE_ID (c) = t;
16646 OMP_CLAUSE_CHAIN (c) = list;
16647 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
16654 dist_schedule ( static )
16655 dist_schedule ( static , expression ) */
16658 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
16660 tree c, t = NULL_TREE;
16661 location_t loc = c_parser_peek_token (parser)->location;
16663 matching_parens parens;
16664 if (!parens.require_open (parser))
16667 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
16669 c_parser_error (parser, "invalid dist_schedule kind");
16670 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16675 c_parser_consume_token (parser);
16676 if (c_parser_next_token_is (parser, CPP_COMMA))
16678 c_parser_consume_token (parser);
16680 location_t expr_loc = c_parser_peek_token (parser)->location;
16681 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16682 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16684 t = c_fully_fold (t, false, NULL);
16685 parens.skip_until_found_close (parser);
16688 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16689 "expected %<,%> or %<)%>");
16691 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16692 "dist_schedule"); */
16693 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
16694 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
16695 if (t == error_mark_node)
16698 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
16699 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
16700 OMP_CLAUSE_CHAIN (c) = list;
16705 proc_bind ( proc-bind-kind )
16708 primary | master | close | spread
16709 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16712 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16714 location_t clause_loc = c_parser_peek_token (parser)->location;
16715 enum omp_clause_proc_bind_kind kind;
16718 matching_parens parens;
16719 if (!parens.require_open (parser))
16722 if (c_parser_next_token_is (parser, CPP_NAME))
16724 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16725 if (strcmp ("primary", p) == 0)
16726 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16727 else if (strcmp ("master", p) == 0)
16728 kind = OMP_CLAUSE_PROC_BIND_MASTER;
16729 else if (strcmp ("close", p) == 0)
16730 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16731 else if (strcmp ("spread", p) == 0)
16732 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16739 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16740 c_parser_consume_token (parser);
16741 parens.skip_until_found_close (parser);
16742 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16743 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16744 OMP_CLAUSE_CHAIN (c) = list;
16748 c_parser_error (parser, "invalid proc_bind kind");
16749 parens.skip_until_found_close (parser);
16754 device_type ( host | nohost | any ) */
16757 c_parser_omp_clause_device_type (c_parser *parser, tree list)
16759 location_t clause_loc = c_parser_peek_token (parser)->location;
16760 enum omp_clause_device_type_kind kind;
16763 matching_parens parens;
16764 if (!parens.require_open (parser))
16767 if (c_parser_next_token_is (parser, CPP_NAME))
16769 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16770 if (strcmp ("host", p) == 0)
16771 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
16772 else if (strcmp ("nohost", p) == 0)
16773 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
16774 else if (strcmp ("any", p) == 0)
16775 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
16782 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16784 c_parser_consume_token (parser);
16785 parens.skip_until_found_close (parser);
16786 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
16787 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
16788 OMP_CLAUSE_CHAIN (c) = list;
16792 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
16793 parens.skip_until_found_close (parser);
16798 to ( variable-list ) */
16801 c_parser_omp_clause_to (c_parser *parser, tree list)
16803 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
16807 from ( variable-list ) */
16810 c_parser_omp_clause_from (c_parser *parser, tree list)
16812 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
16816 uniform ( variable-list ) */
16819 c_parser_omp_clause_uniform (c_parser *parser, tree list)
16821 /* The clauses location. */
16822 location_t loc = c_parser_peek_token (parser)->location;
16824 matching_parens parens;
16825 if (parens.require_open (parser))
16827 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
16829 parens.skip_until_found_close (parser);
16835 detach ( event-handle ) */
16838 c_parser_omp_clause_detach (c_parser *parser, tree list)
16840 matching_parens parens;
16841 location_t clause_loc = c_parser_peek_token (parser)->location;
16843 if (!parens.require_open (parser))
16846 if (c_parser_next_token_is_not (parser, CPP_NAME)
16847 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16849 c_parser_error (parser, "expected identifier");
16850 parens.skip_until_found_close (parser);
16854 tree t = lookup_name (c_parser_peek_token (parser)->value);
16855 if (t == NULL_TREE)
16857 undeclared_variable (c_parser_peek_token (parser)->location,
16858 c_parser_peek_token (parser)->value);
16859 parens.skip_until_found_close (parser);
16862 c_parser_consume_token (parser);
16864 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16865 if (!INTEGRAL_TYPE_P (type)
16866 || TREE_CODE (type) != ENUMERAL_TYPE
16867 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16869 error_at (clause_loc, "%<detach%> clause event handle "
16870 "has type %qT rather than "
16871 "%<omp_event_handle_t%>",
16873 parens.skip_until_found_close (parser);
16877 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16878 OMP_CLAUSE_DECL (u) = t;
16879 OMP_CLAUSE_CHAIN (u) = list;
16880 parens.skip_until_found_close (parser);
16884 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16885 is a bitmask in MASK. Return the list of clauses found. */
16888 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16889 const char *where, bool finish_p = true)
16891 tree clauses = NULL;
16894 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16897 pragma_omp_clause c_kind;
16898 const char *c_name;
16899 tree prev = clauses;
16901 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16902 c_parser_consume_token (parser);
16904 here = c_parser_peek_token (parser)->location;
16905 c_kind = c_parser_omp_clause_name (parser);
16909 case PRAGMA_OACC_CLAUSE_ASYNC:
16910 clauses = c_parser_oacc_clause_async (parser, clauses);
16913 case PRAGMA_OACC_CLAUSE_AUTO:
16914 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16918 case PRAGMA_OACC_CLAUSE_ATTACH:
16919 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16922 case PRAGMA_OACC_CLAUSE_COLLAPSE:
16923 clauses = c_parser_omp_clause_collapse (parser, clauses);
16924 c_name = "collapse";
16926 case PRAGMA_OACC_CLAUSE_COPY:
16927 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16930 case PRAGMA_OACC_CLAUSE_COPYIN:
16931 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16934 case PRAGMA_OACC_CLAUSE_COPYOUT:
16935 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16936 c_name = "copyout";
16938 case PRAGMA_OACC_CLAUSE_CREATE:
16939 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16942 case PRAGMA_OACC_CLAUSE_DELETE:
16943 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16946 case PRAGMA_OMP_CLAUSE_DEFAULT:
16947 clauses = c_parser_omp_clause_default (parser, clauses, true);
16948 c_name = "default";
16950 case PRAGMA_OACC_CLAUSE_DETACH:
16951 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16954 case PRAGMA_OACC_CLAUSE_DEVICE:
16955 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16958 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16959 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16960 c_name = "deviceptr";
16962 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16963 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16964 c_name = "device_resident";
16966 case PRAGMA_OACC_CLAUSE_FINALIZE:
16967 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16969 c_name = "finalize";
16971 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16972 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16973 c_name = "firstprivate";
16975 case PRAGMA_OACC_CLAUSE_GANG:
16977 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16980 case PRAGMA_OACC_CLAUSE_HOST:
16981 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16984 case PRAGMA_OACC_CLAUSE_IF:
16985 clauses = c_parser_omp_clause_if (parser, clauses, false);
16988 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16989 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16991 c_name = "if_present";
16993 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16994 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16996 c_name = "independent";
16998 case PRAGMA_OACC_CLAUSE_LINK:
16999 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17002 case PRAGMA_OACC_CLAUSE_NO_CREATE:
17003 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17004 c_name = "no_create";
17006 case PRAGMA_OACC_CLAUSE_NOHOST:
17007 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
17011 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
17012 clauses = c_parser_oacc_single_int_clause (parser,
17013 OMP_CLAUSE_NUM_GANGS,
17015 c_name = "num_gangs";
17017 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
17018 clauses = c_parser_oacc_single_int_clause (parser,
17019 OMP_CLAUSE_NUM_WORKERS,
17021 c_name = "num_workers";
17023 case PRAGMA_OACC_CLAUSE_PRESENT:
17024 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17025 c_name = "present";
17027 case PRAGMA_OACC_CLAUSE_PRIVATE:
17028 clauses = c_parser_omp_clause_private (parser, clauses);
17029 c_name = "private";
17031 case PRAGMA_OACC_CLAUSE_REDUCTION:
17033 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17035 c_name = "reduction";
17037 case PRAGMA_OACC_CLAUSE_SEQ:
17038 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
17042 case PRAGMA_OACC_CLAUSE_TILE:
17043 clauses = c_parser_oacc_clause_tile (parser, clauses);
17046 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
17047 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17048 c_name = "use_device";
17050 case PRAGMA_OACC_CLAUSE_VECTOR:
17052 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
17055 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
17056 clauses = c_parser_oacc_single_int_clause (parser,
17057 OMP_CLAUSE_VECTOR_LENGTH,
17059 c_name = "vector_length";
17061 case PRAGMA_OACC_CLAUSE_WAIT:
17062 clauses = c_parser_oacc_clause_wait (parser, clauses);
17065 case PRAGMA_OACC_CLAUSE_WORKER:
17067 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
17071 c_parser_error (parser, "expected %<#pragma acc%> clause");
17077 if (((mask >> c_kind) & 1) == 0)
17079 /* Remove the invalid clause(s) from the list to avoid
17080 confusing the rest of the compiler. */
17082 error_at (here, "%qs is not valid for %qs", c_name, where);
17087 c_parser_skip_to_pragma_eol (parser);
17090 return c_finish_omp_clauses (clauses, C_ORT_ACC);
17095 /* Parse all OpenMP clauses. The set clauses allowed by the directive
17096 is a bitmask in MASK. Return the list of clauses found.
17097 FINISH_P set if c_finish_omp_clauses should be called.
17098 NESTED non-zero if clauses should be terminated by closing paren instead
17099 of end of pragma. If it is 2, additionally commas are required in between
17103 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
17104 const char *where, bool finish_p = true,
17107 tree clauses = NULL;
17110 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17113 pragma_omp_clause c_kind;
17114 const char *c_name;
17115 tree prev = clauses;
17117 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
17122 if (c_parser_next_token_is (parser, CPP_COMMA))
17123 c_parser_consume_token (parser);
17124 else if (nested == 2)
17125 error_at (c_parser_peek_token (parser)->location,
17126 "clauses in %<simd%> trait should be separated "
17130 here = c_parser_peek_token (parser)->location;
17131 c_kind = c_parser_omp_clause_name (parser);
17135 case PRAGMA_OMP_CLAUSE_BIND:
17136 clauses = c_parser_omp_clause_bind (parser, clauses);
17139 case PRAGMA_OMP_CLAUSE_COLLAPSE:
17140 clauses = c_parser_omp_clause_collapse (parser, clauses);
17141 c_name = "collapse";
17143 case PRAGMA_OMP_CLAUSE_COPYIN:
17144 clauses = c_parser_omp_clause_copyin (parser, clauses);
17147 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
17148 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
17149 c_name = "copyprivate";
17151 case PRAGMA_OMP_CLAUSE_DEFAULT:
17152 clauses = c_parser_omp_clause_default (parser, clauses, false);
17153 c_name = "default";
17155 case PRAGMA_OMP_CLAUSE_DETACH:
17156 clauses = c_parser_omp_clause_detach (parser, clauses);
17159 case PRAGMA_OMP_CLAUSE_FILTER:
17160 clauses = c_parser_omp_clause_filter (parser, clauses);
17163 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
17164 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
17165 c_name = "firstprivate";
17167 case PRAGMA_OMP_CLAUSE_FINAL:
17168 clauses = c_parser_omp_clause_final (parser, clauses);
17171 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
17172 clauses = c_parser_omp_clause_grainsize (parser, clauses);
17173 c_name = "grainsize";
17175 case PRAGMA_OMP_CLAUSE_HINT:
17176 clauses = c_parser_omp_clause_hint (parser, clauses);
17179 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
17180 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
17181 c_name = "defaultmap";
17183 case PRAGMA_OMP_CLAUSE_IF:
17184 clauses = c_parser_omp_clause_if (parser, clauses, true);
17187 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
17189 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
17191 c_name = "in_reduction";
17193 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
17194 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
17195 c_name = "lastprivate";
17197 case PRAGMA_OMP_CLAUSE_MERGEABLE:
17198 clauses = c_parser_omp_clause_mergeable (parser, clauses);
17199 c_name = "mergeable";
17201 case PRAGMA_OMP_CLAUSE_NOWAIT:
17202 clauses = c_parser_omp_clause_nowait (parser, clauses);
17205 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
17206 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
17207 c_name = "num_tasks";
17209 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
17210 clauses = c_parser_omp_clause_num_threads (parser, clauses);
17211 c_name = "num_threads";
17213 case PRAGMA_OMP_CLAUSE_ORDER:
17214 clauses = c_parser_omp_clause_order (parser, clauses);
17217 case PRAGMA_OMP_CLAUSE_ORDERED:
17218 clauses = c_parser_omp_clause_ordered (parser, clauses);
17219 c_name = "ordered";
17221 case PRAGMA_OMP_CLAUSE_PRIORITY:
17222 clauses = c_parser_omp_clause_priority (parser, clauses);
17223 c_name = "priority";
17225 case PRAGMA_OMP_CLAUSE_PRIVATE:
17226 clauses = c_parser_omp_clause_private (parser, clauses);
17227 c_name = "private";
17229 case PRAGMA_OMP_CLAUSE_REDUCTION:
17231 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17233 c_name = "reduction";
17235 case PRAGMA_OMP_CLAUSE_SCHEDULE:
17236 clauses = c_parser_omp_clause_schedule (parser, clauses);
17237 c_name = "schedule";
17239 case PRAGMA_OMP_CLAUSE_SHARED:
17240 clauses = c_parser_omp_clause_shared (parser, clauses);
17243 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
17245 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
17247 c_name = "task_reduction";
17249 case PRAGMA_OMP_CLAUSE_UNTIED:
17250 clauses = c_parser_omp_clause_untied (parser, clauses);
17253 case PRAGMA_OMP_CLAUSE_INBRANCH:
17254 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
17256 c_name = "inbranch";
17258 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
17259 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
17260 c_name = "nontemporal";
17262 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
17263 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
17265 c_name = "notinbranch";
17267 case PRAGMA_OMP_CLAUSE_PARALLEL:
17269 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
17271 c_name = "parallel";
17275 error_at (here, "%qs must be the first clause of %qs",
17280 case PRAGMA_OMP_CLAUSE_FOR:
17282 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
17286 goto clause_not_first;
17288 case PRAGMA_OMP_CLAUSE_SECTIONS:
17290 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17292 c_name = "sections";
17294 goto clause_not_first;
17296 case PRAGMA_OMP_CLAUSE_TASKGROUP:
17298 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17300 c_name = "taskgroup";
17302 goto clause_not_first;
17304 case PRAGMA_OMP_CLAUSE_LINK:
17306 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17309 case PRAGMA_OMP_CLAUSE_TO:
17310 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17312 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17314 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
17315 OMP_CLAUSE_ENTER_TO (c) = 1;
17319 clauses = c_parser_omp_clause_to (parser, clauses);
17322 case PRAGMA_OMP_CLAUSE_FROM:
17323 clauses = c_parser_omp_clause_from (parser, clauses);
17326 case PRAGMA_OMP_CLAUSE_UNIFORM:
17327 clauses = c_parser_omp_clause_uniform (parser, clauses);
17328 c_name = "uniform";
17330 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17331 clauses = c_parser_omp_clause_num_teams (parser, clauses);
17332 c_name = "num_teams";
17334 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17335 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17336 c_name = "thread_limit";
17338 case PRAGMA_OMP_CLAUSE_ALIGNED:
17339 clauses = c_parser_omp_clause_aligned (parser, clauses);
17340 c_name = "aligned";
17342 case PRAGMA_OMP_CLAUSE_ALLOCATE:
17343 clauses = c_parser_omp_clause_allocate (parser, clauses);
17344 c_name = "allocate";
17346 case PRAGMA_OMP_CLAUSE_LINEAR:
17347 clauses = c_parser_omp_clause_linear (parser, clauses);
17350 case PRAGMA_OMP_CLAUSE_AFFINITY:
17351 clauses = c_parser_omp_clause_affinity (parser, clauses);
17352 c_name = "affinity";
17354 case PRAGMA_OMP_CLAUSE_DEPEND:
17355 clauses = c_parser_omp_clause_depend (parser, clauses);
17358 case PRAGMA_OMP_CLAUSE_DOACROSS:
17359 clauses = c_parser_omp_clause_doacross (parser, clauses);
17360 c_name = "doacross";
17362 case PRAGMA_OMP_CLAUSE_MAP:
17363 clauses = c_parser_omp_clause_map (parser, clauses);
17366 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17367 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17368 c_name = "use_device_ptr";
17370 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17371 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17372 c_name = "use_device_addr";
17374 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17375 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17376 c_name = "has_device_addr";
17378 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17379 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17380 c_name = "is_device_ptr";
17382 case PRAGMA_OMP_CLAUSE_DEVICE:
17383 clauses = c_parser_omp_clause_device (parser, clauses);
17386 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
17387 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
17388 c_name = "dist_schedule";
17390 case PRAGMA_OMP_CLAUSE_PROC_BIND:
17391 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
17392 c_name = "proc_bind";
17394 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
17395 clauses = c_parser_omp_clause_device_type (parser, clauses);
17396 c_name = "device_type";
17398 case PRAGMA_OMP_CLAUSE_SAFELEN:
17399 clauses = c_parser_omp_clause_safelen (parser, clauses);
17400 c_name = "safelen";
17402 case PRAGMA_OMP_CLAUSE_SIMDLEN:
17403 clauses = c_parser_omp_clause_simdlen (parser, clauses);
17404 c_name = "simdlen";
17406 case PRAGMA_OMP_CLAUSE_NOGROUP:
17407 clauses = c_parser_omp_clause_nogroup (parser, clauses);
17408 c_name = "nogroup";
17410 case PRAGMA_OMP_CLAUSE_THREADS:
17412 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
17414 c_name = "threads";
17416 case PRAGMA_OMP_CLAUSE_SIMD:
17418 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
17422 case PRAGMA_OMP_CLAUSE_ENTER:
17424 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17429 c_parser_error (parser, "expected %<#pragma omp%> clause");
17435 if (((mask >> c_kind) & 1) == 0)
17437 /* Remove the invalid clause(s) from the list to avoid
17438 confusing the rest of the compiler. */
17440 error_at (here, "%qs is not valid for %qs", c_name, where);
17446 c_parser_skip_to_pragma_eol (parser);
17450 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
17451 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
17452 return c_finish_omp_clauses (clauses, C_ORT_OMP);
17458 /* OpenACC 2.0, OpenMP 2.5:
17462 In practice, we're also interested in adding the statement to an
17463 outer node. So it is convenient if we work around the fact that
17464 c_parser_statement calls add_stmt. */
17467 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
17469 tree stmt = push_stmt_list ();
17470 c_parser_statement (parser, if_p);
17471 return pop_stmt_list (stmt);
17475 # pragma acc cache (variable-list) new-line
17477 LOC is the location of the #pragma token.
17481 c_parser_oacc_cache (location_t loc, c_parser *parser)
17483 tree stmt, clauses;
17485 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
17486 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17488 c_parser_skip_to_pragma_eol (parser);
17490 stmt = make_node (OACC_CACHE);
17491 TREE_TYPE (stmt) = void_type_node;
17492 OACC_CACHE_CLAUSES (stmt) = clauses;
17493 SET_EXPR_LOCATION (stmt, loc);
17500 # pragma acc data oacc-data-clause[optseq] new-line
17503 LOC is the location of the #pragma token.
17506 #define OACC_DATA_CLAUSE_MASK \
17507 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17514 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17515 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17518 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
17520 tree stmt, clauses, block;
17522 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
17523 "#pragma acc data");
17525 block = c_begin_omp_parallel ();
17526 add_stmt (c_parser_omp_structured_block (parser, if_p));
17528 stmt = c_finish_oacc_data (loc, clauses, block);
17534 # pragma acc declare oacc-data-clause[optseq] new-line
17537 #define OACC_DECLARE_CLAUSE_MASK \
17538 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17548 c_parser_oacc_declare (c_parser *parser)
17550 location_t pragma_loc = c_parser_peek_token (parser)->location;
17551 tree clauses, stmt, t, decl;
17553 bool error = false;
17555 c_parser_consume_pragma (parser);
17557 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
17558 "#pragma acc declare");
17561 error_at (pragma_loc,
17562 "no valid clauses specified in %<#pragma acc declare%>");
17566 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
17568 location_t loc = OMP_CLAUSE_LOCATION (t);
17569 decl = OMP_CLAUSE_DECL (t);
17570 if (!DECL_P (decl))
17572 error_at (loc, "array section in %<#pragma acc declare%>");
17577 switch (OMP_CLAUSE_MAP_KIND (t))
17579 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17580 case GOMP_MAP_ALLOC:
17582 case GOMP_MAP_FORCE_DEVICEPTR:
17583 case GOMP_MAP_DEVICE_RESIDENT:
17586 case GOMP_MAP_LINK:
17587 if (!global_bindings_p ()
17588 && (TREE_STATIC (decl)
17589 || !DECL_EXTERNAL (decl)))
17592 "%qD must be a global variable in "
17593 "%<#pragma acc declare link%>",
17601 if (global_bindings_p ())
17603 error_at (loc, "invalid OpenACC clause at file scope");
17607 if (DECL_EXTERNAL (decl))
17610 "invalid use of %<extern%> variable %qD "
17611 "in %<#pragma acc declare%>", decl);
17615 else if (TREE_PUBLIC (decl))
17618 "invalid use of %<global%> variable %qD "
17619 "in %<#pragma acc declare%>", decl);
17626 if (!c_check_in_current_scope (decl))
17629 "%qD must be a variable declared in the same scope as "
17630 "%<#pragma acc declare%>", decl);
17635 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
17636 || lookup_attribute ("omp declare target link",
17637 DECL_ATTRIBUTES (decl)))
17639 error_at (loc, "variable %qD used more than once with "
17640 "%<#pragma acc declare%>", decl);
17649 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
17650 id = get_identifier ("omp declare target link");
17652 id = get_identifier ("omp declare target");
17654 DECL_ATTRIBUTES (decl)
17655 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
17657 if (global_bindings_p ())
17659 symtab_node *node = symtab_node::get (decl);
17662 node->offloadable = 1;
17663 if (ENABLE_OFFLOADING)
17665 g->have_offload = true;
17666 if (is_a <varpool_node *> (node))
17667 vec_safe_push (offload_vars, decl);
17674 if (error || global_bindings_p ())
17677 stmt = make_node (OACC_DECLARE);
17678 TREE_TYPE (stmt) = void_type_node;
17679 OACC_DECLARE_CLAUSES (stmt) = clauses;
17680 SET_EXPR_LOCATION (stmt, pragma_loc);
17688 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17692 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17695 LOC is the location of the #pragma token.
17698 #define OACC_ENTER_DATA_CLAUSE_MASK \
17699 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17706 #define OACC_EXIT_DATA_CLAUSE_MASK \
17707 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17708 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17709 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17716 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
17718 location_t loc = c_parser_peek_token (parser)->location;
17719 tree clauses, stmt;
17720 const char *p = "";
17722 c_parser_consume_pragma (parser);
17724 if (c_parser_next_token_is (parser, CPP_NAME))
17726 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17727 c_parser_consume_token (parser);
17730 if (strcmp (p, "data") != 0)
17732 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17733 enter ? "enter" : "exit");
17734 parser->error = true;
17735 c_parser_skip_to_pragma_eol (parser);
17740 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17741 "#pragma acc enter data");
17743 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17744 "#pragma acc exit data");
17746 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17748 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17749 enter ? "enter" : "exit");
17753 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
17754 TREE_TYPE (stmt) = void_type_node;
17755 OMP_STANDALONE_CLAUSES (stmt) = clauses;
17756 SET_EXPR_LOCATION (stmt, loc);
17762 # pragma acc host_data oacc-data-clause[optseq] new-line
17766 #define OACC_HOST_DATA_CLAUSE_MASK \
17767 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17768 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17769 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17772 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
17774 tree stmt, clauses, block;
17776 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
17777 "#pragma acc host_data");
17779 block = c_begin_omp_parallel ();
17780 add_stmt (c_parser_omp_structured_block (parser, if_p));
17781 stmt = c_finish_oacc_host_data (loc, clauses, block);
17788 # pragma acc loop oacc-loop-clause[optseq] new-line
17791 LOC is the location of the #pragma token.
17794 #define OACC_LOOP_CLAUSE_MASK \
17795 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17796 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17797 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17798 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17799 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17800 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17806 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
17807 omp_clause_mask mask, tree *cclauses, bool *if_p)
17809 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
17811 strcat (p_name, " loop");
17812 mask |= OACC_LOOP_CLAUSE_MASK;
17814 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
17818 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
17820 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
17822 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17825 tree block = c_begin_compound_stmt (true);
17826 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
17828 block = c_end_compound_stmt (loc, block, true);
17835 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17840 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17845 # pragma acc serial oacc-serial-clause[optseq] new-line
17848 LOC is the location of the #pragma token.
17851 #define OACC_KERNELS_CLAUSE_MASK \
17852 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17853 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17854 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17858 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17860 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17864 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17865 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17866 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17868 #define OACC_PARALLEL_CLAUSE_MASK \
17869 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17870 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17871 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17872 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17873 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17874 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17875 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17876 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17877 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17883 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17888 #define OACC_SERIAL_CLAUSE_MASK \
17889 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17894 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17906 c_parser_oacc_compute (location_t loc, c_parser *parser,
17907 enum pragma_kind p_kind, char *p_name, bool *if_p)
17909 omp_clause_mask mask;
17910 enum tree_code code;
17913 case PRAGMA_OACC_KERNELS:
17914 strcat (p_name, " kernels");
17915 mask = OACC_KERNELS_CLAUSE_MASK;
17916 code = OACC_KERNELS;
17918 case PRAGMA_OACC_PARALLEL:
17919 strcat (p_name, " parallel");
17920 mask = OACC_PARALLEL_CLAUSE_MASK;
17921 code = OACC_PARALLEL;
17923 case PRAGMA_OACC_SERIAL:
17924 strcat (p_name, " serial");
17925 mask = OACC_SERIAL_CLAUSE_MASK;
17926 code = OACC_SERIAL;
17929 gcc_unreachable ();
17932 if (c_parser_next_token_is (parser, CPP_NAME))
17934 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17935 if (strcmp (p, "loop") == 0)
17937 c_parser_consume_token (parser);
17938 tree block = c_begin_omp_parallel ();
17940 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17941 return c_finish_omp_construct (loc, code, block, clauses);
17945 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17947 tree block = c_begin_omp_parallel ();
17948 add_stmt (c_parser_omp_structured_block (parser, if_p));
17950 return c_finish_omp_construct (loc, code, block, clauses);
17954 # pragma acc routine oacc-routine-clause[optseq] new-line
17955 function-definition
17957 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17960 #define OACC_ROUTINE_CLAUSE_MASK \
17961 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17962 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17963 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17964 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17965 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17967 /* Parse an OpenACC routine directive. For named directives, we apply
17968 immediately to the named function. For unnamed ones we then parse
17969 a declaration or definition, which must be for a function. */
17972 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17974 gcc_checking_assert (context == pragma_external);
17976 oacc_routine_data data;
17977 data.error_seen = false;
17978 data.fndecl_seen = false;
17979 data.loc = c_parser_peek_token (parser)->location;
17981 c_parser_consume_pragma (parser);
17983 /* Look for optional '( name )'. */
17984 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17986 c_parser_consume_token (parser); /* '(' */
17988 tree decl = NULL_TREE;
17989 c_token *name_token = c_parser_peek_token (parser);
17990 location_t name_loc = name_token->location;
17991 if (name_token->type == CPP_NAME
17992 && (name_token->id_kind == C_ID_ID
17993 || name_token->id_kind == C_ID_TYPENAME))
17995 decl = lookup_name (name_token->value);
17997 error_at (name_loc,
17998 "%qE has not been declared", name_token->value);
17999 c_parser_consume_token (parser);
18002 c_parser_error (parser, "expected function name");
18005 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
18007 c_parser_skip_to_pragma_eol (parser, false);
18012 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
18013 "#pragma acc routine");
18014 /* The clauses are in reverse order; fix that to make later diagnostic
18015 emission easier. */
18016 data.clauses = nreverse (data.clauses);
18018 if (TREE_CODE (decl) != FUNCTION_DECL)
18020 error_at (name_loc, "%qD does not refer to a function", decl);
18024 c_finish_oacc_routine (&data, decl, false);
18026 else /* No optional '( name )'. */
18029 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
18030 "#pragma acc routine");
18031 /* The clauses are in reverse order; fix that to make later diagnostic
18032 emission easier. */
18033 data.clauses = nreverse (data.clauses);
18035 /* Emit a helpful diagnostic if there's another pragma following this
18036 one. Also don't allow a static assertion declaration, as in the
18037 following we'll just parse a *single* "declaration or function
18038 definition", and the static assertion counts an one. */
18039 if (c_parser_next_token_is (parser, CPP_PRAGMA)
18040 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
18042 error_at (data.loc,
18043 "%<#pragma acc routine%> not immediately followed by"
18044 " function declaration or definition");
18045 /* ..., and then just keep going. */
18049 /* We only have to consider the pragma_external case here. */
18050 if (c_parser_next_token_is (parser, CPP_KEYWORD)
18051 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
18053 int ext = disable_extension_diagnostics ();
18055 c_parser_consume_token (parser);
18056 while (c_parser_next_token_is (parser, CPP_KEYWORD)
18057 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
18058 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
18059 NULL, NULL, false, NULL, &data);
18060 restore_extension_diagnostics (ext);
18063 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
18064 NULL, NULL, false, NULL, &data);
18068 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
18069 IS_DEFN is true if we're applying it to the definition. */
18072 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
18075 /* Keep going if we're in error reporting mode. */
18076 if (data->error_seen
18077 || fndecl == error_mark_node)
18080 if (data->fndecl_seen)
18082 error_at (data->loc,
18083 "%<#pragma acc routine%> not immediately followed by"
18084 " a single function declaration or definition");
18085 data->error_seen = true;
18088 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
18090 error_at (data->loc,
18091 "%<#pragma acc routine%> not immediately followed by"
18092 " function declaration or definition");
18093 data->error_seen = true;
18098 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
18099 "#pragma acc routine");
18100 if (compatible < 0)
18102 data->error_seen = true;
18105 if (compatible > 0)
18110 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
18112 error_at (data->loc,
18114 ? G_("%<#pragma acc routine%> must be applied before use")
18115 : G_("%<#pragma acc routine%> must be applied before"
18117 data->error_seen = true;
18121 /* Set the routine's level of parallelism. */
18122 tree dims = oacc_build_routine_dims (data->clauses);
18123 oacc_replace_fn_attrib (fndecl, dims);
18125 /* Add an "omp declare target" attribute. */
18126 DECL_ATTRIBUTES (fndecl)
18127 = tree_cons (get_identifier ("omp declare target"),
18128 data->clauses, DECL_ATTRIBUTES (fndecl));
18131 /* Remember that we've used this "#pragma acc routine". */
18132 data->fndecl_seen = true;
18136 # pragma acc update oacc-update-clause[optseq] new-line
18139 #define OACC_UPDATE_CLAUSE_MASK \
18140 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18141 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
18142 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
18143 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18144 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
18145 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18148 c_parser_oacc_update (c_parser *parser)
18150 location_t loc = c_parser_peek_token (parser)->location;
18152 c_parser_consume_pragma (parser);
18154 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
18155 "#pragma acc update");
18156 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
18159 "%<#pragma acc update%> must contain at least one "
18160 "%<device%> or %<host%> or %<self%> clause");
18167 tree stmt = make_node (OACC_UPDATE);
18168 TREE_TYPE (stmt) = void_type_node;
18169 OACC_UPDATE_CLAUSES (stmt) = clauses;
18170 SET_EXPR_LOCATION (stmt, loc);
18175 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18177 LOC is the location of the #pragma token.
18180 #define OACC_WAIT_CLAUSE_MASK \
18181 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18184 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
18186 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
18188 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
18189 list = c_parser_oacc_wait_list (parser, loc, list);
18191 strcpy (p_name, " wait");
18192 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
18193 stmt = c_finish_oacc_wait (loc, list, clauses);
18200 # pragma omp allocate (list) [allocator(allocator)] */
18203 c_parser_omp_allocate (location_t loc, c_parser *parser)
18205 tree allocator = NULL_TREE;
18206 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
18207 if (c_parser_next_token_is (parser, CPP_NAME))
18209 matching_parens parens;
18210 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18211 c_parser_consume_token (parser);
18212 if (strcmp ("allocator", p) != 0)
18213 error_at (c_parser_peek_token (parser)->location,
18214 "expected %<allocator%>");
18215 else if (parens.require_open (parser))
18217 location_t expr_loc = c_parser_peek_token (parser)->location;
18218 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18219 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18220 allocator = expr.value;
18221 allocator = c_fully_fold (allocator, false, NULL);
18223 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
18224 orig_type = TYPE_MAIN_VARIANT (orig_type);
18225 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
18226 || TREE_CODE (orig_type) != ENUMERAL_TYPE
18227 || TYPE_NAME (orig_type)
18228 != get_identifier ("omp_allocator_handle_t"))
18230 error_at (expr_loc, "%<allocator%> clause allocator expression "
18231 "has type %qT rather than "
18232 "%<omp_allocator_handle_t%>",
18233 TREE_TYPE (allocator));
18234 allocator = NULL_TREE;
18236 parens.skip_until_found_close (parser);
18239 c_parser_skip_to_pragma_eol (parser);
18242 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
18243 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18245 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
18249 # pragma omp atomic new-line
18253 x binop= expr | x++ | ++x | x-- | --x
18255 +, *, -, /, &, ^, |, <<, >>
18257 where x is an lvalue expression with scalar type.
18260 # pragma omp atomic new-line
18263 # pragma omp atomic read new-line
18266 # pragma omp atomic write new-line
18269 # pragma omp atomic update new-line
18272 # pragma omp atomic capture new-line
18275 # pragma omp atomic capture new-line
18283 expression-stmt | x = x binop expr
18285 v = expression-stmt
18287 { v = x; update-stmt; } | { update-stmt; v = x; }
18291 expression-stmt | x = x binop expr | x = expr binop x
18295 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18298 # pragma omp atomic compare new-line
18299 conditional-update-atomic
18301 # pragma omp atomic compare capture new-line
18302 conditional-update-capture-atomic
18304 conditional-update-atomic:
18305 cond-expr-stmt | cond-update-stmt
18307 x = expr ordop x ? expr : x;
18308 x = x ordop expr ? expr : x;
18309 x = x == e ? d : x;
18311 if (expr ordop x) { x = expr; }
18312 if (x ordop expr) { x = expr; }
18313 if (x == e) { x = d; }
18316 conditional-update-capture-atomic:
18318 { v = x; cond-expr-stmt }
18319 { cond-expr-stmt v = x; }
18320 { v = x; cond-update-stmt }
18321 { cond-update-stmt v = x; }
18322 if (x == e) { x = d; } else { v = x; }
18323 { r = x == e; if (r) { x = d; } }
18324 { r = x == e; if (r) { x = d; } else { v = x; } }
18326 where x, r and v are lvalue expressions with scalar type,
18327 expr, e and d are expressions with scalar type and e might be
18330 LOC is the location of the #pragma token. */
18333 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18335 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18336 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18337 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
18338 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
18339 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
18340 struct c_expr expr;
18342 bool structured_block = false;
18343 bool swapped = false;
18346 tree clauses = NULL_TREE;
18347 bool capture = false;
18348 bool compare = false;
18350 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18351 bool no_semicolon = false;
18352 bool extra_scope = false;
18354 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18357 && c_parser_next_token_is (parser, CPP_COMMA)
18358 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18359 c_parser_consume_token (parser);
18363 if (c_parser_next_token_is (parser, CPP_NAME))
18366 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18367 location_t cloc = c_parser_peek_token (parser)->location;
18368 enum tree_code new_code = ERROR_MARK;
18369 enum omp_memory_order new_memory_order
18370 = OMP_MEMORY_ORDER_UNSPECIFIED;
18371 bool new_capture = false;
18372 bool new_compare = false;
18373 bool new_weak = false;
18374 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18376 if (!strcmp (p, "read"))
18377 new_code = OMP_ATOMIC_READ;
18378 else if (!strcmp (p, "write"))
18379 new_code = NOP_EXPR;
18380 else if (!strcmp (p, "update"))
18381 new_code = OMP_ATOMIC;
18382 else if (openacc && !strcmp (p, "capture"))
18383 new_code = OMP_ATOMIC_CAPTURE_NEW;
18387 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18388 "or %<capture%> clause");
18390 else if (!strcmp (p, "capture"))
18391 new_capture = true;
18392 else if (!strcmp (p, "compare"))
18393 new_compare = true;
18394 else if (!strcmp (p, "weak"))
18396 else if (!strcmp (p, "fail"))
18398 matching_parens parens;
18400 c_parser_consume_token (parser);
18401 if (!parens.require_open (parser))
18404 if (c_parser_next_token_is (parser, CPP_NAME))
18407 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18409 if (!strcmp (q, "seq_cst"))
18410 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
18411 else if (!strcmp (q, "acquire"))
18412 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
18413 else if (!strcmp (q, "relaxed"))
18414 new_fail = OMP_MEMORY_ORDER_RELAXED;
18417 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18419 c_parser_consume_token (parser);
18420 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18421 error_at (cloc, "too many %qs clauses", "fail");
18426 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
18428 parens.skip_until_found_close (parser);
18431 else if (!strcmp (p, "seq_cst"))
18432 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18433 else if (!strcmp (p, "acq_rel"))
18434 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18435 else if (!strcmp (p, "release"))
18436 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
18437 else if (!strcmp (p, "acquire"))
18438 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18439 else if (!strcmp (p, "relaxed"))
18440 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
18441 else if (!strcmp (p, "hint"))
18443 c_parser_consume_token (parser);
18444 clauses = c_parser_omp_clause_hint (parser, clauses);
18450 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18451 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18452 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18453 "%<relaxed%> or %<hint%> clause");
18457 if (new_code != ERROR_MARK)
18459 /* OpenACC permits 'update capture'. */
18461 && code == OMP_ATOMIC
18462 && new_code == OMP_ATOMIC_CAPTURE_NEW)
18464 else if (code != ERROR_MARK)
18465 error_at (cloc, "too many atomic clauses");
18469 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18471 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18472 error_at (cloc, "too many memory order clauses");
18474 memory_order = new_memory_order;
18476 else if (new_capture)
18479 error_at (cloc, "too many %qs clauses", "capture");
18483 else if (new_compare)
18486 error_at (cloc, "too many %qs clauses", "compare");
18493 error_at (cloc, "too many %qs clauses", "weak");
18497 c_parser_consume_token (parser);
18503 c_parser_skip_to_pragma_eol (parser);
18505 if (code == ERROR_MARK)
18509 if (code != OMP_ATOMIC)
18510 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18511 "clauses", "capture");
18513 code = OMP_ATOMIC_CAPTURE_NEW;
18515 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
18517 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18518 "clauses", "compare");
18521 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
18523 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
18524 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18526 if (weak && !compare)
18528 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
18532 memory_order = OMP_MEMORY_ORDER_RELAXED;
18533 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
18536 = (enum omp_requires) (omp_requires_mask
18537 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
18538 switch ((enum omp_memory_order)
18539 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
18541 case OMP_MEMORY_ORDER_UNSPECIFIED:
18542 case OMP_MEMORY_ORDER_RELAXED:
18543 memory_order = OMP_MEMORY_ORDER_RELAXED;
18545 case OMP_MEMORY_ORDER_SEQ_CST:
18546 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18548 case OMP_MEMORY_ORDER_ACQ_REL:
18551 case OMP_ATOMIC_READ:
18552 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18554 case NOP_EXPR: /* atomic write */
18555 memory_order = OMP_MEMORY_ORDER_RELEASE;
18558 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18563 gcc_unreachable ();
18569 case OMP_ATOMIC_READ:
18570 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
18572 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
18573 "%<release%> clause");
18574 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18576 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18577 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18579 case NOP_EXPR: /* atomic write */
18580 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
18582 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
18583 "%<acquire%> clause");
18584 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18586 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18587 memory_order = OMP_MEMORY_ORDER_RELEASE;
18592 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18594 = (enum omp_memory_order) (memory_order
18595 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
18599 case OMP_ATOMIC_READ:
18600 case NOP_EXPR: /* atomic write */
18601 v = c_parser_cast_expression (parser, NULL).value;
18602 non_lvalue_p = !lvalue_p (v);
18603 v = c_fully_fold (v, false, NULL, true);
18604 if (v == error_mark_node)
18607 v = non_lvalue (v);
18608 loc = c_parser_peek_token (parser)->location;
18609 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18611 if (code == NOP_EXPR)
18613 lhs = c_parser_expression (parser).value;
18614 lhs = c_fully_fold (lhs, false, NULL);
18615 if (lhs == error_mark_node)
18620 lhs = c_parser_cast_expression (parser, NULL).value;
18621 non_lvalue_p = !lvalue_p (lhs);
18622 lhs = c_fully_fold (lhs, false, NULL, true);
18623 if (lhs == error_mark_node)
18626 lhs = non_lvalue (lhs);
18628 if (code == NOP_EXPR)
18630 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18638 case OMP_ATOMIC_CAPTURE_NEW:
18639 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18641 c_parser_consume_token (parser);
18642 structured_block = true;
18645 && c_parser_next_token_is_keyword (parser, RID_IF))
18649 v = c_parser_cast_expression (parser, NULL).value;
18650 non_lvalue_p = !lvalue_p (v);
18651 v = c_fully_fold (v, false, NULL, true);
18652 if (v == error_mark_node)
18655 v = non_lvalue (v);
18656 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18658 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18660 eloc = c_parser_peek_token (parser)->location;
18661 error_at (eloc, "expected expression");
18670 /* For structured_block case we don't know yet whether
18671 old or new x should be captured. */
18673 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18675 c_parser_consume_token (parser);
18677 matching_parens parens;
18678 if (!parens.require_open (parser))
18680 eloc = c_parser_peek_token (parser)->location;
18684 cmp_expr = c_parser_cast_expression (parser, NULL);
18685 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
18688 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
18689 parens.skip_until_found_close (parser);
18690 if (cmp_expr.value == error_mark_node)
18694 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
18696 cmp_expr.value = rhs1;
18698 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
18700 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18702 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18704 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18705 "expected %<==%> comparison in %<if%> condition");
18708 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
18709 && TREE_CODE (cmp_expr.value) != LT_EXPR)
18711 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18712 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18716 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18719 extra_scope = true;
18720 eloc = c_parser_peek_token (parser)->location;
18721 expr = c_parser_cast_expression (parser, NULL);
18723 expr = default_function_array_conversion (eloc, expr);
18724 unfolded_lhs = expr.value;
18725 lhs = c_fully_fold (lhs, false, NULL, true);
18727 if (lhs == error_mark_node)
18729 if (!lvalue_p (unfolded_lhs))
18730 lhs = non_lvalue (lhs);
18731 if (!c_parser_next_token_is (parser, CPP_EQ))
18733 c_parser_error (parser, "expected %<=%>");
18736 c_parser_consume_token (parser);
18737 eloc = c_parser_peek_token (parser)->location;
18738 expr = c_parser_expr_no_commas (parser, NULL);
18741 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18744 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18747 extra_scope = false;
18748 no_semicolon = true;
18750 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
18752 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18754 opcode = COND_EXPR;
18755 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18756 false, NULL, true);
18757 rhs1 = c_fully_fold (rhs1, false, NULL, true);
18759 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
18761 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18762 ? MIN_EXPR : MAX_EXPR);
18763 rhs = c_fully_fold (rhs1, false, NULL, true);
18764 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
18765 false, NULL, true);
18770 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18772 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
18773 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
18775 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18776 ? MAX_EXPR : MIN_EXPR);
18777 rhs = c_fully_fold (rhs1, false, NULL, true);
18778 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18779 false, NULL, true);
18784 c_parser_error (parser,
18785 "invalid form of %<#pragma omp atomic compare%>");
18789 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
18791 if (code != OMP_ATOMIC_CAPTURE_NEW
18792 || (structured_block && r == NULL_TREE)
18793 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
18795 eloc = c_parser_peek_token (parser)->location;
18796 error_at (eloc, "unexpected %<else%>");
18800 c_parser_consume_token (parser);
18802 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18805 extra_scope = true;
18806 v = c_parser_cast_expression (parser, NULL).value;
18807 non_lvalue_p = !lvalue_p (v);
18808 v = c_fully_fold (v, false, NULL, true);
18809 if (v == error_mark_node)
18812 v = non_lvalue (v);
18813 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18816 expr = c_parser_expr_no_commas (parser, NULL);
18818 if (!c_tree_equal (expr.value, unfolded_lhs))
18821 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18824 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18827 extra_scope = false;
18828 code = OMP_ATOMIC_CAPTURE_OLD;
18829 if (r == NULL_TREE)
18830 /* Signal to c_finish_omp_atomic that in
18831 if (x == e) { x = d; } else { v = x; }
18832 case the store to v should be conditional. */
18833 r = void_list_node;
18835 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18837 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
18840 else if (code == OMP_ATOMIC_CAPTURE_NEW
18846 eloc = c_parser_peek_token (parser)->location;
18847 expr = c_parser_cast_expression (parser, NULL);
18849 expr = default_function_array_conversion (eloc, expr);
18850 unfolded_lhs = expr.value;
18851 lhs = c_fully_fold (lhs, false, NULL, true);
18853 switch (TREE_CODE (lhs))
18856 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
18860 c_parser_skip_to_end_of_block_or_statement (parser);
18861 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18862 c_parser_consume_token (parser);
18863 if (structured_block)
18865 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18866 c_parser_consume_token (parser);
18867 else if (code == OMP_ATOMIC_CAPTURE_NEW)
18869 c_parser_skip_to_end_of_block_or_statement (parser);
18870 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18871 c_parser_consume_token (parser);
18876 case POSTINCREMENT_EXPR:
18877 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18878 code = OMP_ATOMIC_CAPTURE_OLD;
18880 case PREINCREMENT_EXPR:
18881 lhs = TREE_OPERAND (lhs, 0);
18882 unfolded_lhs = NULL_TREE;
18883 opcode = PLUS_EXPR;
18884 rhs = integer_one_node;
18886 goto invalid_compare;
18889 case POSTDECREMENT_EXPR:
18890 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18891 code = OMP_ATOMIC_CAPTURE_OLD;
18893 case PREDECREMENT_EXPR:
18894 lhs = TREE_OPERAND (lhs, 0);
18895 unfolded_lhs = NULL_TREE;
18896 opcode = MINUS_EXPR;
18897 rhs = integer_one_node;
18899 goto invalid_compare;
18902 case COMPOUND_EXPR:
18903 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
18904 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
18905 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
18906 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
18907 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18908 (TREE_OPERAND (lhs, 1), 0), 0)))
18910 /* Undo effects of boolean_increment for post {in,de}crement. */
18911 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
18914 if (TREE_CODE (lhs) == MODIFY_EXPR
18915 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
18917 /* Undo effects of boolean_increment. */
18918 if (integer_onep (TREE_OPERAND (lhs, 1)))
18920 /* This is pre or post increment. */
18921 rhs = TREE_OPERAND (lhs, 1);
18922 lhs = TREE_OPERAND (lhs, 0);
18923 unfolded_lhs = NULL_TREE;
18925 if (code == OMP_ATOMIC_CAPTURE_NEW
18926 && !structured_block
18927 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18928 code = OMP_ATOMIC_CAPTURE_OLD;
18930 goto invalid_compare;
18933 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
18934 && TREE_OPERAND (lhs, 0)
18935 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
18937 /* This is pre or post decrement. */
18938 rhs = TREE_OPERAND (lhs, 1);
18939 lhs = TREE_OPERAND (lhs, 0);
18940 unfolded_lhs = NULL_TREE;
18942 if (code == OMP_ATOMIC_CAPTURE_NEW
18943 && !structured_block
18944 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18945 code = OMP_ATOMIC_CAPTURE_OLD;
18947 goto invalid_compare;
18953 if (!lvalue_p (unfolded_lhs))
18954 lhs = non_lvalue (lhs);
18955 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
18957 c_parser_error (parser, "expected %<=%>");
18960 switch (c_parser_peek_token (parser)->type)
18963 opcode = MULT_EXPR;
18966 opcode = TRUNC_DIV_EXPR;
18969 opcode = PLUS_EXPR;
18972 opcode = MINUS_EXPR;
18974 case CPP_LSHIFT_EQ:
18975 opcode = LSHIFT_EXPR;
18977 case CPP_RSHIFT_EQ:
18978 opcode = RSHIFT_EXPR;
18981 opcode = BIT_AND_EXPR;
18984 opcode = BIT_IOR_EXPR;
18987 opcode = BIT_XOR_EXPR;
18990 c_parser_consume_token (parser);
18991 eloc = c_parser_peek_token (parser)->location;
18992 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
18994 switch (TREE_CODE (rhs1))
18997 case TRUNC_DIV_EXPR:
19008 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
19010 opcode = TREE_CODE (rhs1);
19011 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19013 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
19017 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
19019 opcode = TREE_CODE (rhs1);
19020 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
19022 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19024 swapped = !commutative_tree_code (opcode);
19031 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
19032 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
19033 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
19035 if (!TREE_OPERAND (rhs1, 1))
19037 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
19039 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
19042 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
19044 opcode = COND_EXPR;
19045 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
19047 false, NULL, true);
19048 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
19052 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
19053 TREE_OPERAND (rhs1, 1)))
19055 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
19056 ? MIN_EXPR : MAX_EXPR);
19057 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19059 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
19061 false, NULL, true);
19065 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
19067 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
19070 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
19071 TREE_OPERAND (rhs1, 1)))
19073 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
19074 ? MAX_EXPR : MIN_EXPR);
19075 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19077 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
19079 false, NULL, true);
19086 || code != OMP_ATOMIC_CAPTURE_NEW
19087 || !structured_block
19091 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
19092 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
19096 c_parser_consume_token (parser);
19105 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
19107 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
19109 code = OMP_ATOMIC_CAPTURE_OLD;
19112 expr = default_function_array_read_conversion (eloc, expr);
19113 unfolded_lhs1 = expr.value;
19114 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
19116 c_parser_consume_token (parser);
19119 if (structured_block && !compare)
19122 expr = default_function_array_read_conversion (eloc, expr);
19123 rhs = c_fully_fold (expr.value, false, NULL, true);
19128 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
19131 c_parser_error (parser,
19132 "invalid operator for %<#pragma omp atomic%>");
19136 /* Arrange to pass the location of the assignment operator to
19137 c_finish_omp_atomic. */
19138 loc = c_parser_peek_token (parser)->location;
19139 c_parser_consume_token (parser);
19140 eloc = c_parser_peek_token (parser)->location;
19141 expr = c_parser_expression (parser);
19142 expr = default_function_array_read_conversion (eloc, expr);
19144 rhs = c_fully_fold (rhs, false, NULL, true);
19148 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
19151 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
19153 no_semicolon = false;
19154 v = c_parser_cast_expression (parser, NULL).value;
19155 non_lvalue_p = !lvalue_p (v);
19156 v = c_fully_fold (v, false, NULL, true);
19157 if (v == error_mark_node)
19160 v = non_lvalue (v);
19161 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19163 eloc = c_parser_peek_token (parser)->location;
19164 expr = c_parser_cast_expression (parser, NULL);
19166 expr = default_function_array_read_conversion (eloc, expr);
19167 unfolded_lhs1 = expr.value;
19168 lhs1 = c_fully_fold (lhs1, false, NULL, true);
19169 if (lhs1 == error_mark_node)
19171 if (!lvalue_p (unfolded_lhs1))
19172 lhs1 = non_lvalue (lhs1);
19174 if (structured_block)
19177 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19178 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
19181 if (weak && opcode != COND_EXPR)
19183 error_at (loc, "%<weak%> clause requires atomic equality comparison");
19186 if (unfolded_lhs && unfolded_lhs1
19187 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
19189 error ("%<#pragma omp atomic capture%> uses two different "
19190 "expressions for memory");
19191 stmt = error_mark_node;
19194 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
19195 swapped, memory_order, weak);
19196 if (stmt != error_mark_node)
19199 if (!structured_block && !no_semicolon)
19200 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19205 # pragma omp barrier new-line
19209 c_parser_omp_barrier (c_parser *parser)
19211 location_t loc = c_parser_peek_token (parser)->location;
19212 c_parser_consume_pragma (parser);
19213 c_parser_skip_to_pragma_eol (parser);
19215 c_finish_omp_barrier (loc);
19219 # pragma omp critical [(name)] new-line
19223 # pragma omp critical [(name) [hint(expression)]] new-line
19225 LOC is the location of the #pragma itself. */
19227 #define OMP_CRITICAL_CLAUSE_MASK \
19228 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19231 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
19233 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
19235 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19237 c_parser_consume_token (parser);
19238 if (c_parser_next_token_is (parser, CPP_NAME))
19240 name = c_parser_peek_token (parser)->value;
19241 c_parser_consume_token (parser);
19242 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
19245 c_parser_error (parser, "expected identifier");
19247 if (c_parser_next_token_is (parser, CPP_COMMA)
19248 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
19249 c_parser_consume_token (parser);
19251 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
19252 "#pragma omp critical");
19253 stmt = c_parser_omp_structured_block (parser, if_p);
19254 return c_finish_omp_critical (loc, stmt, name, clauses);
19258 # pragma omp depobj ( depobj ) depobj-clause new-line
19261 depend (dependence-type : locator)
19263 update (dependence-type)
19272 c_parser_omp_depobj (c_parser *parser)
19274 location_t loc = c_parser_peek_token (parser)->location;
19275 c_parser_consume_pragma (parser);
19276 matching_parens parens;
19277 if (!parens.require_open (parser))
19279 c_parser_skip_to_pragma_eol (parser);
19283 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
19284 if (depobj != error_mark_node)
19286 if (!lvalue_p (depobj))
19288 error_at (EXPR_LOC_OR_LOC (depobj, loc),
19289 "%<depobj%> expression is not lvalue expression");
19290 depobj = error_mark_node;
19294 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
19296 if (addr == error_mark_node)
19297 depobj = error_mark_node;
19299 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
19300 addr, RO_UNARY_STAR);
19304 parens.skip_until_found_close (parser);
19305 tree clause = NULL_TREE;
19306 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
19307 location_t c_loc = c_parser_peek_token (parser)->location;
19308 if (c_parser_next_token_is (parser, CPP_NAME))
19310 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19312 c_parser_consume_token (parser);
19313 if (!strcmp ("depend", p))
19315 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19316 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19318 clause = error_mark_node;
19320 else if (!strcmp ("destroy", p))
19321 kind = OMP_CLAUSE_DEPEND_LAST;
19322 else if (!strcmp ("update", p))
19324 matching_parens c_parens;
19325 if (c_parens.require_open (parser))
19327 location_t c2_loc = c_parser_peek_token (parser)->location;
19328 if (c_parser_next_token_is (parser, CPP_NAME))
19331 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19333 c_parser_consume_token (parser);
19334 if (!strcmp ("in", p2))
19335 kind = OMP_CLAUSE_DEPEND_IN;
19336 else if (!strcmp ("out", p2))
19337 kind = OMP_CLAUSE_DEPEND_OUT;
19338 else if (!strcmp ("inout", p2))
19339 kind = OMP_CLAUSE_DEPEND_INOUT;
19340 else if (!strcmp ("mutexinoutset", p2))
19341 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
19342 else if (!strcmp ("inoutset", p2))
19343 kind = OMP_CLAUSE_DEPEND_INOUTSET;
19345 if (kind == OMP_CLAUSE_DEPEND_INVALID)
19347 clause = error_mark_node;
19348 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
19349 "%<mutexinoutset%> or %<inoutset%>");
19351 c_parens.skip_until_found_close (parser);
19354 clause = error_mark_node;
19357 if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
19359 clause = error_mark_node;
19360 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
19362 c_parser_skip_to_pragma_eol (parser);
19364 c_finish_omp_depobj (loc, depobj, kind, clause);
19369 # pragma omp flush flush-vars[opt] new-line
19375 # pragma omp flush memory-order-clause new-line */
19378 c_parser_omp_flush (c_parser *parser)
19380 location_t loc = c_parser_peek_token (parser)->location;
19381 c_parser_consume_pragma (parser);
19382 enum memmodel mo = MEMMODEL_LAST;
19383 if (c_parser_next_token_is (parser, CPP_NAME))
19386 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19388 if (!strcmp (p, "seq_cst"))
19389 mo = MEMMODEL_SEQ_CST;
19390 else if (!strcmp (p, "acq_rel"))
19391 mo = MEMMODEL_ACQ_REL;
19392 else if (!strcmp (p, "release"))
19393 mo = MEMMODEL_RELEASE;
19394 else if (!strcmp (p, "acquire"))
19395 mo = MEMMODEL_ACQUIRE;
19397 error_at (c_parser_peek_token (parser)->location,
19398 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19400 c_parser_consume_token (parser);
19402 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19404 if (mo != MEMMODEL_LAST)
19405 error_at (c_parser_peek_token (parser)->location,
19406 "%<flush%> list specified together with memory order "
19408 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
19410 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19411 c_parser_error (parser, "expected %<(%> or end of line");
19412 c_parser_skip_to_pragma_eol (parser);
19414 c_finish_omp_flush (loc, mo);
19417 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19418 separating directive. */
19421 c_parser_omp_structured_block_sequence (c_parser *parser,
19422 enum pragma_kind kind)
19424 tree stmt = push_stmt_list ();
19425 c_parser_statement (parser, NULL);
19428 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19430 if (c_parser_next_token_is (parser, CPP_EOF))
19433 if (kind != PRAGMA_NONE
19434 && c_parser_peek_token (parser)->pragma_kind == kind)
19436 c_parser_statement (parser, NULL);
19439 return pop_stmt_list (stmt);
19445 { structured-block scan-directive structured-block } */
19448 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
19452 tree clauses = NULL_TREE;
19454 loc = c_parser_peek_token (parser)->location;
19455 if (!open_brace_parsed
19456 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19458 /* Avoid skipping until the end of the block. */
19459 parser->error = false;
19463 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
19464 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
19465 SET_EXPR_LOCATION (substmt, loc);
19466 add_stmt (substmt);
19468 loc = c_parser_peek_token (parser)->location;
19469 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
19471 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
19473 c_parser_consume_pragma (parser);
19475 if (c_parser_next_token_is (parser, CPP_NAME))
19478 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19479 if (strcmp (p, "inclusive") == 0)
19480 clause = OMP_CLAUSE_INCLUSIVE;
19481 else if (strcmp (p, "exclusive") == 0)
19482 clause = OMP_CLAUSE_EXCLUSIVE;
19484 if (clause != OMP_CLAUSE_ERROR)
19486 c_parser_consume_token (parser);
19487 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
19490 c_parser_error (parser, "expected %<inclusive%> or "
19491 "%<exclusive%> clause");
19492 c_parser_skip_to_pragma_eol (parser);
19495 error ("expected %<#pragma omp scan%>");
19497 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19498 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
19499 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
19500 SET_EXPR_LOCATION (substmt, loc);
19501 add_stmt (substmt);
19503 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19507 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19508 The real trick here is to determine the loop control variable early
19509 so that we can push a new decl if necessary to make it private.
19510 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19514 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
19515 tree clauses, tree *cclauses, bool *if_p)
19517 tree decl, cond, incr, body, init, stmt, cl;
19518 unsigned char save_in_statement;
19519 tree declv, condv, incrv, initv, ret = NULL_TREE;
19520 tree pre_body = NULL_TREE, this_pre_body;
19521 tree ordered_cl = NULL_TREE;
19522 bool fail = false, open_brace_parsed = false;
19523 int i, collapse = 1, ordered = 0, count, nbraces = 0;
19524 location_t for_loc;
19525 bool tiling = false;
19526 bool inscan = false;
19527 vec<tree, va_gc> *for_block = make_tree_vector ();
19529 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
19530 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
19531 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
19532 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
19535 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
19537 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
19538 && OMP_CLAUSE_ORDERED_EXPR (cl))
19541 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
19543 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
19544 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
19545 && (code == OMP_SIMD || code == OMP_FOR))
19548 if (ordered && ordered < collapse)
19550 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
19551 "%<ordered%> clause parameter is less than %<collapse%>");
19552 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
19553 = build_int_cst (NULL_TREE, collapse);
19554 ordered = collapse;
19557 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
19558 count = ordered ? ordered : collapse;
19560 declv = make_tree_vec (count);
19561 initv = make_tree_vec (count);
19562 condv = make_tree_vec (count);
19563 incrv = make_tree_vec (count);
19565 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
19567 c_parser_error (parser, "for statement expected");
19570 for_loc = c_parser_peek_token (parser)->location;
19571 c_parser_consume_token (parser);
19573 /* Forbid break/continue in the loop initializer, condition, and
19574 increment expressions. */
19575 save_in_statement = in_statement;
19576 in_statement = IN_OMP_BLOCK;
19578 for (i = 0; i < count; i++)
19580 int bracecount = 0;
19582 matching_parens parens;
19583 if (!parens.require_open (parser))
19586 /* Parse the initialization declaration or expression. */
19587 if (c_parser_next_tokens_start_declaration (parser))
19590 vec_safe_push (for_block, c_begin_compound_stmt (true));
19591 this_pre_body = push_stmt_list ();
19592 c_in_omp_for = true;
19593 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
19594 c_in_omp_for = false;
19597 this_pre_body = pop_stmt_list (this_pre_body);
19601 pre_body = push_stmt_list ();
19603 add_stmt (this_pre_body);
19604 pre_body = pop_stmt_list (pre_body);
19607 pre_body = this_pre_body;
19609 decl = check_for_loop_decls (for_loc, flag_isoc99);
19612 if (DECL_INITIAL (decl) == error_mark_node)
19613 decl = error_mark_node;
19616 else if (c_parser_next_token_is (parser, CPP_NAME)
19617 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
19619 struct c_expr decl_exp;
19620 struct c_expr init_exp;
19621 location_t init_loc;
19623 decl_exp = c_parser_postfix_expression (parser);
19624 decl = decl_exp.value;
19626 c_parser_require (parser, CPP_EQ, "expected %<=%>");
19628 init_loc = c_parser_peek_token (parser)->location;
19629 init_exp = c_parser_expr_no_commas (parser, NULL);
19630 init_exp = default_function_array_read_conversion (init_loc,
19632 c_in_omp_for = true;
19633 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
19634 NOP_EXPR, init_loc, init_exp.value,
19635 init_exp.original_type);
19636 c_in_omp_for = false;
19637 init = c_process_expr_stmt (init_loc, init);
19639 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19644 c_parser_error (parser,
19645 "expected iteration declaration or initialization");
19646 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19652 /* Parse the loop condition. */
19654 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
19656 location_t cond_loc = c_parser_peek_token (parser)->location;
19657 c_in_omp_for = true;
19658 struct c_expr cond_expr
19659 = c_parser_binary_expression (parser, NULL, NULL_TREE);
19660 c_in_omp_for = false;
19662 cond = cond_expr.value;
19663 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
19664 switch (cond_expr.original_code)
19672 if (code != OACC_LOOP)
19676 /* Can't be cond = error_mark_node, because we want to preserve
19677 the location until c_finish_omp_for. */
19678 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
19681 protected_set_expr_location (cond, cond_loc);
19683 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19685 /* Parse the increment expression. */
19687 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
19689 location_t incr_loc = c_parser_peek_token (parser)->location;
19691 incr = c_process_expr_stmt (incr_loc,
19692 c_parser_expression (parser).value);
19694 parens.skip_until_found_close (parser);
19696 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
19700 TREE_VEC_ELT (declv, i) = decl;
19701 TREE_VEC_ELT (initv, i) = init;
19702 TREE_VEC_ELT (condv, i) = cond;
19703 TREE_VEC_ELT (incrv, i) = incr;
19707 if (i == count - 1)
19710 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19711 in between the collapsed for loops to be still considered perfectly
19712 nested. Hopefully the final version clarifies this.
19713 For now handle (multiple) {'s and empty statements. */
19716 if (c_parser_next_token_is_keyword (parser, RID_FOR))
19718 c_parser_consume_token (parser);
19721 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19723 c_parser_consume_token (parser);
19726 else if (bracecount
19727 && c_parser_next_token_is (parser, CPP_SEMICOLON))
19728 c_parser_consume_token (parser);
19731 c_parser_error (parser, "not enough perfectly nested loops");
19734 open_brace_parsed = true;
19744 nbraces += bracecount;
19750 in_statement = IN_OMP_FOR;
19751 body = push_stmt_list ();
19754 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
19755 else if (open_brace_parsed)
19757 location_t here = c_parser_peek_token (parser)->location;
19758 stmt = c_begin_compound_stmt (true);
19759 c_parser_compound_statement_nostart (parser);
19760 add_stmt (c_end_compound_stmt (here, stmt, true));
19763 add_stmt (c_parser_c99_block_statement (parser, if_p));
19765 body = pop_stmt_list (body);
19766 in_statement = save_in_statement;
19770 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19772 c_parser_consume_token (parser);
19775 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
19776 c_parser_consume_token (parser);
19779 c_parser_error (parser, "collapsed loops not perfectly nested");
19782 location_t here = c_parser_peek_token (parser)->location;
19783 stmt = c_begin_compound_stmt (true);
19785 c_parser_compound_statement_nostart (parser);
19786 body = c_end_compound_stmt (here, stmt, true);
19793 /* Only bother calling c_finish_omp_for if we haven't already generated
19794 an error from the initialization parsing. */
19797 c_in_omp_for = true;
19798 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
19799 incrv, body, pre_body, true);
19800 c_in_omp_for = false;
19802 /* Check for iterators appearing in lb, b or incr expressions. */
19803 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
19810 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
19812 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
19813 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
19814 tree decl = TREE_OPERAND (init, 0);
19815 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
19816 gcc_assert (COMPARISON_CLASS_P (cond));
19817 gcc_assert (TREE_OPERAND (cond, 0) == decl);
19819 tree op0 = TREE_OPERAND (init, 1);
19820 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19821 || TREE_CODE (op0) != TREE_VEC)
19822 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
19825 TREE_VEC_ELT (op0, 1)
19826 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
19827 TREE_VEC_ELT (op0, 2)
19828 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
19831 tree op1 = TREE_OPERAND (cond, 1);
19832 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19833 || TREE_CODE (op1) != TREE_VEC)
19834 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
19837 TREE_VEC_ELT (op1, 1)
19838 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
19839 TREE_VEC_ELT (op1, 2)
19840 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
19844 if (cclauses != NULL
19845 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
19848 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
19849 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
19850 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
19851 c = &OMP_CLAUSE_CHAIN (*c);
19854 for (i = 0; i < count; i++)
19855 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
19858 c = &OMP_CLAUSE_CHAIN (*c);
19859 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
19862 "iteration variable %qD should not be firstprivate",
19863 OMP_CLAUSE_DECL (*c));
19864 *c = OMP_CLAUSE_CHAIN (*c);
19868 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19870 *c = OMP_CLAUSE_CHAIN (*c);
19871 if (code == OMP_SIMD)
19873 OMP_CLAUSE_CHAIN (l)
19874 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19875 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
19879 OMP_CLAUSE_CHAIN (l) = clauses;
19885 OMP_FOR_CLAUSES (stmt) = clauses;
19890 while (!for_block->is_empty ())
19892 /* FIXME diagnostics: LOC below should be the actual location of
19893 this particular for block. We need to build a list of
19894 locations to go along with FOR_BLOCK. */
19895 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
19898 release_tree_vector (for_block);
19902 /* Helper function for OpenMP parsing, split clauses and call
19903 finish_omp_clauses on each of the set of clauses afterwards. */
19906 omp_split_clauses (location_t loc, enum tree_code code,
19907 omp_clause_mask mask, tree clauses, tree *cclauses)
19910 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
19911 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
19913 cclauses[i] = c_finish_omp_clauses (cclauses[i],
19914 i == C_OMP_CLAUSE_SPLIT_TARGET
19915 ? C_ORT_OMP_TARGET : C_ORT_OMP);
19919 #pragma omp loop loop-clause[optseq] new-line
19922 LOC is the location of the #pragma token.
19925 #define OMP_LOOP_CLAUSE_MASK \
19926 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19928 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19929 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19930 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19931 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19934 c_parser_omp_loop (location_t loc, c_parser *parser,
19935 char *p_name, omp_clause_mask mask, tree *cclauses,
19938 tree block, clauses, ret;
19940 strcat (p_name, " loop");
19941 mask |= OMP_LOOP_CLAUSE_MASK;
19943 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19946 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
19947 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
19950 block = c_begin_compound_stmt (true);
19951 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
19952 block = c_end_compound_stmt (loc, block, true);
19959 #pragma omp simd simd-clause[optseq] new-line
19962 LOC is the location of the #pragma token.
19965 #define OMP_SIMD_CLAUSE_MASK \
19966 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19967 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19968 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19969 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19970 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19971 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19972 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19973 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19974 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19975 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19976 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19979 c_parser_omp_simd (location_t loc, c_parser *parser,
19980 char *p_name, omp_clause_mask mask, tree *cclauses,
19983 tree block, clauses, ret;
19985 strcat (p_name, " simd");
19986 mask |= OMP_SIMD_CLAUSE_MASK;
19988 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19991 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
19992 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
19995 block = c_begin_compound_stmt (true);
19996 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
19997 block = c_end_compound_stmt (loc, block, true);
20004 #pragma omp for for-clause[optseq] new-line
20008 #pragma omp for simd for-simd-clause[optseq] new-line
20011 LOC is the location of the #pragma token.
20014 #define OMP_FOR_CLAUSE_MASK \
20015 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20016 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20017 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20018 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20019 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20020 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
20021 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
20022 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20023 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
20024 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20025 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20028 c_parser_omp_for (location_t loc, c_parser *parser,
20029 char *p_name, omp_clause_mask mask, tree *cclauses,
20032 tree block, clauses, ret;
20034 strcat (p_name, " for");
20035 mask |= OMP_FOR_CLAUSE_MASK;
20036 /* parallel for{, simd} disallows nowait clause, but for
20037 target {teams distribute ,}parallel for{, simd} it should be accepted. */
20038 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
20039 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20040 /* Composite distribute parallel for{, simd} disallows ordered clause. */
20041 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20042 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
20044 if (c_parser_next_token_is (parser, CPP_NAME))
20046 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20048 if (strcmp (p, "simd") == 0)
20050 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20051 if (cclauses == NULL)
20052 cclauses = cclauses_buf;
20054 c_parser_consume_token (parser);
20055 if (!flag_openmp) /* flag_openmp_simd */
20056 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20058 block = c_begin_compound_stmt (true);
20059 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
20060 block = c_end_compound_stmt (loc, block, true);
20061 if (ret == NULL_TREE)
20063 ret = make_node (OMP_FOR);
20064 TREE_TYPE (ret) = void_type_node;
20065 OMP_FOR_BODY (ret) = block;
20066 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
20067 SET_EXPR_LOCATION (ret, loc);
20072 if (!flag_openmp) /* flag_openmp_simd */
20074 c_parser_skip_to_pragma_eol (parser, false);
20078 /* Composite distribute parallel for disallows linear clause. */
20079 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20080 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
20082 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20085 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
20086 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
20089 block = c_begin_compound_stmt (true);
20090 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
20091 block = c_end_compound_stmt (loc, block, true);
20097 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
20098 omp_clause_mask, tree *, bool *);
20101 # pragma omp master new-line
20104 LOC is the location of the #pragma token.
20108 c_parser_omp_master (location_t loc, c_parser *parser,
20109 char *p_name, omp_clause_mask mask, tree *cclauses,
20112 tree block, clauses, ret;
20114 strcat (p_name, " master");
20116 if (c_parser_next_token_is (parser, CPP_NAME))
20118 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20120 if (strcmp (p, "taskloop") == 0)
20122 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20123 if (cclauses == NULL)
20124 cclauses = cclauses_buf;
20126 c_parser_consume_token (parser);
20127 if (!flag_openmp) /* flag_openmp_simd */
20128 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20130 block = c_begin_compound_stmt (true);
20131 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20133 block = c_end_compound_stmt (loc, block, true);
20134 if (ret == NULL_TREE)
20136 ret = c_finish_omp_master (loc, block);
20137 OMP_MASTER_COMBINED (ret) = 1;
20141 if (!flag_openmp) /* flag_openmp_simd */
20143 c_parser_skip_to_pragma_eol (parser, false);
20149 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
20150 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
20153 c_parser_skip_to_pragma_eol (parser);
20155 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
20160 # pragma omp masked masked-clauses new-line
20163 LOC is the location of the #pragma token.
20166 #define OMP_MASKED_CLAUSE_MASK \
20167 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20170 c_parser_omp_masked (location_t loc, c_parser *parser,
20171 char *p_name, omp_clause_mask mask, tree *cclauses,
20174 tree block, clauses, ret;
20176 strcat (p_name, " masked");
20177 mask |= OMP_MASKED_CLAUSE_MASK;
20179 if (c_parser_next_token_is (parser, CPP_NAME))
20181 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20183 if (strcmp (p, "taskloop") == 0)
20185 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20186 if (cclauses == NULL)
20187 cclauses = cclauses_buf;
20189 c_parser_consume_token (parser);
20190 if (!flag_openmp) /* flag_openmp_simd */
20191 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20193 block = c_begin_compound_stmt (true);
20194 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20196 block = c_end_compound_stmt (loc, block, true);
20197 if (ret == NULL_TREE)
20199 ret = c_finish_omp_masked (loc, block,
20200 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
20201 OMP_MASKED_COMBINED (ret) = 1;
20205 if (!flag_openmp) /* flag_openmp_simd */
20207 c_parser_skip_to_pragma_eol (parser, false);
20211 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20214 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
20215 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
20218 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
20224 # pragma omp ordered new-line
20228 # pragma omp ordered ordered-clauses new-line
20231 # pragma omp ordered depend-clauses new-line
20234 # pragma omp ordered doacross-clauses new-line */
20236 #define OMP_ORDERED_CLAUSE_MASK \
20237 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20240 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20241 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
20245 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
20248 location_t loc = c_parser_peek_token (parser)->location;
20249 c_parser_consume_pragma (parser);
20251 if (context != pragma_stmt && context != pragma_compound)
20253 c_parser_error (parser, "expected declaration specifiers");
20254 c_parser_skip_to_pragma_eol (parser, false);
20258 if (c_parser_next_token_is (parser, CPP_NAME))
20260 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20262 if (!strcmp ("depend", p) || !strcmp ("doacross", p))
20264 if (!flag_openmp) /* flag_openmp_simd */
20266 c_parser_skip_to_pragma_eol (parser, false);
20269 if (context == pragma_stmt)
20272 "%<#pragma omp ordered%> with %qs clause may "
20273 "only be used in compound statements", p);
20274 c_parser_skip_to_pragma_eol (parser, false);
20279 = c_parser_omp_all_clauses (parser,
20280 OMP_ORDERED_DEPEND_CLAUSE_MASK,
20281 "#pragma omp ordered");
20282 c_finish_omp_ordered (loc, clauses, NULL_TREE);
20287 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20288 "#pragma omp ordered");
20290 if (!flag_openmp /* flag_openmp_simd */
20291 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20294 c_finish_omp_ordered (loc, clauses,
20295 c_parser_omp_structured_block (parser, if_p));
20302 { section-sequence }
20305 section-directive[opt] structured-block
20306 section-sequence section-directive structured-block
20308 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20310 SECTIONS_LOC is the location of the #pragma omp sections. */
20313 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20315 tree stmt, substmt;
20316 bool error_suppress = false;
20319 loc = c_parser_peek_token (parser)->location;
20320 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20322 /* Avoid skipping until the end of the block. */
20323 parser->error = false;
20327 stmt = push_stmt_list ();
20329 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
20331 substmt = c_parser_omp_structured_block_sequence (parser,
20332 PRAGMA_OMP_SECTION);
20333 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20334 SET_EXPR_LOCATION (substmt, loc);
20335 add_stmt (substmt);
20340 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20342 if (c_parser_next_token_is (parser, CPP_EOF))
20345 loc = c_parser_peek_token (parser)->location;
20346 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
20348 c_parser_consume_pragma (parser);
20349 c_parser_skip_to_pragma_eol (parser);
20350 error_suppress = false;
20352 else if (!error_suppress)
20354 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
20355 error_suppress = true;
20358 substmt = c_parser_omp_structured_block_sequence (parser,
20359 PRAGMA_OMP_SECTION);
20360 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20361 SET_EXPR_LOCATION (substmt, loc);
20362 add_stmt (substmt);
20364 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20365 "expected %<#pragma omp section%> or %<}%>");
20367 substmt = pop_stmt_list (stmt);
20369 stmt = make_node (OMP_SECTIONS);
20370 SET_EXPR_LOCATION (stmt, sections_loc);
20371 TREE_TYPE (stmt) = void_type_node;
20372 OMP_SECTIONS_BODY (stmt) = substmt;
20374 return add_stmt (stmt);
20378 # pragma omp sections sections-clause[optseq] newline
20381 LOC is the location of the #pragma token.
20384 #define OMP_SECTIONS_CLAUSE_MASK \
20385 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20387 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20388 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20389 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20390 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20393 c_parser_omp_sections (location_t loc, c_parser *parser,
20394 char *p_name, omp_clause_mask mask, tree *cclauses)
20396 tree block, clauses, ret;
20398 strcat (p_name, " sections");
20399 mask |= OMP_SECTIONS_CLAUSE_MASK;
20401 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20403 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20406 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
20407 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
20410 block = c_begin_compound_stmt (true);
20411 ret = c_parser_omp_sections_scope (loc, parser);
20413 OMP_SECTIONS_CLAUSES (ret) = clauses;
20414 block = c_end_compound_stmt (loc, block, true);
20421 # pragma omp parallel parallel-clause[optseq] new-line
20423 # pragma omp parallel for parallel-for-clause[optseq] new-line
20425 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20429 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20432 LOC is the location of the #pragma token.
20435 #define OMP_PARALLEL_CLAUSE_MASK \
20436 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20437 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20438 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20439 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20440 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20441 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20442 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20443 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20444 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20445 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20448 c_parser_omp_parallel (location_t loc, c_parser *parser,
20449 char *p_name, omp_clause_mask mask, tree *cclauses,
20452 tree stmt, clauses, block;
20454 strcat (p_name, " parallel");
20455 mask |= OMP_PARALLEL_CLAUSE_MASK;
20456 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20457 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
20458 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
20459 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
20461 if (c_parser_next_token_is_keyword (parser, RID_FOR))
20463 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20464 if (cclauses == NULL)
20465 cclauses = cclauses_buf;
20467 c_parser_consume_token (parser);
20468 if (!flag_openmp) /* flag_openmp_simd */
20469 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20470 block = c_begin_omp_parallel ();
20471 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20473 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20475 if (ret == NULL_TREE)
20477 OMP_PARALLEL_COMBINED (stmt) = 1;
20480 /* When combined with distribute, parallel has to be followed by for.
20481 #pragma omp target parallel is allowed though. */
20483 && (mask & (OMP_CLAUSE_MASK_1
20484 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20486 error_at (loc, "expected %<for%> after %qs", p_name);
20487 c_parser_skip_to_pragma_eol (parser);
20490 else if (c_parser_next_token_is (parser, CPP_NAME))
20492 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20493 if (cclauses == NULL && strcmp (p, "masked") == 0)
20495 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20496 cclauses = cclauses_buf;
20498 c_parser_consume_token (parser);
20499 if (!flag_openmp) /* flag_openmp_simd */
20500 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20502 block = c_begin_omp_parallel ();
20503 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20505 stmt = c_finish_omp_parallel (loc,
20506 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20510 /* masked does have just filter clause, but during gimplification
20511 isn't represented by a gimplification omp context, so for
20512 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20514 #pragma omp parallel masked
20515 #pragma omp taskloop simd lastprivate (x)
20516 isn't confused with
20517 #pragma omp parallel masked taskloop simd lastprivate (x) */
20518 if (OMP_MASKED_COMBINED (ret))
20519 OMP_PARALLEL_COMBINED (stmt) = 1;
20522 else if (cclauses == NULL && strcmp (p, "master") == 0)
20524 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20525 cclauses = cclauses_buf;
20527 c_parser_consume_token (parser);
20528 if (!flag_openmp) /* flag_openmp_simd */
20529 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20531 block = c_begin_omp_parallel ();
20532 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20534 stmt = c_finish_omp_parallel (loc,
20535 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20539 /* master doesn't have any clauses and during gimplification
20540 isn't represented by a gimplification omp context, so for
20541 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20543 #pragma omp parallel master
20544 #pragma omp taskloop simd lastprivate (x)
20545 isn't confused with
20546 #pragma omp parallel master taskloop simd lastprivate (x) */
20547 if (OMP_MASTER_COMBINED (ret))
20548 OMP_PARALLEL_COMBINED (stmt) = 1;
20551 else if (strcmp (p, "loop") == 0)
20553 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20554 if (cclauses == NULL)
20555 cclauses = cclauses_buf;
20557 c_parser_consume_token (parser);
20558 if (!flag_openmp) /* flag_openmp_simd */
20559 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20561 block = c_begin_omp_parallel ();
20562 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20565 = c_finish_omp_parallel (loc,
20566 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20568 if (ret == NULL_TREE)
20570 OMP_PARALLEL_COMBINED (stmt) = 1;
20573 else if (!flag_openmp) /* flag_openmp_simd */
20575 c_parser_skip_to_pragma_eol (parser, false);
20578 else if (cclauses == NULL && strcmp (p, "sections") == 0)
20580 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20581 cclauses = cclauses_buf;
20583 c_parser_consume_token (parser);
20584 block = c_begin_omp_parallel ();
20585 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
20586 stmt = c_finish_omp_parallel (loc,
20587 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20589 OMP_PARALLEL_COMBINED (stmt) = 1;
20593 else if (!flag_openmp) /* flag_openmp_simd */
20595 c_parser_skip_to_pragma_eol (parser, false);
20599 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20602 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
20603 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
20606 block = c_begin_omp_parallel ();
20607 c_parser_statement (parser, if_p);
20608 stmt = c_finish_omp_parallel (loc, clauses, block);
20614 # pragma omp single single-clause[optseq] new-line
20617 LOC is the location of the #pragma.
20620 #define OMP_SINGLE_CLAUSE_MASK \
20621 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20622 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20623 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20624 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20625 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20628 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
20630 tree stmt = make_node (OMP_SINGLE);
20631 SET_EXPR_LOCATION (stmt, loc);
20632 TREE_TYPE (stmt) = void_type_node;
20634 OMP_SINGLE_CLAUSES (stmt)
20635 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
20636 "#pragma omp single");
20637 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20639 return add_stmt (stmt);
20643 # pragma omp scope scope-clause[optseq] new-line
20646 LOC is the location of the #pragma.
20649 #define OMP_SCOPE_CLAUSE_MASK \
20650 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20653 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20654 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20657 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
20659 tree stmt = make_node (OMP_SCOPE);
20660 SET_EXPR_LOCATION (stmt, loc);
20661 TREE_TYPE (stmt) = void_type_node;
20663 OMP_SCOPE_CLAUSES (stmt)
20664 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
20665 "#pragma omp scope");
20666 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20668 return add_stmt (stmt);
20672 # pragma omp task task-clause[optseq] new-line
20674 LOC is the location of the #pragma.
20677 #define OMP_TASK_CLAUSE_MASK \
20678 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20679 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20680 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20683 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20684 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20685 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20686 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20687 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20688 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20689 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20690 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20691 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20694 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
20696 tree clauses, block;
20698 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
20699 "#pragma omp task");
20701 block = c_begin_omp_task ();
20702 c_parser_statement (parser, if_p);
20703 return c_finish_omp_task (loc, clauses, block);
20707 # pragma omp taskwait new-line
20710 # pragma omp taskwait taskwait-clause[optseq] new-line
20713 #define OMP_TASKWAIT_CLAUSE_MASK \
20714 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20715 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20718 c_parser_omp_taskwait (c_parser *parser)
20720 location_t loc = c_parser_peek_token (parser)->location;
20721 c_parser_consume_pragma (parser);
20724 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
20725 "#pragma omp taskwait");
20729 tree stmt = make_node (OMP_TASK);
20730 TREE_TYPE (stmt) = void_node;
20731 OMP_TASK_CLAUSES (stmt) = clauses;
20732 OMP_TASK_BODY (stmt) = NULL_TREE;
20733 SET_EXPR_LOCATION (stmt, loc);
20737 c_finish_omp_taskwait (loc);
20741 # pragma omp taskyield new-line
20745 c_parser_omp_taskyield (c_parser *parser)
20747 location_t loc = c_parser_peek_token (parser)->location;
20748 c_parser_consume_pragma (parser);
20749 c_parser_skip_to_pragma_eol (parser);
20751 c_finish_omp_taskyield (loc);
20755 # pragma omp taskgroup new-line
20758 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20761 #define OMP_TASKGROUP_CLAUSE_MASK \
20762 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20763 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20766 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
20768 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
20769 "#pragma omp taskgroup");
20771 tree body = c_parser_omp_structured_block (parser, if_p);
20772 return c_finish_omp_taskgroup (loc, body, clauses);
20776 # pragma omp cancel cancel-clause[optseq] new-line
20778 LOC is the location of the #pragma.
20781 #define OMP_CANCEL_CLAUSE_MASK \
20782 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20785 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20786 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20789 c_parser_omp_cancel (c_parser *parser)
20791 location_t loc = c_parser_peek_token (parser)->location;
20793 c_parser_consume_pragma (parser);
20794 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
20795 "#pragma omp cancel");
20797 c_finish_omp_cancel (loc, clauses);
20801 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20803 LOC is the location of the #pragma.
20806 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20807 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20813 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
20815 location_t loc = c_parser_peek_token (parser)->location;
20817 bool point_seen = false;
20819 c_parser_consume_pragma (parser);
20820 if (c_parser_next_token_is (parser, CPP_NAME))
20822 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20823 if (strcmp (p, "point") == 0)
20825 c_parser_consume_token (parser);
20831 c_parser_error (parser, "expected %<point%>");
20832 c_parser_skip_to_pragma_eol (parser);
20836 if (context != pragma_compound)
20838 if (context == pragma_stmt)
20840 "%<#pragma %s%> may only be used in compound statements",
20841 "omp cancellation point");
20843 c_parser_error (parser, "expected declaration specifiers");
20844 c_parser_skip_to_pragma_eol (parser, false);
20849 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
20850 "#pragma omp cancellation point");
20852 c_finish_omp_cancellation_point (loc, clauses);
20857 #pragma omp distribute distribute-clause[optseq] new-line
20860 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20861 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20864 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20865 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20866 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20867 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20870 c_parser_omp_distribute (location_t loc, c_parser *parser,
20871 char *p_name, omp_clause_mask mask, tree *cclauses,
20874 tree clauses, block, ret;
20876 strcat (p_name, " distribute");
20877 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
20879 if (c_parser_next_token_is (parser, CPP_NAME))
20881 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20883 bool parallel = false;
20885 if (strcmp (p, "simd") == 0)
20888 parallel = strcmp (p, "parallel") == 0;
20889 if (parallel || simd)
20891 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20892 if (cclauses == NULL)
20893 cclauses = cclauses_buf;
20894 c_parser_consume_token (parser);
20895 if (!flag_openmp) /* flag_openmp_simd */
20898 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20901 return c_parser_omp_parallel (loc, parser, p_name, mask,
20904 block = c_begin_compound_stmt (true);
20906 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20909 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
20911 block = c_end_compound_stmt (loc, block, true);
20914 ret = make_node (OMP_DISTRIBUTE);
20915 TREE_TYPE (ret) = void_type_node;
20916 OMP_FOR_BODY (ret) = block;
20917 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20918 SET_EXPR_LOCATION (ret, loc);
20923 if (!flag_openmp) /* flag_openmp_simd */
20925 c_parser_skip_to_pragma_eol (parser, false);
20929 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20932 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
20933 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20936 block = c_begin_compound_stmt (true);
20937 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
20939 block = c_end_compound_stmt (loc, block, true);
20946 # pragma omp teams teams-clause[optseq] new-line
20947 structured-block */
20949 #define OMP_TEAMS_CLAUSE_MASK \
20950 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20951 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20952 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20953 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20954 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20955 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20956 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20957 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20960 c_parser_omp_teams (location_t loc, c_parser *parser,
20961 char *p_name, omp_clause_mask mask, tree *cclauses,
20964 tree clauses, block, ret;
20966 strcat (p_name, " teams");
20967 mask |= OMP_TEAMS_CLAUSE_MASK;
20969 if (c_parser_next_token_is (parser, CPP_NAME))
20971 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20972 if (strcmp (p, "distribute") == 0)
20974 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20975 if (cclauses == NULL)
20976 cclauses = cclauses_buf;
20978 c_parser_consume_token (parser);
20979 if (!flag_openmp) /* flag_openmp_simd */
20980 return c_parser_omp_distribute (loc, parser, p_name, mask,
20982 block = c_begin_omp_parallel ();
20983 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
20985 block = c_end_compound_stmt (loc, block, true);
20988 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20989 ret = make_node (OMP_TEAMS);
20990 TREE_TYPE (ret) = void_type_node;
20991 OMP_TEAMS_CLAUSES (ret) = clauses;
20992 OMP_TEAMS_BODY (ret) = block;
20993 OMP_TEAMS_COMBINED (ret) = 1;
20994 SET_EXPR_LOCATION (ret, loc);
20995 return add_stmt (ret);
20997 else if (strcmp (p, "loop") == 0)
20999 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21000 if (cclauses == NULL)
21001 cclauses = cclauses_buf;
21003 c_parser_consume_token (parser);
21004 if (!flag_openmp) /* flag_openmp_simd */
21005 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
21007 block = c_begin_omp_parallel ();
21008 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
21009 block = c_end_compound_stmt (loc, block, true);
21012 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21013 ret = make_node (OMP_TEAMS);
21014 TREE_TYPE (ret) = void_type_node;
21015 OMP_TEAMS_CLAUSES (ret) = clauses;
21016 OMP_TEAMS_BODY (ret) = block;
21017 OMP_TEAMS_COMBINED (ret) = 1;
21018 SET_EXPR_LOCATION (ret, loc);
21019 return add_stmt (ret);
21022 if (!flag_openmp) /* flag_openmp_simd */
21024 c_parser_skip_to_pragma_eol (parser, false);
21028 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21031 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
21032 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21035 tree stmt = make_node (OMP_TEAMS);
21036 TREE_TYPE (stmt) = void_type_node;
21037 OMP_TEAMS_CLAUSES (stmt) = clauses;
21038 block = c_begin_omp_parallel ();
21039 add_stmt (c_parser_omp_structured_block (parser, if_p));
21040 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21041 SET_EXPR_LOCATION (stmt, loc);
21043 return add_stmt (stmt);
21047 # pragma omp target data target-data-clause[optseq] new-line
21048 structured-block */
21050 #define OMP_TARGET_DATA_CLAUSE_MASK \
21051 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21053 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21054 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
21055 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
21058 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
21062 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21065 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
21066 "#pragma omp target data");
21067 c_omp_adjust_map_clauses (clauses, false);
21069 for (tree *pc = &clauses; *pc;)
21071 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21072 switch (OMP_CLAUSE_MAP_KIND (*pc))
21075 case GOMP_MAP_ALWAYS_TO:
21076 case GOMP_MAP_FROM:
21077 case GOMP_MAP_ALWAYS_FROM:
21078 case GOMP_MAP_TOFROM:
21079 case GOMP_MAP_ALWAYS_TOFROM:
21080 case GOMP_MAP_ALLOC:
21083 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21084 case GOMP_MAP_ALWAYS_POINTER:
21085 case GOMP_MAP_ATTACH_DETACH:
21089 error_at (OMP_CLAUSE_LOCATION (*pc),
21090 "%<#pragma omp target data%> with map-type other "
21091 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21092 "on %<map%> clause");
21093 *pc = OMP_CLAUSE_CHAIN (*pc);
21096 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
21097 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
21099 pc = &OMP_CLAUSE_CHAIN (*pc);
21106 "%<#pragma omp target data%> must contain at least "
21107 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
21112 tree stmt = make_node (OMP_TARGET_DATA);
21113 TREE_TYPE (stmt) = void_type_node;
21114 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
21115 keep_next_level ();
21116 tree block = c_begin_compound_stmt (true);
21117 add_stmt (c_parser_omp_structured_block (parser, if_p));
21118 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21120 SET_EXPR_LOCATION (stmt, loc);
21121 return add_stmt (stmt);
21125 # pragma omp target update target-update-clause[optseq] new-line */
21127 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
21128 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
21129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21136 c_parser_omp_target_update (location_t loc, c_parser *parser,
21137 enum pragma_context context)
21139 if (context == pragma_stmt)
21141 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21142 "omp target update");
21143 c_parser_skip_to_pragma_eol (parser, false);
21148 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
21149 "#pragma omp target update");
21150 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
21151 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
21154 "%<#pragma omp target update%> must contain at least one "
21155 "%<from%> or %<to%> clauses");
21161 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21163 tree stmt = make_node (OMP_TARGET_UPDATE);
21164 TREE_TYPE (stmt) = void_type_node;
21165 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
21166 SET_EXPR_LOCATION (stmt, loc);
21172 # pragma omp target enter data target-data-clause[optseq] new-line */
21174 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21175 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21177 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21182 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
21183 enum pragma_context context)
21185 bool data_seen = false;
21186 if (c_parser_next_token_is (parser, CPP_NAME))
21188 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21189 if (strcmp (p, "data") == 0)
21191 c_parser_consume_token (parser);
21197 c_parser_error (parser, "expected %<data%>");
21198 c_parser_skip_to_pragma_eol (parser);
21202 if (context == pragma_stmt)
21204 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21205 "omp target enter data");
21206 c_parser_skip_to_pragma_eol (parser, false);
21212 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21215 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
21216 "#pragma omp target enter data");
21217 c_omp_adjust_map_clauses (clauses, false);
21219 for (tree *pc = &clauses; *pc;)
21221 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21222 switch (OMP_CLAUSE_MAP_KIND (*pc))
21225 case GOMP_MAP_ALWAYS_TO:
21226 case GOMP_MAP_ALLOC:
21229 case GOMP_MAP_TOFROM:
21230 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
21233 case GOMP_MAP_ALWAYS_TOFROM:
21234 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
21237 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21238 case GOMP_MAP_ALWAYS_POINTER:
21239 case GOMP_MAP_ATTACH_DETACH:
21243 error_at (OMP_CLAUSE_LOCATION (*pc),
21244 "%<#pragma omp target enter data%> with map-type other "
21245 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21246 *pc = OMP_CLAUSE_CHAIN (*pc);
21249 pc = &OMP_CLAUSE_CHAIN (*pc);
21256 "%<#pragma omp target enter data%> must contain at least "
21257 "one %<map%> clause");
21261 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
21262 TREE_TYPE (stmt) = void_type_node;
21263 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
21264 SET_EXPR_LOCATION (stmt, loc);
21270 # pragma omp target exit data target-data-clause[optseq] new-line */
21272 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21273 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21274 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21275 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21276 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21277 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21280 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
21281 enum pragma_context context)
21283 bool data_seen = false;
21284 if (c_parser_next_token_is (parser, CPP_NAME))
21286 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21287 if (strcmp (p, "data") == 0)
21289 c_parser_consume_token (parser);
21295 c_parser_error (parser, "expected %<data%>");
21296 c_parser_skip_to_pragma_eol (parser);
21300 if (context == pragma_stmt)
21302 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21303 "omp target exit data");
21304 c_parser_skip_to_pragma_eol (parser, false);
21310 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21313 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21314 "#pragma omp target exit data");
21315 c_omp_adjust_map_clauses (clauses, false);
21317 for (tree *pc = &clauses; *pc;)
21319 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21320 switch (OMP_CLAUSE_MAP_KIND (*pc))
21322 case GOMP_MAP_FROM:
21323 case GOMP_MAP_ALWAYS_FROM:
21324 case GOMP_MAP_RELEASE:
21325 case GOMP_MAP_DELETE:
21328 case GOMP_MAP_TOFROM:
21329 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
21332 case GOMP_MAP_ALWAYS_TOFROM:
21333 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
21336 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21337 case GOMP_MAP_ALWAYS_POINTER:
21338 case GOMP_MAP_ATTACH_DETACH:
21342 error_at (OMP_CLAUSE_LOCATION (*pc),
21343 "%<#pragma omp target exit data%> with map-type other "
21344 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
21345 "on %<map%> clause");
21346 *pc = OMP_CLAUSE_CHAIN (*pc);
21349 pc = &OMP_CLAUSE_CHAIN (*pc);
21356 "%<#pragma omp target exit data%> must contain at least one "
21361 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
21362 TREE_TYPE (stmt) = void_type_node;
21363 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
21364 SET_EXPR_LOCATION (stmt, loc);
21370 # pragma omp target target-clause[optseq] new-line
21371 structured-block */
21373 #define OMP_TARGET_CLAUSE_MASK \
21374 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21375 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21376 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21377 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21378 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21381 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21383 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21384 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21389 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
21391 location_t loc = c_parser_peek_token (parser)->location;
21392 c_parser_consume_pragma (parser);
21393 tree *pc = NULL, stmt, block;
21395 if (context != pragma_stmt && context != pragma_compound)
21397 c_parser_error (parser, "expected declaration specifiers");
21398 c_parser_skip_to_pragma_eol (parser);
21404 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21406 if (c_parser_next_token_is (parser, CPP_NAME))
21408 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21409 enum tree_code ccode = ERROR_MARK;
21411 if (strcmp (p, "teams") == 0)
21413 else if (strcmp (p, "parallel") == 0)
21414 ccode = OMP_PARALLEL;
21415 else if (strcmp (p, "simd") == 0)
21417 if (ccode != ERROR_MARK)
21419 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
21420 char p_name[sizeof ("#pragma omp target teams distribute "
21421 "parallel for simd")];
21423 c_parser_consume_token (parser);
21424 strcpy (p_name, "#pragma omp target");
21425 if (!flag_openmp) /* flag_openmp_simd */
21431 stmt = c_parser_omp_teams (loc, parser, p_name,
21432 OMP_TARGET_CLAUSE_MASK,
21436 stmt = c_parser_omp_parallel (loc, parser, p_name,
21437 OMP_TARGET_CLAUSE_MASK,
21441 stmt = c_parser_omp_simd (loc, parser, p_name,
21442 OMP_TARGET_CLAUSE_MASK,
21446 gcc_unreachable ();
21448 return stmt != NULL_TREE;
21450 keep_next_level ();
21451 tree block = c_begin_compound_stmt (true), ret;
21455 ret = c_parser_omp_teams (loc, parser, p_name,
21456 OMP_TARGET_CLAUSE_MASK, cclauses,
21460 ret = c_parser_omp_parallel (loc, parser, p_name,
21461 OMP_TARGET_CLAUSE_MASK, cclauses,
21465 ret = c_parser_omp_simd (loc, parser, p_name,
21466 OMP_TARGET_CLAUSE_MASK, cclauses,
21470 gcc_unreachable ();
21472 block = c_end_compound_stmt (loc, block, true);
21473 if (ret == NULL_TREE)
21475 if (ccode == OMP_TEAMS)
21476 /* For combined target teams, ensure the num_teams and
21477 thread_limit clause expressions are evaluated on the host,
21478 before entering the target construct. */
21479 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21480 c; c = OMP_CLAUSE_CHAIN (c))
21481 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
21482 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
21484 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
21485 if (OMP_CLAUSE_OPERAND (c, i)
21486 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
21488 tree expr = OMP_CLAUSE_OPERAND (c, i);
21489 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
21490 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
21491 expr, NULL_TREE, NULL_TREE);
21493 OMP_CLAUSE_OPERAND (c, i) = expr;
21494 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
21495 OMP_CLAUSE_FIRSTPRIVATE);
21496 OMP_CLAUSE_DECL (tc) = tmp;
21497 OMP_CLAUSE_CHAIN (tc)
21498 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21499 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
21501 tree stmt = make_node (OMP_TARGET);
21502 TREE_TYPE (stmt) = void_type_node;
21503 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21504 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21505 OMP_TARGET_BODY (stmt) = block;
21506 OMP_TARGET_COMBINED (stmt) = 1;
21507 SET_EXPR_LOCATION (stmt, loc);
21509 pc = &OMP_TARGET_CLAUSES (stmt);
21510 goto check_clauses;
21512 else if (!flag_openmp) /* flag_openmp_simd */
21514 c_parser_skip_to_pragma_eol (parser, false);
21517 else if (strcmp (p, "data") == 0)
21519 c_parser_consume_token (parser);
21520 c_parser_omp_target_data (loc, parser, if_p);
21523 else if (strcmp (p, "enter") == 0)
21525 c_parser_consume_token (parser);
21526 return c_parser_omp_target_enter_data (loc, parser, context);
21528 else if (strcmp (p, "exit") == 0)
21530 c_parser_consume_token (parser);
21531 return c_parser_omp_target_exit_data (loc, parser, context);
21533 else if (strcmp (p, "update") == 0)
21535 c_parser_consume_token (parser);
21536 return c_parser_omp_target_update (loc, parser, context);
21539 if (!flag_openmp) /* flag_openmp_simd */
21541 c_parser_skip_to_pragma_eol (parser, false);
21545 stmt = make_node (OMP_TARGET);
21546 TREE_TYPE (stmt) = void_type_node;
21548 OMP_TARGET_CLAUSES (stmt)
21549 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
21550 "#pragma omp target", false);
21551 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
21552 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
21554 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
21555 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
21556 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
21557 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
21558 OMP_CLAUSE_CHAIN (c) = nc;
21560 OMP_TARGET_CLAUSES (stmt)
21561 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
21562 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21564 pc = &OMP_TARGET_CLAUSES (stmt);
21565 keep_next_level ();
21566 block = c_begin_compound_stmt (true);
21567 add_stmt (c_parser_omp_structured_block (parser, if_p));
21568 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21570 SET_EXPR_LOCATION (stmt, loc);
21576 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21577 switch (OMP_CLAUSE_MAP_KIND (*pc))
21580 case GOMP_MAP_ALWAYS_TO:
21581 case GOMP_MAP_FROM:
21582 case GOMP_MAP_ALWAYS_FROM:
21583 case GOMP_MAP_TOFROM:
21584 case GOMP_MAP_ALWAYS_TOFROM:
21585 case GOMP_MAP_ALLOC:
21586 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21587 case GOMP_MAP_ALWAYS_POINTER:
21588 case GOMP_MAP_ATTACH_DETACH:
21591 error_at (OMP_CLAUSE_LOCATION (*pc),
21592 "%<#pragma omp target%> with map-type other "
21593 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21594 "on %<map%> clause");
21595 *pc = OMP_CLAUSE_CHAIN (*pc);
21598 pc = &OMP_CLAUSE_CHAIN (*pc);
21600 cfun->has_omp_target = true;
21605 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21608 # pragma omp declare variant (identifier) match(context-selector) new-line
21611 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21612 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21613 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21614 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21615 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21616 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21617 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21620 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
21622 c_token *token = c_parser_peek_token (parser);
21623 gcc_assert (token->type == CPP_NAME);
21624 tree kind = token->value;
21625 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
21626 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
21628 auto_vec<c_token> clauses;
21629 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21631 c_token *token = c_parser_peek_token (parser);
21632 if (token->type == CPP_EOF)
21634 c_parser_skip_to_pragma_eol (parser);
21637 clauses.safe_push (*token);
21638 c_parser_consume_token (parser);
21640 clauses.safe_push (*c_parser_peek_token (parser));
21641 c_parser_skip_to_pragma_eol (parser);
21643 while (c_parser_next_token_is (parser, CPP_PRAGMA))
21645 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
21646 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
21647 || c_parser_peek_2nd_token (parser)->value != kind)
21649 error ("%<#pragma omp declare %s%> must be followed by "
21650 "function declaration or definition or another "
21651 "%<#pragma omp declare %s%>",
21652 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
21655 c_parser_consume_pragma (parser);
21656 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21658 c_token *token = c_parser_peek_token (parser);
21659 if (token->type == CPP_EOF)
21661 c_parser_skip_to_pragma_eol (parser);
21664 clauses.safe_push (*token);
21665 c_parser_consume_token (parser);
21667 clauses.safe_push (*c_parser_peek_token (parser));
21668 c_parser_skip_to_pragma_eol (parser);
21671 /* Make sure nothing tries to read past the end of the tokens. */
21673 memset (&eof_token, 0, sizeof (eof_token));
21674 eof_token.type = CPP_EOF;
21675 clauses.safe_push (eof_token);
21676 clauses.safe_push (eof_token);
21680 case pragma_external:
21681 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21682 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21684 int ext = disable_extension_diagnostics ();
21686 c_parser_consume_token (parser);
21687 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21688 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21689 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21691 restore_extension_diagnostics (ext);
21694 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21697 case pragma_struct:
21700 error ("%<#pragma omp declare %s%> must be followed by "
21701 "function declaration or definition",
21702 IDENTIFIER_POINTER (kind));
21704 case pragma_compound:
21705 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21706 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21708 int ext = disable_extension_diagnostics ();
21710 c_parser_consume_token (parser);
21711 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21712 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21713 if (c_parser_next_tokens_start_declaration (parser))
21715 c_parser_declaration_or_fndef (parser, true, true, true, true,
21716 true, NULL, &clauses);
21717 restore_extension_diagnostics (ext);
21720 restore_extension_diagnostics (ext);
21722 else if (c_parser_next_tokens_start_declaration (parser))
21724 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
21728 error ("%<#pragma omp declare %s%> must be followed by "
21729 "function declaration or definition",
21730 IDENTIFIER_POINTER (kind));
21733 gcc_unreachable ();
21737 static const char *const omp_construct_selectors[] = {
21738 "simd", "target", "teams", "parallel", "for", NULL };
21739 static const char *const omp_device_selectors[] = {
21740 "kind", "isa", "arch", NULL };
21741 static const char *const omp_implementation_selectors[] = {
21742 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21743 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
21744 static const char *const omp_user_selectors[] = {
21745 "condition", NULL };
21750 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21753 score(score-expression) */
21756 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
21758 tree ret = NULL_TREE;
21762 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21763 || c_parser_next_token_is (parser, CPP_NAME))
21764 selector = c_parser_peek_token (parser)->value;
21767 c_parser_error (parser, "expected trait selector name");
21768 return error_mark_node;
21771 tree properties = NULL_TREE;
21772 const char *const *selectors = NULL;
21773 bool allow_score = true;
21774 bool allow_user = false;
21775 int property_limit = 0;
21776 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
21777 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
21778 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
21779 switch (IDENTIFIER_POINTER (set)[0])
21781 case 'c': /* construct */
21782 selectors = omp_construct_selectors;
21783 allow_score = false;
21784 property_limit = 1;
21785 property_kind = CTX_PROPERTY_SIMD;
21787 case 'd': /* device */
21788 selectors = omp_device_selectors;
21789 allow_score = false;
21791 property_limit = 3;
21792 property_kind = CTX_PROPERTY_NAME_LIST;
21794 case 'i': /* implementation */
21795 selectors = omp_implementation_selectors;
21797 property_limit = 3;
21798 property_kind = CTX_PROPERTY_NAME_LIST;
21800 case 'u': /* user */
21801 selectors = omp_user_selectors;
21802 property_limit = 1;
21803 property_kind = CTX_PROPERTY_EXPR;
21806 gcc_unreachable ();
21808 for (int i = 0; ; i++)
21810 if (selectors[i] == NULL)
21814 property_kind = CTX_PROPERTY_USER;
21819 error_at (c_parser_peek_token (parser)->location,
21820 "selector %qs not allowed for context selector "
21821 "set %qs", IDENTIFIER_POINTER (selector),
21822 IDENTIFIER_POINTER (set));
21823 c_parser_consume_token (parser);
21824 return error_mark_node;
21827 if (i == property_limit)
21828 property_kind = CTX_PROPERTY_NONE;
21829 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
21832 if (property_kind == CTX_PROPERTY_NAME_LIST
21833 && IDENTIFIER_POINTER (set)[0] == 'i'
21834 && strcmp (IDENTIFIER_POINTER (selector),
21835 "atomic_default_mem_order") == 0)
21836 property_kind = CTX_PROPERTY_ID;
21838 c_parser_consume_token (parser);
21840 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21842 if (property_kind == CTX_PROPERTY_NONE)
21844 error_at (c_parser_peek_token (parser)->location,
21845 "selector %qs does not accept any properties",
21846 IDENTIFIER_POINTER (selector));
21847 return error_mark_node;
21850 matching_parens parens;
21851 parens.require_open (parser);
21853 c_token *token = c_parser_peek_token (parser);
21855 && c_parser_next_token_is (parser, CPP_NAME)
21856 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
21857 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
21859 c_parser_consume_token (parser);
21861 matching_parens parens2;
21862 parens2.require_open (parser);
21863 tree score = c_parser_expr_no_commas (parser, NULL).value;
21864 parens2.skip_until_found_close (parser);
21865 c_parser_require (parser, CPP_COLON, "expected %<:%>");
21866 if (score != error_mark_node)
21868 mark_exp_read (score);
21869 score = c_fully_fold (score, false, NULL);
21870 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
21871 || TREE_CODE (score) != INTEGER_CST)
21872 error_at (token->location, "score argument must be "
21873 "constant integer expression");
21874 else if (tree_int_cst_sgn (score) < 0)
21875 error_at (token->location, "score argument must be "
21878 properties = tree_cons (get_identifier (" score"),
21879 score, properties);
21881 token = c_parser_peek_token (parser);
21884 switch (property_kind)
21887 case CTX_PROPERTY_USER:
21890 t = c_parser_expr_no_commas (parser, NULL).value;
21891 if (TREE_CODE (t) == STRING_CST)
21892 properties = tree_cons (NULL_TREE, t, properties);
21893 else if (t != error_mark_node)
21896 t = c_fully_fold (t, false, NULL);
21897 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21898 || !tree_fits_shwi_p (t))
21899 error_at (token->location, "property must be "
21900 "constant integer expression or string "
21903 properties = tree_cons (NULL_TREE, t, properties);
21906 return error_mark_node;
21908 if (c_parser_next_token_is (parser, CPP_COMMA))
21909 c_parser_consume_token (parser);
21915 case CTX_PROPERTY_ID:
21916 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21917 || c_parser_next_token_is (parser, CPP_NAME))
21919 tree prop = c_parser_peek_token (parser)->value;
21920 c_parser_consume_token (parser);
21921 properties = tree_cons (prop, NULL_TREE, properties);
21925 c_parser_error (parser, "expected identifier");
21926 return error_mark_node;
21929 case CTX_PROPERTY_NAME_LIST:
21932 tree prop = NULL_TREE, value = NULL_TREE;
21933 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21934 || c_parser_next_token_is (parser, CPP_NAME))
21936 prop = c_parser_peek_token (parser)->value;
21937 c_parser_consume_token (parser);
21939 else if (c_parser_next_token_is (parser, CPP_STRING))
21940 value = c_parser_string_literal (parser, false,
21944 c_parser_error (parser, "expected identifier or "
21946 return error_mark_node;
21949 properties = tree_cons (prop, value, properties);
21951 if (c_parser_next_token_is (parser, CPP_COMMA))
21952 c_parser_consume_token (parser);
21958 case CTX_PROPERTY_EXPR:
21959 t = c_parser_expr_no_commas (parser, NULL).value;
21960 if (t != error_mark_node)
21963 t = c_fully_fold (t, false, NULL);
21964 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21965 || !tree_fits_shwi_p (t))
21966 error_at (token->location, "property must be "
21967 "constant integer expression");
21969 properties = tree_cons (NULL_TREE, t, properties);
21972 return error_mark_node;
21974 case CTX_PROPERTY_SIMD:
21975 if (parms == NULL_TREE)
21977 error_at (token->location, "properties for %<simd%> "
21978 "selector may not be specified in "
21979 "%<metadirective%>");
21980 return error_mark_node;
21983 c = c_parser_omp_all_clauses (parser,
21984 OMP_DECLARE_SIMD_CLAUSE_MASK,
21986 c = c_omp_declare_simd_clauses_to_numbers (parms
21988 ? NULL_TREE : parms,
21993 gcc_unreachable ();
21996 parens.skip_until_found_close (parser);
21997 properties = nreverse (properties);
21999 else if (property_kind == CTX_PROPERTY_NAME_LIST
22000 || property_kind == CTX_PROPERTY_ID
22001 || property_kind == CTX_PROPERTY_EXPR)
22003 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
22004 return error_mark_node;
22007 ret = tree_cons (selector, properties, ret);
22009 if (c_parser_next_token_is (parser, CPP_COMMA))
22010 c_parser_consume_token (parser);
22016 return nreverse (ret);
22021 trait-set-selector[,trait-set-selector[,...]]
22023 trait-set-selector:
22024 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
22026 trait-set-selector-name:
22033 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
22035 tree ret = NULL_TREE;
22038 const char *setp = "";
22039 if (c_parser_next_token_is (parser, CPP_NAME))
22040 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22044 if (strcmp (setp, "construct") == 0)
22048 if (strcmp (setp, "device") == 0)
22052 if (strcmp (setp, "implementation") == 0)
22056 if (strcmp (setp, "user") == 0)
22064 c_parser_error (parser, "expected %<construct%>, %<device%>, "
22065 "%<implementation%> or %<user%>");
22066 return error_mark_node;
22069 tree set = c_parser_peek_token (parser)->value;
22070 c_parser_consume_token (parser);
22072 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22073 return error_mark_node;
22075 matching_braces braces;
22076 if (!braces.require_open (parser))
22077 return error_mark_node;
22079 tree selectors = c_parser_omp_context_selector (parser, set, parms);
22080 if (selectors == error_mark_node)
22081 ret = error_mark_node;
22082 else if (ret != error_mark_node)
22083 ret = tree_cons (set, selectors, ret);
22085 braces.skip_until_found_close (parser);
22087 if (c_parser_next_token_is (parser, CPP_COMMA))
22088 c_parser_consume_token (parser);
22094 if (ret == error_mark_node)
22096 return nreverse (ret);
22099 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
22100 that into "omp declare variant base" attribute. */
22103 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
22105 matching_parens parens;
22106 if (!parens.require_open (parser))
22109 c_parser_skip_to_pragma_eol (parser, false);
22113 if (c_parser_next_token_is_not (parser, CPP_NAME)
22114 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22116 c_parser_error (parser, "expected identifier");
22120 c_token *token = c_parser_peek_token (parser);
22121 tree variant = lookup_name (token->value);
22123 if (variant == NULL_TREE)
22125 undeclared_variable (token->location, token->value);
22126 variant = error_mark_node;
22129 c_parser_consume_token (parser);
22131 parens.require_close (parser);
22133 const char *clause = "";
22134 location_t match_loc = c_parser_peek_token (parser)->location;
22135 if (c_parser_next_token_is (parser, CPP_NAME))
22136 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22137 if (strcmp (clause, "match"))
22139 c_parser_error (parser, "expected %<match%>");
22143 c_parser_consume_token (parser);
22145 if (!parens.require_open (parser))
22148 if (parms == NULL_TREE)
22149 parms = error_mark_node;
22151 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
22152 if (ctx == error_mark_node)
22154 ctx = omp_check_context_selector (match_loc, ctx);
22155 if (ctx != error_mark_node && variant != error_mark_node)
22157 if (TREE_CODE (variant) != FUNCTION_DECL)
22159 error_at (token->location, "variant %qD is not a function", variant);
22160 variant = error_mark_node;
22162 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
22163 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
22165 error_at (token->location, "variant %qD and base %qD have "
22166 "incompatible types", variant, fndecl);
22167 variant = error_mark_node;
22169 else if (fndecl_built_in_p (variant)
22170 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22171 "__builtin_", strlen ("__builtin_")) == 0
22172 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22173 "__sync_", strlen ("__sync_")) == 0
22174 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22175 "__atomic_", strlen ("__atomic_")) == 0))
22177 error_at (token->location, "variant %qD is a built-in", variant);
22178 variant = error_mark_node;
22180 if (variant != error_mark_node)
22182 C_DECL_USED (variant) = 1;
22183 tree construct = omp_get_context_selector (ctx, "construct", NULL);
22184 omp_mark_declare_variant (match_loc, variant, construct);
22185 if (omp_context_selector_matches (ctx))
22188 = tree_cons (get_identifier ("omp declare variant base"),
22189 build_tree_list (variant, ctx),
22190 DECL_ATTRIBUTES (fndecl));
22191 DECL_ATTRIBUTES (fndecl) = attr;
22196 parens.require_close (parser);
22197 c_parser_skip_to_pragma_eol (parser);
22200 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22201 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22202 or "omp declare variant base" attribute. */
22205 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
22206 vec<c_token> *pclauses)
22208 vec<c_token> &clauses = *pclauses;
22210 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22211 indicates error has been reported and CPP_PRAGMA that
22212 c_finish_omp_declare_simd has already processed the tokens. */
22213 if (clauses.exists () && clauses[0].type == CPP_EOF)
22215 const char *kind = "simd";
22216 if (clauses.exists ()
22217 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
22218 kind = IDENTIFIER_POINTER (clauses[0].value);
22219 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
22220 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
22222 error ("%<#pragma omp declare %s%> not immediately followed by "
22223 "a function declaration or definition", kind);
22224 clauses[0].type = CPP_EOF;
22227 if (clauses.exists () && clauses[0].type != CPP_NAME)
22229 error_at (DECL_SOURCE_LOCATION (fndecl),
22230 "%<#pragma omp declare %s%> not immediately followed by "
22231 "a single function declaration or definition", kind);
22232 clauses[0].type = CPP_EOF;
22236 if (parms == NULL_TREE)
22237 parms = DECL_ARGUMENTS (fndecl);
22239 unsigned int tokens_avail = parser->tokens_avail;
22240 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22242 parser->tokens = clauses.address ();
22243 parser->tokens_avail = clauses.length ();
22245 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22246 while (parser->tokens_avail > 3)
22248 c_token *token = c_parser_peek_token (parser);
22249 gcc_assert (token->type == CPP_NAME
22250 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
22251 c_parser_consume_token (parser);
22252 parser->in_pragma = true;
22254 if (strcmp (kind, "simd") == 0)
22257 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
22258 "#pragma omp declare simd");
22259 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
22260 if (c != NULL_TREE)
22261 c = tree_cons (NULL_TREE, c, NULL_TREE);
22262 c = build_tree_list (get_identifier ("omp declare simd"), c);
22263 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
22264 DECL_ATTRIBUTES (fndecl) = c;
22268 gcc_assert (strcmp (kind, "variant") == 0);
22269 c_finish_omp_declare_variant (parser, fndecl, parms);
22273 parser->tokens = &parser->tokens_buf[0];
22274 parser->tokens_avail = tokens_avail;
22275 if (clauses.exists ())
22276 clauses[0].type = CPP_PRAGMA;
22281 # pragma omp declare target new-line
22282 declarations and definitions
22283 # pragma omp end declare target new-line
22286 # pragma omp declare target ( extended-list ) new-line
22288 # pragma omp declare target declare-target-clauses[seq] new-line */
22290 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22291 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22292 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22293 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22294 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22297 c_parser_omp_declare_target (c_parser *parser)
22299 tree clauses = NULL_TREE;
22300 int device_type = 0;
22301 bool only_device_type = true;
22302 if (c_parser_next_token_is (parser, CPP_NAME))
22303 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
22304 "#pragma omp declare target");
22305 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22307 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
22309 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22310 c_parser_skip_to_pragma_eol (parser);
22314 c_parser_skip_to_pragma_eol (parser);
22315 current_omp_declare_target_attribute++;
22318 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22319 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22320 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22321 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22323 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22325 tree t = OMP_CLAUSE_DECL (c), id;
22326 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
22327 tree at2 = lookup_attribute ("omp declare target link",
22328 DECL_ATTRIBUTES (t));
22329 only_device_type = false;
22330 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
22332 id = get_identifier ("omp declare target link");
22333 std::swap (at1, at2);
22336 id = get_identifier ("omp declare target");
22339 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
22340 error_at (OMP_CLAUSE_LOCATION (c),
22341 "%qD specified both in declare target %<link%> and %qs"
22342 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
22344 error_at (OMP_CLAUSE_LOCATION (c),
22345 "%qD specified both in declare target %<link%> and "
22346 "%<to%> or %<enter%> clauses", t);
22351 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22352 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
22355 symtab_node *node = symtab_node::get (t);
22358 node->offloadable = 1;
22359 if (ENABLE_OFFLOADING)
22361 g->have_offload = true;
22362 if (is_a <varpool_node *> (node))
22363 vec_safe_push (offload_vars, t);
22367 if (TREE_CODE (t) != FUNCTION_DECL)
22369 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
22371 tree at3 = lookup_attribute ("omp declare target host",
22372 DECL_ATTRIBUTES (t));
22373 if (at3 == NULL_TREE)
22375 id = get_identifier ("omp declare target host");
22376 DECL_ATTRIBUTES (t)
22377 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22380 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
22382 tree at3 = lookup_attribute ("omp declare target nohost",
22383 DECL_ATTRIBUTES (t));
22384 if (at3 == NULL_TREE)
22386 id = get_identifier ("omp declare target nohost");
22387 DECL_ATTRIBUTES (t)
22388 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22392 if (device_type && only_device_type)
22393 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
22394 "directive with only %<device_type%> clauses ignored");
22398 c_parser_omp_end_declare_target (c_parser *parser)
22400 location_t loc = c_parser_peek_token (parser)->location;
22401 c_parser_consume_pragma (parser);
22402 if (c_parser_next_token_is (parser, CPP_NAME)
22403 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22406 c_parser_consume_token (parser);
22407 if (c_parser_next_token_is (parser, CPP_NAME)
22408 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22410 c_parser_consume_token (parser);
22413 c_parser_error (parser, "expected %<target%>");
22414 c_parser_skip_to_pragma_eol (parser);
22420 c_parser_error (parser, "expected %<declare%>");
22421 c_parser_skip_to_pragma_eol (parser);
22424 c_parser_skip_to_pragma_eol (parser);
22425 if (!current_omp_declare_target_attribute)
22426 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
22427 "%<#pragma omp declare target%>");
22429 current_omp_declare_target_attribute--;
22434 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22435 initializer-clause[opt] new-line
22437 initializer-clause:
22438 initializer (omp_priv = initializer)
22439 initializer (function-name (argument-list)) */
22442 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
22444 unsigned int tokens_avail = 0, i;
22445 vec<tree> types = vNULL;
22446 vec<c_token> clauses = vNULL;
22447 enum tree_code reduc_code = ERROR_MARK;
22448 tree reduc_id = NULL_TREE;
22450 location_t rloc = c_parser_peek_token (parser)->location;
22452 if (context == pragma_struct || context == pragma_param)
22454 error ("%<#pragma omp declare reduction%> not at file or block scope");
22458 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22461 switch (c_parser_peek_token (parser)->type)
22464 reduc_code = PLUS_EXPR;
22467 reduc_code = MULT_EXPR;
22470 reduc_code = MINUS_EXPR;
22473 reduc_code = BIT_AND_EXPR;
22476 reduc_code = BIT_XOR_EXPR;
22479 reduc_code = BIT_IOR_EXPR;
22482 reduc_code = TRUTH_ANDIF_EXPR;
22485 reduc_code = TRUTH_ORIF_EXPR;
22489 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22490 if (strcmp (p, "min") == 0)
22492 reduc_code = MIN_EXPR;
22495 if (strcmp (p, "max") == 0)
22497 reduc_code = MAX_EXPR;
22500 reduc_id = c_parser_peek_token (parser)->value;
22503 c_parser_error (parser,
22504 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22505 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22509 tree orig_reduc_id, reduc_decl;
22510 orig_reduc_id = reduc_id;
22511 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
22512 reduc_decl = c_omp_reduction_decl (reduc_id);
22513 c_parser_consume_token (parser);
22515 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
22520 location_t loc = c_parser_peek_token (parser)->location;
22521 struct c_type_name *ctype = c_parser_type_name (parser);
22524 type = groktypename (ctype, NULL, NULL);
22525 if (type == error_mark_node)
22527 else if ((INTEGRAL_TYPE_P (type)
22528 || TREE_CODE (type) == REAL_TYPE
22529 || TREE_CODE (type) == COMPLEX_TYPE)
22530 && orig_reduc_id == NULL_TREE)
22531 error_at (loc, "predeclared arithmetic type in "
22532 "%<#pragma omp declare reduction%>");
22533 else if (TREE_CODE (type) == FUNCTION_TYPE
22534 || TREE_CODE (type) == ARRAY_TYPE)
22535 error_at (loc, "function or array type in "
22536 "%<#pragma omp declare reduction%>");
22537 else if (TYPE_ATOMIC (type))
22538 error_at (loc, "%<_Atomic%> qualified type in "
22539 "%<#pragma omp declare reduction%>");
22540 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
22541 error_at (loc, "const, volatile or restrict qualified type in "
22542 "%<#pragma omp declare reduction%>");
22546 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
22547 if (comptypes (TREE_PURPOSE (t), type))
22549 error_at (loc, "redeclaration of %qs "
22550 "%<#pragma omp declare reduction%> for "
22552 IDENTIFIER_POINTER (reduc_id)
22553 + sizeof ("omp declare reduction ") - 1,
22556 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
22558 error_at (ploc, "previous %<#pragma omp declare "
22562 if (t == NULL_TREE)
22563 types.safe_push (type);
22565 if (c_parser_next_token_is (parser, CPP_COMMA))
22566 c_parser_consume_token (parser);
22574 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
22575 || types.is_empty ())
22578 clauses.release ();
22582 c_token *token = c_parser_peek_token (parser);
22583 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
22585 c_parser_consume_token (parser);
22587 c_parser_skip_to_pragma_eol (parser);
22591 if (types.length () > 1)
22593 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22595 c_token *token = c_parser_peek_token (parser);
22596 if (token->type == CPP_EOF)
22598 clauses.safe_push (*token);
22599 c_parser_consume_token (parser);
22601 clauses.safe_push (*c_parser_peek_token (parser));
22602 c_parser_skip_to_pragma_eol (parser);
22604 /* Make sure nothing tries to read past the end of the tokens. */
22606 memset (&eof_token, 0, sizeof (eof_token));
22607 eof_token.type = CPP_EOF;
22608 clauses.safe_push (eof_token);
22609 clauses.safe_push (eof_token);
22612 int errs = errorcount;
22613 FOR_EACH_VEC_ELT (types, i, type)
22615 tokens_avail = parser->tokens_avail;
22616 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22617 if (!clauses.is_empty ())
22619 parser->tokens = clauses.address ();
22620 parser->tokens_avail = clauses.length ();
22621 parser->in_pragma = true;
22624 bool nested = current_function_decl != NULL_TREE;
22626 c_push_function_context ();
22627 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
22628 reduc_id, default_function_type);
22629 current_function_decl = fndecl;
22630 allocate_struct_function (fndecl, true);
22632 tree stmt = push_stmt_list ();
22633 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22634 warn about these. */
22635 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
22636 get_identifier ("omp_out"), type);
22637 DECL_ARTIFICIAL (omp_out) = 1;
22638 DECL_CONTEXT (omp_out) = fndecl;
22639 pushdecl (omp_out);
22640 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
22641 get_identifier ("omp_in"), type);
22642 DECL_ARTIFICIAL (omp_in) = 1;
22643 DECL_CONTEXT (omp_in) = fndecl;
22645 struct c_expr combiner = c_parser_expression (parser);
22646 struct c_expr initializer;
22647 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
22649 initializer.set_error ();
22650 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22652 else if (c_parser_next_token_is (parser, CPP_NAME)
22653 && strcmp (IDENTIFIER_POINTER
22654 (c_parser_peek_token (parser)->value),
22655 "initializer") == 0)
22657 c_parser_consume_token (parser);
22660 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
22661 get_identifier ("omp_priv"), type);
22662 DECL_ARTIFICIAL (omp_priv) = 1;
22663 DECL_INITIAL (omp_priv) = error_mark_node;
22664 DECL_CONTEXT (omp_priv) = fndecl;
22665 pushdecl (omp_priv);
22666 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
22667 get_identifier ("omp_orig"), type);
22668 DECL_ARTIFICIAL (omp_orig) = 1;
22669 DECL_CONTEXT (omp_orig) = fndecl;
22670 pushdecl (omp_orig);
22671 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22673 else if (!c_parser_next_token_is (parser, CPP_NAME))
22675 c_parser_error (parser, "expected %<omp_priv%> or "
22679 else if (strcmp (IDENTIFIER_POINTER
22680 (c_parser_peek_token (parser)->value),
22683 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
22684 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22686 c_parser_error (parser, "expected function-name %<(%>");
22690 initializer = c_parser_postfix_expression (parser);
22691 if (initializer.value
22692 && TREE_CODE (initializer.value) == CALL_EXPR)
22695 tree c = initializer.value;
22696 for (j = 0; j < call_expr_nargs (c); j++)
22698 tree a = CALL_EXPR_ARG (c, j);
22700 if (TREE_CODE (a) == ADDR_EXPR
22701 && TREE_OPERAND (a, 0) == omp_priv)
22704 if (j == call_expr_nargs (c))
22705 error ("one of the initializer call arguments should be "
22711 c_parser_consume_token (parser);
22712 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22716 tree st = push_stmt_list ();
22717 location_t loc = c_parser_peek_token (parser)->location;
22718 rich_location richloc (line_table, loc);
22719 start_init (omp_priv, NULL_TREE, 0, &richloc);
22720 struct c_expr init = c_parser_initializer (parser, omp_priv);
22722 finish_decl (omp_priv, loc, init.value,
22723 init.original_type, NULL_TREE);
22724 pop_stmt_list (st);
22728 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22734 c_parser_skip_to_pragma_eol (parser);
22736 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
22737 DECL_INITIAL (reduc_decl));
22738 DECL_INITIAL (reduc_decl) = t;
22739 DECL_SOURCE_LOCATION (omp_out) = rloc;
22740 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
22741 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
22742 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
22743 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
22744 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
22747 DECL_SOURCE_LOCATION (omp_priv) = rloc;
22748 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
22749 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
22750 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
22751 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
22752 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22753 walk_tree (&DECL_INITIAL (omp_priv),
22754 c_check_omp_declare_reduction_r,
22755 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22759 pop_stmt_list (stmt);
22761 if (cfun->language != NULL)
22763 ggc_free (cfun->language);
22764 cfun->language = NULL;
22767 current_function_decl = NULL_TREE;
22769 c_pop_function_context ();
22771 if (!clauses.is_empty ())
22773 parser->tokens = &parser->tokens_buf[0];
22774 parser->tokens_avail = tokens_avail;
22778 if (errs != errorcount)
22782 clauses.release ();
22788 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22789 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22790 initializer-clause[opt] new-line
22791 #pragma omp declare target new-line
22794 #pragma omp declare variant (identifier) match (context-selector) */
22797 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
22799 c_parser_consume_pragma (parser);
22800 if (c_parser_next_token_is (parser, CPP_NAME))
22802 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22803 if (strcmp (p, "simd") == 0)
22805 /* c_parser_consume_token (parser); done in
22806 c_parser_omp_declare_simd. */
22807 c_parser_omp_declare_simd (parser, context);
22810 if (strcmp (p, "reduction") == 0)
22812 c_parser_consume_token (parser);
22813 c_parser_omp_declare_reduction (parser, context);
22816 if (!flag_openmp) /* flag_openmp_simd */
22818 c_parser_skip_to_pragma_eol (parser, false);
22821 if (strcmp (p, "target") == 0)
22823 c_parser_consume_token (parser);
22824 c_parser_omp_declare_target (parser);
22827 if (strcmp (p, "variant") == 0)
22829 /* c_parser_consume_token (parser); done in
22830 c_parser_omp_declare_simd. */
22831 c_parser_omp_declare_simd (parser, context);
22836 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
22837 "%<target%> or %<variant%>");
22838 c_parser_skip_to_pragma_eol (parser);
22843 #pragma omp requires clauses[optseq] new-line */
22846 c_parser_omp_requires (c_parser *parser)
22849 enum omp_requires new_req = (enum omp_requires) 0;
22851 c_parser_consume_pragma (parser);
22853 location_t loc = c_parser_peek_token (parser)->location;
22854 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22857 && c_parser_next_token_is (parser, CPP_COMMA)
22858 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22859 c_parser_consume_token (parser);
22863 if (c_parser_next_token_is (parser, CPP_NAME))
22866 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22867 location_t cloc = c_parser_peek_token (parser)->location;
22868 enum omp_requires this_req = (enum omp_requires) 0;
22870 if (!strcmp (p, "unified_address"))
22871 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
22872 else if (!strcmp (p, "unified_shared_memory"))
22873 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
22874 else if (!strcmp (p, "dynamic_allocators"))
22875 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
22876 else if (!strcmp (p, "reverse_offload"))
22877 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
22878 else if (!strcmp (p, "atomic_default_mem_order"))
22880 c_parser_consume_token (parser);
22882 matching_parens parens;
22883 if (parens.require_open (parser))
22885 if (c_parser_next_token_is (parser, CPP_NAME))
22887 tree v = c_parser_peek_token (parser)->value;
22888 p = IDENTIFIER_POINTER (v);
22890 if (!strcmp (p, "seq_cst"))
22892 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
22893 else if (!strcmp (p, "relaxed"))
22895 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
22896 else if (!strcmp (p, "acq_rel"))
22898 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
22902 error_at (c_parser_peek_token (parser)->location,
22903 "expected %<seq_cst%>, %<relaxed%> or "
22905 switch (c_parser_peek_token (parser)->type)
22908 case CPP_PRAGMA_EOL:
22909 case CPP_CLOSE_PAREN:
22912 if (c_parser_peek_2nd_token (parser)->type
22913 == CPP_CLOSE_PAREN)
22914 c_parser_consume_token (parser);
22919 c_parser_consume_token (parser);
22921 parens.skip_until_found_close (parser);
22924 c_parser_skip_to_pragma_eol (parser, false);
22932 error_at (cloc, "expected %<unified_address%>, "
22933 "%<unified_shared_memory%>, "
22934 "%<dynamic_allocators%>, "
22935 "%<reverse_offload%> "
22936 "or %<atomic_default_mem_order%> clause");
22937 c_parser_skip_to_pragma_eol (parser, false);
22941 c_parser_consume_token (parser);
22944 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22946 if ((this_req & new_req) != 0)
22947 error_at (cloc, "too many %qs clauses", p);
22948 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
22949 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
22950 error_at (cloc, "%qs clause used lexically after first "
22951 "target construct or offloading API", p);
22953 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22955 error_at (cloc, "too many %qs clauses",
22956 "atomic_default_mem_order");
22957 this_req = (enum omp_requires) 0;
22959 else if ((omp_requires_mask
22960 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22962 error_at (cloc, "more than one %<atomic_default_mem_order%>"
22963 " clause in a single compilation unit");
22965 = (enum omp_requires)
22967 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
22969 else if ((omp_requires_mask
22970 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
22971 error_at (cloc, "%<atomic_default_mem_order%> clause used "
22972 "lexically after first %<atomic%> construct "
22973 "without memory order clause");
22974 new_req = (enum omp_requires) (new_req | this_req);
22976 = (enum omp_requires) (omp_requires_mask | this_req);
22982 c_parser_skip_to_pragma_eol (parser);
22985 error_at (loc, "%<pragma omp requires%> requires at least one clause");
22988 /* Helper function for c_parser_omp_taskloop.
22989 Disallow zero sized or potentially zero sized task reductions. */
22992 c_finish_taskloop_clauses (tree clauses)
22994 tree *pc = &clauses;
22995 for (tree c = clauses; c; c = *pc)
22997 bool remove = false;
22998 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
23000 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
23001 if (integer_zerop (TYPE_SIZE_UNIT (type)))
23003 error_at (OMP_CLAUSE_LOCATION (c),
23004 "zero sized type %qT in %<reduction%> clause", type);
23007 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
23009 error_at (OMP_CLAUSE_LOCATION (c),
23010 "variable sized type %qT in %<reduction%> clause",
23016 *pc = OMP_CLAUSE_CHAIN (c);
23018 pc = &OMP_CLAUSE_CHAIN (c);
23024 #pragma omp taskloop taskloop-clause[optseq] new-line
23027 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
23030 #define OMP_TASKLOOP_CLAUSE_MASK \
23031 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23032 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23033 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23034 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23035 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23036 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
23037 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
23038 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23039 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23040 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23041 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23042 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23043 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
23044 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23047 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
23050 c_parser_omp_taskloop (location_t loc, c_parser *parser,
23051 char *p_name, omp_clause_mask mask, tree *cclauses,
23054 tree clauses, block, ret;
23056 strcat (p_name, " taskloop");
23057 mask |= OMP_TASKLOOP_CLAUSE_MASK;
23058 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
23060 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
23061 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
23063 if (c_parser_next_token_is (parser, CPP_NAME))
23065 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23067 if (strcmp (p, "simd") == 0)
23069 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23070 if (cclauses == NULL)
23071 cclauses = cclauses_buf;
23072 c_parser_consume_token (parser);
23073 if (!flag_openmp) /* flag_openmp_simd */
23074 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23076 block = c_begin_compound_stmt (true);
23077 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
23078 block = c_end_compound_stmt (loc, block, true);
23081 ret = make_node (OMP_TASKLOOP);
23082 TREE_TYPE (ret) = void_type_node;
23083 OMP_FOR_BODY (ret) = block;
23084 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
23085 OMP_FOR_CLAUSES (ret)
23086 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
23087 SET_EXPR_LOCATION (ret, loc);
23092 if (!flag_openmp) /* flag_openmp_simd */
23094 c_parser_skip_to_pragma_eol (parser, false);
23098 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23101 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
23102 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
23105 clauses = c_finish_taskloop_clauses (clauses);
23106 block = c_begin_compound_stmt (true);
23107 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
23108 block = c_end_compound_stmt (loc, block, true);
23115 #pragma omp nothing new-line */
23118 c_parser_omp_nothing (c_parser *parser)
23120 c_parser_consume_pragma (parser);
23121 c_parser_skip_to_pragma_eol (parser);
23125 #pragma omp error clauses[optseq] new-line */
23128 c_parser_omp_error (c_parser *parser, enum pragma_context context)
23130 int at_compilation = -1;
23131 int severity_fatal = -1;
23132 tree message = NULL_TREE;
23135 location_t loc = c_parser_peek_token (parser)->location;
23137 c_parser_consume_pragma (parser);
23139 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23142 && c_parser_next_token_is (parser, CPP_COMMA)
23143 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23144 c_parser_consume_token (parser);
23148 if (!c_parser_next_token_is (parser, CPP_NAME))
23152 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23153 location_t cloc = c_parser_peek_token (parser)->location;
23154 static const char *args[] = {
23155 "execution", "compilation", "warning", "fatal"
23158 int idx = 0, n = -1;
23159 tree m = NULL_TREE;
23161 if (!strcmp (p, "at"))
23162 v = &at_compilation;
23163 else if (!strcmp (p, "severity"))
23165 v = &severity_fatal;
23168 else if (strcmp (p, "message"))
23171 "expected %<at%>, %<severity%> or %<message%> clause");
23172 c_parser_skip_to_pragma_eol (parser, false);
23176 c_parser_consume_token (parser);
23178 matching_parens parens;
23179 if (parens.require_open (parser))
23183 location_t expr_loc = c_parser_peek_token (parser)->location;
23184 c_expr expr = c_parser_expr_no_commas (parser, NULL);
23185 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
23186 m = convert (const_string_type_node, expr.value);
23187 m = c_fully_fold (m, false, NULL);
23191 if (c_parser_next_token_is (parser, CPP_NAME))
23193 tree val = c_parser_peek_token (parser)->value;
23194 const char *q = IDENTIFIER_POINTER (val);
23196 if (!strcmp (q, args[idx]))
23198 else if (!strcmp (q, args[idx + 1]))
23203 error_at (c_parser_peek_token (parser)->location,
23204 "expected %qs or %qs", args[idx], args[idx + 1]);
23206 switch (c_parser_peek_token (parser)->type)
23209 case CPP_PRAGMA_EOL:
23210 case CPP_CLOSE_PAREN:
23213 if (c_parser_peek_2nd_token (parser)->type
23214 == CPP_CLOSE_PAREN)
23215 c_parser_consume_token (parser);
23220 c_parser_consume_token (parser);
23223 parens.skip_until_found_close (parser);
23229 error_at (cloc, "too many %qs clauses", p);
23239 error_at (cloc, "too many %qs clauses", p);
23249 c_parser_skip_to_pragma_eol (parser);
23253 if (at_compilation == -1)
23254 at_compilation = 1;
23255 if (severity_fatal == -1)
23256 severity_fatal = 1;
23257 if (!at_compilation)
23259 if (context != pragma_compound)
23261 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
23262 "may only be used in compound statements");
23266 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
23267 : BUILT_IN_GOMP_WARNING);
23269 message = build_zero_cst (const_string_type_node);
23270 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
23271 build_all_ones_cst (size_type_node));
23275 const char *msg = NULL;
23278 msg = c_getstr (message);
23280 msg = _("<message unknown at compile time>");
23283 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23284 "%<pragma omp error%> encountered: %s", msg);
23286 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23287 "%<pragma omp error%> encountered");
23291 /* Main entry point to parsing most OpenMP pragmas. */
23294 c_parser_omp_construct (c_parser *parser, bool *if_p)
23296 enum pragma_kind p_kind;
23299 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
23300 omp_clause_mask mask (0);
23302 loc = c_parser_peek_token (parser)->location;
23303 p_kind = c_parser_peek_token (parser)->pragma_kind;
23304 c_parser_consume_pragma (parser);
23308 case PRAGMA_OACC_ATOMIC:
23309 c_parser_omp_atomic (loc, parser, true);
23311 case PRAGMA_OACC_CACHE:
23312 strcpy (p_name, "#pragma acc");
23313 stmt = c_parser_oacc_cache (loc, parser);
23315 case PRAGMA_OACC_DATA:
23316 stmt = c_parser_oacc_data (loc, parser, if_p);
23318 case PRAGMA_OACC_HOST_DATA:
23319 stmt = c_parser_oacc_host_data (loc, parser, if_p);
23321 case PRAGMA_OACC_KERNELS:
23322 case PRAGMA_OACC_PARALLEL:
23323 case PRAGMA_OACC_SERIAL:
23324 strcpy (p_name, "#pragma acc");
23325 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
23327 case PRAGMA_OACC_LOOP:
23328 strcpy (p_name, "#pragma acc");
23329 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
23331 case PRAGMA_OACC_WAIT:
23332 strcpy (p_name, "#pragma wait");
23333 stmt = c_parser_oacc_wait (loc, parser, p_name);
23335 case PRAGMA_OMP_ALLOCATE:
23336 c_parser_omp_allocate (loc, parser);
23338 case PRAGMA_OMP_ATOMIC:
23339 c_parser_omp_atomic (loc, parser, false);
23341 case PRAGMA_OMP_CRITICAL:
23342 stmt = c_parser_omp_critical (loc, parser, if_p);
23344 case PRAGMA_OMP_DISTRIBUTE:
23345 strcpy (p_name, "#pragma omp");
23346 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
23348 case PRAGMA_OMP_FOR:
23349 strcpy (p_name, "#pragma omp");
23350 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
23352 case PRAGMA_OMP_LOOP:
23353 strcpy (p_name, "#pragma omp");
23354 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
23356 case PRAGMA_OMP_MASKED:
23357 strcpy (p_name, "#pragma omp");
23358 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
23360 case PRAGMA_OMP_MASTER:
23361 strcpy (p_name, "#pragma omp");
23362 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
23364 case PRAGMA_OMP_PARALLEL:
23365 strcpy (p_name, "#pragma omp");
23366 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
23368 case PRAGMA_OMP_SCOPE:
23369 stmt = c_parser_omp_scope (loc, parser, if_p);
23371 case PRAGMA_OMP_SECTIONS:
23372 strcpy (p_name, "#pragma omp");
23373 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
23375 case PRAGMA_OMP_SIMD:
23376 strcpy (p_name, "#pragma omp");
23377 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
23379 case PRAGMA_OMP_SINGLE:
23380 stmt = c_parser_omp_single (loc, parser, if_p);
23382 case PRAGMA_OMP_TASK:
23383 stmt = c_parser_omp_task (loc, parser, if_p);
23385 case PRAGMA_OMP_TASKGROUP:
23386 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
23388 case PRAGMA_OMP_TASKLOOP:
23389 strcpy (p_name, "#pragma omp");
23390 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
23392 case PRAGMA_OMP_TEAMS:
23393 strcpy (p_name, "#pragma omp");
23394 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
23397 gcc_unreachable ();
23400 if (stmt && stmt != error_mark_node)
23401 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
23406 # pragma omp threadprivate (variable-list) */
23409 c_parser_omp_threadprivate (c_parser *parser)
23414 c_parser_consume_pragma (parser);
23415 loc = c_parser_peek_token (parser)->location;
23416 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
23418 /* Mark every variable in VARS to be assigned thread local storage. */
23419 for (t = vars; t; t = TREE_CHAIN (t))
23421 tree v = TREE_PURPOSE (t);
23423 /* FIXME diagnostics: Ideally we should keep individual
23424 locations for all the variables in the var list to make the
23425 following errors more precise. Perhaps
23426 c_parser_omp_var_list_parens() should construct a list of
23427 locations to go along with the var list. */
23429 /* If V had already been marked threadprivate, it doesn't matter
23430 whether it had been used prior to this point. */
23432 error_at (loc, "%qD is not a variable", v);
23433 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
23434 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
23435 else if (! is_global_var (v))
23436 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
23437 else if (TREE_TYPE (v) == error_mark_node)
23439 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
23440 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
23443 if (! DECL_THREAD_LOCAL_P (v))
23445 set_decl_tls_model (v, decl_default_tls_model (v));
23446 /* If rtl has been already set for this var, call
23447 make_decl_rtl once again, so that encode_section_info
23448 has a chance to look at the new decl flags. */
23449 if (DECL_RTL_SET_P (v))
23452 C_DECL_THREADPRIVATE_P (v) = 1;
23456 c_parser_skip_to_pragma_eol (parser);
23459 /* Parse a transaction attribute (GCC Extension).
23461 transaction-attribute:
23463 attribute-specifier
23467 c_parser_transaction_attributes (c_parser *parser)
23469 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
23470 return c_parser_gnu_attributes (parser);
23472 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
23474 return c_parser_std_attribute_specifier (parser, true);
23477 /* Parse a __transaction_atomic or __transaction_relaxed statement
23480 transaction-statement:
23481 __transaction_atomic transaction-attribute[opt] compound-statement
23482 __transaction_relaxed compound-statement
23484 Note that the only valid attribute is: "outer".
23488 c_parser_transaction (c_parser *parser, enum rid keyword)
23490 unsigned int old_in = parser->in_transaction;
23491 unsigned int this_in = 1, new_in;
23492 location_t loc = c_parser_peek_token (parser)->location;
23495 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23496 || keyword == RID_TRANSACTION_RELAXED)
23497 && c_parser_next_token_is_keyword (parser, keyword));
23498 c_parser_consume_token (parser);
23500 if (keyword == RID_TRANSACTION_RELAXED)
23501 this_in |= TM_STMT_ATTR_RELAXED;
23504 attrs = c_parser_transaction_attributes (parser);
23506 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
23509 /* Keep track if we're in the lexical scope of an outer transaction. */
23510 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
23512 parser->in_transaction = new_in;
23513 stmt = c_parser_compound_statement (parser);
23514 parser->in_transaction = old_in;
23517 stmt = c_finish_transaction (loc, stmt, this_in);
23519 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23520 "%<__transaction_atomic%> without transactional memory support enabled"
23521 : "%<__transaction_relaxed %> "
23522 "without transactional memory support enabled"));
23527 /* Parse a __transaction_atomic or __transaction_relaxed expression
23530 transaction-expression:
23531 __transaction_atomic ( expression )
23532 __transaction_relaxed ( expression )
23535 static struct c_expr
23536 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
23539 unsigned int old_in = parser->in_transaction;
23540 unsigned int this_in = 1;
23541 location_t loc = c_parser_peek_token (parser)->location;
23544 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23545 || keyword == RID_TRANSACTION_RELAXED)
23546 && c_parser_next_token_is_keyword (parser, keyword));
23547 c_parser_consume_token (parser);
23549 if (keyword == RID_TRANSACTION_RELAXED)
23550 this_in |= TM_STMT_ATTR_RELAXED;
23553 attrs = c_parser_transaction_attributes (parser);
23555 this_in |= parse_tm_stmt_attr (attrs, 0);
23558 parser->in_transaction = this_in;
23559 matching_parens parens;
23560 if (parens.require_open (parser))
23562 tree expr = c_parser_expression (parser).value;
23563 ret.original_type = TREE_TYPE (expr);
23564 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
23565 if (this_in & TM_STMT_ATTR_RELAXED)
23566 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
23567 SET_EXPR_LOCATION (ret.value, loc);
23568 ret.original_code = TRANSACTION_EXPR;
23569 if (!parens.require_close (parser))
23571 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
23579 ret.original_code = ERROR_MARK;
23580 ret.original_type = NULL;
23582 parser->in_transaction = old_in;
23585 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23586 "%<__transaction_atomic%> without transactional memory support enabled"
23587 : "%<__transaction_relaxed %> "
23588 "without transactional memory support enabled"));
23590 set_c_expr_source_range (&ret, loc, loc);
23595 /* Parse a __transaction_cancel statement (GCC Extension).
23597 transaction-cancel-statement:
23598 __transaction_cancel transaction-attribute[opt] ;
23600 Note that the only valid attribute is "outer".
23604 c_parser_transaction_cancel (c_parser *parser)
23606 location_t loc = c_parser_peek_token (parser)->location;
23608 bool is_outer = false;
23610 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
23611 c_parser_consume_token (parser);
23613 attrs = c_parser_transaction_attributes (parser);
23615 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
23619 error_at (loc, "%<__transaction_cancel%> without "
23620 "transactional memory support enabled");
23623 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
23625 error_at (loc, "%<__transaction_cancel%> within a "
23626 "%<__transaction_relaxed%>");
23631 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
23632 && !is_tm_may_cancel_outer (current_function_decl))
23634 error_at (loc, "outer %<__transaction_cancel%> not "
23635 "within outer %<__transaction_atomic%> or "
23636 "a %<transaction_may_cancel_outer%> function");
23640 else if (parser->in_transaction == 0)
23642 error_at (loc, "%<__transaction_cancel%> not within "
23643 "%<__transaction_atomic%>");
23647 return add_stmt (build_tm_abort_call (loc, is_outer));
23650 return build1 (NOP_EXPR, void_type_node, error_mark_node);
23653 /* Parse a single source file. */
23656 c_parse_file (void)
23658 /* Use local storage to begin. If the first token is a pragma, parse it.
23659 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23660 which will cause garbage collection. */
23663 memset (&tparser, 0, sizeof tparser);
23664 tparser.translate_strings_p = true;
23665 tparser.tokens = &tparser.tokens_buf[0];
23666 the_parser = &tparser;
23668 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
23669 c_parser_pragma_pch_preprocess (&tparser);
23671 c_common_no_more_pch ();
23673 the_parser = ggc_alloc<c_parser> ();
23674 *the_parser = tparser;
23675 if (tparser.tokens == &tparser.tokens_buf[0])
23676 the_parser->tokens = &the_parser->tokens_buf[0];
23678 /* Initialize EH, if we've been told to do so. */
23679 if (flag_exceptions)
23680 using_eh_for_cleanups ();
23682 c_parser_translation_unit (the_parser);
23686 /* Parse the body of a function declaration marked with "__RTL".
23688 The RTL parser works on the level of characters read from a
23689 FILE *, whereas c_parser works at the level of tokens.
23690 Square this circle by consuming all of the tokens up to and
23691 including the closing brace, recording the start/end of the RTL
23692 fragment, and reopening the file and re-reading the relevant
23693 lines within the RTL parser.
23695 This requires the opening and closing braces of the C function
23696 to be on separate lines from the RTL they wrap.
23698 Take ownership of START_WITH_PASS, if non-NULL. */
23701 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
23703 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23705 free (start_with_pass);
23706 return c_parser_peek_token (parser)->location;
23709 location_t start_loc = c_parser_peek_token (parser)->location;
23711 /* Consume all tokens, up to the closing brace, handling
23712 matching pairs of braces in the rtl dump. */
23713 int num_open_braces = 1;
23716 switch (c_parser_peek_token (parser)->type)
23718 case CPP_OPEN_BRACE:
23721 case CPP_CLOSE_BRACE:
23722 if (--num_open_braces == 0)
23723 goto found_closing_brace;
23726 error_at (start_loc, "no closing brace");
23727 free (start_with_pass);
23728 return c_parser_peek_token (parser)->location;
23732 c_parser_consume_token (parser);
23735 found_closing_brace:
23736 /* At the closing brace; record its location. */
23737 location_t end_loc = c_parser_peek_token (parser)->location;
23739 /* Consume the closing brace. */
23740 c_parser_consume_token (parser);
23742 /* Invoke the RTL parser. */
23743 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
23745 free (start_with_pass);
23749 /* Run the backend on the cfun created above, transferring ownership of
23750 START_WITH_PASS. */
23751 run_rtl_passes (start_with_pass);
23755 #include "gt-c-c-parser.h"