1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
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_UNIQUE_PTR
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"
73 /* We need to walk over decls with incomplete struct/union/enum types
74 after parsing the whole translation unit.
75 In finish_decl(), if the decl is static, has incomplete
76 struct/union/enum type, it is appeneded to incomplete_record_decls.
77 In c_parser_translation_unit(), we iterate over incomplete_record_decls
78 and report error if any of the decls are still incomplete. */
80 vec<tree> incomplete_record_decls;
83 set_c_expr_source_range (c_expr *expr,
84 location_t start, location_t finish)
86 expr->src_range.m_start = start;
87 expr->src_range.m_finish = finish;
89 set_source_range (expr->value, start, finish);
93 set_c_expr_source_range (c_expr *expr,
94 source_range src_range)
96 expr->src_range = src_range;
98 set_source_range (expr->value, src_range);
102 /* Initialization routine for this file. */
107 /* The only initialization required is of the reserved word
113 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
114 the c_token structure. */
115 gcc_assert (RID_MAX <= 255);
122 mask |= D_ASM | D_EXT;
126 if (!c_dialect_objc ())
127 mask |= D_OBJC | D_CXX_OBJC;
129 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
130 for (i = 0; i < num_c_common_reswords; i++)
132 /* If a keyword is disabled, do not enter it into the table
133 and so create a canonical spelling that isn't a keyword. */
134 if (c_common_reswords[i].disable & mask)
137 && (c_common_reswords[i].disable & D_CXXWARN))
139 id = get_identifier (c_common_reswords[i].word);
140 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
141 C_IS_RESERVED_WORD (id) = 1;
146 id = get_identifier (c_common_reswords[i].word);
147 C_SET_RID_CODE (id, c_common_reswords[i].rid);
148 C_IS_RESERVED_WORD (id) = 1;
149 ridpointers [(int) c_common_reswords[i].rid] = id;
152 for (i = 0; i < NUM_INT_N_ENTS; i++)
154 /* We always create the symbols but they aren't always supported. */
156 sprintf (name, "__int%d", int_n_data[i].bitsize);
157 id = get_identifier (name);
158 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
159 C_IS_RESERVED_WORD (id) = 1;
161 sprintf (name, "__int%d__", int_n_data[i].bitsize);
162 id = get_identifier (name);
163 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
164 C_IS_RESERVED_WORD (id) = 1;
168 /* A parser structure recording information about the state and
169 context of parsing. Includes lexer information with up to two
170 tokens of look-ahead; more are not needed for C. */
171 struct GTY(()) c_parser {
172 /* The look-ahead tokens. */
173 c_token * GTY((skip)) tokens;
174 /* Buffer for look-ahead tokens. */
175 c_token tokens_buf[4];
176 /* How many look-ahead tokens are available (0 - 4, or
177 more if parsing from pre-lexed tokens). */
178 unsigned int tokens_avail;
179 /* Raw look-ahead tokens, used only for checking in Objective-C
180 whether '[[' starts attributes. */
181 vec<c_token, va_gc> *raw_tokens;
182 /* The number of raw look-ahead tokens that have since been fully
184 unsigned int raw_tokens_used;
185 /* True if a syntax error is being recovered from; false otherwise.
186 c_parser_error sets this flag. It should clear this flag when
187 enough tokens have been consumed to recover from the error. */
188 BOOL_BITFIELD error : 1;
189 /* True if we're processing a pragma, and shouldn't automatically
190 consume CPP_PRAGMA_EOL. */
191 BOOL_BITFIELD in_pragma : 1;
192 /* True if we're parsing the outermost block of an if statement. */
193 BOOL_BITFIELD in_if_block : 1;
194 /* True if we want to lex a translated, joined string (for an
195 initial #pragma pch_preprocess). Otherwise the parser is
196 responsible for concatenating strings and translating to the
197 execution character set as needed. */
198 BOOL_BITFIELD lex_joined_string : 1;
199 /* True if, when the parser is concatenating string literals, it
200 should translate them to the execution character set (false
201 inside attributes). */
202 BOOL_BITFIELD translate_strings_p : 1;
204 /* Objective-C specific parser/lexer information. */
206 /* True if we are in a context where the Objective-C "PQ" keywords
207 are considered keywords. */
208 BOOL_BITFIELD objc_pq_context : 1;
209 /* True if we are parsing a (potential) Objective-C foreach
210 statement. This is set to true after we parsed 'for (' and while
211 we wait for 'in' or ';' to decide if it's a standard C for loop or an
212 Objective-C foreach loop. */
213 BOOL_BITFIELD objc_could_be_foreach_context : 1;
214 /* The following flag is needed to contextualize Objective-C lexical
215 analysis. In some cases (e.g., 'int NSObject;'), it is
216 undesirable to bind an identifier to an Objective-C class, even
217 if a class with that name exists. */
218 BOOL_BITFIELD objc_need_raw_identifier : 1;
219 /* Nonzero if we're processing a __transaction statement. The value
220 is 1 | TM_STMT_ATTR_*. */
221 unsigned int in_transaction : 4;
222 /* True if we are in a context where the Objective-C "Property attribute"
223 keywords are valid. */
224 BOOL_BITFIELD objc_property_attr_context : 1;
226 /* Location of the last consumed token. */
227 location_t last_token_location;
230 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
233 c_parser_tokens_buf (c_parser *parser, unsigned n)
235 return &parser->tokens_buf[n];
238 /* Return the error state of PARSER. */
241 c_parser_error (c_parser *parser)
243 return parser->error;
246 /* Set the error state of PARSER to ERR. */
249 c_parser_set_error (c_parser *parser, bool err)
255 /* The actual parser and external interface. ??? Does this need to be
256 garbage-collected? */
258 static GTY (()) c_parser *the_parser;
260 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
261 context-sensitive postprocessing of the token is not done. */
264 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
266 timevar_push (TV_LEX);
268 if (raw || vec_safe_length (parser->raw_tokens) == 0)
270 token->type = c_lex_with_flags (&token->value, &token->location,
272 (parser->lex_joined_string
273 ? 0 : C_LEX_STRING_NO_JOIN));
274 token->id_kind = C_ID_NONE;
275 token->keyword = RID_MAX;
276 token->pragma_kind = PRAGMA_NONE;
280 /* Use a token previously lexed as a raw look-ahead token, and
281 complete the processing on it. */
282 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
283 ++parser->raw_tokens_used;
284 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
286 vec_free (parser->raw_tokens);
287 parser->raw_tokens_used = 0;
300 bool objc_force_identifier = parser->objc_need_raw_identifier;
301 if (c_dialect_objc ())
302 parser->objc_need_raw_identifier = false;
304 if (C_IS_RESERVED_WORD (token->value))
306 enum rid rid_code = C_RID_CODE (token->value);
308 if (rid_code == RID_CXX_COMPAT_WARN)
310 warning_at (token->location,
312 "identifier %qE conflicts with C++ keyword",
315 else if (rid_code >= RID_FIRST_ADDR_SPACE
316 && rid_code <= RID_LAST_ADDR_SPACE)
319 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
320 targetm.addr_space.diagnose_usage (as, token->location);
321 token->id_kind = C_ID_ADDRSPACE;
322 token->keyword = rid_code;
325 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
327 /* We found an Objective-C "pq" keyword (in, out,
328 inout, bycopy, byref, oneway). They need special
329 care because the interpretation depends on the
331 if (parser->objc_pq_context)
333 token->type = CPP_KEYWORD;
334 token->keyword = rid_code;
337 else if (parser->objc_could_be_foreach_context
338 && rid_code == RID_IN)
340 /* We are in Objective-C, inside a (potential)
341 foreach context (which means after having
342 parsed 'for (', but before having parsed ';'),
343 and we found 'in'. We consider it the keyword
344 which terminates the declaration at the
345 beginning of a foreach-statement. Note that
346 this means you can't use 'in' for anything else
347 in that context; in particular, in Objective-C
348 you can't use 'in' as the name of the running
349 variable in a C for loop. We could potentially
350 try to add code here to disambiguate, but it
351 seems a reasonable limitation. */
352 token->type = CPP_KEYWORD;
353 token->keyword = rid_code;
356 /* Else, "pq" keywords outside of the "pq" context are
357 not keywords, and we fall through to the code for
360 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
362 /* We found an Objective-C "property attribute"
363 keyword (getter, setter, readonly, etc). These are
364 only valid in the property context. */
365 if (parser->objc_property_attr_context)
367 token->type = CPP_KEYWORD;
368 token->keyword = rid_code;
371 /* Else they are not special keywords.
374 else if (c_dialect_objc ()
375 && (OBJC_IS_AT_KEYWORD (rid_code)
376 || OBJC_IS_CXX_KEYWORD (rid_code)))
378 /* We found one of the Objective-C "@" keywords (defs,
379 selector, synchronized, etc) or one of the
380 Objective-C "cxx" keywords (class, private,
381 protected, public, try, catch, throw) without a
382 preceding '@' sign. Do nothing and fall through to
383 the code for normal tokens (in C++ we would still
384 consider the CXX ones keywords, but not in C). */
389 token->type = CPP_KEYWORD;
390 token->keyword = rid_code;
395 decl = lookup_name (token->value);
398 if (TREE_CODE (decl) == TYPE_DECL)
400 token->id_kind = C_ID_TYPENAME;
404 else if (c_dialect_objc ())
406 tree objc_interface_decl = objc_is_class_name (token->value);
407 /* Objective-C class names are in the same namespace as
408 variables and typedefs, and hence are shadowed by local
410 if (objc_interface_decl
411 && (!objc_force_identifier || global_bindings_p ()))
413 token->value = objc_interface_decl;
414 token->id_kind = C_ID_CLASSNAME;
418 token->id_kind = C_ID_ID;
422 /* This only happens in Objective-C; it must be a keyword. */
423 token->type = CPP_KEYWORD;
424 switch (C_RID_CODE (token->value))
426 /* Replace 'class' with '@class', 'private' with '@private',
427 etc. This prevents confusion with the C++ keyword
428 'class', and makes the tokens consistent with other
429 Objective-C 'AT' keywords. For example '@class' is
430 reported as RID_AT_CLASS which is consistent with
431 '@synchronized', which is reported as
434 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
435 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
436 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
437 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
438 case RID_THROW: token->keyword = RID_AT_THROW; break;
439 case RID_TRY: token->keyword = RID_AT_TRY; break;
440 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
441 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
442 default: token->keyword = C_RID_CODE (token->value);
447 case CPP_CLOSE_PAREN:
449 /* These tokens may affect the interpretation of any identifiers
450 following, if doing Objective-C. */
451 if (c_dialect_objc ())
452 parser->objc_need_raw_identifier = false;
455 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
456 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
463 timevar_pop (TV_LEX);
466 /* Return a pointer to the next token from PARSER, reading it in if
470 c_parser_peek_token (c_parser *parser)
472 if (parser->tokens_avail == 0)
474 c_lex_one_token (parser, &parser->tokens[0]);
475 parser->tokens_avail = 1;
477 return &parser->tokens[0];
480 /* Return a pointer to the next-but-one token from PARSER, reading it
481 in if necessary. The next token is already read in. */
484 c_parser_peek_2nd_token (c_parser *parser)
486 if (parser->tokens_avail >= 2)
487 return &parser->tokens[1];
488 gcc_assert (parser->tokens_avail == 1);
489 gcc_assert (parser->tokens[0].type != CPP_EOF);
490 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
491 c_lex_one_token (parser, &parser->tokens[1]);
492 parser->tokens_avail = 2;
493 return &parser->tokens[1];
496 /* Return a pointer to the Nth token from PARSER, reading it
497 in if necessary. The N-1th token is already read in. */
500 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
502 /* N is 1-based, not zero-based. */
505 if (parser->tokens_avail >= n)
506 return &parser->tokens[n - 1];
507 gcc_assert (parser->tokens_avail == n - 1);
508 c_lex_one_token (parser, &parser->tokens[n - 1]);
509 parser->tokens_avail = n;
510 return &parser->tokens[n - 1];
513 /* Return a pointer to the Nth token from PARSER, reading it in as a
514 raw look-ahead token if necessary. The N-1th token is already read
515 in. Raw look-ahead tokens remain available for when the non-raw
516 functions above are called. */
519 c_parser_peek_nth_token_raw (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 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
527 unsigned int raw_avail
528 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
529 gcc_assert (raw_avail >= n - 1);
531 return &(*parser->raw_tokens)[parser->raw_tokens_used
532 + n - 1 - parser->tokens_avail];
533 vec_safe_reserve (parser->raw_tokens, 1);
534 parser->raw_tokens->quick_grow (raw_len + 1);
535 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
536 return &(*parser->raw_tokens)[raw_len];
540 c_keyword_starts_typename (enum rid keyword)
575 if (keyword >= RID_FIRST_INT_N
576 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
577 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
583 /* Return true if TOKEN can start a type name,
586 c_token_starts_typename (c_token *token)
591 switch (token->id_kind)
600 gcc_assert (c_dialect_objc ());
606 return c_keyword_starts_typename (token->keyword);
608 if (c_dialect_objc ())
616 /* Return true if the next token from PARSER can start a type name,
617 false otherwise. LA specifies how to do lookahead in order to
618 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
621 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
623 c_token *token = c_parser_peek_token (parser);
624 if (c_token_starts_typename (token))
627 /* Try a bit harder to detect an unknown typename. */
628 if (la != cla_prefer_id
629 && token->type == CPP_NAME
630 && token->id_kind == C_ID_ID
632 /* Do not try too hard when we could have "object in array". */
633 && !parser->objc_could_be_foreach_context
635 && (la == cla_prefer_type
636 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
637 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
639 /* Only unknown identifiers. */
640 && !lookup_name (token->value))
646 /* Return true if TOKEN is a type qualifier, false otherwise. */
648 c_token_is_qualifier (c_token *token)
653 switch (token->id_kind)
661 switch (token->keyword)
679 /* Return true if the next token from PARSER is a type qualifier,
682 c_parser_next_token_is_qualifier (c_parser *parser)
684 c_token *token = c_parser_peek_token (parser);
685 return c_token_is_qualifier (token);
688 /* Return true if TOKEN can start declaration specifiers (not
689 including standard attributes), false otherwise. */
691 c_token_starts_declspecs (c_token *token)
696 switch (token->id_kind)
705 gcc_assert (c_dialect_objc ());
711 switch (token->keyword)
752 if (token->keyword >= RID_FIRST_INT_N
753 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
754 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
759 if (c_dialect_objc ())
768 /* Return true if TOKEN can start declaration specifiers (not
769 including standard attributes) or a static assertion, false
772 c_token_starts_declaration (c_token *token)
774 if (c_token_starts_declspecs (token)
775 || token->keyword == RID_STATIC_ASSERT)
781 /* Return true if the next token from PARSER can start declaration
782 specifiers (not including standard attributes), false
785 c_parser_next_token_starts_declspecs (c_parser *parser)
787 c_token *token = c_parser_peek_token (parser);
789 /* In Objective-C, a classname normally starts a declspecs unless it
790 is immediately followed by a dot. In that case, it is the
791 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
792 setter/getter on the class. c_token_starts_declspecs() can't
793 differentiate between the two cases because it only checks the
794 current token, so we have a special check here. */
795 if (c_dialect_objc ()
796 && token->type == CPP_NAME
797 && token->id_kind == C_ID_CLASSNAME
798 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
801 return c_token_starts_declspecs (token);
804 /* Return true if the next tokens from PARSER can start declaration
805 specifiers (not including standard attributes) or a static
806 assertion, false otherwise. */
808 c_parser_next_tokens_start_declaration (c_parser *parser)
810 c_token *token = c_parser_peek_token (parser);
813 if (c_dialect_objc ()
814 && token->type == CPP_NAME
815 && token->id_kind == C_ID_CLASSNAME
816 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
819 /* Labels do not start declarations. */
820 if (token->type == CPP_NAME
821 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
824 if (c_token_starts_declaration (token))
827 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
833 /* Consume the next token from PARSER. */
836 c_parser_consume_token (c_parser *parser)
838 gcc_assert (parser->tokens_avail >= 1);
839 gcc_assert (parser->tokens[0].type != CPP_EOF);
840 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
841 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
842 parser->last_token_location = parser->tokens[0].location;
843 if (parser->tokens != &parser->tokens_buf[0])
845 else if (parser->tokens_avail >= 2)
847 parser->tokens[0] = parser->tokens[1];
848 if (parser->tokens_avail >= 3)
850 parser->tokens[1] = parser->tokens[2];
851 if (parser->tokens_avail >= 4)
852 parser->tokens[2] = parser->tokens[3];
855 parser->tokens_avail--;
858 /* Expect the current token to be a #pragma. Consume it and remember
859 that we've begun parsing a pragma. */
862 c_parser_consume_pragma (c_parser *parser)
864 gcc_assert (!parser->in_pragma);
865 gcc_assert (parser->tokens_avail >= 1);
866 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
867 if (parser->tokens != &parser->tokens_buf[0])
869 else if (parser->tokens_avail >= 2)
871 parser->tokens[0] = parser->tokens[1];
872 if (parser->tokens_avail >= 3)
873 parser->tokens[1] = parser->tokens[2];
875 parser->tokens_avail--;
876 parser->in_pragma = true;
879 /* Update the global input_location from TOKEN. */
881 c_parser_set_source_position_from_token (c_token *token)
883 if (token->type != CPP_EOF)
885 input_location = token->location;
889 /* Helper function for c_parser_error.
890 Having peeked a token of kind TOK1_KIND that might signify
891 a conflict marker, peek successor tokens to determine
892 if we actually do have a conflict marker.
893 Specifically, we consider a run of 7 '<', '=' or '>' characters
894 at the start of a line as a conflict marker.
895 These come through the lexer as three pairs and a single,
896 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
897 If it returns true, *OUT_LOC is written to with the location/range
901 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
904 c_token *token2 = c_parser_peek_2nd_token (parser);
905 if (token2->type != tok1_kind)
907 c_token *token3 = c_parser_peek_nth_token (parser, 3);
908 if (token3->type != tok1_kind)
910 c_token *token4 = c_parser_peek_nth_token (parser, 4);
911 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
914 /* It must be at the start of the line. */
915 location_t start_loc = c_parser_peek_token (parser)->location;
916 if (LOCATION_COLUMN (start_loc) != 1)
919 /* We have a conflict marker. Construct a location of the form:
922 with start == caret, finishing at the end of the marker. */
923 location_t finish_loc = get_finish (token4->location);
924 *out_loc = make_location (start_loc, start_loc, finish_loc);
929 /* Issue a diagnostic of the form
930 FILE:LINE: MESSAGE before TOKEN
931 where TOKEN is the next token in the input stream of PARSER.
932 MESSAGE (specified by the caller) is usually of the form "expected
935 Use RICHLOC as the location of the diagnostic.
937 Do not issue a diagnostic if still recovering from an error.
939 Return true iff an error was actually emitted.
941 ??? This is taken from the C++ parser, but building up messages in
942 this way is not i18n-friendly and some other approach should be
946 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
947 rich_location *richloc)
949 c_token *token = c_parser_peek_token (parser);
952 parser->error = true;
956 /* If this is actually a conflict marker, report it as such. */
957 if (token->type == CPP_LSHIFT
958 || token->type == CPP_RSHIFT
959 || token->type == CPP_EQ_EQ)
962 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
964 error_at (loc, "version control conflict marker in file");
969 c_parse_error (gmsgid,
970 /* Because c_parse_error does not understand
971 CPP_KEYWORD, keywords are treated like
973 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
974 /* ??? The C parser does not save the cpp flags of a
975 token, we need to pass 0 here and we will not get
976 the source spelling of some tokens but rather the
977 canonical spelling. */
978 token->value, /*flags=*/0, richloc);
982 /* As c_parser_error_richloc, but issue the message at the
983 location of PARSER's next token, or at input_location
984 if the next token is EOF. */
987 c_parser_error (c_parser *parser, const char *gmsgid)
989 c_token *token = c_parser_peek_token (parser);
990 c_parser_set_source_position_from_token (token);
991 rich_location richloc (line_table, input_location);
992 return c_parser_error_richloc (parser, gmsgid, &richloc);
995 /* Some tokens naturally come in pairs e.g.'(' and ')'.
996 This class is for tracking such a matching pair of symbols.
997 In particular, it tracks the location of the first token,
998 so that if the second token is missing, we can highlight the
999 location of the first token when notifying the user about the
1002 template <typename traits_t>
1006 /* token_pair's ctor. */
1007 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1009 /* If the next token is the opening symbol for this pair, consume it and
1011 Otherwise, issue an error and return false.
1012 In either case, record the location of the opening token. */
1014 bool require_open (c_parser *parser)
1016 c_token *token = c_parser_peek_token (parser);
1018 m_open_loc = token->location;
1020 return c_parser_require (parser, traits_t::open_token_type,
1021 traits_t::open_gmsgid);
1024 /* Consume the next token from PARSER, recording its location as
1025 that of the opening token within the pair. */
1027 void consume_open (c_parser *parser)
1029 c_token *token = c_parser_peek_token (parser);
1030 gcc_assert (token->type == traits_t::open_token_type);
1031 m_open_loc = token->location;
1032 c_parser_consume_token (parser);
1035 /* If the next token is the closing symbol for this pair, consume it
1037 Otherwise, issue an error, highlighting the location of the
1038 corresponding opening token, and return false. */
1040 bool require_close (c_parser *parser) const
1042 return c_parser_require (parser, traits_t::close_token_type,
1043 traits_t::close_gmsgid, m_open_loc);
1046 /* Like token_pair::require_close, except that tokens will be skipped
1047 until the desired token is found. An error message is still produced
1048 if the next token is not as expected. */
1050 void skip_until_found_close (c_parser *parser) const
1052 c_parser_skip_until_found (parser, traits_t::close_token_type,
1053 traits_t::close_gmsgid, m_open_loc);
1057 location_t m_open_loc;
1060 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1062 struct matching_paren_traits
1064 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1065 static const char * const open_gmsgid;
1066 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1067 static const char * const close_gmsgid;
1070 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1071 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1073 /* "matching_parens" is a token_pair<T> class for tracking matching
1074 pairs of parentheses. */
1076 typedef token_pair<matching_paren_traits> matching_parens;
1078 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1080 struct matching_brace_traits
1082 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1083 static const char * const open_gmsgid;
1084 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1085 static const char * const close_gmsgid;
1088 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1089 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1091 /* "matching_braces" is a token_pair<T> class for tracking matching
1094 typedef token_pair<matching_brace_traits> matching_braces;
1096 /* Get a description of the matching symbol to TYPE e.g. "(" for
1100 get_matching_symbol (enum cpp_ttype type)
1107 case CPP_CLOSE_PAREN:
1109 case CPP_CLOSE_BRACE:
1114 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1115 issue the error MSGID. If MSGID is NULL then a message has already
1116 been produced and no message will be produced this time. Returns
1117 true if found, false otherwise.
1119 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1120 within any error as the location of an "opening" token matching
1121 the close token TYPE (e.g. the location of the '(' when TYPE is
1124 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1125 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1126 attempt to generate a fix-it hint for the problem.
1127 Otherwise msgid describes multiple token types (e.g.
1128 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1129 generate a fix-it hint. */
1132 c_parser_require (c_parser *parser,
1133 enum cpp_ttype type,
1135 location_t matching_location,
1136 bool type_is_unique)
1138 if (c_parser_next_token_is (parser, type))
1140 c_parser_consume_token (parser);
1145 location_t next_token_loc = c_parser_peek_token (parser)->location;
1146 gcc_rich_location richloc (next_token_loc);
1148 /* Potentially supply a fix-it hint, suggesting to add the
1149 missing token immediately after the *previous* token.
1150 This may move the primary location within richloc. */
1151 if (!parser->error && type_is_unique)
1152 maybe_suggest_missing_token_insertion (&richloc, type,
1153 parser->last_token_location);
1155 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1156 Attempt to consolidate diagnostics by printing it as a
1157 secondary range within the main diagnostic. */
1158 bool added_matching_location = false;
1159 if (matching_location != UNKNOWN_LOCATION)
1160 added_matching_location
1161 = richloc.add_location_if_nearby (matching_location);
1163 if (c_parser_error_richloc (parser, msgid, &richloc))
1164 /* If we weren't able to consolidate matching_location, then
1165 print it as a secondary diagnostic. */
1166 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1167 inform (matching_location, "to match this %qs",
1168 get_matching_symbol (type));
1174 /* If the next token is the indicated keyword, consume it. Otherwise,
1175 issue the error MSGID. Returns true if found, false otherwise. */
1178 c_parser_require_keyword (c_parser *parser,
1182 if (c_parser_next_token_is_keyword (parser, keyword))
1184 c_parser_consume_token (parser);
1189 c_parser_error (parser, msgid);
1194 /* Like c_parser_require, except that tokens will be skipped until the
1195 desired token is found. An error message is still produced if the
1196 next token is not as expected. If MSGID is NULL then a message has
1197 already been produced and no message will be produced this
1200 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1201 within any error as the location of an "opening" token matching
1202 the close token TYPE (e.g. the location of the '(' when TYPE is
1203 CPP_CLOSE_PAREN). */
1206 c_parser_skip_until_found (c_parser *parser,
1207 enum cpp_ttype type,
1209 location_t matching_location)
1211 unsigned nesting_depth = 0;
1213 if (c_parser_require (parser, type, msgid, matching_location))
1216 /* Skip tokens until the desired token is found. */
1219 /* Peek at the next token. */
1220 c_token *token = c_parser_peek_token (parser);
1221 /* If we've reached the token we want, consume it and stop. */
1222 if (token->type == type && !nesting_depth)
1224 c_parser_consume_token (parser);
1228 /* If we've run out of tokens, stop. */
1229 if (token->type == CPP_EOF)
1231 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1233 if (token->type == CPP_OPEN_BRACE
1234 || token->type == CPP_OPEN_PAREN
1235 || token->type == CPP_OPEN_SQUARE)
1237 else if (token->type == CPP_CLOSE_BRACE
1238 || token->type == CPP_CLOSE_PAREN
1239 || token->type == CPP_CLOSE_SQUARE)
1241 if (nesting_depth-- == 0)
1244 /* Consume this token. */
1245 c_parser_consume_token (parser);
1247 parser->error = false;
1250 /* Skip tokens until the end of a parameter is found, but do not
1251 consume the comma, semicolon or closing delimiter. */
1254 c_parser_skip_to_end_of_parameter (c_parser *parser)
1256 unsigned nesting_depth = 0;
1260 c_token *token = c_parser_peek_token (parser);
1261 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1264 /* If we've run out of tokens, stop. */
1265 if (token->type == CPP_EOF)
1267 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1269 if (token->type == CPP_OPEN_BRACE
1270 || token->type == CPP_OPEN_PAREN
1271 || token->type == CPP_OPEN_SQUARE)
1273 else if (token->type == CPP_CLOSE_BRACE
1274 || token->type == CPP_CLOSE_PAREN
1275 || token->type == CPP_CLOSE_SQUARE)
1277 if (nesting_depth-- == 0)
1280 /* Consume this token. */
1281 c_parser_consume_token (parser);
1283 parser->error = false;
1286 /* Expect to be at the end of the pragma directive and consume an
1287 end of line marker. */
1290 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1292 gcc_assert (parser->in_pragma);
1293 parser->in_pragma = false;
1295 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1296 c_parser_error (parser, "expected end of line");
1298 cpp_ttype token_type;
1301 c_token *token = c_parser_peek_token (parser);
1302 token_type = token->type;
1303 if (token_type == CPP_EOF)
1305 c_parser_consume_token (parser);
1307 while (token_type != CPP_PRAGMA_EOL);
1309 parser->error = false;
1312 /* Skip tokens until we have consumed an entire block, or until we
1313 have consumed a non-nested ';'. */
1316 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1318 unsigned nesting_depth = 0;
1319 bool save_error = parser->error;
1325 /* Peek at the next token. */
1326 token = c_parser_peek_token (parser);
1328 switch (token->type)
1333 case CPP_PRAGMA_EOL:
1334 if (parser->in_pragma)
1339 /* If the next token is a ';', we have reached the
1340 end of the statement. */
1343 /* Consume the ';'. */
1344 c_parser_consume_token (parser);
1349 case CPP_CLOSE_BRACE:
1350 /* If the next token is a non-nested '}', then we have
1351 reached the end of the current block. */
1352 if (nesting_depth == 0 || --nesting_depth == 0)
1354 c_parser_consume_token (parser);
1359 case CPP_OPEN_BRACE:
1360 /* If it the next token is a '{', then we are entering a new
1361 block. Consume the entire block. */
1366 /* If we see a pragma, consume the whole thing at once. We
1367 have some safeguards against consuming pragmas willy-nilly.
1368 Normally, we'd expect to be here with parser->error set,
1369 which disables these safeguards. But it's possible to get
1370 here for secondary error recovery, after parser->error has
1372 c_parser_consume_pragma (parser);
1373 c_parser_skip_to_pragma_eol (parser);
1374 parser->error = save_error;
1381 c_parser_consume_token (parser);
1385 parser->error = false;
1388 /* CPP's options (initialized by c-opts.c). */
1389 extern cpp_options *cpp_opts;
1391 /* Save the warning flags which are controlled by __extension__. */
1394 disable_extension_diagnostics (void)
1397 | (warn_pointer_arith << 1)
1398 | (warn_traditional << 2)
1400 | (warn_long_long << 4)
1401 | (warn_cxx_compat << 5)
1402 | (warn_overlength_strings << 6)
1403 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1404 play tricks to properly restore it. */
1405 | ((warn_c90_c99_compat == 1) << 7)
1406 | ((warn_c90_c99_compat == -1) << 8)
1407 /* Similarly for warn_c99_c11_compat. */
1408 | ((warn_c99_c11_compat == 1) << 9)
1409 | ((warn_c99_c11_compat == -1) << 10)
1410 /* Similarly for warn_c11_c2x_compat. */
1411 | ((warn_c11_c2x_compat == 1) << 11)
1412 | ((warn_c11_c2x_compat == -1) << 12)
1414 cpp_opts->cpp_pedantic = pedantic = 0;
1415 warn_pointer_arith = 0;
1416 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1418 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1419 warn_cxx_compat = 0;
1420 warn_overlength_strings = 0;
1421 warn_c90_c99_compat = 0;
1422 warn_c99_c11_compat = 0;
1423 warn_c11_c2x_compat = 0;
1427 /* Restore the warning flags which are controlled by __extension__.
1428 FLAGS is the return value from disable_extension_diagnostics. */
1431 restore_extension_diagnostics (int flags)
1433 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1434 warn_pointer_arith = (flags >> 1) & 1;
1435 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1436 flag_iso = (flags >> 3) & 1;
1437 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1438 warn_cxx_compat = (flags >> 5) & 1;
1439 warn_overlength_strings = (flags >> 6) & 1;
1440 /* See above for why is this needed. */
1441 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1442 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1443 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1446 /* Helper data structure for parsing #pragma acc routine. */
1447 struct oacc_routine_data {
1448 bool error_seen; /* Set if error has been reported. */
1449 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1454 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1456 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1457 static void c_parser_external_declaration (c_parser *);
1458 static void c_parser_asm_definition (c_parser *);
1459 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1460 bool, bool, tree *, vec<c_token>,
1461 bool have_attrs = false,
1463 struct oacc_routine_data * = NULL,
1465 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1466 static void c_parser_static_assert_declaration (c_parser *);
1467 static struct c_typespec c_parser_enum_specifier (c_parser *);
1468 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1469 static tree c_parser_struct_declaration (c_parser *);
1470 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1471 static tree c_parser_alignas_specifier (c_parser *);
1472 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1474 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1476 struct c_declarator *);
1477 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1479 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1481 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1482 static tree c_parser_simple_asm_expr (c_parser *);
1483 static tree c_parser_gnu_attributes (c_parser *);
1484 static struct c_expr c_parser_initializer (c_parser *);
1485 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1487 static void c_parser_initelt (c_parser *, struct obstack *);
1488 static void c_parser_initval (c_parser *, struct c_expr *,
1490 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1491 static location_t c_parser_compound_statement_nostart (c_parser *);
1492 static void c_parser_label (c_parser *);
1493 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1494 static void c_parser_statement_after_labels (c_parser *, bool *,
1495 vec<tree> * = NULL);
1496 static tree c_parser_c99_block_statement (c_parser *, bool *,
1497 location_t * = NULL);
1498 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1499 static void c_parser_switch_statement (c_parser *, bool *);
1500 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1501 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1502 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1503 static tree c_parser_asm_statement (c_parser *);
1504 static tree c_parser_asm_operands (c_parser *);
1505 static tree c_parser_asm_goto_operands (c_parser *);
1506 static tree c_parser_asm_clobbers (c_parser *);
1507 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1509 static struct c_expr c_parser_conditional_expression (c_parser *,
1510 struct c_expr *, tree);
1511 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1513 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1514 static struct c_expr c_parser_unary_expression (c_parser *);
1515 static struct c_expr c_parser_sizeof_expression (c_parser *);
1516 static struct c_expr c_parser_alignof_expression (c_parser *);
1517 static struct c_expr c_parser_postfix_expression (c_parser *);
1518 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1519 struct c_type_name *,
1521 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1524 static tree c_parser_transaction (c_parser *, enum rid);
1525 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1526 static tree c_parser_transaction_cancel (c_parser *);
1527 static struct c_expr c_parser_expression (c_parser *);
1528 static struct c_expr c_parser_expression_conv (c_parser *);
1529 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1530 vec<tree, va_gc> **, location_t *,
1531 tree *, vec<location_t> *,
1532 unsigned int * = NULL);
1533 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1535 static void c_parser_oacc_declare (c_parser *);
1536 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1537 static void c_parser_oacc_update (c_parser *);
1538 static void c_parser_omp_construct (c_parser *, bool *);
1539 static void c_parser_omp_threadprivate (c_parser *);
1540 static void c_parser_omp_barrier (c_parser *);
1541 static void c_parser_omp_depobj (c_parser *);
1542 static void c_parser_omp_flush (c_parser *);
1543 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1544 tree, tree *, bool *);
1545 static void c_parser_omp_taskwait (c_parser *);
1546 static void c_parser_omp_taskyield (c_parser *);
1547 static void c_parser_omp_cancel (c_parser *);
1549 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1550 pragma_stmt, pragma_compound };
1551 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1552 static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1553 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1554 static void c_parser_omp_end_declare_target (c_parser *);
1555 static void c_parser_omp_declare (c_parser *, enum pragma_context);
1556 static void c_parser_omp_requires (c_parser *);
1557 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1558 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1560 /* These Objective-C parser functions are only ever called when
1561 compiling Objective-C. */
1562 static void c_parser_objc_class_definition (c_parser *, tree);
1563 static void c_parser_objc_class_instance_variables (c_parser *);
1564 static void c_parser_objc_class_declaration (c_parser *);
1565 static void c_parser_objc_alias_declaration (c_parser *);
1566 static void c_parser_objc_protocol_definition (c_parser *, tree);
1567 static bool c_parser_objc_method_type (c_parser *);
1568 static void c_parser_objc_method_definition (c_parser *);
1569 static void c_parser_objc_methodprotolist (c_parser *);
1570 static void c_parser_objc_methodproto (c_parser *);
1571 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1572 static tree c_parser_objc_type_name (c_parser *);
1573 static tree c_parser_objc_protocol_refs (c_parser *);
1574 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1575 static void c_parser_objc_synchronized_statement (c_parser *);
1576 static tree c_parser_objc_selector (c_parser *);
1577 static tree c_parser_objc_selector_arg (c_parser *);
1578 static tree c_parser_objc_receiver (c_parser *);
1579 static tree c_parser_objc_message_args (c_parser *);
1580 static tree c_parser_objc_keywordexpr (c_parser *);
1581 static void c_parser_objc_at_property_declaration (c_parser *);
1582 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1583 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1584 static bool c_parser_objc_diagnose_bad_element_prefix
1585 (c_parser *, struct c_declspecs *);
1586 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1588 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1591 external-declarations
1593 external-declarations:
1594 external-declaration
1595 external-declarations external-declaration
1604 c_parser_translation_unit (c_parser *parser)
1606 if (c_parser_next_token_is (parser, CPP_EOF))
1608 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1609 "ISO C forbids an empty translation unit");
1613 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1614 mark_valid_location_for_stdc_pragma (false);
1618 c_parser_external_declaration (parser);
1619 obstack_free (&parser_obstack, obstack_position);
1621 while (c_parser_next_token_is_not (parser, CPP_EOF));
1626 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1627 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1628 error ("storage size of %q+D isn%'t known", decl);
1630 if (current_omp_declare_target_attribute)
1633 error ("%<#pragma omp declare target%> without corresponding "
1634 "%<#pragma omp end declare target%>");
1635 current_omp_declare_target_attribute = 0;
1639 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1641 external-declaration:
1647 external-declaration:
1650 __extension__ external-declaration
1654 external-declaration:
1655 objc-class-definition
1656 objc-class-declaration
1657 objc-alias-declaration
1658 objc-protocol-definition
1659 objc-method-definition
1664 c_parser_external_declaration (c_parser *parser)
1667 switch (c_parser_peek_token (parser)->type)
1670 switch (c_parser_peek_token (parser)->keyword)
1673 ext = disable_extension_diagnostics ();
1674 c_parser_consume_token (parser);
1675 c_parser_external_declaration (parser);
1676 restore_extension_diagnostics (ext);
1679 c_parser_asm_definition (parser);
1681 case RID_AT_INTERFACE:
1682 case RID_AT_IMPLEMENTATION:
1683 gcc_assert (c_dialect_objc ());
1684 c_parser_objc_class_definition (parser, NULL_TREE);
1687 gcc_assert (c_dialect_objc ());
1688 c_parser_objc_class_declaration (parser);
1691 gcc_assert (c_dialect_objc ());
1692 c_parser_objc_alias_declaration (parser);
1694 case RID_AT_PROTOCOL:
1695 gcc_assert (c_dialect_objc ());
1696 c_parser_objc_protocol_definition (parser, NULL_TREE);
1698 case RID_AT_PROPERTY:
1699 gcc_assert (c_dialect_objc ());
1700 c_parser_objc_at_property_declaration (parser);
1702 case RID_AT_SYNTHESIZE:
1703 gcc_assert (c_dialect_objc ());
1704 c_parser_objc_at_synthesize_declaration (parser);
1706 case RID_AT_DYNAMIC:
1707 gcc_assert (c_dialect_objc ());
1708 c_parser_objc_at_dynamic_declaration (parser);
1711 gcc_assert (c_dialect_objc ());
1712 c_parser_consume_token (parser);
1713 objc_finish_implementation ();
1720 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1721 "ISO C does not allow extra %<;%> outside of a function");
1722 c_parser_consume_token (parser);
1725 mark_valid_location_for_stdc_pragma (true);
1726 c_parser_pragma (parser, pragma_external, NULL);
1727 mark_valid_location_for_stdc_pragma (false);
1731 if (c_dialect_objc ())
1733 c_parser_objc_method_definition (parser);
1736 /* Else fall through, and yield a syntax error trying to parse
1737 as a declaration or function definition. */
1741 /* A declaration or a function definition (or, in Objective-C,
1742 an @interface or @protocol with prefix attributes). We can
1743 only tell which after parsing the declaration specifiers, if
1744 any, and the first declarator. */
1745 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
1751 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
1752 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1754 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1757 add_debug_begin_stmt (location_t loc)
1759 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1760 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1763 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1764 SET_EXPR_LOCATION (stmt, loc);
1768 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1769 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1770 is accepted; otherwise (old-style parameter declarations) only other
1771 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1772 assertion is accepted; otherwise (old-style parameter declarations)
1773 it is not. If NESTED is true, we are inside a function or parsing
1774 old-style parameter declarations; any functions encountered are
1775 nested functions and declaration specifiers are required; otherwise
1776 we are at top level and functions are normal functions and
1777 declaration specifiers may be optional. If EMPTY_OK is true, empty
1778 declarations are OK (subject to all other constraints); otherwise
1779 (old-style parameter declarations) they are diagnosed. If
1780 START_ATTR_OK is true, the declaration specifiers may start with
1781 attributes (GNU or standard); otherwise they may not.
1782 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1783 declaration when parsing an Objective-C foreach statement.
1784 FALLTHRU_ATTR_P is used to signal whether this function parsed
1785 "__attribute__((fallthrough));". ATTRS are any standard attributes
1786 parsed in the caller (in contexts where such attributes had to be
1787 parsed to determine whether what follows is a declaration or a
1788 statement); HAVE_ATTRS says whether there were any such attributes
1792 declaration-specifiers init-declarator-list[opt] ;
1793 static_assert-declaration
1795 function-definition:
1796 declaration-specifiers[opt] declarator declaration-list[opt]
1801 declaration-list declaration
1803 init-declarator-list:
1805 init-declarator-list , init-declarator
1808 declarator simple-asm-expr[opt] gnu-attributes[opt]
1809 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1813 nested-function-definition:
1814 declaration-specifiers declarator declaration-list[opt]
1820 gnu-attributes objc-class-definition
1821 gnu-attributes objc-category-definition
1822 gnu-attributes objc-protocol-definition
1824 The simple-asm-expr and gnu-attributes are GNU extensions.
1826 This function does not handle __extension__; that is handled in its
1827 callers. ??? Following the old parser, __extension__ may start
1828 external declarations, declarations in functions and declarations
1829 at the start of "for" loops, but not old-style parameter
1832 C99 requires declaration specifiers in a function definition; the
1833 absence is diagnosed through the diagnosis of implicit int. In GNU
1834 C we also allow but diagnose declarations without declaration
1835 specifiers, but only at top level (elsewhere they conflict with
1838 In Objective-C, declarations of the looping variable in a foreach
1839 statement are exceptionally terminated by 'in' (for example, 'for
1840 (NSObject *object in array) { ... }').
1845 threadprivate-directive
1849 gimple-function-definition:
1850 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1851 declaration-list[opt] compound-statement
1853 rtl-function-definition:
1854 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1855 declaration-list[opt] compound-statement */
1858 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1859 bool static_assert_ok, bool empty_ok,
1860 bool nested, bool start_attr_ok,
1861 tree *objc_foreach_object_declaration,
1862 vec<c_token> omp_declare_simd_clauses,
1863 bool have_attrs, tree attrs,
1864 struct oacc_routine_data *oacc_routine_data,
1865 bool *fallthru_attr_p)
1867 struct c_declspecs *specs;
1869 tree all_prefix_attrs;
1870 bool diagnosed_no_specs = false;
1871 location_t here = c_parser_peek_token (parser)->location;
1873 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1875 if (static_assert_ok
1876 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1878 c_parser_static_assert_declaration (parser);
1881 specs = build_null_declspecs ();
1883 /* Handle any standard attributes parsed in the caller. */
1886 declspecs_add_attrs (here, specs, attrs);
1887 specs->non_std_attrs_seen_p = false;
1890 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1891 if (c_parser_peek_token (parser)->type == CPP_NAME
1892 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1893 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1894 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1895 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1897 tree name = c_parser_peek_token (parser)->value;
1899 /* Issue a warning about NAME being an unknown type name, perhaps
1900 with some kind of hint.
1901 If the user forgot a "struct" etc, suggest inserting
1902 it. Otherwise, attempt to look for misspellings. */
1903 gcc_rich_location richloc (here);
1904 if (tag_exists_p (RECORD_TYPE, name))
1906 /* This is not C++ with its implicit typedef. */
1907 richloc.add_fixit_insert_before ("struct ");
1909 "unknown type name %qE;"
1910 " use %<struct%> keyword to refer to the type",
1913 else if (tag_exists_p (UNION_TYPE, name))
1915 richloc.add_fixit_insert_before ("union ");
1917 "unknown type name %qE;"
1918 " use %<union%> keyword to refer to the type",
1921 else if (tag_exists_p (ENUMERAL_TYPE, name))
1923 richloc.add_fixit_insert_before ("enum ");
1925 "unknown type name %qE;"
1926 " use %<enum%> keyword to refer to the type",
1931 auto_diagnostic_group d;
1932 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1934 if (const char *suggestion = hint.suggestion ())
1936 richloc.add_fixit_replace (suggestion);
1938 "unknown type name %qE; did you mean %qs?",
1942 error_at (here, "unknown type name %qE", name);
1945 /* Parse declspecs normally to get a correct pointer type, but avoid
1946 a further "fails to be a type name" error. Refuse nested functions
1947 since it is not how the user likely wants us to recover. */
1948 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1949 c_parser_peek_token (parser)->keyword = RID_VOID;
1950 c_parser_peek_token (parser)->value = error_mark_node;
1954 /* When there are standard attributes at the start of the
1955 declaration (to apply to the entity being declared), an
1956 init-declarator-list or function definition must be present. */
1957 if (c_parser_nth_token_starts_std_attributes (parser, 1))
1960 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1961 true, true, start_attr_ok, true, cla_nonabstract_decl);
1964 c_parser_skip_to_end_of_block_or_statement (parser);
1967 if (nested && !specs->declspecs_seen_p)
1969 c_parser_error (parser, "expected declaration specifiers");
1970 c_parser_skip_to_end_of_block_or_statement (parser);
1974 finish_declspecs (specs);
1975 bool auto_type_p = specs->typespec_word == cts_auto_type;
1976 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1979 error_at (here, "%<__auto_type%> in empty declaration");
1980 else if (specs->typespec_kind == ctsk_none
1981 && attribute_fallthrough_p (specs->attrs))
1983 if (fallthru_attr_p != NULL)
1984 *fallthru_attr_p = true;
1987 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
1992 pedwarn (here, OPT_Wattributes,
1993 "%<fallthrough%> attribute at top level");
1995 else if (empty_ok && !(have_attrs
1996 && specs->non_std_attrs_seen_p))
2000 shadow_tag_warned (specs, 1);
2001 pedwarn (here, 0, "empty declaration");
2003 c_parser_consume_token (parser);
2004 if (oacc_routine_data)
2005 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2009 /* Provide better error recovery. Note that a type name here is usually
2010 better diagnosed as a redeclaration. */
2012 && specs->typespec_kind == ctsk_tagdef
2013 && c_parser_next_token_starts_declspecs (parser)
2014 && !c_parser_next_token_is (parser, CPP_NAME))
2016 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2017 parser->error = false;
2018 shadow_tag_warned (specs, 1);
2021 else if (c_dialect_objc () && !auto_type_p)
2023 /* Prefix attributes are an error on method decls. */
2024 switch (c_parser_peek_token (parser)->type)
2028 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2032 warning_at (c_parser_peek_token (parser)->location,
2034 "prefix attributes are ignored for methods");
2035 specs->attrs = NULL_TREE;
2038 c_parser_objc_method_definition (parser);
2040 c_parser_objc_methodproto (parser);
2046 /* This is where we parse 'attributes @interface ...',
2047 'attributes @implementation ...', 'attributes @protocol ...'
2048 (where attributes could be, for example, __attribute__
2051 switch (c_parser_peek_token (parser)->keyword)
2053 case RID_AT_INTERFACE:
2055 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2057 c_parser_objc_class_definition (parser, specs->attrs);
2061 case RID_AT_IMPLEMENTATION:
2063 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2067 warning_at (c_parser_peek_token (parser)->location,
2069 "prefix attributes are ignored for implementations");
2070 specs->attrs = NULL_TREE;
2072 c_parser_objc_class_definition (parser, NULL_TREE);
2076 case RID_AT_PROTOCOL:
2078 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2080 c_parser_objc_protocol_definition (parser, specs->attrs);
2087 case RID_AT_PROPERTY:
2090 c_parser_error (parser, "unexpected attribute");
2091 specs->attrs = NULL;
2098 else if (attribute_fallthrough_p (specs->attrs))
2099 warning_at (here, OPT_Wattributes,
2100 "%<fallthrough%> attribute not followed by %<;%>");
2102 pending_xref_error ();
2103 prefix_attrs = specs->attrs;
2104 all_prefix_attrs = prefix_attrs;
2105 specs->attrs = NULL_TREE;
2108 struct c_declarator *declarator;
2111 tree fnbody = NULL_TREE;
2112 /* Declaring either one or more declarators (in which case we
2113 should diagnose if there were no declaration specifiers) or a
2114 function definition (in which case the diagnostic for
2115 implicit int suffices). */
2116 declarator = c_parser_declarator (parser,
2117 specs->typespec_kind != ctsk_none,
2118 C_DTR_NORMAL, &dummy);
2119 if (declarator == NULL)
2121 if (omp_declare_simd_clauses.exists ())
2122 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2123 omp_declare_simd_clauses);
2124 if (oacc_routine_data)
2125 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2126 c_parser_skip_to_end_of_block_or_statement (parser);
2129 if (auto_type_p && declarator->kind != cdk_id)
2132 "%<__auto_type%> requires a plain identifier"
2134 c_parser_skip_to_end_of_block_or_statement (parser);
2137 if (c_parser_next_token_is (parser, CPP_EQ)
2138 || c_parser_next_token_is (parser, CPP_COMMA)
2139 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2140 || c_parser_next_token_is_keyword (parser, RID_ASM)
2141 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2142 || c_parser_next_token_is_keyword (parser, RID_IN))
2144 tree asm_name = NULL_TREE;
2145 tree postfix_attrs = NULL_TREE;
2146 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2148 diagnosed_no_specs = true;
2149 pedwarn (here, 0, "data definition has no type or storage class");
2151 /* Having seen a data definition, there cannot now be a
2152 function definition. */
2154 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2155 asm_name = c_parser_simple_asm_expr (parser);
2156 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2158 postfix_attrs = c_parser_gnu_attributes (parser);
2159 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2161 /* This means there is an attribute specifier after
2162 the declarator in a function definition. Provide
2163 some more information for the user. */
2164 error_at (here, "attributes should be specified before the "
2165 "declarator in a function definition");
2166 c_parser_skip_to_end_of_block_or_statement (parser);
2170 if (c_parser_next_token_is (parser, CPP_EQ))
2174 location_t init_loc;
2175 c_parser_consume_token (parser);
2178 init_loc = c_parser_peek_token (parser)->location;
2179 rich_location richloc (line_table, init_loc);
2180 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2181 /* A parameter is initialized, which is invalid. Don't
2182 attempt to instrument the initializer. */
2183 int flag_sanitize_save = flag_sanitize;
2184 if (nested && !empty_ok)
2186 init = c_parser_expr_no_commas (parser, NULL);
2187 flag_sanitize = flag_sanitize_save;
2188 if (TREE_CODE (init.value) == COMPONENT_REF
2189 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2191 "%<__auto_type%> used with a bit-field"
2193 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2194 tree init_type = TREE_TYPE (init.value);
2195 /* As with typeof, remove all qualifiers from atomic types. */
2196 if (init_type != error_mark_node && TYPE_ATOMIC (init_type))
2198 = c_build_qualified_type (init_type, TYPE_UNQUALIFIED);
2199 bool vm_type = variably_modified_type_p (init_type,
2202 init.value = save_expr (init.value);
2204 specs->typespec_kind = ctsk_typeof;
2205 specs->locations[cdw_typedef] = init_loc;
2206 specs->typedef_p = true;
2207 specs->type = init_type;
2210 bool maybe_const = true;
2211 tree type_expr = c_fully_fold (init.value, false,
2213 specs->expr_const_operands &= maybe_const;
2215 specs->expr = build2 (COMPOUND_EXPR,
2216 TREE_TYPE (type_expr),
2217 specs->expr, type_expr);
2219 specs->expr = type_expr;
2221 d = start_decl (declarator, specs, true,
2222 chainon (postfix_attrs, all_prefix_attrs));
2224 d = error_mark_node;
2225 if (omp_declare_simd_clauses.exists ())
2226 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2227 omp_declare_simd_clauses);
2231 /* The declaration of the variable is in effect while
2232 its initializer is parsed. */
2233 d = start_decl (declarator, specs, true,
2234 chainon (postfix_attrs, all_prefix_attrs));
2236 d = error_mark_node;
2237 if (omp_declare_simd_clauses.exists ())
2238 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2239 omp_declare_simd_clauses);
2240 init_loc = c_parser_peek_token (parser)->location;
2241 rich_location richloc (line_table, init_loc);
2242 start_init (d, asm_name, global_bindings_p (), &richloc);
2243 /* A parameter is initialized, which is invalid. Don't
2244 attempt to instrument the initializer. */
2245 int flag_sanitize_save = flag_sanitize;
2246 if (TREE_CODE (d) == PARM_DECL)
2248 init = c_parser_initializer (parser);
2249 flag_sanitize = flag_sanitize_save;
2252 if (oacc_routine_data)
2253 c_finish_oacc_routine (oacc_routine_data, d, false);
2254 if (d != error_mark_node)
2256 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2257 finish_decl (d, init_loc, init.value,
2258 init.original_type, asm_name);
2266 "%<__auto_type%> requires an initialized "
2267 "data declaration");
2268 c_parser_skip_to_end_of_block_or_statement (parser);
2271 tree d = start_decl (declarator, specs, false,
2272 chainon (postfix_attrs,
2275 && TREE_CODE (d) == FUNCTION_DECL
2276 && DECL_ARGUMENTS (d) == NULL_TREE
2277 && DECL_INITIAL (d) == NULL_TREE)
2279 /* Find the innermost declarator that is neither cdk_id
2281 const struct c_declarator *decl = declarator;
2282 const struct c_declarator *last_non_id_attrs = NULL;
2290 last_non_id_attrs = decl;
2291 decl = decl->declarator;
2295 decl = decl->declarator;
2306 /* If it exists and is cdk_function, use its parameters. */
2307 if (last_non_id_attrs
2308 && last_non_id_attrs->kind == cdk_function)
2309 DECL_ARGUMENTS (d) = last_non_id_attrs->u.arg_info->parms;
2311 if (omp_declare_simd_clauses.exists ())
2313 tree parms = NULL_TREE;
2314 if (d && TREE_CODE (d) == FUNCTION_DECL)
2316 struct c_declarator *ce = declarator;
2318 if (ce->kind == cdk_function)
2320 parms = ce->u.arg_info->parms;
2324 ce = ce->declarator;
2327 temp_store_parm_decls (d, parms);
2328 c_finish_omp_declare_simd (parser, d, parms,
2329 omp_declare_simd_clauses);
2331 temp_pop_parm_decls ();
2333 if (oacc_routine_data)
2334 c_finish_oacc_routine (oacc_routine_data, d, false);
2336 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2337 NULL_TREE, asm_name);
2339 if (c_parser_next_token_is_keyword (parser, RID_IN))
2342 *objc_foreach_object_declaration = d;
2344 *objc_foreach_object_declaration = error_mark_node;
2347 if (c_parser_next_token_is (parser, CPP_COMMA))
2352 "%<__auto_type%> may only be used with"
2353 " a single declarator");
2354 c_parser_skip_to_end_of_block_or_statement (parser);
2357 c_parser_consume_token (parser);
2358 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2359 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2362 all_prefix_attrs = prefix_attrs;
2365 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2367 c_parser_consume_token (parser);
2370 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2372 /* This can only happen in Objective-C: we found the
2373 'in' that terminates the declaration inside an
2374 Objective-C foreach statement. Do not consume the
2375 token, so that the caller can use it to determine
2376 that this indeed is a foreach context. */
2381 c_parser_error (parser, "expected %<,%> or %<;%>");
2382 c_parser_skip_to_end_of_block_or_statement (parser);
2386 else if (auto_type_p)
2389 "%<__auto_type%> requires an initialized data declaration");
2390 c_parser_skip_to_end_of_block_or_statement (parser);
2395 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2396 "%<asm%> or %<__attribute__%>");
2397 c_parser_skip_to_end_of_block_or_statement (parser);
2400 /* Function definition (nested or otherwise). */
2403 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2404 c_push_function_context ();
2406 if (!start_function (specs, declarator, all_prefix_attrs))
2408 /* At this point we've consumed:
2409 declaration-specifiers declarator
2410 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2411 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2413 declaration-specifiers declarator
2414 aren't grokkable as a function definition, so we have
2416 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2417 if (c_parser_next_token_starts_declspecs (parser))
2420 declaration-specifiers declarator decl-specs
2421 then assume we have a missing semicolon, which would
2423 declaration-specifiers declarator decl-specs
2426 <~~~~~~~~~ declaration ~~~~~~~~~~>
2427 Use c_parser_require to get an error with a fix-it hint. */
2428 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2429 parser->error = false;
2433 /* This can appear in many cases looking nothing like a
2434 function definition, so we don't give a more specific
2435 error suggesting there was one. */
2436 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2437 "or %<__attribute__%>");
2440 c_pop_function_context ();
2444 if (DECL_DECLARED_INLINE_P (current_function_decl))
2445 tv = TV_PARSE_INLINE;
2448 auto_timevar at (g_timer, tv);
2450 /* Parse old-style parameter declarations. ??? Attributes are
2451 not allowed to start declaration specifiers here because of a
2452 syntax conflict between a function declaration with attribute
2453 suffix and a function definition with an attribute prefix on
2454 first old-style parameter declaration. Following the old
2455 parser, they are not accepted on subsequent old-style
2456 parameter declarations either. However, there is no
2457 ambiguity after the first declaration, nor indeed on the
2458 first as long as we don't allow postfix attributes after a
2459 declarator with a nonempty identifier list in a definition;
2460 and postfix attributes have never been accepted here in
2461 function definitions either. */
2462 while (c_parser_next_token_is_not (parser, CPP_EOF)
2463 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2464 c_parser_declaration_or_fndef (parser, false, false, false,
2465 true, false, NULL, vNULL);
2466 store_parm_decls ();
2467 if (omp_declare_simd_clauses.exists ())
2468 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2469 omp_declare_simd_clauses);
2470 if (oacc_routine_data)
2471 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2472 location_t startloc = c_parser_peek_token (parser)->location;
2473 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2475 location_t endloc = startloc;
2477 /* If the definition was marked with __RTL, use the RTL parser now,
2478 consuming the function body. */
2479 if (specs->declspec_il == cdil_rtl)
2481 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2483 /* Normally, store_parm_decls sets next_is_function_body,
2484 anticipating a function body. We need a push_scope/pop_scope
2485 pair to flush out this state, or subsequent function parsing
2490 finish_function (endloc);
2493 /* If the definition was marked with __GIMPLE then parse the
2494 function body as GIMPLE. */
2495 else if (specs->declspec_il != cdil_none)
2497 bool saved = in_late_binary_op;
2498 in_late_binary_op = true;
2499 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2501 specs->entry_bb_count);
2502 in_late_binary_op = saved;
2505 fnbody = c_parser_compound_statement (parser, &endloc);
2506 tree fndecl = current_function_decl;
2509 tree decl = current_function_decl;
2510 /* Mark nested functions as needing static-chain initially.
2511 lower_nested_functions will recompute it but the
2512 DECL_STATIC_CHAIN flag is also used before that happens,
2513 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2514 DECL_STATIC_CHAIN (decl) = 1;
2516 finish_function (endloc);
2517 c_pop_function_context ();
2518 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2524 finish_function (endloc);
2526 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2527 if (specs->declspec_il != cdil_none)
2528 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2534 /* Parse an asm-definition (asm() outside a function body). This is a
2542 c_parser_asm_definition (c_parser *parser)
2544 tree asm_str = c_parser_simple_asm_expr (parser);
2546 symtab->finalize_toplevel_asm (asm_str);
2547 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2550 /* Parse a static assertion (C11 6.7.10).
2552 static_assert-declaration:
2553 static_assert-declaration-no-semi ;
2557 c_parser_static_assert_declaration (c_parser *parser)
2559 c_parser_static_assert_declaration_no_semi (parser);
2561 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2562 c_parser_skip_to_end_of_block_or_statement (parser);
2565 /* Parse a static assertion (C11 6.7.10), without the trailing
2568 static_assert-declaration-no-semi:
2569 _Static_assert ( constant-expression , string-literal )
2572 static_assert-declaration-no-semi:
2573 _Static_assert ( constant-expression )
2577 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2579 location_t assert_loc, value_loc;
2581 tree string = NULL_TREE;
2583 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2584 assert_loc = c_parser_peek_token (parser)->location;
2586 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2587 "ISO C99 does not support %<_Static_assert%>");
2589 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2590 "ISO C90 does not support %<_Static_assert%>");
2591 c_parser_consume_token (parser);
2592 matching_parens parens;
2593 if (!parens.require_open (parser))
2595 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2596 value = c_parser_expr_no_commas (parser, NULL).value;
2597 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2598 if (c_parser_next_token_is (parser, CPP_COMMA))
2600 c_parser_consume_token (parser);
2601 switch (c_parser_peek_token (parser)->type)
2607 case CPP_UTF8STRING:
2608 string = c_parser_string_literal (parser, false, true).value;
2611 c_parser_error (parser, "expected string literal");
2615 else if (flag_isoc11)
2616 /* If pedantic for pre-C11, the use of _Static_assert itself will
2617 have been diagnosed, so do not also diagnose the use of this
2618 new C2X feature of _Static_assert. */
2619 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2620 "ISO C11 does not support omitting the string in "
2621 "%<_Static_assert%>");
2622 parens.require_close (parser);
2624 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2626 error_at (value_loc, "expression in static assertion is not an integer");
2629 if (TREE_CODE (value) != INTEGER_CST)
2631 value = c_fully_fold (value, false, NULL);
2632 /* Strip no-op conversions. */
2633 STRIP_TYPE_NOPS (value);
2634 if (TREE_CODE (value) == INTEGER_CST)
2635 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2636 "is not an integer constant expression");
2638 if (TREE_CODE (value) != INTEGER_CST)
2640 error_at (value_loc, "expression in static assertion is not constant");
2643 constant_expression_warning (value);
2644 if (integer_zerop (value))
2647 error_at (assert_loc, "static assertion failed: %E", string);
2649 error_at (assert_loc, "static assertion failed");
2653 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2654 6.7, C11 6.7), adding them to SPECS (which may already include some).
2655 Storage class specifiers are accepted iff SCSPEC_OK; type
2656 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2657 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2658 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2659 addition to the syntax shown, standard attributes are accepted at
2660 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2661 unlike gnu-attributes, they are not accepted in the middle of the
2662 list. (This combines various different syntax productions in the C
2663 standard, and in some cases gnu-attributes and standard attributes
2664 at the start may already have been parsed before this function is
2667 declaration-specifiers:
2668 storage-class-specifier declaration-specifiers[opt]
2669 type-specifier declaration-specifiers[opt]
2670 type-qualifier declaration-specifiers[opt]
2671 function-specifier declaration-specifiers[opt]
2672 alignment-specifier declaration-specifiers[opt]
2674 Function specifiers (inline) are from C99, and are currently
2675 handled as storage class specifiers, as is __thread. Alignment
2676 specifiers are from C11.
2678 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2679 storage-class-specifier:
2687 (_Thread_local is new in C11.)
2689 C99 6.7.4, C11 6.7.4:
2694 (_Noreturn is new in C11.)
2696 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2709 [_Imaginary removed in C99 TC2]
2710 struct-or-union-specifier
2713 atomic-type-specifier
2715 (_Bool and _Complex are new in C99.)
2716 (atomic-type-specifier is new in C11.)
2718 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2724 address-space-qualifier
2727 (restrict is new in C99.)
2728 (_Atomic is new in C11.)
2732 declaration-specifiers:
2733 gnu-attributes declaration-specifiers[opt]
2739 identifier recognized by the target
2741 storage-class-specifier:
2755 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2756 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2758 atomic-type-specifier
2759 _Atomic ( type-name )
2764 class-name objc-protocol-refs[opt]
2765 typedef-name objc-protocol-refs
2770 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2771 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2772 bool alignspec_ok, bool auto_type_ok,
2773 bool start_std_attr_ok, bool end_std_attr_ok,
2774 enum c_lookahead_kind la)
2776 bool attrs_ok = start_attr_ok;
2777 bool seen_type = specs->typespec_kind != ctsk_none;
2780 gcc_assert (la == cla_prefer_id);
2782 if (start_std_attr_ok
2783 && c_parser_nth_token_starts_std_attributes (parser, 1))
2785 gcc_assert (!specs->non_std_attrs_seen_p);
2786 location_t loc = c_parser_peek_token (parser)->location;
2787 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2788 declspecs_add_attrs (loc, specs, attrs);
2789 specs->non_std_attrs_seen_p = false;
2792 while (c_parser_next_token_is (parser, CPP_NAME)
2793 || c_parser_next_token_is (parser, CPP_KEYWORD)
2794 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2796 struct c_typespec t;
2799 location_t loc = c_parser_peek_token (parser)->location;
2801 /* If we cannot accept a type, exit if the next token must start
2802 one. Also, if we already have seen a tagged definition,
2803 a typename would be an error anyway and likely the user
2804 has simply forgotten a semicolon, so we exit. */
2805 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2806 && c_parser_next_tokens_start_typename (parser, la)
2807 && !c_parser_next_token_is_qualifier (parser)
2808 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2811 if (c_parser_next_token_is (parser, CPP_NAME))
2813 c_token *name_token = c_parser_peek_token (parser);
2814 tree value = name_token->value;
2815 c_id_kind kind = name_token->id_kind;
2817 if (kind == C_ID_ADDRSPACE)
2820 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2821 declspecs_add_addrspace (name_token->location, specs, as);
2822 c_parser_consume_token (parser);
2827 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2829 /* If we cannot accept a type, and the next token must start one,
2830 exit. Do the same if we already have seen a tagged definition,
2831 since it would be an error anyway and likely the user has simply
2832 forgotten a semicolon. */
2833 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2836 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2837 a C_ID_CLASSNAME. */
2838 c_parser_consume_token (parser);
2841 if (kind == C_ID_ID)
2843 error_at (loc, "unknown type name %qE", value);
2844 t.kind = ctsk_typedef;
2845 t.spec = error_mark_node;
2847 else if (kind == C_ID_TYPENAME
2848 && (!c_dialect_objc ()
2849 || c_parser_next_token_is_not (parser, CPP_LESS)))
2851 t.kind = ctsk_typedef;
2852 /* For a typedef name, record the meaning, not the name.
2853 In case of 'foo foo, bar;'. */
2854 t.spec = lookup_name (value);
2858 tree proto = NULL_TREE;
2859 gcc_assert (c_dialect_objc ());
2861 if (c_parser_next_token_is (parser, CPP_LESS))
2862 proto = c_parser_objc_protocol_refs (parser);
2863 t.spec = objc_get_protocol_qualified_type (value, proto);
2866 t.expr_const_operands = true;
2867 declspecs_add_type (name_token->location, specs, t);
2870 if (c_parser_next_token_is (parser, CPP_LESS))
2872 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2873 nisse@lysator.liu.se. */
2875 gcc_assert (c_dialect_objc ());
2876 if (!typespec_ok || seen_type)
2878 proto = c_parser_objc_protocol_refs (parser);
2880 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2882 t.expr_const_operands = true;
2883 declspecs_add_type (loc, specs, t);
2886 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2887 switch (c_parser_peek_token (parser)->keyword)
2900 /* TODO: Distinguish between function specifiers (inline, noreturn)
2901 and storage class specifiers, either here or in
2902 declspecs_add_scspec. */
2903 declspecs_add_scspec (loc, specs,
2904 c_parser_peek_token (parser)->value);
2905 c_parser_consume_token (parser);
2937 if (c_dialect_objc ())
2938 parser->objc_need_raw_identifier = true;
2939 t.kind = ctsk_resword;
2940 t.spec = c_parser_peek_token (parser)->value;
2942 t.expr_const_operands = true;
2943 declspecs_add_type (loc, specs, t);
2944 c_parser_consume_token (parser);
2951 t = c_parser_enum_specifier (parser);
2952 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2953 declspecs_add_type (loc, specs, t);
2961 t = c_parser_struct_or_union_specifier (parser);
2962 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2963 declspecs_add_type (loc, specs, t);
2966 /* ??? The old parser rejected typeof after other type
2967 specifiers, but is a syntax error the best way of
2969 if (!typespec_ok || seen_type)
2973 t = c_parser_typeof_specifier (parser);
2974 declspecs_add_type (loc, specs, t);
2977 /* C parser handling of Objective-C constructs needs
2978 checking for correct lvalue-to-rvalue conversions, and
2979 the code in build_modify_expr handling various
2980 Objective-C cases, and that in build_unary_op handling
2981 Objective-C cases for increment / decrement, also needs
2982 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
2983 and objc_types_are_equivalent may also need updates. */
2984 if (c_dialect_objc ())
2985 sorry ("%<_Atomic%> in Objective-C");
2987 pedwarn_c99 (loc, OPT_Wpedantic,
2988 "ISO C99 does not support the %<_Atomic%> qualifier");
2990 pedwarn_c99 (loc, OPT_Wpedantic,
2991 "ISO C90 does not support the %<_Atomic%> qualifier");
2994 value = c_parser_peek_token (parser)->value;
2995 c_parser_consume_token (parser);
2996 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
2998 /* _Atomic ( type-name ). */
3000 c_parser_consume_token (parser);
3001 struct c_type_name *type = c_parser_type_name (parser);
3002 t.kind = ctsk_typeof;
3003 t.spec = error_mark_node;
3005 t.expr_const_operands = true;
3007 t.spec = groktypename (type, &t.expr,
3008 &t.expr_const_operands);
3009 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3011 if (t.spec != error_mark_node)
3013 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3014 error_at (loc, "%<_Atomic%>-qualified array type");
3015 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3016 error_at (loc, "%<_Atomic%>-qualified function type");
3017 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3018 error_at (loc, "%<_Atomic%> applied to a qualified type");
3020 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3022 declspecs_add_type (loc, specs, t);
3025 declspecs_add_qual (loc, specs, value);
3031 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3032 c_parser_consume_token (parser);
3037 attrs = c_parser_gnu_attributes (parser);
3038 declspecs_add_attrs (loc, specs, attrs);
3043 align = c_parser_alignas_specifier (parser);
3044 declspecs_add_alignas (loc, specs, align);
3048 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3049 c_parser_consume_token (parser);
3050 specs->declspec_il = cdil_gimple;
3051 specs->locations[cdw_gimple] = loc;
3052 c_parser_gimple_or_rtl_pass_list (parser, specs);
3055 c_parser_consume_token (parser);
3056 specs->declspec_il = cdil_rtl;
3057 specs->locations[cdw_rtl] = loc;
3058 c_parser_gimple_or_rtl_pass_list (parser, specs);
3066 && c_parser_nth_token_starts_std_attributes (parser, 1))
3067 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3070 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3073 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3075 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3077 enum gnu-attributes[opt] identifier
3079 The form with trailing comma is new in C99. The forms with
3080 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3081 without commas in the syntax (assignment expressions, not just
3082 conditional expressions); assignment expressions will be diagnosed
3087 enumerator-list , enumerator
3090 enumeration-constant attribute-specifier-sequence[opt]
3091 enumeration-constant attribute-specifier-sequence[opt]
3092 = constant-expression
3097 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3098 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3099 = constant-expression
3103 static struct c_typespec
3104 c_parser_enum_specifier (c_parser *parser)
3106 struct c_typespec ret;
3107 bool have_std_attrs;
3108 tree std_attrs = NULL_TREE;
3110 tree ident = NULL_TREE;
3111 location_t enum_loc;
3112 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3113 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3114 c_parser_consume_token (parser);
3115 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3117 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3118 attrs = c_parser_gnu_attributes (parser);
3119 enum_loc = c_parser_peek_token (parser)->location;
3120 /* Set the location in case we create a decl now. */
3121 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3122 if (c_parser_next_token_is (parser, CPP_NAME))
3124 ident = c_parser_peek_token (parser)->value;
3125 ident_loc = c_parser_peek_token (parser)->location;
3126 enum_loc = ident_loc;
3127 c_parser_consume_token (parser);
3129 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3131 /* Parse an enum definition. */
3132 struct c_enum_contents the_enum;
3135 /* We chain the enumerators in reverse order, then put them in
3136 forward order at the end. */
3138 timevar_push (TV_PARSE_ENUM);
3139 type = start_enum (enum_loc, &the_enum, ident);
3141 c_parser_consume_token (parser);
3149 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3150 location_t decl_loc, value_loc;
3151 if (c_parser_next_token_is_not (parser, CPP_NAME))
3153 /* Give a nicer error for "enum {}". */
3154 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3157 error_at (c_parser_peek_token (parser)->location,
3158 "empty enum is invalid");
3159 parser->error = true;
3162 c_parser_error (parser, "expected identifier");
3163 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3164 values = error_mark_node;
3167 token = c_parser_peek_token (parser);
3168 enum_id = token->value;
3169 /* Set the location in case we create a decl now. */
3170 c_parser_set_source_position_from_token (token);
3171 decl_loc = value_loc = token->location;
3172 c_parser_consume_token (parser);
3173 /* Parse any specified attributes. */
3174 tree std_attrs = NULL_TREE;
3175 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3176 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3177 tree enum_attrs = chainon (std_attrs,
3178 c_parser_gnu_attributes (parser));
3179 if (c_parser_next_token_is (parser, CPP_EQ))
3181 c_parser_consume_token (parser);
3182 value_loc = c_parser_peek_token (parser)->location;
3183 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3186 enum_value = NULL_TREE;
3187 enum_decl = build_enumerator (decl_loc, value_loc,
3188 &the_enum, enum_id, enum_value);
3190 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3191 TREE_CHAIN (enum_decl) = values;
3194 if (c_parser_next_token_is (parser, CPP_COMMA))
3196 comma_loc = c_parser_peek_token (parser)->location;
3198 c_parser_consume_token (parser);
3200 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3203 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3204 "comma at end of enumerator list");
3205 c_parser_consume_token (parser);
3210 c_parser_error (parser, "expected %<,%> or %<}%>");
3211 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3212 values = error_mark_node;
3216 postfix_attrs = c_parser_gnu_attributes (parser);
3217 ret.spec = finish_enum (type, nreverse (values),
3219 chainon (attrs, postfix_attrs)));
3220 ret.kind = ctsk_tagdef;
3221 ret.expr = NULL_TREE;
3222 ret.expr_const_operands = true;
3223 timevar_pop (TV_PARSE_ENUM);
3228 c_parser_error (parser, "expected %<{%>");
3229 ret.spec = error_mark_node;
3230 ret.kind = ctsk_tagref;
3231 ret.expr = NULL_TREE;
3232 ret.expr_const_operands = true;
3235 /* Attributes may only appear when the members are defined or in
3236 certain forward declarations (treat enum forward declarations in
3237 GNU C analogously to struct and union forward declarations in
3239 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3240 c_parser_error (parser, "expected %<;%>");
3241 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3243 /* In ISO C, enumerated types can be referred to only if already
3245 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3248 pedwarn (enum_loc, OPT_Wpedantic,
3249 "ISO C forbids forward references to %<enum%> types");
3254 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3256 struct-or-union-specifier:
3257 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3258 identifier[opt] { struct-contents } gnu-attributes[opt]
3259 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3263 struct-declaration-list
3265 struct-declaration-list:
3266 struct-declaration ;
3267 struct-declaration-list struct-declaration ;
3274 struct-declaration-list struct-declaration
3276 struct-declaration-list:
3277 struct-declaration-list ;
3280 (Note that in the syntax here, unlike that in ISO C, the semicolons
3281 are included here rather than in struct-declaration, in order to
3282 describe the syntax with extra semicolons and missing semicolon at
3287 struct-declaration-list:
3288 @defs ( class-name )
3290 (Note this does not include a trailing semicolon, but can be
3291 followed by further declarations, and gets a pedwarn-if-pedantic
3292 when followed by a semicolon.) */
3294 static struct c_typespec
3295 c_parser_struct_or_union_specifier (c_parser *parser)
3297 struct c_typespec ret;
3298 bool have_std_attrs;
3299 tree std_attrs = NULL_TREE;
3301 tree ident = NULL_TREE;
3302 location_t struct_loc;
3303 location_t ident_loc = UNKNOWN_LOCATION;
3304 enum tree_code code;
3305 switch (c_parser_peek_token (parser)->keyword)
3316 struct_loc = c_parser_peek_token (parser)->location;
3317 c_parser_consume_token (parser);
3318 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3320 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3321 attrs = c_parser_gnu_attributes (parser);
3323 /* Set the location in case we create a decl now. */
3324 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3326 if (c_parser_next_token_is (parser, CPP_NAME))
3328 ident = c_parser_peek_token (parser)->value;
3329 ident_loc = c_parser_peek_token (parser)->location;
3330 struct_loc = ident_loc;
3331 c_parser_consume_token (parser);
3333 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3335 /* Parse a struct or union definition. Start the scope of the
3336 tag before parsing components. */
3337 class c_struct_parse_info *struct_info;
3338 tree type = start_struct (struct_loc, code, ident, &struct_info);
3340 /* We chain the components in reverse order, then put them in
3341 forward order at the end. Each struct-declaration may
3342 declare multiple components (comma-separated), so we must use
3343 chainon to join them, although when parsing each
3344 struct-declaration we can use TREE_CHAIN directly.
3346 The theory behind all this is that there will be more
3347 semicolon separated fields than comma separated fields, and
3348 so we'll be minimizing the number of node traversals required
3351 timevar_push (TV_PARSE_STRUCT);
3352 contents = NULL_TREE;
3353 c_parser_consume_token (parser);
3354 /* Handle the Objective-C @defs construct,
3355 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3356 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3359 gcc_assert (c_dialect_objc ());
3360 c_parser_consume_token (parser);
3361 matching_parens parens;
3362 if (!parens.require_open (parser))
3364 if (c_parser_next_token_is (parser, CPP_NAME)
3365 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3367 name = c_parser_peek_token (parser)->value;
3368 c_parser_consume_token (parser);
3372 c_parser_error (parser, "expected class name");
3373 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3376 parens.skip_until_found_close (parser);
3377 contents = nreverse (objc_get_class_ivars (name));
3380 /* Parse the struct-declarations and semicolons. Problems with
3381 semicolons are diagnosed here; empty structures are diagnosed
3386 /* Parse any stray semicolon. */
3387 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3389 location_t semicolon_loc
3390 = c_parser_peek_token (parser)->location;
3391 gcc_rich_location richloc (semicolon_loc);
3392 richloc.add_fixit_remove ();
3393 pedwarn (&richloc, OPT_Wpedantic,
3394 "extra semicolon in struct or union specified");
3395 c_parser_consume_token (parser);
3398 /* Stop if at the end of the struct or union contents. */
3399 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3401 c_parser_consume_token (parser);
3404 /* Accept #pragmas at struct scope. */
3405 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3407 c_parser_pragma (parser, pragma_struct, NULL);
3410 /* Parse some comma-separated declarations, but not the
3411 trailing semicolon if any. */
3412 decls = c_parser_struct_declaration (parser);
3413 contents = chainon (decls, contents);
3414 /* If no semicolon follows, either we have a parse error or
3415 are at the end of the struct or union and should
3417 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3418 c_parser_consume_token (parser);
3421 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3422 pedwarn (c_parser_peek_token (parser)->location, 0,
3423 "no semicolon at end of struct or union");
3424 else if (parser->error
3425 || !c_parser_next_token_starts_declspecs (parser))
3427 c_parser_error (parser, "expected %<;%>");
3428 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3432 /* If we come here, we have already emitted an error
3433 for an expected `;', identifier or `(', and we also
3434 recovered already. Go on with the next field. */
3437 postfix_attrs = c_parser_gnu_attributes (parser);
3438 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3440 chainon (attrs, postfix_attrs)),
3442 ret.kind = ctsk_tagdef;
3443 ret.expr = NULL_TREE;
3444 ret.expr_const_operands = true;
3445 timevar_pop (TV_PARSE_STRUCT);
3450 c_parser_error (parser, "expected %<{%>");
3451 ret.spec = error_mark_node;
3452 ret.kind = ctsk_tagref;
3453 ret.expr = NULL_TREE;
3454 ret.expr_const_operands = true;
3457 /* Attributes may only appear when the members are defined or in
3458 certain forward declarations. */
3459 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3460 c_parser_error (parser, "expected %<;%>");
3461 /* ??? Existing practice is that GNU attributes are ignored after
3462 the struct or union keyword when not defining the members. */
3463 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3467 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3468 *without* the trailing semicolon.
3471 attribute-specifier-sequence[opt] specifier-qualifier-list
3472 attribute-specifier-sequence[opt] struct-declarator-list
3473 static_assert-declaration-no-semi
3475 specifier-qualifier-list:
3476 type-specifier specifier-qualifier-list[opt]
3477 type-qualifier specifier-qualifier-list[opt]
3478 alignment-specifier specifier-qualifier-list[opt]
3479 gnu-attributes specifier-qualifier-list[opt]
3481 struct-declarator-list:
3483 struct-declarator-list , gnu-attributes[opt] struct-declarator
3486 declarator gnu-attributes[opt]
3487 declarator[opt] : constant-expression gnu-attributes[opt]
3492 __extension__ struct-declaration
3493 specifier-qualifier-list
3495 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3496 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3497 any expression without commas in the syntax (assignment
3498 expressions, not just conditional expressions); assignment
3499 expressions will be diagnosed as non-constant. */
3502 c_parser_struct_declaration (c_parser *parser)
3504 struct c_declspecs *specs;
3506 tree all_prefix_attrs;
3508 location_t decl_loc;
3509 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3513 ext = disable_extension_diagnostics ();
3514 c_parser_consume_token (parser);
3515 decl = c_parser_struct_declaration (parser);
3516 restore_extension_diagnostics (ext);
3519 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3521 c_parser_static_assert_declaration_no_semi (parser);
3524 specs = build_null_declspecs ();
3525 decl_loc = c_parser_peek_token (parser)->location;
3526 /* Strictly by the standard, we shouldn't allow _Alignas here,
3527 but it appears to have been intended to allow it there, so
3528 we're keeping it as it is until WG14 reaches a conclusion
3530 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3531 c_parser_declspecs (parser, specs, false, true, true,
3532 true, false, true, true, cla_nonabstract_decl);
3535 if (!specs->declspecs_seen_p)
3537 c_parser_error (parser, "expected specifier-qualifier-list");
3540 finish_declspecs (specs);
3541 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3542 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3545 if (specs->typespec_kind == ctsk_none)
3547 pedwarn (decl_loc, OPT_Wpedantic,
3548 "ISO C forbids member declarations with no members");
3549 shadow_tag_warned (specs, pedantic);
3554 /* Support for unnamed structs or unions as members of
3555 structs or unions (which is [a] useful and [b] supports
3559 ret = grokfield (c_parser_peek_token (parser)->location,
3560 build_id_declarator (NULL_TREE), specs,
3563 decl_attributes (&ret, attrs, 0);
3568 /* Provide better error recovery. Note that a type name here is valid,
3569 and will be treated as a field name. */
3570 if (specs->typespec_kind == ctsk_tagdef
3571 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3572 && c_parser_next_token_starts_declspecs (parser)
3573 && !c_parser_next_token_is (parser, CPP_NAME))
3575 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3576 parser->error = false;
3580 pending_xref_error ();
3581 prefix_attrs = specs->attrs;
3582 all_prefix_attrs = prefix_attrs;
3583 specs->attrs = NULL_TREE;
3587 /* Declaring one or more declarators or un-named bit-fields. */
3588 struct c_declarator *declarator;
3590 if (c_parser_next_token_is (parser, CPP_COLON))
3591 declarator = build_id_declarator (NULL_TREE);
3593 declarator = c_parser_declarator (parser,
3594 specs->typespec_kind != ctsk_none,
3595 C_DTR_NORMAL, &dummy);
3596 if (declarator == NULL)
3598 c_parser_skip_to_end_of_block_or_statement (parser);
3601 if (c_parser_next_token_is (parser, CPP_COLON)
3602 || c_parser_next_token_is (parser, CPP_COMMA)
3603 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3604 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3605 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3607 tree postfix_attrs = NULL_TREE;
3608 tree width = NULL_TREE;
3610 if (c_parser_next_token_is (parser, CPP_COLON))
3612 c_parser_consume_token (parser);
3613 width = c_parser_expr_no_commas (parser, NULL).value;
3615 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3616 postfix_attrs = c_parser_gnu_attributes (parser);
3617 d = grokfield (c_parser_peek_token (parser)->location,
3618 declarator, specs, width, &all_prefix_attrs);
3619 decl_attributes (&d, chainon (postfix_attrs,
3620 all_prefix_attrs), 0);
3621 DECL_CHAIN (d) = decls;
3623 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3624 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3627 all_prefix_attrs = prefix_attrs;
3628 if (c_parser_next_token_is (parser, CPP_COMMA))
3629 c_parser_consume_token (parser);
3630 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3631 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3633 /* Semicolon consumed in caller. */
3638 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3644 c_parser_error (parser,
3645 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3646 "%<__attribute__%>");
3653 /* Parse a typeof specifier (a GNU extension).
3656 typeof ( expression )
3657 typeof ( type-name )
3660 static struct c_typespec
3661 c_parser_typeof_specifier (c_parser *parser)
3663 struct c_typespec ret;
3664 ret.kind = ctsk_typeof;
3665 ret.spec = error_mark_node;
3666 ret.expr = NULL_TREE;
3667 ret.expr_const_operands = true;
3668 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3669 c_parser_consume_token (parser);
3670 c_inhibit_evaluation_warnings++;
3672 matching_parens parens;
3673 if (!parens.require_open (parser))
3675 c_inhibit_evaluation_warnings--;
3679 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3681 struct c_type_name *type = c_parser_type_name (parser);
3682 c_inhibit_evaluation_warnings--;
3686 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3687 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3693 location_t here = c_parser_peek_token (parser)->location;
3694 struct c_expr expr = c_parser_expression (parser);
3695 c_inhibit_evaluation_warnings--;
3697 if (TREE_CODE (expr.value) == COMPONENT_REF
3698 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3699 error_at (here, "%<typeof%> applied to a bit-field");
3700 mark_exp_read (expr.value);
3701 ret.spec = TREE_TYPE (expr.value);
3702 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3703 /* This is returned with the type so that when the type is
3704 evaluated, this can be evaluated. */
3706 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3707 pop_maybe_used (was_vm);
3708 /* For use in macros such as those in <stdatomic.h>, remove all
3709 qualifiers from atomic types. (const can be an issue for more macros
3710 using typeof than just the <stdatomic.h> ones.) */
3711 if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec))
3712 ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED);
3714 parens.skip_until_found_close (parser);
3718 /* Parse an alignment-specifier.
3722 alignment-specifier:
3723 _Alignas ( type-name )
3724 _Alignas ( constant-expression )
3728 c_parser_alignas_specifier (c_parser * parser)
3730 tree ret = error_mark_node;
3731 location_t loc = c_parser_peek_token (parser)->location;
3732 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3733 c_parser_consume_token (parser);
3735 pedwarn_c99 (loc, OPT_Wpedantic,
3736 "ISO C99 does not support %<_Alignas%>");
3738 pedwarn_c99 (loc, OPT_Wpedantic,
3739 "ISO C90 does not support %<_Alignas%>");
3740 matching_parens parens;
3741 if (!parens.require_open (parser))
3743 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3745 struct c_type_name *type = c_parser_type_name (parser);
3747 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3751 ret = c_parser_expr_no_commas (parser, NULL).value;
3752 parens.skip_until_found_close (parser);
3756 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3757 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3758 a typedef name may be redeclared; otherwise it may not. KIND
3759 indicates which kind of declarator is wanted. Returns a valid
3760 declarator except in the case of a syntax error in which case NULL is
3761 returned. *SEEN_ID is set to true if an identifier being declared is
3762 seen; this is used to diagnose bad forms of abstract array declarators
3763 and to determine whether an identifier list is syntactically permitted.
3766 pointer[opt] direct-declarator
3770 ( gnu-attributes[opt] declarator )
3771 direct-declarator array-declarator
3772 direct-declarator ( parameter-type-list )
3773 direct-declarator ( identifier-list[opt] )
3776 * type-qualifier-list[opt]
3777 * type-qualifier-list[opt] pointer
3779 type-qualifier-list:
3782 type-qualifier-list type-qualifier
3783 type-qualifier-list gnu-attributes
3786 [ type-qualifier-list[opt] assignment-expression[opt] ]
3787 [ static type-qualifier-list[opt] assignment-expression ]
3788 [ type-qualifier-list static assignment-expression ]
3789 [ type-qualifier-list[opt] * ]
3791 parameter-type-list:
3793 parameter-list , ...
3796 parameter-declaration
3797 parameter-list , parameter-declaration
3799 parameter-declaration:
3800 declaration-specifiers declarator gnu-attributes[opt]
3801 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3805 identifier-list , identifier
3807 abstract-declarator:
3809 pointer[opt] direct-abstract-declarator
3811 direct-abstract-declarator:
3812 ( gnu-attributes[opt] abstract-declarator )
3813 direct-abstract-declarator[opt] array-declarator
3814 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3819 direct-declarator ( parameter-forward-declarations
3820 parameter-type-list[opt] )
3822 direct-abstract-declarator:
3823 direct-abstract-declarator[opt] ( parameter-forward-declarations
3824 parameter-type-list[opt] )
3826 parameter-forward-declarations:
3828 parameter-forward-declarations parameter-list ;
3830 The uses of gnu-attributes shown above are GNU extensions.
3832 Some forms of array declarator are not included in C99 in the
3833 syntax for abstract declarators; these are disallowed elsewhere.
3834 This may be a defect (DR#289).
3836 This function also accepts an omitted abstract declarator as being
3837 an abstract declarator, although not part of the formal syntax. */
3839 struct c_declarator *
3840 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3843 /* Parse any initial pointer part. */
3844 if (c_parser_next_token_is (parser, CPP_MULT))
3846 struct c_declspecs *quals_attrs = build_null_declspecs ();
3847 struct c_declarator *inner;
3848 c_parser_consume_token (parser);
3849 c_parser_declspecs (parser, quals_attrs, false, false, true,
3850 false, false, true, false, cla_prefer_id);
3851 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3855 return make_pointer_declarator (quals_attrs, inner);
3857 /* Now we have a direct declarator, direct abstract declarator or
3858 nothing (which counts as a direct abstract declarator here). */
3859 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3862 /* Parse a direct declarator or direct abstract declarator; arguments
3863 as c_parser_declarator. */
3865 static struct c_declarator *
3866 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3869 /* The direct declarator must start with an identifier (possibly
3870 omitted) or a parenthesized declarator (possibly abstract). In
3871 an ordinary declarator, initial parentheses must start a
3872 parenthesized declarator. In an abstract declarator or parameter
3873 declarator, they could start a parenthesized declarator or a
3874 parameter list. To tell which, the open parenthesis and any
3875 following gnu-attributes must be read. If a declaration
3876 specifier or standard attributes follow, then it is a parameter
3877 list; if the specifier is a typedef name, there might be an
3878 ambiguity about redeclaring it, which is resolved in the
3879 direction of treating it as a typedef name. If a close
3880 parenthesis follows, it is also an empty parameter list, as the
3881 syntax does not permit empty abstract declarators. Otherwise, it
3882 is a parenthesized declarator (in which case the analysis may be
3883 repeated inside it, recursively).
3885 ??? There is an ambiguity in a parameter declaration "int
3886 (__attribute__((foo)) x)", where x is not a typedef name: it
3887 could be an abstract declarator for a function, or declare x with
3888 parentheses. The proper resolution of this ambiguity needs
3889 documenting. At present we follow an accident of the old
3890 parser's implementation, whereby the first parameter must have
3891 some declaration specifiers other than just gnu-attributes. Thus as
3892 a parameter declaration it is treated as a parenthesized
3893 parameter named x, and as an abstract declarator it is
3896 ??? Also following the old parser, gnu-attributes inside an empty
3897 parameter list are ignored, making it a list not yielding a
3898 prototype, rather than giving an error or making it have one
3899 parameter with implicit type int.
3901 ??? Also following the old parser, typedef names may be
3902 redeclared in declarators, but not Objective-C class names. */
3904 if (kind != C_DTR_ABSTRACT
3905 && c_parser_next_token_is (parser, CPP_NAME)
3907 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3908 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3909 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3911 struct c_declarator *inner
3912 = build_id_declarator (c_parser_peek_token (parser)->value);
3914 inner->id_loc = c_parser_peek_token (parser)->location;
3915 c_parser_consume_token (parser);
3916 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3917 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3918 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3921 if (kind != C_DTR_NORMAL
3922 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3923 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3925 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3926 inner->id_loc = c_parser_peek_token (parser)->location;
3927 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3930 /* Either we are at the end of an abstract declarator, or we have
3933 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3936 struct c_declarator *inner;
3937 c_parser_consume_token (parser);
3938 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3940 attrs = c_parser_gnu_attributes (parser);
3941 if (kind != C_DTR_NORMAL
3942 && (c_parser_next_token_starts_declspecs (parser)
3944 && c_parser_nth_token_starts_std_attributes (parser, 1))
3945 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3947 struct c_arg_info *args
3948 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3949 attrs, have_gnu_attrs);
3954 inner = build_id_declarator (NULL_TREE);
3956 && args->types != error_mark_node
3957 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
3958 && c_parser_nth_token_starts_std_attributes (parser, 1))
3961 = c_parser_std_attribute_specifier_sequence (parser);
3963 inner = build_attrs_declarator (std_attrs, inner);
3965 inner = build_function_declarator (args, inner);
3966 return c_parser_direct_declarator_inner (parser, *seen_id,
3970 /* A parenthesized declarator. */
3971 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3972 if (inner != NULL && attrs != NULL)
3973 inner = build_attrs_declarator (attrs, inner);
3974 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3976 c_parser_consume_token (parser);
3980 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3984 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3991 if (kind == C_DTR_NORMAL)
3993 c_parser_error (parser, "expected identifier or %<(%>");
3997 return build_id_declarator (NULL_TREE);
4001 /* Parse part of a direct declarator or direct abstract declarator,
4002 given that some (in INNER) has already been parsed; ID_PRESENT is
4003 true if an identifier is present, false for an abstract
4006 static struct c_declarator *
4007 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4008 struct c_declarator *inner)
4010 /* Parse a sequence of array declarators and parameter lists. */
4011 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4012 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4014 location_t brace_loc = c_parser_peek_token (parser)->location;
4015 struct c_declarator *declarator;
4016 struct c_declspecs *quals_attrs = build_null_declspecs ();
4019 struct c_expr dimen;
4020 dimen.value = NULL_TREE;
4021 dimen.original_code = ERROR_MARK;
4022 dimen.original_type = NULL_TREE;
4023 c_parser_consume_token (parser);
4024 c_parser_declspecs (parser, quals_attrs, false, false, true,
4025 false, false, false, false, cla_prefer_id);
4026 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4028 c_parser_consume_token (parser);
4029 if (static_seen && !quals_attrs->declspecs_seen_p)
4030 c_parser_declspecs (parser, quals_attrs, false, false, true,
4031 false, false, false, false, cla_prefer_id);
4032 if (!quals_attrs->declspecs_seen_p)
4034 /* If "static" is present, there must be an array dimension.
4035 Otherwise, there may be a dimension, "*", or no
4040 dimen = c_parser_expr_no_commas (parser, NULL);
4044 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4046 dimen.value = NULL_TREE;
4049 else if (c_parser_next_token_is (parser, CPP_MULT))
4051 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4053 dimen.value = NULL_TREE;
4055 c_parser_consume_token (parser);
4060 dimen = c_parser_expr_no_commas (parser, NULL);
4066 dimen = c_parser_expr_no_commas (parser, NULL);
4069 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4070 c_parser_consume_token (parser);
4073 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4078 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4079 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4080 static_seen, star_seen);
4081 if (declarator == NULL)
4083 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4086 = c_parser_std_attribute_specifier_sequence (parser);
4088 inner = build_attrs_declarator (std_attrs, inner);
4090 inner = set_array_declarator_inner (declarator, inner);
4091 return c_parser_direct_declarator_inner (parser, id_present, inner);
4093 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4096 struct c_arg_info *args;
4097 c_parser_consume_token (parser);
4098 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4100 attrs = c_parser_gnu_attributes (parser);
4101 args = c_parser_parms_declarator (parser, id_present, attrs,
4108 && args->types != error_mark_node
4109 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4110 && c_parser_nth_token_starts_std_attributes (parser, 1))
4113 = c_parser_std_attribute_specifier_sequence (parser);
4115 inner = build_attrs_declarator (std_attrs, inner);
4117 inner = build_function_declarator (args, inner);
4118 return c_parser_direct_declarator_inner (parser, id_present, inner);
4124 /* Parse a parameter list or identifier list, including the closing
4125 parenthesis but not the opening one. ATTRS are the gnu-attributes
4126 at the start of the list. ID_LIST_OK is true if an identifier list
4127 is acceptable; such a list must not have attributes at the start.
4128 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4129 attributes) were present (in which case standard attributes cannot
4132 static struct c_arg_info *
4133 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4134 bool have_gnu_attrs)
4137 declare_parm_level ();
4138 /* If the list starts with an identifier, it is an identifier list.
4139 Otherwise, it is either a prototype list or an empty list. */
4142 && c_parser_next_token_is (parser, CPP_NAME)
4143 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4145 /* Look ahead to detect typos in type names. */
4146 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4147 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4148 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4149 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4150 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4152 tree list = NULL_TREE, *nextp = &list;
4153 while (c_parser_next_token_is (parser, CPP_NAME)
4154 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4156 *nextp = build_tree_list (NULL_TREE,
4157 c_parser_peek_token (parser)->value);
4158 nextp = & TREE_CHAIN (*nextp);
4159 c_parser_consume_token (parser);
4160 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4162 c_parser_consume_token (parser);
4163 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4165 c_parser_error (parser, "expected identifier");
4169 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4171 struct c_arg_info *ret = build_arg_info ();
4173 c_parser_consume_token (parser);
4179 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4187 struct c_arg_info *ret
4188 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4194 /* Parse a parameter list (possibly empty), including the closing
4195 parenthesis but not the opening one. ATTRS are the gnu-attributes
4196 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4197 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4198 which means standard attributes cannot start the list. EXPR is
4199 NULL or an expression that needs to be evaluated for the side
4200 effects of array size expressions in the parameters. */
4202 static struct c_arg_info *
4203 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4204 bool have_gnu_attrs)
4206 bool bad_parm = false;
4208 /* ??? Following the old parser, forward parameter declarations may
4209 use abstract declarators, and if no real parameter declarations
4210 follow the forward declarations then this is not diagnosed. Also
4211 note as above that gnu-attributes are ignored as the only contents of
4212 the parentheses, or as the only contents after forward
4214 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4216 struct c_arg_info *ret = build_arg_info ();
4217 c_parser_consume_token (parser);
4220 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4222 struct c_arg_info *ret = build_arg_info ();
4224 if (flag_allow_parameterless_variadic_functions)
4226 /* F (...) is allowed. */
4227 ret->types = NULL_TREE;
4231 /* Suppress -Wold-style-definition for this case. */
4232 ret->types = error_mark_node;
4233 error_at (c_parser_peek_token (parser)->location,
4234 "ISO C requires a named argument before %<...%>");
4236 c_parser_consume_token (parser);
4237 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4239 c_parser_consume_token (parser);
4244 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4249 /* Nonempty list of parameters, either terminated with semicolon
4250 (forward declarations; recurse) or with close parenthesis (normal
4251 function) or with ", ... )" (variadic function). */
4254 /* Parse a parameter. */
4255 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4258 have_gnu_attrs = false;
4262 push_parm_decl (parm, &expr);
4263 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4266 c_parser_consume_token (parser);
4267 mark_forward_parm_decls ();
4268 bool new_have_gnu_attrs
4269 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4270 new_attrs = c_parser_gnu_attributes (parser);
4271 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4272 new_have_gnu_attrs);
4274 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4276 c_parser_consume_token (parser);
4280 return get_parm_info (false, expr);
4282 if (!c_parser_require (parser, CPP_COMMA,
4283 "expected %<;%>, %<,%> or %<)%>",
4284 UNKNOWN_LOCATION, false))
4286 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4289 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4291 c_parser_consume_token (parser);
4292 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4294 c_parser_consume_token (parser);
4298 return get_parm_info (true, expr);
4302 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4310 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4311 start of the declaration if it is the first parameter;
4312 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4315 static struct c_parm *
4316 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4317 bool have_gnu_attrs)
4319 struct c_declspecs *specs;
4320 struct c_declarator *declarator;
4322 tree postfix_attrs = NULL_TREE;
4325 /* Accept #pragmas between parameter declarations. */
4326 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4327 c_parser_pragma (parser, pragma_param, NULL);
4329 if (!c_parser_next_token_starts_declspecs (parser)
4330 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4332 c_token *token = c_parser_peek_token (parser);
4335 c_parser_set_source_position_from_token (token);
4336 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4338 auto_diagnostic_group d;
4339 name_hint hint = lookup_name_fuzzy (token->value,
4340 FUZZY_LOOKUP_TYPENAME,
4342 if (const char *suggestion = hint.suggestion ())
4344 gcc_rich_location richloc (token->location);
4345 richloc.add_fixit_replace (suggestion);
4347 "unknown type name %qE; did you mean %qs?",
4348 token->value, suggestion);
4351 error_at (token->location, "unknown type name %qE", token->value);
4352 parser->error = true;
4354 /* ??? In some Objective-C cases '...' isn't applicable so there
4355 should be a different message. */
4357 c_parser_error (parser,
4358 "expected declaration specifiers or %<...%>");
4359 c_parser_skip_to_end_of_parameter (parser);
4363 location_t start_loc = c_parser_peek_token (parser)->location;
4365 specs = build_null_declspecs ();
4368 declspecs_add_attrs (input_location, specs, attrs);
4371 c_parser_declspecs (parser, specs, true, true, true, true, false,
4372 !have_gnu_attrs, true, cla_nonabstract_decl);
4373 finish_declspecs (specs);
4374 pending_xref_error ();
4375 prefix_attrs = specs->attrs;
4376 specs->attrs = NULL_TREE;
4377 declarator = c_parser_declarator (parser,
4378 specs->typespec_kind != ctsk_none,
4379 C_DTR_PARM, &dummy);
4380 if (declarator == NULL)
4382 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4385 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4386 postfix_attrs = c_parser_gnu_attributes (parser);
4388 /* Generate a location for the parameter, ranging from the start of the
4389 initial token to the end of the final token.
4391 If we have a identifier, then use it for the caret location, e.g.
4393 extern int callee (int one, int (*two)(int, int), float three);
4394 ~~~~~~^~~~~~~~~~~~~~
4396 otherwise, reuse the start location for the caret location e.g.:
4398 extern int callee (int one, int (*)(int, int), float three);
4401 location_t end_loc = parser->last_token_location;
4403 /* Find any cdk_id declarator; determine if we have an identifier. */
4404 c_declarator *id_declarator = declarator;
4405 while (id_declarator && id_declarator->kind != cdk_id)
4406 id_declarator = id_declarator->declarator;
4407 location_t caret_loc = (id_declarator->u.id.id
4408 ? id_declarator->id_loc
4410 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4412 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4413 declarator, param_loc);
4416 /* Parse a string literal in an asm expression. It should not be
4417 translated, and wide string literals are an error although
4418 permitted by the syntax. This is a GNU extension.
4425 c_parser_asm_string_literal (c_parser *parser)
4428 int save_flag = warn_overlength_strings;
4429 warn_overlength_strings = 0;
4430 str = c_parser_string_literal (parser, false, false).value;
4431 warn_overlength_strings = save_flag;
4435 /* Parse a simple asm expression. This is used in restricted
4436 contexts, where a full expression with inputs and outputs does not
4437 make sense. This is a GNU extension.
4440 asm ( asm-string-literal )
4444 c_parser_simple_asm_expr (c_parser *parser)
4447 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4448 c_parser_consume_token (parser);
4449 matching_parens parens;
4450 if (!parens.require_open (parser))
4452 str = c_parser_asm_string_literal (parser);
4453 if (!parens.require_close (parser))
4455 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4462 c_parser_gnu_attribute_any_word (c_parser *parser)
4464 tree attr_name = NULL_TREE;
4466 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4468 /* ??? See comment above about what keywords are accepted here. */
4470 switch (c_parser_peek_token (parser)->keyword)
4501 case RID_TRANSACTION_ATOMIC:
4502 case RID_TRANSACTION_CANCEL:
4518 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4519 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4521 else if (c_parser_next_token_is (parser, CPP_NAME))
4522 attr_name = c_parser_peek_token (parser)->value;
4527 /* Parse attribute arguments. This is a common form of syntax
4528 covering all currently valid GNU and standard attributes.
4530 gnu-attribute-arguments:
4532 identifier , nonempty-expr-list
4535 where the "identifier" must not be declared as a type. ??? Why not
4536 allow identifiers declared as types to start the arguments? */
4539 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4540 bool require_string, bool allow_empty_args)
4542 vec<tree, va_gc> *expr_list;
4544 /* Parse the attribute contents. If they start with an
4545 identifier which is followed by a comma or close
4546 parenthesis, then the arguments start with that
4547 identifier; otherwise they are an expression list.
4548 In objective-c the identifier may be a classname. */
4549 if (c_parser_next_token_is (parser, CPP_NAME)
4550 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4551 || (c_dialect_objc ()
4552 && c_parser_peek_token (parser)->id_kind
4554 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4555 || (c_parser_peek_2nd_token (parser)->type
4556 == CPP_CLOSE_PAREN))
4557 && (takes_identifier
4558 || (c_dialect_objc ()
4559 && c_parser_peek_token (parser)->id_kind
4560 == C_ID_CLASSNAME)))
4562 tree arg1 = c_parser_peek_token (parser)->value;
4563 c_parser_consume_token (parser);
4564 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4565 attr_args = build_tree_list (NULL_TREE, arg1);
4569 c_parser_consume_token (parser);
4570 expr_list = c_parser_expr_list (parser, false, true,
4571 NULL, NULL, NULL, NULL);
4572 tree_list = build_tree_list_vec (expr_list);
4573 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4574 release_tree_vector (expr_list);
4579 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4581 if (!allow_empty_args)
4582 error_at (c_parser_peek_token (parser)->location,
4583 "parentheses must be omitted if "
4584 "attribute argument list is empty");
4585 attr_args = NULL_TREE;
4587 else if (require_string)
4589 /* The only valid argument for this attribute is a string
4590 literal. Handle this specially here to avoid accepting
4591 string literals with excess parentheses. */
4592 tree string = c_parser_string_literal (parser, false, true).value;
4593 attr_args = build_tree_list (NULL_TREE, string);
4597 expr_list = c_parser_expr_list (parser, false, true,
4598 NULL, NULL, NULL, NULL);
4599 attr_args = build_tree_list_vec (expr_list);
4600 release_tree_vector (expr_list);
4606 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4610 gnu-attributes gnu-attribute
4613 __attribute__ ( ( gnu-attribute-list ) )
4617 gnu-attribute_list , gnu-attrib
4622 any-word ( gnu-attribute-arguments )
4624 where "any-word" may be any identifier (including one declared as a
4625 type), a reserved word storage class specifier, type specifier or
4626 type qualifier. ??? This still leaves out most reserved keywords
4627 (following the old parser), shouldn't we include them?
4628 When EXPECT_COMMA is true, expect the attribute to be preceded
4629 by a comma and fail if it isn't.
4630 When EMPTY_OK is true, allow and consume any number of consecutive
4631 commas with no attributes in between. */
4634 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4635 bool expect_comma = false, bool empty_ok = true)
4637 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4639 && !c_parser_next_token_is (parser, CPP_NAME)
4640 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4643 while (c_parser_next_token_is (parser, CPP_COMMA))
4645 c_parser_consume_token (parser);
4650 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4651 if (attr_name == NULL_TREE)
4654 attr_name = canonicalize_attr_name (attr_name);
4655 c_parser_consume_token (parser);
4658 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4660 if (expect_comma && !comma_first)
4662 /* A comma is missing between the last attribute on the chain
4664 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4666 return error_mark_node;
4668 attr = build_tree_list (attr_name, NULL_TREE);
4669 /* Add this attribute to the list. */
4670 attrs = chainon (attrs, attr);
4673 c_parser_consume_token (parser);
4676 = c_parser_attribute_arguments (parser,
4677 attribute_takes_identifier_p (attr_name),
4680 attr = build_tree_list (attr_name, attr_args);
4681 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4682 c_parser_consume_token (parser);
4685 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4687 return error_mark_node;
4690 if (expect_comma && !comma_first)
4692 /* A comma is missing between the last attribute on the chain
4694 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4696 return error_mark_node;
4699 /* Add this attribute to the list. */
4700 attrs = chainon (attrs, attr);
4705 c_parser_gnu_attributes (c_parser *parser)
4707 tree attrs = NULL_TREE;
4708 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4710 bool save_translate_strings_p = parser->translate_strings_p;
4711 parser->translate_strings_p = false;
4712 /* Consume the `__attribute__' keyword. */
4713 c_parser_consume_token (parser);
4714 /* Look for the two `(' tokens. */
4715 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4717 parser->translate_strings_p = save_translate_strings_p;
4720 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4722 parser->translate_strings_p = save_translate_strings_p;
4723 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4726 /* Parse the attribute list. Require a comma between successive
4727 (possibly empty) attributes. */
4728 for (bool expect_comma = false; ; expect_comma = true)
4730 /* Parse a single attribute. */
4731 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4732 if (attr == error_mark_node)
4739 /* Look for the two `)' tokens. */
4740 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4741 c_parser_consume_token (parser);
4744 parser->translate_strings_p = save_translate_strings_p;
4745 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4749 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4750 c_parser_consume_token (parser);
4753 parser->translate_strings_p = save_translate_strings_p;
4754 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4758 parser->translate_strings_p = save_translate_strings_p;
4764 /* Parse an optional balanced token sequence.
4766 balanced-token-sequence:
4768 balanced-token-sequence balanced-token
4771 ( balanced-token-sequence[opt] )
4772 [ balanced-token-sequence[opt] ]
4773 { balanced-token-sequence[opt] }
4774 any token other than ()[]{}
4778 c_parser_balanced_token_sequence (c_parser *parser)
4782 c_token *token = c_parser_peek_token (parser);
4783 switch (token->type)
4785 case CPP_OPEN_BRACE:
4787 matching_braces braces;
4788 braces.consume_open (parser);
4789 c_parser_balanced_token_sequence (parser);
4790 braces.require_close (parser);
4794 case CPP_OPEN_PAREN:
4796 matching_parens parens;
4797 parens.consume_open (parser);
4798 c_parser_balanced_token_sequence (parser);
4799 parens.require_close (parser);
4803 case CPP_OPEN_SQUARE:
4804 c_parser_consume_token (parser);
4805 c_parser_balanced_token_sequence (parser);
4806 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4809 case CPP_CLOSE_BRACE:
4810 case CPP_CLOSE_PAREN:
4811 case CPP_CLOSE_SQUARE:
4816 c_parser_consume_token (parser);
4822 /* Parse standard (C2X) attributes (including GNU attributes in the
4825 attribute-specifier-sequence:
4826 attribute-specifier-sequence[opt] attribute-specifier
4828 attribute-specifier:
4829 [ [ attribute-list ] ]
4833 attribute-list, attribute[opt]
4836 attribute-token attribute-argument-clause[opt]
4840 attribute-prefixed-token
4845 attribute-prefixed-token:
4846 attribute-prefix :: identifier
4851 attribute-argument-clause:
4852 ( balanced-token-sequence[opt] )
4854 Keywords are accepted as identifiers for this purpose.
4858 c_parser_std_attribute (c_parser *parser, bool for_tm)
4860 c_token *token = c_parser_peek_token (parser);
4861 tree ns, name, attribute;
4863 /* Parse the attribute-token. */
4864 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4866 c_parser_error (parser, "expected identifier");
4867 return error_mark_node;
4869 name = canonicalize_attr_name (token->value);
4870 c_parser_consume_token (parser);
4871 if (c_parser_next_token_is (parser, CPP_SCOPE))
4874 c_parser_consume_token (parser);
4875 token = c_parser_peek_token (parser);
4876 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4878 c_parser_error (parser, "expected identifier");
4879 return error_mark_node;
4881 name = canonicalize_attr_name (token->value);
4882 c_parser_consume_token (parser);
4886 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4888 /* Parse the arguments, if any. */
4889 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4890 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4893 location_t open_loc = c_parser_peek_token (parser)->location;
4894 matching_parens parens;
4895 parens.consume_open (parser);
4896 if ((as && as->max_length == 0)
4897 /* Special-case the transactional-memory attribute "outer",
4898 which is specially handled but not registered as an
4899 attribute, to avoid allowing arbitrary balanced token
4900 sequences as arguments. */
4901 || is_attribute_p ("outer", name))
4903 error_at (open_loc, "%qE attribute does not take any arguments", name);
4904 parens.skip_until_found_close (parser);
4905 return error_mark_node;
4909 bool takes_identifier
4911 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4912 && attribute_takes_identifier_p (name));
4915 && strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0);
4916 TREE_VALUE (attribute)
4917 = c_parser_attribute_arguments (parser, takes_identifier,
4918 require_string, false);
4921 c_parser_balanced_token_sequence (parser);
4922 parens.require_close (parser);
4925 if (ns == NULL_TREE && !for_tm && !as && !is_attribute_p ("nodiscard", name))
4927 /* An attribute with standard syntax and no namespace specified
4928 is a constraint violation if it is not one of the known
4929 standard attributes (of which nodiscard is the only one
4930 without a handler in GCC). Diagnose it here with a pedwarn
4931 and then discard it to prevent a duplicate warning later. */
4932 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4934 return error_mark_node;
4940 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4942 bool seen_deprecated = false;
4943 bool seen_fallthrough = false;
4944 bool seen_maybe_unused = false;
4945 location_t loc = c_parser_peek_token (parser)->location;
4946 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4948 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4950 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4954 pedwarn_c11 (loc, OPT_Wpedantic,
4955 "ISO C does not support %<[[]]%> attributes before C2X");
4956 tree attributes = NULL_TREE;
4959 c_token *token = c_parser_peek_token (parser);
4960 if (token->type == CPP_CLOSE_SQUARE)
4962 if (token->type == CPP_COMMA)
4964 c_parser_consume_token (parser);
4967 tree attribute = c_parser_std_attribute (parser, for_tm);
4968 if (attribute != error_mark_node)
4970 bool duplicate = false;
4971 tree name = get_attribute_name (attribute);
4972 tree ns = get_attribute_namespace (attribute);
4973 if (ns == NULL_TREE)
4975 /* Some standard attributes may appear at most once in
4976 each attribute list. Diagnose duplicates and remove
4977 them from the list to avoid subsequent diagnostics
4978 such as the more general one for multiple
4979 "fallthrough" attributes in the same place (including
4980 in separate attribute lists in the same attribute
4981 specifier sequence, which is not a constraint
4983 if (is_attribute_p ("deprecated", name))
4985 if (seen_deprecated)
4987 error ("attribute %<deprecated%> can appear at most "
4988 "once in an attribute-list");
4991 seen_deprecated = true;
4993 else if (is_attribute_p ("fallthrough", name))
4995 if (seen_fallthrough)
4997 error ("attribute %<fallthrough%> can appear at most "
4998 "once in an attribute-list");
5001 seen_fallthrough = true;
5003 else if (is_attribute_p ("maybe_unused", name))
5005 if (seen_maybe_unused)
5007 error ("attribute %<maybe_unused%> can appear at most "
5008 "once in an attribute-list");
5011 seen_maybe_unused = true;
5016 TREE_CHAIN (attribute) = attributes;
5017 attributes = attribute;
5020 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5023 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5024 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5025 return nreverse (attributes);
5028 /* Look past an optional balanced token sequence of raw look-ahead
5029 tokens starting with the *Nth token. *N is updated to point to the
5030 following token. Return true if such a sequence was found, false
5031 if the tokens parsed were not balanced. */
5034 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5038 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5039 switch (token->type)
5041 case CPP_OPEN_BRACE:
5044 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5046 token = c_parser_peek_nth_token_raw (parser, *n);
5047 if (token->type == CPP_CLOSE_BRACE)
5057 case CPP_OPEN_PAREN:
5060 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5062 token = c_parser_peek_nth_token_raw (parser, *n);
5063 if (token->type == CPP_CLOSE_PAREN)
5073 case CPP_OPEN_SQUARE:
5076 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5078 token = c_parser_peek_nth_token_raw (parser, *n);
5079 if (token->type == CPP_CLOSE_SQUARE)
5089 case CPP_CLOSE_BRACE:
5090 case CPP_CLOSE_PAREN:
5091 case CPP_CLOSE_SQUARE:
5102 /* Return whether standard attributes start with the Nth token. */
5105 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5107 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5108 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5110 /* In C, '[[' must start attributes. In Objective-C, we need to
5111 check whether '[[' is matched by ']]'. */
5112 if (!c_dialect_objc ())
5115 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5117 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5118 if (token->type != CPP_CLOSE_SQUARE)
5120 token = c_parser_peek_nth_token_raw (parser, n + 1);
5121 return token->type == CPP_CLOSE_SQUARE;
5125 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5127 tree attributes = NULL_TREE;
5130 tree attrs = c_parser_std_attribute_specifier (parser, false);
5131 attributes = chainon (attributes, attrs);
5133 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5137 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5138 says whether alignment specifiers are OK (only in cases that might
5139 be the type name of a compound literal).
5142 specifier-qualifier-list abstract-declarator[opt]
5145 struct c_type_name *
5146 c_parser_type_name (c_parser *parser, bool alignas_ok)
5148 struct c_declspecs *specs = build_null_declspecs ();
5149 struct c_declarator *declarator;
5150 struct c_type_name *ret;
5152 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5153 false, true, cla_prefer_type);
5154 if (!specs->declspecs_seen_p)
5156 c_parser_error (parser, "expected specifier-qualifier-list");
5159 if (specs->type != error_mark_node)
5161 pending_xref_error ();
5162 finish_declspecs (specs);
5164 declarator = c_parser_declarator (parser,
5165 specs->typespec_kind != ctsk_none,
5166 C_DTR_ABSTRACT, &dummy);
5167 if (declarator == NULL)
5169 ret = XOBNEW (&parser_obstack, struct c_type_name);
5171 ret->declarator = declarator;
5175 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5178 assignment-expression
5179 { initializer-list }
5180 { initializer-list , }
5183 designation[opt] initializer
5184 initializer-list , designation[opt] initializer
5191 designator-list designator
5198 [ constant-expression ]
5210 [ constant-expression ... constant-expression ]
5212 Any expression without commas is accepted in the syntax for the
5213 constant-expressions, with non-constant expressions rejected later.
5215 This function is only used for top-level initializers; for nested
5216 ones, see c_parser_initval. */
5218 static struct c_expr
5219 c_parser_initializer (c_parser *parser)
5221 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5222 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5226 location_t loc = c_parser_peek_token (parser)->location;
5227 ret = c_parser_expr_no_commas (parser, NULL);
5228 if (TREE_CODE (ret.value) != STRING_CST
5229 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5230 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5235 /* The location of the last comma within the current initializer list,
5236 or UNKNOWN_LOCATION if not within one. */
5238 location_t last_init_list_comma;
5240 /* Parse a braced initializer list. TYPE is the type specified for a
5241 compound literal, and NULL_TREE for other initializers and for
5242 nested braced lists. NESTED_P is true for nested braced lists,
5243 false for the list of a compound literal or the list that is the
5244 top-level initializer in a declaration. */
5246 static struct c_expr
5247 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5248 struct obstack *outer_obstack)
5251 struct obstack braced_init_obstack;
5252 location_t brace_loc = c_parser_peek_token (parser)->location;
5253 gcc_obstack_init (&braced_init_obstack);
5254 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5255 matching_braces braces;
5256 braces.consume_open (parser);
5259 finish_implicit_inits (brace_loc, outer_obstack);
5260 push_init_level (brace_loc, 0, &braced_init_obstack);
5263 really_start_incremental_init (type);
5264 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5266 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5270 /* Parse a non-empty initializer list, possibly with a trailing
5274 c_parser_initelt (parser, &braced_init_obstack);
5277 if (c_parser_next_token_is (parser, CPP_COMMA))
5279 last_init_list_comma = c_parser_peek_token (parser)->location;
5280 c_parser_consume_token (parser);
5284 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5288 c_token *next_tok = c_parser_peek_token (parser);
5289 if (next_tok->type != CPP_CLOSE_BRACE)
5292 ret.original_code = ERROR_MARK;
5293 ret.original_type = NULL;
5294 braces.skip_until_found_close (parser);
5295 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5296 obstack_free (&braced_init_obstack, NULL);
5299 location_t close_loc = next_tok->location;
5300 c_parser_consume_token (parser);
5301 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5302 obstack_free (&braced_init_obstack, NULL);
5303 set_c_expr_source_range (&ret, brace_loc, close_loc);
5307 /* Parse a nested initializer, including designators. */
5310 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5312 /* Parse any designator or designator list. A single array
5313 designator may have the subsequent "=" omitted in GNU C, but a
5314 longer list or a structure member designator may not. */
5315 if (c_parser_next_token_is (parser, CPP_NAME)
5316 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5318 /* Old-style structure member designator. */
5319 set_init_label (c_parser_peek_token (parser)->location,
5320 c_parser_peek_token (parser)->value,
5321 c_parser_peek_token (parser)->location,
5322 braced_init_obstack);
5323 /* Use the colon as the error location. */
5324 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5325 "obsolete use of designated initializer with %<:%>");
5326 c_parser_consume_token (parser);
5327 c_parser_consume_token (parser);
5331 /* des_seen is 0 if there have been no designators, 1 if there
5332 has been a single array designator and 2 otherwise. */
5334 /* Location of a designator. */
5335 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5336 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5337 || c_parser_next_token_is (parser, CPP_DOT))
5339 int des_prev = des_seen;
5341 des_loc = c_parser_peek_token (parser)->location;
5344 if (c_parser_next_token_is (parser, CPP_DOT))
5347 c_parser_consume_token (parser);
5348 if (c_parser_next_token_is (parser, CPP_NAME))
5350 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5351 c_parser_peek_token (parser)->location,
5352 braced_init_obstack);
5353 c_parser_consume_token (parser);
5359 init.original_code = ERROR_MARK;
5360 init.original_type = NULL;
5361 c_parser_error (parser, "expected identifier");
5362 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5363 process_init_element (input_location, init, false,
5364 braced_init_obstack);
5371 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5372 location_t array_index_loc = UNKNOWN_LOCATION;
5373 /* ??? Following the old parser, [ objc-receiver
5374 objc-message-args ] is accepted as an initializer,
5375 being distinguished from a designator by what follows
5376 the first assignment expression inside the square
5377 brackets, but after a first array designator a
5378 subsequent square bracket is for Objective-C taken to
5379 start an expression, using the obsolete form of
5380 designated initializer without '=', rather than
5381 possibly being a second level of designation: in LALR
5382 terms, the '[' is shifted rather than reducing
5383 designator to designator-list. */
5384 if (des_prev == 1 && c_dialect_objc ())
5386 des_seen = des_prev;
5389 if (des_prev == 0 && c_dialect_objc ())
5391 /* This might be an array designator or an
5392 Objective-C message expression. If the former,
5393 continue parsing here; if the latter, parse the
5394 remainder of the initializer given the starting
5395 primary-expression. ??? It might make sense to
5396 distinguish when des_prev == 1 as well; see
5397 previous comment. */
5399 struct c_expr mexpr;
5400 c_parser_consume_token (parser);
5401 if (c_parser_peek_token (parser)->type == CPP_NAME
5402 && ((c_parser_peek_token (parser)->id_kind
5404 || (c_parser_peek_token (parser)->id_kind
5405 == C_ID_CLASSNAME)))
5407 /* Type name receiver. */
5408 tree id = c_parser_peek_token (parser)->value;
5409 c_parser_consume_token (parser);
5410 rec = objc_get_class_reference (id);
5411 goto parse_message_args;
5413 first = c_parser_expr_no_commas (parser, NULL).value;
5414 mark_exp_read (first);
5415 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5416 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5417 goto array_desig_after_first;
5418 /* Expression receiver. So far only one part
5419 without commas has been parsed; there might be
5420 more of the expression. */
5422 while (c_parser_next_token_is (parser, CPP_COMMA))
5425 location_t comma_loc, exp_loc;
5426 comma_loc = c_parser_peek_token (parser)->location;
5427 c_parser_consume_token (parser);
5428 exp_loc = c_parser_peek_token (parser)->location;
5429 next = c_parser_expr_no_commas (parser, NULL);
5430 next = convert_lvalue_to_rvalue (exp_loc, next,
5432 rec = build_compound_expr (comma_loc, rec, next.value);
5435 /* Now parse the objc-message-args. */
5436 args = c_parser_objc_message_args (parser);
5437 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5440 = objc_build_message_expr (rec, args);
5441 mexpr.original_code = ERROR_MARK;
5442 mexpr.original_type = NULL;
5443 /* Now parse and process the remainder of the
5444 initializer, starting with this message
5445 expression as a primary-expression. */
5446 c_parser_initval (parser, &mexpr, braced_init_obstack);
5449 c_parser_consume_token (parser);
5450 array_index_loc = c_parser_peek_token (parser)->location;
5451 first = c_parser_expr_no_commas (parser, NULL).value;
5452 mark_exp_read (first);
5453 array_desig_after_first:
5454 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5456 ellipsis_loc = c_parser_peek_token (parser)->location;
5457 c_parser_consume_token (parser);
5458 second = c_parser_expr_no_commas (parser, NULL).value;
5459 mark_exp_read (second);
5463 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5465 c_parser_consume_token (parser);
5466 set_init_index (array_index_loc, first, second,
5467 braced_init_obstack);
5469 pedwarn (ellipsis_loc, OPT_Wpedantic,
5470 "ISO C forbids specifying range of elements to initialize");
5473 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5479 if (c_parser_next_token_is (parser, CPP_EQ))
5481 pedwarn_c90 (des_loc, OPT_Wpedantic,
5482 "ISO C90 forbids specifying subobject "
5484 c_parser_consume_token (parser);
5489 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5490 "obsolete use of designated initializer without %<=%>");
5495 init.original_code = ERROR_MARK;
5496 init.original_type = NULL;
5497 c_parser_error (parser, "expected %<=%>");
5498 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5499 process_init_element (input_location, init, false,
5500 braced_init_obstack);
5506 c_parser_initval (parser, NULL, braced_init_obstack);
5509 /* Parse a nested initializer; as c_parser_initializer but parses
5510 initializers within braced lists, after any designators have been
5511 applied. If AFTER is not NULL then it is an Objective-C message
5512 expression which is the primary-expression starting the
5516 c_parser_initval (c_parser *parser, struct c_expr *after,
5517 struct obstack * braced_init_obstack)
5520 gcc_assert (!after || c_dialect_objc ());
5521 location_t loc = c_parser_peek_token (parser)->location;
5523 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5524 init = c_parser_braced_init (parser, NULL_TREE, true,
5525 braced_init_obstack);
5528 init = c_parser_expr_no_commas (parser, after);
5529 if (init.value != NULL_TREE
5530 && TREE_CODE (init.value) != STRING_CST
5531 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5532 init = convert_lvalue_to_rvalue (loc, init, true, true);
5534 process_init_element (loc, init, false, braced_init_obstack);
5537 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5538 C99 6.8.2, C11 6.8.2).
5541 { block-item-list[opt] }
5542 { label-declarations block-item-list }
5546 block-item-list block-item
5558 { label-declarations block-item-list }
5561 __extension__ nested-declaration
5562 nested-function-definition
5566 label-declarations label-declaration
5569 __label__ identifier-list ;
5571 Allowing the mixing of declarations and code is new in C99. The
5572 GNU syntax also permits (not shown above) labels at the end of
5573 compound statements, which yield an error. We don't allow labels
5574 on declarations; this might seem like a natural extension, but
5575 there would be a conflict between gnu-attributes on the label and
5576 prefix gnu-attributes on the declaration. ??? The syntax follows the
5577 old parser in requiring something after label declarations.
5578 Although they are erroneous if the labels declared aren't defined,
5579 is it useful for the syntax to be this way?
5600 cancellation-point-directive */
5603 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5606 location_t brace_loc;
5607 brace_loc = c_parser_peek_token (parser)->location;
5608 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5610 /* Ensure a scope is entered and left anyway to avoid confusion
5611 if we have just prepared to enter a function body. */
5612 stmt = c_begin_compound_stmt (true);
5613 c_end_compound_stmt (brace_loc, stmt, true);
5614 return error_mark_node;
5616 stmt = c_begin_compound_stmt (true);
5617 location_t end_loc = c_parser_compound_statement_nostart (parser);
5621 return c_end_compound_stmt (brace_loc, stmt, true);
5624 /* Parse a compound statement except for the opening brace. This is
5625 used for parsing both compound statements and statement expressions
5626 (which follow different paths to handling the opening). */
5629 c_parser_compound_statement_nostart (c_parser *parser)
5631 bool last_stmt = false;
5632 bool last_label = false;
5633 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5634 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5635 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5637 location_t endloc = c_parser_peek_token (parser)->location;
5638 add_debug_begin_stmt (endloc);
5639 c_parser_consume_token (parser);
5642 mark_valid_location_for_stdc_pragma (true);
5643 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5645 /* Read zero or more forward-declarations for labels that nested
5646 functions can jump to. */
5647 mark_valid_location_for_stdc_pragma (false);
5648 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5650 label_loc = c_parser_peek_token (parser)->location;
5651 c_parser_consume_token (parser);
5652 /* Any identifiers, including those declared as type names,
5657 if (c_parser_next_token_is_not (parser, CPP_NAME))
5659 c_parser_error (parser, "expected identifier");
5663 = declare_label (c_parser_peek_token (parser)->value);
5664 C_DECLARED_LABEL_FLAG (label) = 1;
5665 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5666 c_parser_consume_token (parser);
5667 if (c_parser_next_token_is (parser, CPP_COMMA))
5668 c_parser_consume_token (parser);
5672 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5674 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5676 /* We must now have at least one statement, label or declaration. */
5677 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5679 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5680 c_parser_error (parser, "expected declaration or statement");
5681 location_t endloc = c_parser_peek_token (parser)->location;
5682 c_parser_consume_token (parser);
5685 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5687 location_t loc = c_parser_peek_token (parser)->location;
5688 loc = expansion_point_location_if_in_system_header (loc);
5689 /* Standard attributes may start a statement or a declaration. */
5691 = c_parser_nth_token_starts_std_attributes (parser, 1);
5692 tree std_attrs = NULL_TREE;
5694 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5695 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5696 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5697 || (c_parser_next_token_is (parser, CPP_NAME)
5698 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5700 c_warn_unused_attributes (std_attrs);
5701 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5702 label_loc = c_parser_peek_2nd_token (parser)->location;
5704 label_loc = c_parser_peek_token (parser)->location;
5707 mark_valid_location_for_stdc_pragma (false);
5708 c_parser_label (parser);
5710 else if (!last_label
5711 && (c_parser_next_tokens_start_declaration (parser)
5713 && c_parser_next_token_is (parser, CPP_SEMICOLON))))
5716 mark_valid_location_for_stdc_pragma (false);
5717 bool fallthru_attr_p = false;
5718 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5719 true, true, true, NULL,
5720 vNULL, have_std_attrs, std_attrs,
5721 NULL, &fallthru_attr_p);
5722 if (last_stmt && !fallthru_attr_p)
5723 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5724 "ISO C90 forbids mixed declarations and code");
5725 last_stmt = fallthru_attr_p;
5727 else if (!last_label
5728 && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5730 /* __extension__ can start a declaration, but is also an
5731 unary operator that can start an expression. Consume all
5732 but the last of a possible series of __extension__ to
5733 determine which. If standard attributes have already
5734 been seen, it must start a statement, not a declaration,
5735 but standard attributes starting a declaration may appear
5736 after __extension__. */
5737 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5738 && (c_parser_peek_2nd_token (parser)->keyword
5740 c_parser_consume_token (parser);
5742 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5743 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5746 ext = disable_extension_diagnostics ();
5747 c_parser_consume_token (parser);
5749 mark_valid_location_for_stdc_pragma (false);
5750 c_parser_declaration_or_fndef (parser, true, true, true, true,
5752 /* Following the old parser, __extension__ does not
5753 disable this diagnostic. */
5754 restore_extension_diagnostics (ext);
5756 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5757 "ISO C90 forbids mixed declarations and code");
5763 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5766 c_parser_error (parser, "expected declaration or statement");
5767 /* External pragmas, and some omp pragmas, are not associated
5768 with regular c code, and so are not to be considered statements
5769 syntactically. This ensures that the user doesn't put them
5770 places that would turn into syntax errors if the directive
5772 if (c_parser_pragma (parser,
5773 last_label ? pragma_stmt : pragma_compound,
5775 last_label = false, last_stmt = true;
5777 else if (c_parser_next_token_is (parser, CPP_EOF))
5779 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5780 c_parser_error (parser, "expected declaration or statement");
5781 return c_parser_peek_token (parser)->location;
5783 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5785 if (parser->in_if_block)
5787 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5788 error_at (loc, "expected %<}%> before %<else%>");
5789 return c_parser_peek_token (parser)->location;
5793 error_at (loc, "%<else%> without a previous %<if%>");
5794 c_parser_consume_token (parser);
5801 c_warn_unused_attributes (std_attrs);
5804 mark_valid_location_for_stdc_pragma (false);
5805 c_parser_statement_after_labels (parser, NULL);
5808 parser->error = false;
5811 error_at (label_loc, "label at end of compound statement");
5812 location_t endloc = c_parser_peek_token (parser)->location;
5813 c_parser_consume_token (parser);
5814 /* Restore the value we started with. */
5815 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5819 /* Parse all consecutive labels, possibly preceded by standard
5820 attributes. In this context, a statement is required, not a
5821 declaration, so attributes must be followed by a statement that is
5822 not just a semicolon. */
5825 c_parser_all_labels (c_parser *parser)
5827 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5829 tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5830 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5831 c_parser_error (parser, "expected statement");
5833 c_warn_unused_attributes (std_attrs);
5835 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5836 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5837 || (c_parser_next_token_is (parser, CPP_NAME)
5838 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5839 c_parser_label (parser);
5842 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5845 identifier : gnu-attributes[opt]
5846 case constant-expression :
5852 case constant-expression ... constant-expression :
5854 The use of gnu-attributes on labels is a GNU extension. The syntax in
5855 GNU C accepts any expressions without commas, non-constant
5856 expressions being rejected later. Any standard
5857 attribute-specifier-sequence before the first label has been parsed
5858 in the caller, to distinguish statements from declarations. Any
5859 attribute-specifier-sequence after the label is parsed in this
5863 c_parser_label (c_parser *parser)
5865 location_t loc1 = c_parser_peek_token (parser)->location;
5866 tree label = NULL_TREE;
5868 /* Remember whether this case or a user-defined label is allowed to fall
5870 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5872 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5875 c_parser_consume_token (parser);
5876 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5877 if (c_parser_next_token_is (parser, CPP_COLON))
5879 c_parser_consume_token (parser);
5880 label = do_case (loc1, exp1, NULL_TREE);
5882 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5884 c_parser_consume_token (parser);
5885 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5886 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5887 label = do_case (loc1, exp1, exp2);
5890 c_parser_error (parser, "expected %<:%> or %<...%>");
5892 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5894 c_parser_consume_token (parser);
5895 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5896 label = do_case (loc1, NULL_TREE, NULL_TREE);
5900 tree name = c_parser_peek_token (parser)->value;
5903 location_t loc2 = c_parser_peek_token (parser)->location;
5904 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5905 c_parser_consume_token (parser);
5906 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5907 c_parser_consume_token (parser);
5908 attrs = c_parser_gnu_attributes (parser);
5909 tlab = define_label (loc2, name);
5912 decl_attributes (&tlab, attrs, 0);
5913 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5918 if (TREE_CODE (label) == LABEL_EXPR)
5919 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5921 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5923 /* Standard attributes are only allowed here if they start a
5924 statement, not a declaration (including the case of an
5925 attribute-declaration with only attributes). */
5927 = c_parser_nth_token_starts_std_attributes (parser, 1);
5928 tree std_attrs = NULL_TREE;
5930 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5932 /* Allow '__attribute__((fallthrough));'. */
5934 && c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5936 location_t loc = c_parser_peek_token (parser)->location;
5937 tree attrs = c_parser_gnu_attributes (parser);
5938 if (attribute_fallthrough_p (attrs))
5940 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5942 tree fn = build_call_expr_internal_loc (loc,
5948 warning_at (loc, OPT_Wattributes, "%<fallthrough%> attribute "
5949 "not followed by %<;%>");
5951 else if (attrs != NULL_TREE)
5952 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
5953 " can be applied to a null statement");
5955 if (c_parser_next_tokens_start_declaration (parser)
5957 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5959 error_at (c_parser_peek_token (parser)->location,
5960 "a label can only be part of a statement and "
5961 "a declaration is not a statement");
5962 c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
5963 /*static_assert_ok*/ true,
5964 /*empty_ok*/ true, /*nested*/ true,
5965 /*start_attr_ok*/ true, NULL,
5966 vNULL, have_std_attrs, std_attrs);
5969 /* Nonempty attributes on the following statement are ignored. */
5970 c_warn_unused_attributes (std_attrs);
5974 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5978 attribute-specifier-sequence[opt] compound-statement
5979 expression-statement
5980 attribute-specifier-sequence[opt] selection-statement
5981 attribute-specifier-sequence[opt] iteration-statement
5982 attribute-specifier-sequence[opt] jump-statement
5985 attribute-specifier-sequence[opt] label statement
5987 expression-statement:
5989 attribute-specifier-sequence expression ;
5991 selection-statement:
5995 iteration-statement:
6004 return expression[opt] ;
6009 attribute-specifier-sequence[opt] asm-statement
6014 expression-statement:
6020 attribute-specifier-sequence[opt] objc-throw-statement
6021 attribute-specifier-sequence[opt] objc-try-catch-statement
6022 attribute-specifier-sequence[opt] objc-synchronized-statement
6024 objc-throw-statement:
6031 attribute-specifier-sequence[opt] openacc-construct
6040 parallel-directive structured-block
6043 kernels-directive structured-block
6046 data-directive structured-block
6049 loop-directive structured-block
6054 attribute-specifier-sequence[opt] openmp-construct
6063 parallel-for-construct
6064 parallel-for-simd-construct
6065 parallel-sections-construct
6072 parallel-directive structured-block
6075 for-directive iteration-statement
6078 simd-directive iteration-statements
6081 for-simd-directive iteration-statements
6084 sections-directive section-scope
6087 single-directive structured-block
6089 parallel-for-construct:
6090 parallel-for-directive iteration-statement
6092 parallel-for-simd-construct:
6093 parallel-for-simd-directive iteration-statement
6095 parallel-sections-construct:
6096 parallel-sections-directive section-scope
6099 master-directive structured-block
6102 critical-directive structured-block
6105 atomic-directive expression-statement
6108 ordered-directive structured-block
6110 Transactional Memory:
6113 attribute-specifier-sequence[opt] transaction-statement
6114 attribute-specifier-sequence[opt] transaction-cancel-statement
6116 IF_P is used to track whether there's a (possibly labeled) if statement
6117 which is not enclosed in braces and has an else clause. This is used to
6118 implement -Wparentheses. */
6121 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6123 c_parser_all_labels (parser);
6124 if (loc_after_labels)
6125 *loc_after_labels = c_parser_peek_token (parser)->location;
6126 c_parser_statement_after_labels (parser, if_p, NULL);
6129 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6130 of if-else-if conditions. All labels and standard attributes have
6131 been parsed in the caller.
6133 IF_P is used to track whether there's a (possibly labeled) if statement
6134 which is not enclosed in braces and has an else clause. This is used to
6135 implement -Wparentheses. */
6138 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6141 location_t loc = c_parser_peek_token (parser)->location;
6142 tree stmt = NULL_TREE;
6143 bool in_if_block = parser->in_if_block;
6144 parser->in_if_block = false;
6148 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6149 add_debug_begin_stmt (loc);
6151 switch (c_parser_peek_token (parser)->type)
6153 case CPP_OPEN_BRACE:
6154 add_stmt (c_parser_compound_statement (parser));
6157 switch (c_parser_peek_token (parser)->keyword)
6160 c_parser_if_statement (parser, if_p, chain);
6163 c_parser_switch_statement (parser, if_p);
6166 c_parser_while_statement (parser, false, 0, if_p);
6169 c_parser_do_statement (parser, 0, false);
6172 c_parser_for_statement (parser, false, 0, if_p);
6175 c_parser_consume_token (parser);
6176 if (c_parser_next_token_is (parser, CPP_NAME))
6178 stmt = c_finish_goto_label (loc,
6179 c_parser_peek_token (parser)->value);
6180 c_parser_consume_token (parser);
6182 else if (c_parser_next_token_is (parser, CPP_MULT))
6186 c_parser_consume_token (parser);
6187 val = c_parser_expression (parser);
6188 val = convert_lvalue_to_rvalue (loc, val, false, true);
6189 stmt = c_finish_goto_ptr (loc, val.value);
6192 c_parser_error (parser, "expected identifier or %<*%>");
6193 goto expect_semicolon;
6195 c_parser_consume_token (parser);
6196 stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
6197 goto expect_semicolon;
6199 c_parser_consume_token (parser);
6200 stmt = c_finish_bc_stmt (loc, &c_break_label, true);
6201 goto expect_semicolon;
6203 c_parser_consume_token (parser);
6204 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6206 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6207 c_parser_consume_token (parser);
6211 location_t xloc = c_parser_peek_token (parser)->location;
6212 struct c_expr expr = c_parser_expression_conv (parser);
6213 mark_exp_read (expr.value);
6214 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6215 expr.value, expr.original_type);
6216 goto expect_semicolon;
6220 stmt = c_parser_asm_statement (parser);
6222 case RID_TRANSACTION_ATOMIC:
6223 case RID_TRANSACTION_RELAXED:
6224 stmt = c_parser_transaction (parser,
6225 c_parser_peek_token (parser)->keyword);
6227 case RID_TRANSACTION_CANCEL:
6228 stmt = c_parser_transaction_cancel (parser);
6229 goto expect_semicolon;
6231 gcc_assert (c_dialect_objc ());
6232 c_parser_consume_token (parser);
6233 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6235 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6236 c_parser_consume_token (parser);
6240 struct c_expr expr = c_parser_expression (parser);
6241 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6242 expr.value = c_fully_fold (expr.value, false, NULL);
6243 stmt = objc_build_throw_stmt (loc, expr.value);
6244 goto expect_semicolon;
6248 gcc_assert (c_dialect_objc ());
6249 c_parser_objc_try_catch_finally_statement (parser);
6251 case RID_AT_SYNCHRONIZED:
6252 gcc_assert (c_dialect_objc ());
6253 c_parser_objc_synchronized_statement (parser);
6257 /* Allow '__attribute__((fallthrough));'. */
6258 tree attrs = c_parser_gnu_attributes (parser);
6259 if (attribute_fallthrough_p (attrs))
6261 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6263 tree fn = build_call_expr_internal_loc (loc,
6268 c_parser_consume_token (parser);
6271 warning_at (loc, OPT_Wattributes,
6272 "%<fallthrough%> attribute not followed "
6275 else if (attrs != NULL_TREE)
6276 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6277 " can be applied to a null statement");
6285 c_parser_consume_token (parser);
6287 case CPP_CLOSE_PAREN:
6288 case CPP_CLOSE_SQUARE:
6289 /* Avoid infinite loop in error recovery:
6290 c_parser_skip_until_found stops at a closing nesting
6291 delimiter without consuming it, but here we need to consume
6292 it to proceed further. */
6293 c_parser_error (parser, "expected statement");
6294 c_parser_consume_token (parser);
6297 c_parser_pragma (parser, pragma_stmt, if_p);
6301 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6303 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6306 /* Two cases cannot and do not have line numbers associated: If stmt
6307 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6308 cannot hold line numbers. But that's OK because the statement
6309 will either be changed to a MODIFY_EXPR during gimplification of
6310 the statement expr, or discarded. If stmt was compound, but
6311 without new variables, we will have skipped the creation of a
6312 BIND and will have a bare STATEMENT_LIST. But that's OK because
6313 (recursively) all of the component statements should already have
6314 line numbers assigned. ??? Can we discard no-op statements
6316 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6317 protected_set_expr_location (stmt, loc);
6319 parser->in_if_block = in_if_block;
6322 /* Parse the condition from an if, do, while or for statements. */
6325 c_parser_condition (c_parser *parser)
6327 location_t loc = c_parser_peek_token (parser)->location;
6329 cond = c_parser_expression_conv (parser).value;
6330 cond = c_objc_common_truthvalue_conversion (loc, cond);
6331 cond = c_fully_fold (cond, false, NULL);
6332 if (warn_sequence_point)
6333 verify_sequence_points (cond);
6337 /* Parse a parenthesized condition from an if, do or while statement.
6343 c_parser_paren_condition (c_parser *parser)
6346 matching_parens parens;
6347 if (!parens.require_open (parser))
6348 return error_mark_node;
6349 cond = c_parser_condition (parser);
6350 parens.skip_until_found_close (parser);
6354 /* Parse a statement which is a block in C99.
6356 IF_P is used to track whether there's a (possibly labeled) if statement
6357 which is not enclosed in braces and has an else clause. This is used to
6358 implement -Wparentheses. */
6361 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6362 location_t *loc_after_labels)
6364 tree block = c_begin_compound_stmt (flag_isoc99);
6365 location_t loc = c_parser_peek_token (parser)->location;
6366 c_parser_statement (parser, if_p, loc_after_labels);
6367 return c_end_compound_stmt (loc, block, flag_isoc99);
6370 /* Parse the body of an if statement. This is just parsing a
6371 statement but (a) it is a block in C99, (b) we track whether the
6372 body is an if statement for the sake of -Wparentheses warnings, (c)
6373 we handle an empty body specially for the sake of -Wempty-body
6374 warnings, and (d) we call parser_compound_statement directly
6375 because c_parser_statement_after_labels resets
6376 parser->in_if_block.
6378 IF_P is used to track whether there's a (possibly labeled) if statement
6379 which is not enclosed in braces and has an else clause. This is used to
6380 implement -Wparentheses. */
6383 c_parser_if_body (c_parser *parser, bool *if_p,
6384 const token_indent_info &if_tinfo)
6386 tree block = c_begin_compound_stmt (flag_isoc99);
6387 location_t body_loc = c_parser_peek_token (parser)->location;
6388 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6389 token_indent_info body_tinfo
6390 = get_token_indent_info (c_parser_peek_token (parser));
6392 c_parser_all_labels (parser);
6393 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6395 location_t loc = c_parser_peek_token (parser)->location;
6396 add_stmt (build_empty_stmt (loc));
6397 c_parser_consume_token (parser);
6398 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6399 warning_at (loc, OPT_Wempty_body,
6400 "suggest braces around empty body in an %<if%> statement");
6402 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6403 add_stmt (c_parser_compound_statement (parser));
6406 body_loc_after_labels = c_parser_peek_token (parser)->location;
6407 c_parser_statement_after_labels (parser, if_p);
6410 token_indent_info next_tinfo
6411 = get_token_indent_info (c_parser_peek_token (parser));
6412 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6413 if (body_loc_after_labels != UNKNOWN_LOCATION
6414 && next_tinfo.type != CPP_SEMICOLON)
6415 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6416 if_tinfo.location, RID_IF);
6418 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6421 /* Parse the else body of an if statement. This is just parsing a
6422 statement but (a) it is a block in C99, (b) we handle an empty body
6423 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6424 of if-else-if conditions. */
6427 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6430 location_t body_loc = c_parser_peek_token (parser)->location;
6431 tree block = c_begin_compound_stmt (flag_isoc99);
6432 token_indent_info body_tinfo
6433 = get_token_indent_info (c_parser_peek_token (parser));
6434 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6436 c_parser_all_labels (parser);
6437 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6439 location_t loc = c_parser_peek_token (parser)->location;
6442 "suggest braces around empty body in an %<else%> statement");
6443 add_stmt (build_empty_stmt (loc));
6444 c_parser_consume_token (parser);
6448 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6449 body_loc_after_labels = c_parser_peek_token (parser)->location;
6450 c_parser_statement_after_labels (parser, NULL, chain);
6453 token_indent_info next_tinfo
6454 = get_token_indent_info (c_parser_peek_token (parser));
6455 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6456 if (body_loc_after_labels != UNKNOWN_LOCATION
6457 && next_tinfo.type != CPP_SEMICOLON)
6458 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6459 else_tinfo.location, RID_ELSE);
6461 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6464 /* We might need to reclassify any previously-lexed identifier, e.g.
6465 when we've left a for loop with an if-statement without else in the
6466 body - we might have used a wrong scope for the token. See PR67784. */
6469 c_parser_maybe_reclassify_token (c_parser *parser)
6471 if (c_parser_next_token_is (parser, CPP_NAME))
6473 c_token *token = c_parser_peek_token (parser);
6475 if (token->id_kind != C_ID_CLASSNAME)
6477 tree decl = lookup_name (token->value);
6479 token->id_kind = C_ID_ID;
6482 if (TREE_CODE (decl) == TYPE_DECL)
6483 token->id_kind = C_ID_TYPENAME;
6485 else if (c_dialect_objc ())
6487 tree objc_interface_decl = objc_is_class_name (token->value);
6488 /* Objective-C class names are in the same namespace as
6489 variables and typedefs, and hence are shadowed by local
6491 if (objc_interface_decl)
6493 token->value = objc_interface_decl;
6494 token->id_kind = C_ID_CLASSNAME;
6501 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6504 if ( expression ) statement
6505 if ( expression ) statement else statement
6507 CHAIN is a vector of if-else-if conditions.
6508 IF_P is used to track whether there's a (possibly labeled) if statement
6509 which is not enclosed in braces and has an else clause. This is used to
6510 implement -Wparentheses. */
6513 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6518 bool nested_if = false;
6519 tree first_body, second_body;
6522 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6523 token_indent_info if_tinfo
6524 = get_token_indent_info (c_parser_peek_token (parser));
6525 c_parser_consume_token (parser);
6526 block = c_begin_compound_stmt (flag_isoc99);
6527 loc = c_parser_peek_token (parser)->location;
6528 cond = c_parser_paren_condition (parser);
6529 in_if_block = parser->in_if_block;
6530 parser->in_if_block = true;
6531 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6532 parser->in_if_block = in_if_block;
6534 if (warn_duplicated_cond)
6535 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6537 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6539 token_indent_info else_tinfo
6540 = get_token_indent_info (c_parser_peek_token (parser));
6541 c_parser_consume_token (parser);
6542 if (warn_duplicated_cond)
6544 if (c_parser_next_token_is_keyword (parser, RID_IF)
6547 /* We've got "if (COND) else if (COND2)". Start the
6548 condition chain and add COND as the first element. */
6549 chain = new vec<tree> ();
6550 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6551 chain->safe_push (cond);
6553 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6555 /* This is if-else without subsequent if. Zap the condition
6556 chain; we would have already warned at this point. */
6561 second_body = c_parser_else_body (parser, else_tinfo, chain);
6562 /* Set IF_P to true to indicate that this if statement has an
6563 else clause. This may trigger the Wparentheses warning
6564 below when we get back up to the parent if statement. */
6570 second_body = NULL_TREE;
6572 /* Diagnose an ambiguous else if if-then-else is nested inside
6575 warning_at (loc, OPT_Wdangling_else,
6576 "suggest explicit braces to avoid ambiguous %<else%>");
6578 if (warn_duplicated_cond)
6580 /* This if statement does not have an else clause. We don't
6581 need the condition chain anymore. */
6586 c_finish_if_stmt (loc, cond, first_body, second_body);
6587 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6589 c_parser_maybe_reclassify_token (parser);
6592 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6595 switch (expression) statement
6599 c_parser_switch_statement (c_parser *parser, bool *if_p)
6602 tree block, expr, body, save_break;
6603 location_t switch_loc = c_parser_peek_token (parser)->location;
6604 location_t switch_cond_loc;
6605 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6606 c_parser_consume_token (parser);
6607 block = c_begin_compound_stmt (flag_isoc99);
6608 bool explicit_cast_p = false;
6609 matching_parens parens;
6610 if (parens.require_open (parser))
6612 switch_cond_loc = c_parser_peek_token (parser)->location;
6613 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6614 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6615 explicit_cast_p = true;
6616 ce = c_parser_expression (parser);
6617 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6619 /* ??? expr has no valid location? */
6620 parens.skip_until_found_close (parser);
6624 switch_cond_loc = UNKNOWN_LOCATION;
6625 expr = error_mark_node;
6626 ce.original_type = error_mark_node;
6628 c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6629 save_break = c_break_label;
6630 c_break_label = NULL_TREE;
6631 location_t loc_after_labels;
6632 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6633 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6634 location_t next_loc = c_parser_peek_token (parser)->location;
6635 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6636 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6640 location_t here = c_parser_peek_token (parser)->location;
6641 tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
6642 SET_EXPR_LOCATION (t, here);
6643 SWITCH_BREAK_LABEL_P (c_break_label) = 1;
6644 append_to_statement_list_force (t, &body);
6646 c_finish_case (body, ce.original_type);
6647 c_break_label = save_break;
6648 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6649 c_parser_maybe_reclassify_token (parser);
6652 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6655 while (expression) statement
6657 IF_P is used to track whether there's a (possibly labeled) if statement
6658 which is not enclosed in braces and has an else clause. This is used to
6659 implement -Wparentheses. */
6662 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6665 tree block, cond, body, save_break, save_cont;
6667 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6668 token_indent_info while_tinfo
6669 = get_token_indent_info (c_parser_peek_token (parser));
6670 c_parser_consume_token (parser);
6671 block = c_begin_compound_stmt (flag_isoc99);
6672 loc = c_parser_peek_token (parser)->location;
6673 cond = c_parser_paren_condition (parser);
6674 if (ivdep && cond != error_mark_node)
6675 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6676 build_int_cst (integer_type_node,
6677 annot_expr_ivdep_kind),
6679 if (unroll && cond != error_mark_node)
6680 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6681 build_int_cst (integer_type_node,
6682 annot_expr_unroll_kind),
6683 build_int_cst (integer_type_node, unroll));
6684 save_break = c_break_label;
6685 c_break_label = NULL_TREE;
6686 save_cont = c_cont_label;
6687 c_cont_label = NULL_TREE;
6689 token_indent_info body_tinfo
6690 = get_token_indent_info (c_parser_peek_token (parser));
6692 location_t loc_after_labels;
6693 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6694 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6695 c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body,
6696 c_break_label, c_cont_label, true);
6697 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6698 c_parser_maybe_reclassify_token (parser);
6700 token_indent_info next_tinfo
6701 = get_token_indent_info (c_parser_peek_token (parser));
6702 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6704 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6705 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6706 while_tinfo.location, RID_WHILE);
6708 c_break_label = save_break;
6709 c_cont_label = save_cont;
6712 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6715 do statement while ( expression ) ;
6719 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6721 tree block, cond, body, save_break, save_cont, new_break, new_cont;
6723 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6724 c_parser_consume_token (parser);
6725 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6726 warning_at (c_parser_peek_token (parser)->location,
6728 "suggest braces around empty body in %<do%> statement");
6729 block = c_begin_compound_stmt (flag_isoc99);
6730 loc = c_parser_peek_token (parser)->location;
6731 save_break = c_break_label;
6732 c_break_label = NULL_TREE;
6733 save_cont = c_cont_label;
6734 c_cont_label = NULL_TREE;
6735 body = c_parser_c99_block_statement (parser, NULL);
6736 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6737 new_break = c_break_label;
6738 c_break_label = save_break;
6739 new_cont = c_cont_label;
6740 c_cont_label = save_cont;
6741 location_t cond_loc = c_parser_peek_token (parser)->location;
6742 cond = c_parser_paren_condition (parser);
6743 if (ivdep && cond != error_mark_node)
6744 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6745 build_int_cst (integer_type_node,
6746 annot_expr_ivdep_kind),
6748 if (unroll && cond != error_mark_node)
6749 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6750 build_int_cst (integer_type_node,
6751 annot_expr_unroll_kind),
6752 build_int_cst (integer_type_node, unroll));
6753 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6754 c_parser_skip_to_end_of_block_or_statement (parser);
6755 c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body,
6756 new_break, new_cont, false);
6757 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6760 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6763 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6764 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6766 The form with a declaration is new in C99.
6768 ??? In accordance with the old parser, the declaration may be a
6769 nested function, which is then rejected in check_for_loop_decls,
6770 but does it make any sense for this to be included in the grammar?
6771 Note in particular that the nested function does not include a
6772 trailing ';', whereas the "declaration" production includes one.
6773 Also, can we reject bad declarations earlier and cheaper than
6774 check_for_loop_decls?
6776 In Objective-C, there are two additional variants:
6779 for ( expression in expresssion ) statement
6780 for ( declaration in expression ) statement
6782 This is inconsistent with C, because the second variant is allowed
6783 even if c99 is not enabled.
6785 The rest of the comment documents these Objective-C foreach-statement.
6787 Here is the canonical example of the first variant:
6788 for (object in array) { do something with object }
6789 we call the first expression ("object") the "object_expression" and
6790 the second expression ("array") the "collection_expression".
6791 object_expression must be an lvalue of type "id" (a generic Objective-C
6792 object) because the loop works by assigning to object_expression the
6793 various objects from the collection_expression. collection_expression
6794 must evaluate to something of type "id" which responds to the method
6795 countByEnumeratingWithState:objects:count:.
6797 The canonical example of the second variant is:
6798 for (id object in array) { do something with object }
6799 which is completely equivalent to
6802 for (object in array) { do something with object }
6804 Note that initizializing 'object' in some way (eg, "for ((object =
6805 xxx) in array) { do something with object }") is possibly
6806 technically valid, but completely pointless as 'object' will be
6807 assigned to something else as soon as the loop starts. We should
6808 most likely reject it (TODO).
6810 The beginning of the Objective-C foreach-statement looks exactly
6811 like the beginning of the for-statement, and we can tell it is a
6812 foreach-statement only because the initial declaration or
6813 expression is terminated by 'in' instead of ';'.
6815 IF_P is used to track whether there's a (possibly labeled) if statement
6816 which is not enclosed in braces and has an else clause. This is used to
6817 implement -Wparentheses. */
6820 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6823 tree block, cond, incr, save_break, save_cont, body;
6824 /* The following are only used when parsing an ObjC foreach statement. */
6825 tree object_expression;
6826 /* Silence the bogus uninitialized warning. */
6827 tree collection_expression = NULL;
6828 location_t loc = c_parser_peek_token (parser)->location;
6829 location_t for_loc = loc;
6830 location_t cond_loc = UNKNOWN_LOCATION;
6831 location_t incr_loc = UNKNOWN_LOCATION;
6832 bool is_foreach_statement = false;
6833 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6834 token_indent_info for_tinfo
6835 = get_token_indent_info (c_parser_peek_token (parser));
6836 c_parser_consume_token (parser);
6837 /* Open a compound statement in Objective-C as well, just in case this is
6838 as foreach expression. */
6839 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6840 cond = error_mark_node;
6841 incr = error_mark_node;
6842 matching_parens parens;
6843 if (parens.require_open (parser))
6845 /* Parse the initialization declaration or expression. */
6846 object_expression = error_mark_node;
6847 parser->objc_could_be_foreach_context = c_dialect_objc ();
6848 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6850 parser->objc_could_be_foreach_context = false;
6851 c_parser_consume_token (parser);
6852 c_finish_expr_stmt (loc, NULL_TREE);
6854 else if (c_parser_next_tokens_start_declaration (parser)
6855 || c_parser_nth_token_starts_std_attributes (parser, 1))
6857 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6858 &object_expression, vNULL);
6859 parser->objc_could_be_foreach_context = false;
6861 if (c_parser_next_token_is_keyword (parser, RID_IN))
6863 c_parser_consume_token (parser);
6864 is_foreach_statement = true;
6865 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6866 c_parser_error (parser, "multiple iterating variables in "
6867 "fast enumeration");
6870 check_for_loop_decls (for_loc, flag_isoc99);
6872 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6874 /* __extension__ can start a declaration, but is also an
6875 unary operator that can start an expression. Consume all
6876 but the last of a possible series of __extension__ to
6878 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6879 && (c_parser_peek_2nd_token (parser)->keyword
6881 c_parser_consume_token (parser);
6882 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6883 || c_parser_nth_token_starts_std_attributes (parser, 2))
6886 ext = disable_extension_diagnostics ();
6887 c_parser_consume_token (parser);
6888 c_parser_declaration_or_fndef (parser, true, true, true, true,
6889 true, &object_expression, vNULL);
6890 parser->objc_could_be_foreach_context = false;
6892 restore_extension_diagnostics (ext);
6893 if (c_parser_next_token_is_keyword (parser, RID_IN))
6895 c_parser_consume_token (parser);
6896 is_foreach_statement = true;
6897 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6898 c_parser_error (parser, "multiple iterating variables in "
6899 "fast enumeration");
6902 check_for_loop_decls (for_loc, flag_isoc99);
6912 tree init_expression;
6913 ce = c_parser_expression (parser);
6914 init_expression = ce.value;
6915 parser->objc_could_be_foreach_context = false;
6916 if (c_parser_next_token_is_keyword (parser, RID_IN))
6918 c_parser_consume_token (parser);
6919 is_foreach_statement = true;
6920 if (! lvalue_p (init_expression))
6921 c_parser_error (parser, "invalid iterating variable in "
6922 "fast enumeration");
6924 = c_fully_fold (init_expression, false, NULL);
6928 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6929 init_expression = ce.value;
6930 c_finish_expr_stmt (loc, init_expression);
6931 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6936 /* Parse the loop condition. In the case of a foreach
6937 statement, there is no loop condition. */
6938 gcc_assert (!parser->objc_could_be_foreach_context);
6939 if (!is_foreach_statement)
6941 cond_loc = c_parser_peek_token (parser)->location;
6942 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6946 c_parser_error (parser, "missing loop condition in loop "
6947 "with %<GCC ivdep%> pragma");
6948 cond = error_mark_node;
6952 c_parser_error (parser, "missing loop condition in loop "
6953 "with %<GCC unroll%> pragma");
6954 cond = error_mark_node;
6958 c_parser_consume_token (parser);
6964 cond = c_parser_condition (parser);
6965 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6968 if (ivdep && cond != error_mark_node)
6969 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6970 build_int_cst (integer_type_node,
6971 annot_expr_ivdep_kind),
6973 if (unroll && cond != error_mark_node)
6974 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6975 build_int_cst (integer_type_node,
6976 annot_expr_unroll_kind),
6977 build_int_cst (integer_type_node, unroll));
6979 /* Parse the increment expression (the third expression in a
6980 for-statement). In the case of a foreach-statement, this is
6981 the expression that follows the 'in'. */
6982 loc = incr_loc = c_parser_peek_token (parser)->location;
6983 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6985 if (is_foreach_statement)
6987 c_parser_error (parser,
6988 "missing collection in fast enumeration");
6989 collection_expression = error_mark_node;
6992 incr = c_process_expr_stmt (loc, NULL_TREE);
6996 if (is_foreach_statement)
6997 collection_expression
6998 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
7001 struct c_expr ce = c_parser_expression (parser);
7002 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
7003 incr = c_process_expr_stmt (loc, ce.value);
7006 parens.skip_until_found_close (parser);
7008 save_break = c_break_label;
7009 c_break_label = NULL_TREE;
7010 save_cont = c_cont_label;
7011 c_cont_label = NULL_TREE;
7013 token_indent_info body_tinfo
7014 = get_token_indent_info (c_parser_peek_token (parser));
7016 location_t loc_after_labels;
7017 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
7018 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
7020 if (is_foreach_statement)
7021 objc_finish_foreach_loop (for_loc, object_expression,
7022 collection_expression, body, c_break_label,
7025 c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body,
7026 c_break_label, c_cont_label, true);
7027 add_stmt (c_end_compound_stmt (for_loc, block,
7028 flag_isoc99 || c_dialect_objc ()));
7029 c_parser_maybe_reclassify_token (parser);
7031 token_indent_info next_tinfo
7032 = get_token_indent_info (c_parser_peek_token (parser));
7033 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
7035 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
7036 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7037 for_tinfo.location, RID_FOR);
7039 c_break_label = save_break;
7040 c_cont_label = save_cont;
7043 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7044 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7053 asm-qualifier-list asm-qualifier
7057 asm asm-qualifier-list[opt] ( asm-argument ) ;
7061 asm-string-literal : asm-operands[opt]
7062 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7063 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7065 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7068 The form with asm-goto-operands is valid if and only if the
7069 asm-qualifier-list contains goto, and is the only allowed form in that case.
7070 Duplicate asm-qualifiers are not allowed.
7072 The :: token is considered equivalent to two consecutive : tokens. */
7075 c_parser_asm_statement (c_parser *parser)
7077 tree str, outputs, inputs, clobbers, labels, ret;
7079 location_t asm_loc = c_parser_peek_token (parser)->location;
7080 int section, nsections;
7082 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7083 c_parser_consume_token (parser);
7085 /* Handle the asm-qualifier-list. */
7086 location_t volatile_loc = UNKNOWN_LOCATION;
7087 location_t inline_loc = UNKNOWN_LOCATION;
7088 location_t goto_loc = UNKNOWN_LOCATION;
7091 c_token *token = c_parser_peek_token (parser);
7092 location_t loc = token->location;
7093 switch (token->keyword)
7098 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7099 inform (volatile_loc, "first seen here");
7103 c_parser_consume_token (parser);
7109 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7110 inform (inline_loc, "first seen here");
7114 c_parser_consume_token (parser);
7120 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7121 inform (goto_loc, "first seen here");
7125 c_parser_consume_token (parser);
7130 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7131 c_parser_consume_token (parser);
7140 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7141 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7142 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7146 matching_parens parens;
7147 if (!parens.require_open (parser))
7150 str = c_parser_asm_string_literal (parser);
7151 if (str == NULL_TREE)
7152 goto error_close_paren;
7155 outputs = NULL_TREE;
7157 clobbers = NULL_TREE;
7160 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7163 /* Parse each colon-delimited section of operands. */
7164 nsections = 3 + is_goto;
7165 for (section = 0; section < nsections; ++section)
7167 if (c_parser_next_token_is (parser, CPP_SCOPE))
7170 if (section == nsections)
7172 c_parser_error (parser, "expected %<)%>");
7173 goto error_close_paren;
7175 c_parser_consume_token (parser);
7177 else if (!c_parser_require (parser, CPP_COLON,
7179 ? G_("expected %<:%>")
7180 : G_("expected %<:%> or %<)%>"),
7181 UNKNOWN_LOCATION, is_goto))
7182 goto error_close_paren;
7184 /* Once past any colon, we're no longer a simple asm. */
7187 if ((!c_parser_next_token_is (parser, CPP_COLON)
7188 && !c_parser_next_token_is (parser, CPP_SCOPE)
7189 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7194 /* For asm goto, we don't allow output operands, but reserve
7195 the slot for a future extension that does allow them. */
7197 outputs = c_parser_asm_operands (parser);
7200 inputs = c_parser_asm_operands (parser);
7203 clobbers = c_parser_asm_clobbers (parser);
7206 labels = c_parser_asm_goto_operands (parser);
7212 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7217 if (!parens.require_close (parser))
7219 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7223 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7224 c_parser_skip_to_end_of_block_or_statement (parser);
7226 ret = build_asm_stmt (is_volatile,
7227 build_asm_expr (asm_loc, str, outputs, inputs,
7228 clobbers, labels, simple, is_inline));
7234 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7238 /* Parse asm operands, a GNU extension.
7242 asm-operands , asm-operand
7245 asm-string-literal ( expression )
7246 [ identifier ] asm-string-literal ( expression )
7250 c_parser_asm_operands (c_parser *parser)
7252 tree list = NULL_TREE;
7257 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7259 c_parser_consume_token (parser);
7260 if (c_parser_next_token_is (parser, CPP_NAME))
7262 tree id = c_parser_peek_token (parser)->value;
7263 c_parser_consume_token (parser);
7264 name = build_string (IDENTIFIER_LENGTH (id),
7265 IDENTIFIER_POINTER (id));
7269 c_parser_error (parser, "expected identifier");
7270 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7273 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7278 str = c_parser_asm_string_literal (parser);
7279 if (str == NULL_TREE)
7281 matching_parens parens;
7282 if (!parens.require_open (parser))
7284 expr = c_parser_expression (parser);
7285 mark_exp_read (expr.value);
7286 if (!parens.require_close (parser))
7288 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7291 list = chainon (list, build_tree_list (build_tree_list (name, str),
7293 if (c_parser_next_token_is (parser, CPP_COMMA))
7294 c_parser_consume_token (parser);
7301 /* Parse asm clobbers, a GNU extension.
7305 asm-clobbers , asm-string-literal
7309 c_parser_asm_clobbers (c_parser *parser)
7311 tree list = NULL_TREE;
7314 tree str = c_parser_asm_string_literal (parser);
7316 list = tree_cons (NULL_TREE, str, list);
7319 if (c_parser_next_token_is (parser, CPP_COMMA))
7320 c_parser_consume_token (parser);
7327 /* Parse asm goto labels, a GNU extension.
7331 asm-goto-operands , identifier
7335 c_parser_asm_goto_operands (c_parser *parser)
7337 tree list = NULL_TREE;
7342 if (c_parser_next_token_is (parser, CPP_NAME))
7344 c_token *tok = c_parser_peek_token (parser);
7346 label = lookup_label_for_goto (tok->location, name);
7347 c_parser_consume_token (parser);
7348 TREE_USED (label) = 1;
7352 c_parser_error (parser, "expected identifier");
7356 name = build_string (IDENTIFIER_LENGTH (name),
7357 IDENTIFIER_POINTER (name));
7358 list = tree_cons (name, label, list);
7359 if (c_parser_next_token_is (parser, CPP_COMMA))
7360 c_parser_consume_token (parser);
7362 return nreverse (list);
7366 /* Parse a possibly concatenated sequence of string literals.
7367 TRANSLATE says whether to translate them to the execution character
7368 set; WIDE_OK says whether any kind of prefixed string literal is
7369 permitted in this context. This code is based on that in
7373 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7377 struct obstack str_ob;
7378 struct obstack loc_ob;
7379 cpp_string str, istr, *strs;
7381 location_t loc, last_tok_loc;
7382 enum cpp_ttype type;
7383 tree value, string_tree;
7385 tok = c_parser_peek_token (parser);
7386 loc = tok->location;
7387 last_tok_loc = linemap_resolve_location (line_table, loc,
7388 LRK_MACRO_DEFINITION_LOCATION,
7397 case CPP_UTF8STRING:
7398 string_tree = tok->value;
7402 c_parser_error (parser, "expected string literal");
7404 ret.value = NULL_TREE;
7405 ret.original_code = ERROR_MARK;
7406 ret.original_type = NULL_TREE;
7410 /* Try to avoid the overhead of creating and destroying an obstack
7411 for the common case of just one string. */
7412 switch (c_parser_peek_2nd_token (parser)->type)
7415 c_parser_consume_token (parser);
7416 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7417 str.len = TREE_STRING_LENGTH (string_tree);
7426 case CPP_UTF8STRING:
7427 gcc_obstack_init (&str_ob);
7428 gcc_obstack_init (&loc_ob);
7432 c_parser_consume_token (parser);
7434 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7435 str.len = TREE_STRING_LENGTH (string_tree);
7436 if (type != tok->type)
7438 if (type == CPP_STRING)
7440 else if (tok->type != CPP_STRING)
7441 error ("unsupported non-standard concatenation "
7442 "of string literals");
7444 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7445 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7446 tok = c_parser_peek_token (parser);
7447 string_tree = tok->value;
7449 = linemap_resolve_location (line_table, tok->location,
7450 LRK_MACRO_DEFINITION_LOCATION, NULL);
7452 while (tok->type == CPP_STRING
7453 || tok->type == CPP_WSTRING
7454 || tok->type == CPP_STRING16
7455 || tok->type == CPP_STRING32
7456 || tok->type == CPP_UTF8STRING);
7457 strs = (cpp_string *) obstack_finish (&str_ob);
7460 if (count > 1 && !in_system_header_at (input_location))
7461 warning (OPT_Wtraditional,
7462 "traditional C rejects string constant concatenation");
7464 if ((type == CPP_STRING || wide_ok)
7466 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7467 (parse_in, strs, count, &istr, type)))
7469 value = build_string (istr.len, (const char *) istr.text);
7470 free (CONST_CAST (unsigned char *, istr.text));
7473 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7474 gcc_assert (g_string_concat_db);
7475 g_string_concat_db->record_string_concatenation (count, locs);
7480 if (type != CPP_STRING && !wide_ok)
7482 error_at (loc, "a wide string is invalid in this context");
7485 /* Callers cannot generally handle error_mark_node in this
7486 context, so return the empty string instead. An error has
7487 been issued, either above or from cpp_interpret_string. */
7492 case CPP_UTF8STRING:
7493 value = build_string (1, "");
7496 value = build_string (TYPE_PRECISION (char16_type_node)
7497 / TYPE_PRECISION (char_type_node),
7498 "\0"); /* char16_t is 16 bits */
7501 value = build_string (TYPE_PRECISION (char32_type_node)
7502 / TYPE_PRECISION (char_type_node),
7503 "\0\0\0"); /* char32_t is 32 bits */
7506 value = build_string (TYPE_PRECISION (wchar_type_node)
7507 / TYPE_PRECISION (char_type_node),
7508 "\0\0\0"); /* widest supported wchar_t
7518 case CPP_UTF8STRING:
7519 TREE_TYPE (value) = char_array_type_node;
7522 TREE_TYPE (value) = char16_array_type_node;
7525 TREE_TYPE (value) = char32_array_type_node;
7528 TREE_TYPE (value) = wchar_array_type_node;
7530 value = fix_string_type (value);
7534 obstack_free (&str_ob, 0);
7535 obstack_free (&loc_ob, 0);
7539 ret.original_code = STRING_CST;
7540 ret.original_type = NULL_TREE;
7541 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7545 /* Parse an expression other than a compound expression; that is, an
7546 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7547 AFTER is not NULL then it is an Objective-C message expression which
7548 is the primary-expression starting the expression as an initializer.
7550 assignment-expression:
7551 conditional-expression
7552 unary-expression assignment-operator assignment-expression
7554 assignment-operator: one of
7555 = *= /= %= += -= <<= >>= &= ^= |=
7557 In GNU C we accept any conditional expression on the LHS and
7558 diagnose the invalid lvalue rather than producing a syntax
7561 static struct c_expr
7562 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7563 tree omp_atomic_lhs)
7565 struct c_expr lhs, rhs, ret;
7566 enum tree_code code;
7567 location_t op_location, exp_location;
7568 gcc_assert (!after || c_dialect_objc ());
7569 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7570 op_location = c_parser_peek_token (parser)->location;
7571 switch (c_parser_peek_token (parser)->type)
7580 code = TRUNC_DIV_EXPR;
7583 code = TRUNC_MOD_EXPR;
7598 code = BIT_AND_EXPR;
7601 code = BIT_XOR_EXPR;
7604 code = BIT_IOR_EXPR;
7609 c_parser_consume_token (parser);
7610 exp_location = c_parser_peek_token (parser)->location;
7611 rhs = c_parser_expr_no_commas (parser, NULL);
7612 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7614 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7615 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 TREE_NO_WARNING (ret.value) = 1;
7623 ret.original_code = ERROR_MARK;
7625 ret.original_type = NULL;
7629 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7630 AFTER is not NULL then it is an Objective-C message expression which is
7631 the primary-expression starting the expression as an initializer.
7633 conditional-expression:
7634 logical-OR-expression
7635 logical-OR-expression ? expression : conditional-expression
7639 conditional-expression:
7640 logical-OR-expression ? : conditional-expression
7643 static struct c_expr
7644 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7645 tree omp_atomic_lhs)
7647 struct c_expr cond, exp1, exp2, ret;
7648 location_t start, cond_loc, colon_loc;
7650 gcc_assert (!after || c_dialect_objc ());
7652 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7654 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7656 if (cond.value != error_mark_node)
7657 start = cond.get_start ();
7659 start = UNKNOWN_LOCATION;
7660 cond_loc = c_parser_peek_token (parser)->location;
7661 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7662 c_parser_consume_token (parser);
7663 if (c_parser_next_token_is (parser, CPP_COLON))
7665 tree eptype = NULL_TREE;
7667 location_t middle_loc = c_parser_peek_token (parser)->location;
7668 pedwarn (middle_loc, OPT_Wpedantic,
7669 "ISO C forbids omitting the middle term of a %<?:%> expression");
7670 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7672 eptype = TREE_TYPE (cond.value);
7673 cond.value = TREE_OPERAND (cond.value, 0);
7675 tree e = cond.value;
7676 while (TREE_CODE (e) == COMPOUND_EXPR)
7677 e = TREE_OPERAND (e, 1);
7678 warn_for_omitted_condop (middle_loc, e);
7679 /* Make sure first operand is calculated only once. */
7680 exp1.value = save_expr (default_conversion (cond.value));
7682 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7683 exp1.original_type = NULL;
7684 exp1.src_range = cond.src_range;
7685 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7686 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7691 = c_objc_common_truthvalue_conversion
7692 (cond_loc, default_conversion (cond.value));
7693 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7694 exp1 = c_parser_expression_conv (parser);
7695 mark_exp_read (exp1.value);
7696 c_inhibit_evaluation_warnings +=
7697 ((cond.value == truthvalue_true_node)
7698 - (cond.value == truthvalue_false_node));
7701 colon_loc = c_parser_peek_token (parser)->location;
7702 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7704 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7706 ret.original_code = ERROR_MARK;
7707 ret.original_type = NULL;
7711 location_t exp2_loc = c_parser_peek_token (parser)->location;
7712 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7713 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7715 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7716 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7717 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7718 ret.value = build_conditional_expr (colon_loc, cond.value,
7719 cond.original_code == C_MAYBE_CONST_EXPR,
7720 exp1.value, exp1.original_type, loc1,
7721 exp2.value, exp2.original_type, loc2);
7722 ret.original_code = ERROR_MARK;
7723 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7724 ret.original_type = NULL;
7729 /* If both sides are enum type, the default conversion will have
7730 made the type of the result be an integer type. We want to
7731 remember the enum types we started with. */
7732 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7733 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7734 ret.original_type = ((t1 != error_mark_node
7735 && t2 != error_mark_node
7736 && (TYPE_MAIN_VARIANT (t1)
7737 == TYPE_MAIN_VARIANT (t2)))
7741 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7745 /* Parse a binary expression; that is, a logical-OR-expression (C90
7746 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7747 NULL then it is an Objective-C message expression which is the
7748 primary-expression starting the expression as an initializer.
7750 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7751 when it should be the unfolded lhs. In a valid OpenMP source,
7752 one of the operands of the toplevel binary expression must be equal
7753 to it. In that case, just return a build2 created binary operation
7754 rather than result of parser_build_binary_op.
7756 multiplicative-expression:
7758 multiplicative-expression * cast-expression
7759 multiplicative-expression / cast-expression
7760 multiplicative-expression % cast-expression
7762 additive-expression:
7763 multiplicative-expression
7764 additive-expression + multiplicative-expression
7765 additive-expression - multiplicative-expression
7769 shift-expression << additive-expression
7770 shift-expression >> additive-expression
7772 relational-expression:
7774 relational-expression < shift-expression
7775 relational-expression > shift-expression
7776 relational-expression <= shift-expression
7777 relational-expression >= shift-expression
7779 equality-expression:
7780 relational-expression
7781 equality-expression == relational-expression
7782 equality-expression != relational-expression
7786 AND-expression & equality-expression
7788 exclusive-OR-expression:
7790 exclusive-OR-expression ^ AND-expression
7792 inclusive-OR-expression:
7793 exclusive-OR-expression
7794 inclusive-OR-expression | exclusive-OR-expression
7796 logical-AND-expression:
7797 inclusive-OR-expression
7798 logical-AND-expression && inclusive-OR-expression
7800 logical-OR-expression:
7801 logical-AND-expression
7802 logical-OR-expression || logical-AND-expression
7805 static struct c_expr
7806 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7807 tree omp_atomic_lhs)
7809 /* A binary expression is parsed using operator-precedence parsing,
7810 with the operands being cast expressions. All the binary
7811 operators are left-associative. Thus a binary expression is of
7814 E0 op1 E1 op2 E2 ...
7816 which we represent on a stack. On the stack, the precedence
7817 levels are strictly increasing. When a new operator is
7818 encountered of higher precedence than that at the top of the
7819 stack, it is pushed; its LHS is the top expression, and its RHS
7820 is everything parsed until it is popped. When a new operator is
7821 encountered with precedence less than or equal to that at the top
7822 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7823 by the result of the operation until the operator at the top of
7824 the stack has lower precedence than the new operator or there is
7825 only one element on the stack; then the top expression is the LHS
7826 of the new operator. In the case of logical AND and OR
7827 expressions, we also need to adjust c_inhibit_evaluation_warnings
7828 as appropriate when the operators are pushed and popped. */
7831 /* The expression at this stack level. */
7833 /* The precedence of the operator on its left, PREC_NONE at the
7834 bottom of the stack. */
7835 enum c_parser_prec prec;
7836 /* The operation on its left. */
7838 /* The source location of this operation. */
7840 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
7844 /* Location of the binary operator. */
7845 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7848 switch (stack[sp].op) \
7850 case TRUTH_ANDIF_EXPR: \
7851 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7852 == truthvalue_false_node); \
7854 case TRUTH_ORIF_EXPR: \
7855 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7856 == truthvalue_true_node); \
7858 case TRUNC_DIV_EXPR: \
7859 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7860 && stack[sp].expr.original_code == SIZEOF_EXPR) \
7862 tree type0 = stack[sp - 1].sizeof_arg; \
7863 tree type1 = stack[sp].sizeof_arg; \
7864 tree first_arg = type0; \
7865 if (!TYPE_P (type0)) \
7866 type0 = TREE_TYPE (type0); \
7867 if (!TYPE_P (type1)) \
7868 type1 = TREE_TYPE (type1); \
7869 if (POINTER_TYPE_P (type0) \
7870 && comptypes (TREE_TYPE (type0), type1) \
7871 && !(TREE_CODE (first_arg) == PARM_DECL \
7872 && C_ARRAY_PARAMETER (first_arg) \
7873 && warn_sizeof_array_argument)) \
7875 auto_diagnostic_group d; \
7876 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7877 "division %<sizeof (%T) / sizeof (%T)%> " \
7878 "does not compute the number of array " \
7881 if (DECL_P (first_arg)) \
7882 inform (DECL_SOURCE_LOCATION (first_arg), \
7883 "first %<sizeof%> operand was declared here"); \
7890 stack[sp - 1].expr \
7891 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7892 stack[sp - 1].expr, true, true); \
7894 = convert_lvalue_to_rvalue (stack[sp].loc, \
7895 stack[sp].expr, true, true); \
7896 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7897 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7898 && ((1 << stack[sp].prec) \
7899 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7900 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7901 && stack[sp].op != TRUNC_MOD_EXPR \
7902 && stack[0].expr.value != error_mark_node \
7903 && stack[1].expr.value != error_mark_node \
7904 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7905 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7906 stack[0].expr.value \
7907 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
7908 stack[0].expr.value, stack[1].expr.value); \
7910 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7912 stack[sp - 1].expr, \
7916 gcc_assert (!after || c_dialect_objc ());
7917 stack[0].loc = c_parser_peek_token (parser)->location;
7918 stack[0].expr = c_parser_cast_expression (parser, after);
7919 stack[0].prec = PREC_NONE;
7920 stack[0].sizeof_arg = c_last_sizeof_arg;
7924 enum c_parser_prec oprec;
7925 enum tree_code ocode;
7926 source_range src_range;
7929 switch (c_parser_peek_token (parser)->type)
7937 ocode = TRUNC_DIV_EXPR;
7941 ocode = TRUNC_MOD_EXPR;
7953 ocode = LSHIFT_EXPR;
7957 ocode = RSHIFT_EXPR;
7971 case CPP_GREATER_EQ:
7984 oprec = PREC_BITAND;
7985 ocode = BIT_AND_EXPR;
7988 oprec = PREC_BITXOR;
7989 ocode = BIT_XOR_EXPR;
7993 ocode = BIT_IOR_EXPR;
7996 oprec = PREC_LOGAND;
7997 ocode = TRUTH_ANDIF_EXPR;
8001 ocode = TRUTH_ORIF_EXPR;
8004 /* Not a binary operator, so end of the binary
8008 binary_loc = c_parser_peek_token (parser)->location;
8009 while (oprec <= stack[sp].prec)
8011 c_parser_consume_token (parser);
8014 case TRUTH_ANDIF_EXPR:
8015 src_range = stack[sp].expr.src_range;
8017 = convert_lvalue_to_rvalue (stack[sp].loc,
8018 stack[sp].expr, true, true);
8019 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8020 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8021 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8022 == truthvalue_false_node);
8023 set_c_expr_source_range (&stack[sp].expr, src_range);
8025 case TRUTH_ORIF_EXPR:
8026 src_range = stack[sp].expr.src_range;
8028 = convert_lvalue_to_rvalue (stack[sp].loc,
8029 stack[sp].expr, true, true);
8030 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8031 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8032 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8033 == truthvalue_true_node);
8034 set_c_expr_source_range (&stack[sp].expr, src_range);
8040 stack[sp].loc = binary_loc;
8041 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8042 stack[sp].prec = oprec;
8043 stack[sp].op = ocode;
8044 stack[sp].sizeof_arg = c_last_sizeof_arg;
8049 return stack[0].expr;
8053 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8054 is not NULL then it is an Objective-C message expression which is the
8055 primary-expression starting the expression as an initializer.
8059 ( type-name ) unary-expression
8062 static struct c_expr
8063 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8065 location_t cast_loc = c_parser_peek_token (parser)->location;
8066 gcc_assert (!after || c_dialect_objc ());
8068 return c_parser_postfix_expression_after_primary (parser,
8070 /* If the expression begins with a parenthesized type name, it may
8071 be either a cast or a compound literal; we need to see whether
8072 the next character is '{' to tell the difference. If not, it is
8073 an unary expression. Full detection of unknown typenames here
8074 would require a 3-token lookahead. */
8075 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8076 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8078 struct c_type_name *type_name;
8081 matching_parens parens;
8082 parens.consume_open (parser);
8083 type_name = c_parser_type_name (parser, true);
8084 parens.skip_until_found_close (parser);
8085 if (type_name == NULL)
8088 ret.original_code = ERROR_MARK;
8089 ret.original_type = NULL;
8093 /* Save casted types in the function's used types hash table. */
8094 used_types_insert (type_name->specs->type);
8096 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8097 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8099 if (type_name->specs->alignas_p)
8100 error_at (type_name->specs->locations[cdw_alignas],
8101 "alignment specified for type name in cast");
8103 location_t expr_loc = c_parser_peek_token (parser)->location;
8104 expr = c_parser_cast_expression (parser, NULL);
8105 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8107 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8108 if (ret.value && expr.value)
8109 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8110 ret.original_code = ERROR_MARK;
8111 ret.original_type = NULL;
8115 return c_parser_unary_expression (parser);
8118 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8124 unary-operator cast-expression
8125 sizeof unary-expression
8126 sizeof ( type-name )
8128 unary-operator: one of
8134 __alignof__ unary-expression
8135 __alignof__ ( type-name )
8138 (C11 permits _Alignof with type names only.)
8140 unary-operator: one of
8141 __extension__ __real__ __imag__
8143 Transactional Memory:
8146 transaction-expression
8148 In addition, the GNU syntax treats ++ and -- as unary operators, so
8149 they may be applied to cast expressions with errors for non-lvalues
8152 static struct c_expr
8153 c_parser_unary_expression (c_parser *parser)
8156 struct c_expr ret, op;
8157 location_t op_loc = c_parser_peek_token (parser)->location;
8160 ret.original_code = ERROR_MARK;
8161 ret.original_type = NULL;
8162 switch (c_parser_peek_token (parser)->type)
8165 c_parser_consume_token (parser);
8166 exp_loc = c_parser_peek_token (parser)->location;
8167 op = c_parser_cast_expression (parser, NULL);
8169 op = default_function_array_read_conversion (exp_loc, op);
8170 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8171 case CPP_MINUS_MINUS:
8172 c_parser_consume_token (parser);
8173 exp_loc = c_parser_peek_token (parser)->location;
8174 op = c_parser_cast_expression (parser, NULL);
8176 op = default_function_array_read_conversion (exp_loc, op);
8177 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8179 c_parser_consume_token (parser);
8180 op = c_parser_cast_expression (parser, NULL);
8181 mark_exp_read (op.value);
8182 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8185 c_parser_consume_token (parser);
8186 exp_loc = c_parser_peek_token (parser)->location;
8187 op = c_parser_cast_expression (parser, NULL);
8188 finish = op.get_finish ();
8189 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8190 location_t combined_loc = make_location (op_loc, op_loc, finish);
8191 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8192 ret.src_range.m_start = op_loc;
8193 ret.src_range.m_finish = finish;
8197 if (!c_dialect_objc () && !in_system_header_at (input_location))
8200 "traditional C rejects the unary plus operator");
8201 c_parser_consume_token (parser);
8202 exp_loc = c_parser_peek_token (parser)->location;
8203 op = c_parser_cast_expression (parser, NULL);
8204 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8205 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8207 c_parser_consume_token (parser);
8208 exp_loc = c_parser_peek_token (parser)->location;
8209 op = c_parser_cast_expression (parser, NULL);
8210 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8211 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8213 c_parser_consume_token (parser);
8214 exp_loc = c_parser_peek_token (parser)->location;
8215 op = c_parser_cast_expression (parser, NULL);
8216 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8217 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8219 c_parser_consume_token (parser);
8220 exp_loc = c_parser_peek_token (parser)->location;
8221 op = c_parser_cast_expression (parser, NULL);
8222 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8223 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8225 /* Refer to the address of a label as a pointer. */
8226 c_parser_consume_token (parser);
8227 if (c_parser_next_token_is (parser, CPP_NAME))
8229 ret.value = finish_label_address_expr
8230 (c_parser_peek_token (parser)->value, op_loc);
8231 set_c_expr_source_range (&ret, op_loc,
8232 c_parser_peek_token (parser)->get_finish ());
8233 c_parser_consume_token (parser);
8237 c_parser_error (parser, "expected identifier");
8242 switch (c_parser_peek_token (parser)->keyword)
8245 return c_parser_sizeof_expression (parser);
8247 return c_parser_alignof_expression (parser);
8248 case RID_BUILTIN_HAS_ATTRIBUTE:
8249 return c_parser_has_attribute_expression (parser);
8251 c_parser_consume_token (parser);
8252 ext = disable_extension_diagnostics ();
8253 ret = c_parser_cast_expression (parser, NULL);
8254 restore_extension_diagnostics (ext);
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 = default_function_array_conversion (exp_loc, op);
8261 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8263 c_parser_consume_token (parser);
8264 exp_loc = c_parser_peek_token (parser)->location;
8265 op = c_parser_cast_expression (parser, NULL);
8266 op = default_function_array_conversion (exp_loc, op);
8267 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8268 case RID_TRANSACTION_ATOMIC:
8269 case RID_TRANSACTION_RELAXED:
8270 return c_parser_transaction_expression (parser,
8271 c_parser_peek_token (parser)->keyword);
8273 return c_parser_postfix_expression (parser);
8276 return c_parser_postfix_expression (parser);
8280 /* Parse a sizeof expression. */
8282 static struct c_expr
8283 c_parser_sizeof_expression (c_parser *parser)
8286 struct c_expr result;
8287 location_t expr_loc;
8288 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8291 location_t finish = UNKNOWN_LOCATION;
8293 start = c_parser_peek_token (parser)->location;
8295 c_parser_consume_token (parser);
8296 c_inhibit_evaluation_warnings++;
8298 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8299 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8301 /* Either sizeof ( type-name ) or sizeof unary-expression
8302 starting with a compound literal. */
8303 struct c_type_name *type_name;
8304 matching_parens parens;
8305 parens.consume_open (parser);
8306 expr_loc = c_parser_peek_token (parser)->location;
8307 type_name = c_parser_type_name (parser, true);
8308 parens.skip_until_found_close (parser);
8309 finish = parser->tokens_buf[0].location;
8310 if (type_name == NULL)
8313 c_inhibit_evaluation_warnings--;
8316 ret.original_code = ERROR_MARK;
8317 ret.original_type = NULL;
8320 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8322 expr = c_parser_postfix_expression_after_paren_type (parser,
8325 finish = expr.get_finish ();
8328 /* sizeof ( type-name ). */
8329 if (type_name->specs->alignas_p)
8330 error_at (type_name->specs->locations[cdw_alignas],
8331 "alignment specified for type name in %<sizeof%>");
8332 c_inhibit_evaluation_warnings--;
8334 result = c_expr_sizeof_type (expr_loc, type_name);
8338 expr_loc = c_parser_peek_token (parser)->location;
8339 expr = c_parser_unary_expression (parser);
8340 finish = expr.get_finish ();
8342 c_inhibit_evaluation_warnings--;
8344 mark_exp_read (expr.value);
8345 if (TREE_CODE (expr.value) == COMPONENT_REF
8346 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8347 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8348 result = c_expr_sizeof_expr (expr_loc, expr);
8350 if (finish == UNKNOWN_LOCATION)
8352 set_c_expr_source_range (&result, start, finish);
8356 /* Parse an alignof expression. */
8358 static struct c_expr
8359 c_parser_alignof_expression (c_parser *parser)
8362 location_t start_loc = c_parser_peek_token (parser)->location;
8364 tree alignof_spelling = c_parser_peek_token (parser)->value;
8365 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8366 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8368 /* A diagnostic is not required for the use of this identifier in
8369 the implementation namespace; only diagnose it for the C11
8370 spelling because of existing code using the other spellings. */
8374 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8377 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8380 c_parser_consume_token (parser);
8381 c_inhibit_evaluation_warnings++;
8383 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8384 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8386 /* Either __alignof__ ( type-name ) or __alignof__
8387 unary-expression starting with a compound literal. */
8389 struct c_type_name *type_name;
8391 matching_parens parens;
8392 parens.consume_open (parser);
8393 loc = c_parser_peek_token (parser)->location;
8394 type_name = c_parser_type_name (parser, true);
8395 end_loc = c_parser_peek_token (parser)->location;
8396 parens.skip_until_found_close (parser);
8397 if (type_name == NULL)
8400 c_inhibit_evaluation_warnings--;
8403 ret.original_code = ERROR_MARK;
8404 ret.original_type = NULL;
8407 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8409 expr = c_parser_postfix_expression_after_paren_type (parser,
8414 /* alignof ( type-name ). */
8415 if (type_name->specs->alignas_p)
8416 error_at (type_name->specs->locations[cdw_alignas],
8417 "alignment specified for type name in %qE",
8419 c_inhibit_evaluation_warnings--;
8421 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8423 false, is_c11_alignof, 1);
8424 ret.original_code = ERROR_MARK;
8425 ret.original_type = NULL;
8426 set_c_expr_source_range (&ret, start_loc, end_loc);
8432 expr = c_parser_unary_expression (parser);
8433 end_loc = expr.src_range.m_finish;
8435 mark_exp_read (expr.value);
8436 c_inhibit_evaluation_warnings--;
8440 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8442 ret.value = c_alignof_expr (start_loc, expr.value);
8443 ret.original_code = ERROR_MARK;
8444 ret.original_type = NULL;
8445 set_c_expr_source_range (&ret, start_loc, end_loc);
8450 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8453 static struct c_expr
8454 c_parser_has_attribute_expression (c_parser *parser)
8456 gcc_assert (c_parser_next_token_is_keyword (parser,
8457 RID_BUILTIN_HAS_ATTRIBUTE));
8458 c_parser_consume_token (parser);
8460 c_inhibit_evaluation_warnings++;
8462 matching_parens parens;
8463 if (!parens.require_open (parser))
8465 c_inhibit_evaluation_warnings--;
8468 struct c_expr result;
8469 result.set_error ();
8470 result.original_code = ERROR_MARK;
8471 result.original_type = NULL;
8475 /* Treat the type argument the same way as in typeof for the purposes
8476 of warnings. FIXME: Generalize this so the warning refers to
8477 __builtin_has_attribute rather than typeof. */
8480 /* The first operand: one of DECL, EXPR, or TYPE. */
8481 tree oper = NULL_TREE;
8482 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8484 struct c_type_name *tname = c_parser_type_name (parser);
8488 oper = groktypename (tname, NULL, NULL);
8489 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8494 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8495 c_inhibit_evaluation_warnings--;
8497 if (cexpr.value != error_mark_node)
8499 mark_exp_read (cexpr.value);
8501 tree etype = TREE_TYPE (oper);
8502 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8503 /* This is returned with the type so that when the type is
8504 evaluated, this can be evaluated. */
8506 oper = c_fully_fold (oper, false, NULL);
8507 pop_maybe_used (was_vm);
8511 struct c_expr result;
8512 result.original_code = ERROR_MARK;
8513 result.original_type = NULL;
8515 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8517 /* Consume the closing parenthesis if that's the next token
8518 in the likely case the built-in was invoked with fewer
8519 than two arguments. */
8520 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8521 c_parser_consume_token (parser);
8522 c_inhibit_evaluation_warnings--;
8523 result.set_error ();
8527 bool save_translate_strings_p = parser->translate_strings_p;
8529 location_t atloc = c_parser_peek_token (parser)->location;
8530 /* Parse a single attribute. Require no leading comma and do not
8531 allow empty attributes. */
8532 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8534 parser->translate_strings_p = save_translate_strings_p;
8536 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8537 c_parser_consume_token (parser);
8540 c_parser_error (parser, "expected identifier");
8541 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8543 result.set_error ();
8549 error_at (atloc, "expected identifier");
8550 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8552 result.set_error ();
8556 result.original_code = INTEGER_CST;
8557 result.original_type = boolean_type_node;
8559 if (has_attribute (atloc, oper, attr, default_conversion))
8560 result.value = boolean_true_node;
8562 result.value = boolean_false_node;
8567 /* Helper function to read arguments of builtins which are interfaces
8568 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8569 others. The name of the builtin is passed using BNAME parameter.
8570 Function returns true if there were no errors while parsing and
8571 stores the arguments in CEXPR_LIST. If it returns true,
8572 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8575 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8576 vec<c_expr_t, va_gc> **ret_cexpr_list,
8578 location_t *out_close_paren_loc)
8580 location_t loc = c_parser_peek_token (parser)->location;
8581 vec<c_expr_t, va_gc> *cexpr_list;
8583 bool saved_force_folding_builtin_constant_p;
8585 *ret_cexpr_list = NULL;
8586 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8588 error_at (loc, "cannot take address of %qs", bname);
8592 c_parser_consume_token (parser);
8594 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8596 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8597 c_parser_consume_token (parser);
8601 saved_force_folding_builtin_constant_p
8602 = force_folding_builtin_constant_p;
8603 force_folding_builtin_constant_p |= choose_expr_p;
8604 expr = c_parser_expr_no_commas (parser, NULL);
8605 force_folding_builtin_constant_p
8606 = saved_force_folding_builtin_constant_p;
8607 vec_alloc (cexpr_list, 1);
8608 vec_safe_push (cexpr_list, expr);
8609 while (c_parser_next_token_is (parser, CPP_COMMA))
8611 c_parser_consume_token (parser);
8612 expr = c_parser_expr_no_commas (parser, NULL);
8613 vec_safe_push (cexpr_list, expr);
8616 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8617 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8620 *ret_cexpr_list = cexpr_list;
8624 /* This represents a single generic-association. */
8626 struct c_generic_association
8628 /* The location of the starting token of the type. */
8629 location_t type_location;
8630 /* The association's type, or NULL_TREE for 'default'. */
8632 /* The association's expression. */
8633 struct c_expr expression;
8636 /* Parse a generic-selection. (C11 6.5.1.1).
8639 _Generic ( assignment-expression , generic-assoc-list )
8643 generic-assoc-list , generic-association
8645 generic-association:
8646 type-name : assignment-expression
8647 default : assignment-expression
8650 static struct c_expr
8651 c_parser_generic_selection (c_parser *parser)
8653 struct c_expr selector, error_expr;
8655 struct c_generic_association matched_assoc;
8656 bool match_found = false;
8657 location_t generic_loc, selector_loc;
8659 error_expr.original_code = ERROR_MARK;
8660 error_expr.original_type = NULL;
8661 error_expr.set_error ();
8662 matched_assoc.type_location = UNKNOWN_LOCATION;
8663 matched_assoc.type = NULL_TREE;
8664 matched_assoc.expression = error_expr;
8666 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8667 generic_loc = c_parser_peek_token (parser)->location;
8668 c_parser_consume_token (parser);
8670 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8671 "ISO C99 does not support %<_Generic%>");
8673 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8674 "ISO C90 does not support %<_Generic%>");
8676 matching_parens parens;
8677 if (!parens.require_open (parser))
8680 c_inhibit_evaluation_warnings++;
8681 selector_loc = c_parser_peek_token (parser)->location;
8682 selector = c_parser_expr_no_commas (parser, NULL);
8683 selector = default_function_array_conversion (selector_loc, selector);
8684 c_inhibit_evaluation_warnings--;
8686 if (selector.value == error_mark_node)
8688 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8691 selector_type = TREE_TYPE (selector.value);
8692 /* In ISO C terms, rvalues (including the controlling expression of
8693 _Generic) do not have qualified types. */
8694 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8695 selector_type = TYPE_MAIN_VARIANT (selector_type);
8696 /* In ISO C terms, _Noreturn is not part of the type of expressions
8697 such as &abort, but in GCC it is represented internally as a type
8699 if (FUNCTION_POINTER_TYPE_P (selector_type)
8700 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8702 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8704 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8706 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8710 auto_vec<c_generic_association> associations;
8713 struct c_generic_association assoc, *iter;
8715 c_token *token = c_parser_peek_token (parser);
8717 assoc.type_location = token->location;
8718 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8720 c_parser_consume_token (parser);
8721 assoc.type = NULL_TREE;
8725 struct c_type_name *type_name;
8727 type_name = c_parser_type_name (parser);
8728 if (type_name == NULL)
8730 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8733 assoc.type = groktypename (type_name, NULL, NULL);
8734 if (assoc.type == error_mark_node)
8736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8740 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8741 error_at (assoc.type_location,
8742 "%<_Generic%> association has function type");
8743 else if (!COMPLETE_TYPE_P (assoc.type))
8744 error_at (assoc.type_location,
8745 "%<_Generic%> association has incomplete type");
8747 if (variably_modified_type_p (assoc.type, NULL_TREE))
8748 error_at (assoc.type_location,
8749 "%<_Generic%> association has "
8750 "variable length type");
8753 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8755 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8759 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8760 if (assoc.expression.value == error_mark_node)
8762 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8766 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8768 if (assoc.type == NULL_TREE)
8770 if (iter->type == NULL_TREE)
8772 error_at (assoc.type_location,
8773 "duplicate %<default%> case in %<_Generic%>");
8774 inform (iter->type_location, "original %<default%> is here");
8777 else if (iter->type != NULL_TREE)
8779 if (comptypes (assoc.type, iter->type))
8781 error_at (assoc.type_location,
8782 "%<_Generic%> specifies two compatible types");
8783 inform (iter->type_location, "compatible type is here");
8788 if (assoc.type == NULL_TREE)
8792 matched_assoc = assoc;
8796 else if (comptypes (assoc.type, selector_type))
8798 if (!match_found || matched_assoc.type == NULL_TREE)
8800 matched_assoc = assoc;
8805 error_at (assoc.type_location,
8806 "%<_Generic%> selector matches multiple associations");
8807 inform (matched_assoc.type_location,
8808 "other match is here");
8812 associations.safe_push (assoc);
8814 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8816 c_parser_consume_token (parser);
8819 if (!parens.require_close (parser))
8821 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8827 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8828 "compatible with any association",
8833 return matched_assoc.expression;
8836 /* Check the validity of a function pointer argument *EXPR (argument
8837 position POS) to __builtin_tgmath. Return the number of function
8838 arguments if possibly valid; return 0 having reported an error if
8842 check_tgmath_function (c_expr *expr, unsigned int pos)
8844 tree type = TREE_TYPE (expr->value);
8845 if (!FUNCTION_POINTER_TYPE_P (type))
8847 error_at (expr->get_location (),
8848 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8852 type = TREE_TYPE (type);
8853 if (!prototype_p (type))
8855 error_at (expr->get_location (),
8856 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8859 if (stdarg_p (type))
8861 error_at (expr->get_location (),
8862 "argument %u of %<__builtin_tgmath%> has variable arguments",
8866 unsigned int nargs = 0;
8867 function_args_iterator iter;
8869 FOREACH_FUNCTION_ARGS (type, t, iter)
8871 if (t == void_type_node)
8877 error_at (expr->get_location (),
8878 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8884 /* Ways in which a parameter or return value of a type-generic macro
8885 may vary between the different functions the macro may call. */
8886 enum tgmath_parm_kind
8888 tgmath_fixed, tgmath_real, tgmath_complex
8891 /* Helper function for c_parser_postfix_expression. Parse predefined
8894 static struct c_expr
8895 c_parser_predefined_identifier (c_parser *parser)
8897 location_t loc = c_parser_peek_token (parser)->location;
8898 switch (c_parser_peek_token (parser)->keyword)
8900 case RID_FUNCTION_NAME:
8901 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8902 "identifier", "__FUNCTION__");
8904 case RID_PRETTY_FUNCTION_NAME:
8905 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8906 "identifier", "__PRETTY_FUNCTION__");
8908 case RID_C99_FUNCTION_NAME:
8909 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8910 "%<__func__%> predefined identifier");
8917 expr.original_code = ERROR_MARK;
8918 expr.original_type = NULL;
8919 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8920 c_parser_peek_token (parser)->value);
8921 set_c_expr_source_range (&expr, loc, loc);
8922 c_parser_consume_token (parser);
8926 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8927 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8928 call c_parser_postfix_expression_after_paren_type on encountering them.
8932 postfix-expression [ expression ]
8933 postfix-expression ( argument-expression-list[opt] )
8934 postfix-expression . identifier
8935 postfix-expression -> identifier
8936 postfix-expression ++
8937 postfix-expression --
8938 ( type-name ) { initializer-list }
8939 ( type-name ) { initializer-list , }
8941 argument-expression-list:
8943 argument-expression-list , argument-expression
8956 (treated as a keyword in GNU C)
8959 ( compound-statement )
8960 __builtin_va_arg ( assignment-expression , type-name )
8961 __builtin_offsetof ( type-name , offsetof-member-designator )
8962 __builtin_choose_expr ( assignment-expression ,
8963 assignment-expression ,
8964 assignment-expression )
8965 __builtin_types_compatible_p ( type-name , type-name )
8966 __builtin_tgmath ( expr-list )
8967 __builtin_complex ( assignment-expression , assignment-expression )
8968 __builtin_shuffle ( assignment-expression , assignment-expression )
8969 __builtin_shuffle ( assignment-expression ,
8970 assignment-expression ,
8971 assignment-expression, )
8972 __builtin_convertvector ( assignment-expression , type-name )
8974 offsetof-member-designator:
8976 offsetof-member-designator . identifier
8977 offsetof-member-designator [ expression ]
8982 [ objc-receiver objc-message-args ]
8983 @selector ( objc-selector-arg )
8984 @protocol ( identifier )
8985 @encode ( type-name )
8987 Classname . identifier
8990 static struct c_expr
8991 c_parser_postfix_expression (c_parser *parser)
8993 struct c_expr expr, e1;
8994 struct c_type_name *t1, *t2;
8995 location_t loc = c_parser_peek_token (parser)->location;
8996 source_range tok_range = c_parser_peek_token (parser)->get_range ();
8997 expr.original_code = ERROR_MARK;
8998 expr.original_type = NULL;
8999 switch (c_parser_peek_token (parser)->type)
9002 expr.value = c_parser_peek_token (parser)->value;
9003 set_c_expr_source_range (&expr, tok_range);
9004 loc = c_parser_peek_token (parser)->location;
9005 c_parser_consume_token (parser);
9006 if (TREE_CODE (expr.value) == FIXED_CST
9007 && !targetm.fixed_point_supported_p ())
9009 error_at (loc, "fixed-point types not supported for this target");
9018 expr.value = c_parser_peek_token (parser)->value;
9019 /* For the purpose of warning when a pointer is compared with
9020 a zero character constant. */
9021 expr.original_type = char_type_node;
9022 set_c_expr_source_range (&expr, tok_range);
9023 c_parser_consume_token (parser);
9029 case CPP_UTF8STRING:
9030 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9033 case CPP_OBJC_STRING:
9034 gcc_assert (c_dialect_objc ());
9036 = objc_build_string_object (c_parser_peek_token (parser)->value);
9037 set_c_expr_source_range (&expr, tok_range);
9038 c_parser_consume_token (parser);
9041 switch (c_parser_peek_token (parser)->id_kind)
9045 tree id = c_parser_peek_token (parser)->value;
9046 c_parser_consume_token (parser);
9047 expr.value = build_external_ref (loc, id,
9048 (c_parser_peek_token (parser)->type
9050 &expr.original_type);
9051 set_c_expr_source_range (&expr, tok_range);
9054 case C_ID_CLASSNAME:
9056 /* Here we parse the Objective-C 2.0 Class.name dot
9058 tree class_name = c_parser_peek_token (parser)->value;
9060 c_parser_consume_token (parser);
9061 gcc_assert (c_dialect_objc ());
9062 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9067 if (c_parser_next_token_is_not (parser, CPP_NAME))
9069 c_parser_error (parser, "expected identifier");
9073 c_token *component_tok = c_parser_peek_token (parser);
9074 component = component_tok->value;
9075 location_t end_loc = component_tok->get_finish ();
9076 c_parser_consume_token (parser);
9077 expr.value = objc_build_class_component_ref (class_name,
9079 set_c_expr_source_range (&expr, loc, end_loc);
9083 c_parser_error (parser, "expected expression");
9088 case CPP_OPEN_PAREN:
9089 /* A parenthesized expression, statement expression or compound
9091 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9093 /* A statement expression. */
9095 location_t brace_loc;
9096 c_parser_consume_token (parser);
9097 brace_loc = c_parser_peek_token (parser)->location;
9098 c_parser_consume_token (parser);
9099 /* If we've not yet started the current function's statement list,
9100 or we're in the parameter scope of an old-style function
9101 declaration, statement expressions are not allowed. */
9102 if (!building_stmt_list_p () || old_style_parameter_scope ())
9104 error_at (loc, "braced-group within expression allowed "
9105 "only inside a function");
9106 parser->error = true;
9107 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9108 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9112 stmt = c_begin_stmt_expr ();
9113 c_parser_compound_statement_nostart (parser);
9114 location_t close_loc = c_parser_peek_token (parser)->location;
9115 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9117 pedwarn (loc, OPT_Wpedantic,
9118 "ISO C forbids braced-groups within expressions");
9119 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9120 set_c_expr_source_range (&expr, loc, close_loc);
9121 mark_exp_read (expr.value);
9125 /* A parenthesized expression. */
9126 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9127 c_parser_consume_token (parser);
9128 expr = c_parser_expression (parser);
9129 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9130 TREE_NO_WARNING (expr.value) = 1;
9131 if (expr.original_code != C_MAYBE_CONST_EXPR
9132 && expr.original_code != SIZEOF_EXPR)
9133 expr.original_code = ERROR_MARK;
9134 /* Don't change EXPR.ORIGINAL_TYPE. */
9135 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9136 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9137 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9138 "expected %<)%>", loc_open_paren);
9142 switch (c_parser_peek_token (parser)->keyword)
9144 case RID_FUNCTION_NAME:
9145 case RID_PRETTY_FUNCTION_NAME:
9146 case RID_C99_FUNCTION_NAME:
9147 expr = c_parser_predefined_identifier (parser);
9151 location_t start_loc = loc;
9152 c_parser_consume_token (parser);
9153 matching_parens parens;
9154 if (!parens.require_open (parser))
9159 e1 = c_parser_expr_no_commas (parser, NULL);
9160 mark_exp_read (e1.value);
9161 e1.value = c_fully_fold (e1.value, false, NULL);
9162 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9164 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9168 loc = c_parser_peek_token (parser)->location;
9169 t1 = c_parser_type_name (parser);
9170 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9171 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9179 tree type_expr = NULL_TREE;
9180 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9181 groktypename (t1, &type_expr, NULL));
9184 expr.value = build2 (C_MAYBE_CONST_EXPR,
9185 TREE_TYPE (expr.value), type_expr,
9187 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9189 set_c_expr_source_range (&expr, start_loc, end_loc);
9195 c_parser_consume_token (parser);
9196 matching_parens parens;
9197 if (!parens.require_open (parser))
9202 t1 = c_parser_type_name (parser);
9204 parser->error = true;
9205 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9206 gcc_assert (parser->error);
9209 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9213 tree type = groktypename (t1, NULL, NULL);
9215 if (type == error_mark_node)
9216 offsetof_ref = error_mark_node;
9219 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9220 SET_EXPR_LOCATION (offsetof_ref, loc);
9222 /* Parse the second argument to __builtin_offsetof. We
9223 must have one identifier, and beyond that we want to
9224 accept sub structure and sub array references. */
9225 if (c_parser_next_token_is (parser, CPP_NAME))
9227 c_token *comp_tok = c_parser_peek_token (parser);
9228 offsetof_ref = build_component_ref
9229 (loc, offsetof_ref, comp_tok->value, comp_tok->location);
9230 c_parser_consume_token (parser);
9231 while (c_parser_next_token_is (parser, CPP_DOT)
9232 || c_parser_next_token_is (parser,
9234 || c_parser_next_token_is (parser,
9237 if (c_parser_next_token_is (parser, CPP_DEREF))
9239 loc = c_parser_peek_token (parser)->location;
9240 offsetof_ref = build_array_ref (loc,
9245 else if (c_parser_next_token_is (parser, CPP_DOT))
9248 c_parser_consume_token (parser);
9249 if (c_parser_next_token_is_not (parser,
9252 c_parser_error (parser, "expected identifier");
9255 c_token *comp_tok = c_parser_peek_token (parser);
9256 offsetof_ref = build_component_ref
9257 (loc, offsetof_ref, comp_tok->value,
9258 comp_tok->location);
9259 c_parser_consume_token (parser);
9265 loc = c_parser_peek_token (parser)->location;
9266 c_parser_consume_token (parser);
9267 ce = c_parser_expression (parser);
9268 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9270 idx = c_fully_fold (idx, false, NULL);
9271 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9273 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9278 c_parser_error (parser, "expected identifier");
9279 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9280 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9282 expr.value = fold_offsetof (offsetof_ref);
9283 set_c_expr_source_range (&expr, loc, end_loc);
9286 case RID_CHOOSE_EXPR:
9288 vec<c_expr_t, va_gc> *cexpr_list;
9289 c_expr_t *e1_p, *e2_p, *e3_p;
9291 location_t close_paren_loc;
9293 c_parser_consume_token (parser);
9294 if (!c_parser_get_builtin_args (parser,
9295 "__builtin_choose_expr",
9303 if (vec_safe_length (cexpr_list) != 3)
9305 error_at (loc, "wrong number of arguments to "
9306 "%<__builtin_choose_expr%>");
9311 e1_p = &(*cexpr_list)[0];
9312 e2_p = &(*cexpr_list)[1];
9313 e3_p = &(*cexpr_list)[2];
9316 mark_exp_read (e2_p->value);
9317 mark_exp_read (e3_p->value);
9318 if (TREE_CODE (c) != INTEGER_CST
9319 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9321 "first argument to %<__builtin_choose_expr%> not"
9323 constant_expression_warning (c);
9324 expr = integer_zerop (c) ? *e3_p : *e2_p;
9325 set_c_expr_source_range (&expr, loc, close_paren_loc);
9328 case RID_TYPES_COMPATIBLE_P:
9330 c_parser_consume_token (parser);
9331 matching_parens parens;
9332 if (!parens.require_open (parser))
9337 t1 = c_parser_type_name (parser);
9343 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9345 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9349 t2 = c_parser_type_name (parser);
9355 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9356 parens.skip_until_found_close (parser);
9358 e1 = groktypename (t1, NULL, NULL);
9359 e2 = groktypename (t2, NULL, NULL);
9360 if (e1 == error_mark_node || e2 == error_mark_node)
9366 e1 = TYPE_MAIN_VARIANT (e1);
9367 e2 = TYPE_MAIN_VARIANT (e2);
9370 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9371 set_c_expr_source_range (&expr, loc, close_paren_loc);
9374 case RID_BUILTIN_TGMATH:
9376 vec<c_expr_t, va_gc> *cexpr_list;
9377 location_t close_paren_loc;
9379 c_parser_consume_token (parser);
9380 if (!c_parser_get_builtin_args (parser,
9389 if (vec_safe_length (cexpr_list) < 3)
9391 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9398 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9399 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9400 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9406 if (vec_safe_length (cexpr_list) < nargs)
9408 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9412 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9413 if (num_functions < 2)
9415 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9420 /* The first NUM_FUNCTIONS expressions are the function
9421 pointers. The remaining NARGS expressions are the
9422 arguments that are to be passed to one of those
9423 functions, chosen following <tgmath.h> rules. */
9424 for (unsigned int j = 1; j < num_functions; j++)
9426 unsigned int this_nargs
9427 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9428 if (this_nargs == 0)
9433 if (this_nargs != nargs)
9435 error_at ((*cexpr_list)[j].get_location (),
9436 "argument %u of %<__builtin_tgmath%> has "
9437 "wrong number of arguments", j + 1);
9443 /* The functions all have the same number of arguments.
9444 Determine whether arguments and return types vary in
9445 ways permitted for <tgmath.h> functions. */
9446 /* The first entry in each of these vectors is for the
9447 return type, subsequent entries for parameter
9449 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9450 auto_vec<tree> parm_first (nargs + 1);
9451 auto_vec<bool> parm_complex (nargs + 1);
9452 auto_vec<bool> parm_varies (nargs + 1);
9453 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9454 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9455 parm_first.quick_push (first_ret);
9456 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9457 parm_varies.quick_push (false);
9458 function_args_iterator iter;
9460 unsigned int argpos;
9461 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9463 if (t == void_type_node)
9465 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9466 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9467 parm_varies.quick_push (false);
9469 for (unsigned int j = 1; j < num_functions; j++)
9471 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9472 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9473 if (ret != parm_first[0])
9475 parm_varies[0] = true;
9476 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9477 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9479 error_at ((*cexpr_list)[0].get_location (),
9480 "invalid type-generic return type for "
9481 "argument %u of %<__builtin_tgmath%>",
9486 if (!SCALAR_FLOAT_TYPE_P (ret)
9487 && !COMPLEX_FLOAT_TYPE_P (ret))
9489 error_at ((*cexpr_list)[j].get_location (),
9490 "invalid type-generic return type for "
9491 "argument %u of %<__builtin_tgmath%>",
9497 if (TREE_CODE (ret) == COMPLEX_TYPE)
9498 parm_complex[0] = true;
9500 FOREACH_FUNCTION_ARGS (type, t, iter)
9502 if (t == void_type_node)
9504 t = TYPE_MAIN_VARIANT (t);
9505 if (t != parm_first[argpos])
9507 parm_varies[argpos] = true;
9508 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9509 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9511 error_at ((*cexpr_list)[0].get_location (),
9512 "invalid type-generic type for "
9513 "argument %u of argument %u of "
9514 "%<__builtin_tgmath%>", argpos, 1);
9518 if (!SCALAR_FLOAT_TYPE_P (t)
9519 && !COMPLEX_FLOAT_TYPE_P (t))
9521 error_at ((*cexpr_list)[j].get_location (),
9522 "invalid type-generic type for "
9523 "argument %u of argument %u of "
9524 "%<__builtin_tgmath%>", argpos, j + 1);
9529 if (TREE_CODE (t) == COMPLEX_TYPE)
9530 parm_complex[argpos] = true;
9534 enum tgmath_parm_kind max_variation = tgmath_fixed;
9535 for (unsigned int j = 0; j <= nargs; j++)
9537 enum tgmath_parm_kind this_kind;
9540 if (parm_complex[j])
9541 max_variation = this_kind = tgmath_complex;
9544 this_kind = tgmath_real;
9545 if (max_variation != tgmath_complex)
9546 max_variation = tgmath_real;
9550 this_kind = tgmath_fixed;
9551 parm_kind.quick_push (this_kind);
9553 if (max_variation == tgmath_fixed)
9555 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9556 "all have the same type");
9561 /* Identify a parameter (not the return type) that varies,
9562 including with complex types if any variation includes
9563 complex types; there must be at least one such
9565 unsigned int tgarg = 0;
9566 for (unsigned int j = 1; j <= nargs; j++)
9567 if (parm_kind[j] == max_variation)
9574 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9575 "lack type-generic parameter");
9580 /* Determine the type of the relevant parameter for each
9582 auto_vec<tree> tg_type (num_functions);
9583 for (unsigned int j = 0; j < num_functions; j++)
9585 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9587 FOREACH_FUNCTION_ARGS (type, t, iter)
9589 if (argpos == tgarg)
9591 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9598 /* Verify that the corresponding types are different for
9599 all the listed functions. Also determine whether all
9600 the types are complex, whether all the types are
9601 standard or binary, and whether all the types are
9603 bool all_complex = true;
9604 bool all_binary = true;
9605 bool all_decimal = true;
9606 hash_set<tree> tg_types;
9607 FOR_EACH_VEC_ELT (tg_type, i, t)
9609 if (TREE_CODE (t) == COMPLEX_TYPE)
9610 all_decimal = false;
9613 all_complex = false;
9614 if (DECIMAL_FLOAT_TYPE_P (t))
9617 all_decimal = false;
9619 if (tg_types.add (t))
9621 error_at ((*cexpr_list)[i].get_location (),
9622 "duplicate type-generic parameter type for "
9623 "function argument %u of %<__builtin_tgmath%>",
9630 /* Verify that other parameters and the return type whose
9631 types vary have their types varying in the correct
9633 for (unsigned int j = 0; j < num_functions; j++)
9635 tree exp_type = tg_type[j];
9636 tree exp_real_type = exp_type;
9637 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9638 exp_real_type = TREE_TYPE (exp_type);
9639 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9640 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9641 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9642 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9644 error_at ((*cexpr_list)[j].get_location (),
9645 "bad return type for function argument %u "
9646 "of %<__builtin_tgmath%>", j + 1);
9651 FOREACH_FUNCTION_ARGS (type, t, iter)
9653 if (t == void_type_node)
9655 t = TYPE_MAIN_VARIANT (t);
9656 if ((parm_kind[argpos] == tgmath_complex
9658 || (parm_kind[argpos] == tgmath_real
9659 && t != exp_real_type))
9661 error_at ((*cexpr_list)[j].get_location (),
9662 "bad type for argument %u of "
9663 "function argument %u of "
9664 "%<__builtin_tgmath%>", argpos, j + 1);
9672 /* The functions listed are a valid set of functions for a
9673 <tgmath.h> macro to select between. Identify the
9674 matching function, if any. First, the argument types
9675 must be combined following <tgmath.h> rules. Integer
9676 types are treated as _Decimal64 if any type-generic
9677 argument is decimal, or if the only alternatives for
9678 type-generic arguments are of decimal types, and are
9679 otherwise treated as double (or _Complex double for
9680 complex integer types, or _Float64 or _Complex _Float64
9681 if all the return types are the same _FloatN or
9682 _FloatNx type). After that adjustment, types are
9683 combined following the usual arithmetic conversions.
9684 If the function only accepts complex arguments, a
9685 complex type is produced. */
9686 bool arg_complex = all_complex;
9687 bool arg_binary = all_binary;
9688 bool arg_int_decimal = all_decimal;
9689 for (unsigned int j = 1; j <= nargs; j++)
9691 if (parm_kind[j] == tgmath_fixed)
9693 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9694 tree type = TREE_TYPE (ce->value);
9695 if (!INTEGRAL_TYPE_P (type)
9696 && !SCALAR_FLOAT_TYPE_P (type)
9697 && TREE_CODE (type) != COMPLEX_TYPE)
9699 error_at (ce->get_location (),
9700 "invalid type of argument %u of type-generic "
9705 if (DECIMAL_FLOAT_TYPE_P (type))
9707 arg_int_decimal = true;
9710 error_at (ce->get_location (),
9711 "decimal floating-point argument %u to "
9712 "complex-only type-generic function", j);
9716 else if (all_binary)
9718 error_at (ce->get_location (),
9719 "decimal floating-point argument %u to "
9720 "binary-only type-generic function", j);
9724 else if (arg_complex)
9726 error_at (ce->get_location (),
9727 "both complex and decimal floating-point "
9728 "arguments to type-generic function");
9732 else if (arg_binary)
9734 error_at (ce->get_location (),
9735 "both binary and decimal floating-point "
9736 "arguments to type-generic function");
9741 else if (TREE_CODE (type) == COMPLEX_TYPE)
9744 if (COMPLEX_FLOAT_TYPE_P (type))
9748 error_at (ce->get_location (),
9749 "complex argument %u to "
9750 "decimal-only type-generic function", j);
9754 else if (arg_int_decimal)
9756 error_at (ce->get_location (),
9757 "both complex and decimal floating-point "
9758 "arguments to type-generic function");
9763 else if (SCALAR_FLOAT_TYPE_P (type))
9768 error_at (ce->get_location (),
9769 "binary argument %u to "
9770 "decimal-only type-generic function", j);
9774 else if (arg_int_decimal)
9776 error_at (ce->get_location (),
9777 "both binary and decimal floating-point "
9778 "arguments to type-generic function");
9784 /* For a macro rounding its result to a narrower type, map
9785 integer types to _Float64 not double if the return type
9786 is a _FloatN or _FloatNx type. */
9787 bool arg_int_float64 = false;
9788 if (parm_kind[0] == tgmath_fixed
9789 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9790 && float64_type_node != NULL_TREE)
9791 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9792 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9794 arg_int_float64 = true;
9797 tree arg_real = NULL_TREE;
9798 for (unsigned int j = 1; j <= nargs; j++)
9800 if (parm_kind[j] == tgmath_fixed)
9802 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9803 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9804 if (TREE_CODE (type) == COMPLEX_TYPE)
9805 type = TREE_TYPE (type);
9806 if (INTEGRAL_TYPE_P (type))
9807 type = (arg_int_decimal
9808 ? dfloat64_type_node
9811 : double_type_node);
9812 if (arg_real == NULL_TREE)
9815 arg_real = common_type (arg_real, type);
9816 if (arg_real == error_mark_node)
9822 tree arg_type = (arg_complex
9823 ? build_complex_type (arg_real)
9826 /* Look for a function to call with type-generic parameter
9828 c_expr_t *fn = NULL;
9829 for (unsigned int j = 0; j < num_functions; j++)
9831 if (tg_type[j] == arg_type)
9833 fn = &(*cexpr_list)[j];
9838 && parm_kind[0] == tgmath_fixed
9839 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9841 /* Presume this is a macro that rounds its result to a
9842 narrower type, and look for the first function with
9843 at least the range and precision of the argument
9845 for (unsigned int j = 0; j < num_functions; j++)
9848 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9850 tree real_tg_type = (arg_complex
9851 ? TREE_TYPE (tg_type[j])
9853 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9854 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9856 scalar_float_mode arg_mode
9857 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9858 scalar_float_mode tg_mode
9859 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9860 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9861 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9862 if (arg_fmt->b == tg_fmt->b
9863 && arg_fmt->p <= tg_fmt->p
9864 && arg_fmt->emax <= tg_fmt->emax
9865 && (arg_fmt->emin - arg_fmt->p
9866 >= tg_fmt->emin - tg_fmt->p))
9868 fn = &(*cexpr_list)[j];
9875 error_at (loc, "no matching function for type-generic call");
9880 /* Construct a call to FN. */
9881 vec<tree, va_gc> *args;
9882 vec_alloc (args, nargs);
9883 vec<tree, va_gc> *origtypes;
9884 vec_alloc (origtypes, nargs);
9885 auto_vec<location_t> arg_loc (nargs);
9886 for (unsigned int j = 0; j < nargs; j++)
9888 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9889 args->quick_push (ce->value);
9890 arg_loc.quick_push (ce->get_location ());
9891 origtypes->quick_push (ce->original_type);
9893 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9895 set_c_expr_source_range (&expr, loc, close_paren_loc);
9898 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9900 vec<c_expr_t, va_gc> *cexpr_list;
9903 location_t close_paren_loc;
9905 c_parser_consume_token (parser);
9906 if (!c_parser_get_builtin_args (parser,
9907 "__builtin_call_with_static_chain",
9914 if (vec_safe_length (cexpr_list) != 2)
9916 error_at (loc, "wrong number of arguments to "
9917 "%<__builtin_call_with_static_chain%>");
9922 expr = (*cexpr_list)[0];
9923 e2_p = &(*cexpr_list)[1];
9924 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9925 chain_value = e2_p->value;
9926 mark_exp_read (chain_value);
9928 if (TREE_CODE (expr.value) != CALL_EXPR)
9929 error_at (loc, "first argument to "
9930 "%<__builtin_call_with_static_chain%> "
9931 "must be a call expression");
9932 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9933 error_at (loc, "second argument to "
9934 "%<__builtin_call_with_static_chain%> "
9935 "must be a pointer type");
9937 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9938 set_c_expr_source_range (&expr, loc, close_paren_loc);
9941 case RID_BUILTIN_COMPLEX:
9943 vec<c_expr_t, va_gc> *cexpr_list;
9944 c_expr_t *e1_p, *e2_p;
9945 location_t close_paren_loc;
9947 c_parser_consume_token (parser);
9948 if (!c_parser_get_builtin_args (parser,
9949 "__builtin_complex",
9957 if (vec_safe_length (cexpr_list) != 2)
9959 error_at (loc, "wrong number of arguments to "
9960 "%<__builtin_complex%>");
9965 e1_p = &(*cexpr_list)[0];
9966 e2_p = &(*cexpr_list)[1];
9968 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9969 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9970 e1_p->value = convert (TREE_TYPE (e1_p->value),
9971 TREE_OPERAND (e1_p->value, 0));
9972 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9973 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9974 e2_p->value = convert (TREE_TYPE (e2_p->value),
9975 TREE_OPERAND (e2_p->value, 0));
9976 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9977 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9978 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9979 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9981 error_at (loc, "%<__builtin_complex%> operand "
9982 "not of real binary floating-point type");
9986 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
9987 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
9990 "%<__builtin_complex%> operands of different types");
9994 pedwarn_c90 (loc, OPT_Wpedantic,
9995 "ISO C90 does not support complex types");
9996 expr.value = build2_loc (loc, COMPLEX_EXPR,
9999 (TREE_TYPE (e1_p->value))),
10000 e1_p->value, e2_p->value);
10001 set_c_expr_source_range (&expr, loc, close_paren_loc);
10004 case RID_BUILTIN_SHUFFLE:
10006 vec<c_expr_t, va_gc> *cexpr_list;
10009 location_t close_paren_loc;
10011 c_parser_consume_token (parser);
10012 if (!c_parser_get_builtin_args (parser,
10013 "__builtin_shuffle",
10014 &cexpr_list, false,
10021 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10022 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10024 if (vec_safe_length (cexpr_list) == 2)
10025 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10027 (*cexpr_list)[1].value);
10029 else if (vec_safe_length (cexpr_list) == 3)
10030 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10031 (*cexpr_list)[1].value,
10032 (*cexpr_list)[2].value);
10035 error_at (loc, "wrong number of arguments to "
10036 "%<__builtin_shuffle%>");
10039 set_c_expr_source_range (&expr, loc, close_paren_loc);
10042 case RID_BUILTIN_CONVERTVECTOR:
10044 location_t start_loc = loc;
10045 c_parser_consume_token (parser);
10046 matching_parens parens;
10047 if (!parens.require_open (parser))
10052 e1 = c_parser_expr_no_commas (parser, NULL);
10053 mark_exp_read (e1.value);
10054 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10056 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10060 loc = c_parser_peek_token (parser)->location;
10061 t1 = c_parser_type_name (parser);
10062 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10063 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10069 tree type_expr = NULL_TREE;
10070 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10071 groktypename (t1, &type_expr,
10073 set_c_expr_source_range (&expr, start_loc, end_loc);
10077 case RID_AT_SELECTOR:
10079 gcc_assert (c_dialect_objc ());
10080 c_parser_consume_token (parser);
10081 matching_parens parens;
10082 if (!parens.require_open (parser))
10087 tree sel = c_parser_objc_selector_arg (parser);
10088 location_t close_loc = c_parser_peek_token (parser)->location;
10089 parens.skip_until_found_close (parser);
10090 expr.value = objc_build_selector_expr (loc, sel);
10091 set_c_expr_source_range (&expr, loc, close_loc);
10094 case RID_AT_PROTOCOL:
10096 gcc_assert (c_dialect_objc ());
10097 c_parser_consume_token (parser);
10098 matching_parens parens;
10099 if (!parens.require_open (parser))
10104 if (c_parser_next_token_is_not (parser, CPP_NAME))
10106 c_parser_error (parser, "expected identifier");
10107 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10111 tree id = c_parser_peek_token (parser)->value;
10112 c_parser_consume_token (parser);
10113 location_t close_loc = c_parser_peek_token (parser)->location;
10114 parens.skip_until_found_close (parser);
10115 expr.value = objc_build_protocol_expr (id);
10116 set_c_expr_source_range (&expr, loc, close_loc);
10119 case RID_AT_ENCODE:
10121 /* Extension to support C-structures in the archiver. */
10122 gcc_assert (c_dialect_objc ());
10123 c_parser_consume_token (parser);
10124 matching_parens parens;
10125 if (!parens.require_open (parser))
10130 t1 = c_parser_type_name (parser);
10134 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10137 location_t close_loc = c_parser_peek_token (parser)->location;
10138 parens.skip_until_found_close (parser);
10139 tree type = groktypename (t1, NULL, NULL);
10140 expr.value = objc_build_encode_expr (type);
10141 set_c_expr_source_range (&expr, loc, close_loc);
10145 expr = c_parser_generic_selection (parser);
10148 c_parser_error (parser, "expected expression");
10153 case CPP_OPEN_SQUARE:
10154 if (c_dialect_objc ())
10156 tree receiver, args;
10157 c_parser_consume_token (parser);
10158 receiver = c_parser_objc_receiver (parser);
10159 args = c_parser_objc_message_args (parser);
10160 location_t close_loc = c_parser_peek_token (parser)->location;
10161 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10163 expr.value = objc_build_message_expr (receiver, args);
10164 set_c_expr_source_range (&expr, loc, close_loc);
10167 /* Else fall through to report error. */
10170 c_parser_error (parser, "expected expression");
10175 return c_parser_postfix_expression_after_primary
10176 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10179 /* Parse a postfix expression after a parenthesized type name: the
10180 brace-enclosed initializer of a compound literal, possibly followed
10181 by some postfix operators. This is separate because it is not
10182 possible to tell until after the type name whether a cast
10183 expression has a cast or a compound literal, or whether the operand
10184 of sizeof is a parenthesized type name or starts with a compound
10185 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10186 location of the first token after the parentheses around the type
10189 static struct c_expr
10190 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10191 struct c_type_name *type_name,
10192 location_t type_loc)
10195 struct c_expr init;
10197 struct c_expr expr;
10198 location_t start_loc;
10199 tree type_expr = NULL_TREE;
10200 bool type_expr_const = true;
10201 check_compound_literal_type (type_loc, type_name);
10202 rich_location richloc (line_table, type_loc);
10203 start_init (NULL_TREE, NULL, 0, &richloc);
10204 type = groktypename (type_name, &type_expr, &type_expr_const);
10205 start_loc = c_parser_peek_token (parser)->location;
10206 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10208 error_at (type_loc, "compound literal has variable size");
10209 type = error_mark_node;
10211 init = c_parser_braced_init (parser, type, false, NULL);
10213 maybe_warn_string_init (type_loc, type, init);
10215 if (type != error_mark_node
10216 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10217 && current_function_decl)
10219 error ("compound literal qualified by address-space qualifier");
10220 type = error_mark_node;
10223 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10224 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10225 ? CONSTRUCTOR_NON_CONST (init.value)
10226 : init.original_code == C_MAYBE_CONST_EXPR);
10227 non_const |= !type_expr_const;
10228 unsigned int alignas_align = 0;
10229 if (type != error_mark_node
10230 && type_name->specs->align_log != -1)
10232 alignas_align = 1U << type_name->specs->align_log;
10233 if (alignas_align < min_align_of_type (type))
10235 error_at (type_name->specs->locations[cdw_alignas],
10236 "%<_Alignas%> specifiers cannot reduce "
10237 "alignment of compound literal");
10241 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10243 set_c_expr_source_range (&expr, init.src_range);
10244 expr.original_code = ERROR_MARK;
10245 expr.original_type = NULL;
10246 if (type != error_mark_node
10247 && expr.value != error_mark_node
10250 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10252 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10253 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10257 gcc_assert (!non_const);
10258 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10259 type_expr, expr.value);
10262 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10265 /* Callback function for sizeof_pointer_memaccess_warning to compare
10269 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10271 return comptypes (type1, type2) == 1;
10274 /* Warn for patterns where abs-like function appears to be used incorrectly,
10275 gracefully ignore any non-abs-like function. The warning location should
10276 be LOC. FNDECL is the declaration of called function, it must be a
10277 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10281 warn_for_abs (location_t loc, tree fndecl, tree arg)
10283 /* Avoid warning in unreachable subexpressions. */
10284 if (c_inhibit_evaluation_warnings)
10287 tree atype = TREE_TYPE (arg);
10289 /* Casts from pointers (and thus arrays and fndecls) will generate
10290 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10291 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10292 types and possibly other exotic types. */
10293 if (!INTEGRAL_TYPE_P (atype)
10294 && !SCALAR_FLOAT_TYPE_P (atype)
10295 && TREE_CODE (atype) != COMPLEX_TYPE)
10298 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10303 case BUILT_IN_LABS:
10304 case BUILT_IN_LLABS:
10305 case BUILT_IN_IMAXABS:
10306 if (!INTEGRAL_TYPE_P (atype))
10308 if (SCALAR_FLOAT_TYPE_P (atype))
10309 warning_at (loc, OPT_Wabsolute_value,
10310 "using integer absolute value function %qD when "
10311 "argument is of floating-point type %qT",
10313 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10314 warning_at (loc, OPT_Wabsolute_value,
10315 "using integer absolute value function %qD when "
10316 "argument is of complex type %qT", fndecl, atype);
10318 gcc_unreachable ();
10321 if (TYPE_UNSIGNED (atype))
10322 warning_at (loc, OPT_Wabsolute_value,
10323 "taking the absolute value of unsigned type %qT "
10324 "has no effect", atype);
10327 CASE_FLT_FN (BUILT_IN_FABS):
10328 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10329 if (!SCALAR_FLOAT_TYPE_P (atype)
10330 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10332 if (INTEGRAL_TYPE_P (atype))
10333 warning_at (loc, OPT_Wabsolute_value,
10334 "using floating-point absolute value function %qD "
10335 "when argument is of integer type %qT", fndecl, atype);
10336 else if (DECIMAL_FLOAT_TYPE_P (atype))
10337 warning_at (loc, OPT_Wabsolute_value,
10338 "using floating-point absolute value function %qD "
10339 "when argument is of decimal floating-point type %qT",
10341 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10342 warning_at (loc, OPT_Wabsolute_value,
10343 "using floating-point absolute value function %qD when "
10344 "argument is of complex type %qT", fndecl, atype);
10346 gcc_unreachable ();
10351 CASE_FLT_FN (BUILT_IN_CABS):
10352 if (TREE_CODE (atype) != COMPLEX_TYPE)
10354 if (INTEGRAL_TYPE_P (atype))
10355 warning_at (loc, OPT_Wabsolute_value,
10356 "using complex absolute value function %qD when "
10357 "argument is of integer type %qT", fndecl, atype);
10358 else if (SCALAR_FLOAT_TYPE_P (atype))
10359 warning_at (loc, OPT_Wabsolute_value,
10360 "using complex absolute value function %qD when "
10361 "argument is of floating-point type %qT",
10364 gcc_unreachable ();
10370 case BUILT_IN_FABSD32:
10371 case BUILT_IN_FABSD64:
10372 case BUILT_IN_FABSD128:
10373 if (!DECIMAL_FLOAT_TYPE_P (atype))
10375 if (INTEGRAL_TYPE_P (atype))
10376 warning_at (loc, OPT_Wabsolute_value,
10377 "using decimal floating-point absolute value "
10378 "function %qD when argument is of integer type %qT",
10380 else if (SCALAR_FLOAT_TYPE_P (atype))
10381 warning_at (loc, OPT_Wabsolute_value,
10382 "using decimal floating-point absolute value "
10383 "function %qD when argument is of floating-point "
10384 "type %qT", fndecl, atype);
10385 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10386 warning_at (loc, OPT_Wabsolute_value,
10387 "using decimal floating-point absolute value "
10388 "function %qD when argument is of complex type %qT",
10391 gcc_unreachable ();
10400 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10403 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10404 if (TREE_CODE (atype) == COMPLEX_TYPE)
10406 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10407 atype = TREE_TYPE (atype);
10408 ftype = TREE_TYPE (ftype);
10411 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10412 warning_at (loc, OPT_Wabsolute_value,
10413 "absolute value function %qD given an argument of type %qT "
10414 "but has parameter of type %qT which may cause truncation "
10415 "of value", fndecl, atype, ftype);
10419 /* Parse a postfix expression after the initial primary or compound
10420 literal; that is, parse a series of postfix operators.
10422 EXPR_LOC is the location of the primary expression. */
10424 static struct c_expr
10425 c_parser_postfix_expression_after_primary (c_parser *parser,
10426 location_t expr_loc,
10427 struct c_expr expr)
10429 struct c_expr orig_expr;
10431 location_t sizeof_arg_loc[3], comp_loc;
10432 tree sizeof_arg[3];
10433 unsigned int literal_zero_mask;
10435 vec<tree, va_gc> *exprlist;
10436 vec<tree, va_gc> *origtypes = NULL;
10437 vec<location_t> arg_loc = vNULL;
10443 location_t op_loc = c_parser_peek_token (parser)->location;
10444 switch (c_parser_peek_token (parser)->type)
10446 case CPP_OPEN_SQUARE:
10447 /* Array reference. */
10448 c_parser_consume_token (parser);
10449 idx = c_parser_expression (parser).value;
10450 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10452 start = expr.get_start ();
10453 finish = parser->tokens_buf[0].location;
10454 expr.value = build_array_ref (op_loc, expr.value, idx);
10455 set_c_expr_source_range (&expr, start, finish);
10456 expr.original_code = ERROR_MARK;
10457 expr.original_type = NULL;
10459 case CPP_OPEN_PAREN:
10460 /* Function call. */
10461 c_parser_consume_token (parser);
10462 for (i = 0; i < 3; i++)
10464 sizeof_arg[i] = NULL_TREE;
10465 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10467 literal_zero_mask = 0;
10468 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10471 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10472 sizeof_arg_loc, sizeof_arg,
10473 &arg_loc, &literal_zero_mask);
10474 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10477 mark_exp_read (expr.value);
10478 if (warn_sizeof_pointer_memaccess)
10479 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10480 expr.value, exprlist,
10482 sizeof_ptr_memacc_comptypes);
10483 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10485 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10486 && vec_safe_length (exprlist) == 3)
10488 tree arg0 = (*exprlist)[0];
10489 tree arg2 = (*exprlist)[2];
10490 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10492 if (warn_absolute_value
10493 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10494 && vec_safe_length (exprlist) == 1)
10495 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10498 start = expr.get_start ();
10499 finish = parser->tokens_buf[0].get_finish ();
10501 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10502 exprlist, origtypes);
10503 set_c_expr_source_range (&expr, start, finish);
10505 expr.original_code = ERROR_MARK;
10506 if (TREE_CODE (expr.value) == INTEGER_CST
10507 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10508 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10509 expr.original_code = C_MAYBE_CONST_EXPR;
10510 expr.original_type = NULL;
10513 release_tree_vector (exprlist);
10514 release_tree_vector (origtypes);
10516 arg_loc.release ();
10519 /* Structure element reference. */
10520 c_parser_consume_token (parser);
10521 expr = default_function_array_conversion (expr_loc, expr);
10522 if (c_parser_next_token_is (parser, CPP_NAME))
10524 c_token *comp_tok = c_parser_peek_token (parser);
10525 ident = comp_tok->value;
10526 comp_loc = comp_tok->location;
10530 c_parser_error (parser, "expected identifier");
10532 expr.original_code = ERROR_MARK;
10533 expr.original_type = NULL;
10536 start = expr.get_start ();
10537 finish = c_parser_peek_token (parser)->get_finish ();
10538 c_parser_consume_token (parser);
10539 expr.value = build_component_ref (op_loc, expr.value, ident,
10541 set_c_expr_source_range (&expr, start, finish);
10542 expr.original_code = ERROR_MARK;
10543 if (TREE_CODE (expr.value) != COMPONENT_REF)
10544 expr.original_type = NULL;
10547 /* Remember the original type of a bitfield. */
10548 tree field = TREE_OPERAND (expr.value, 1);
10549 if (TREE_CODE (field) != FIELD_DECL)
10550 expr.original_type = NULL;
10552 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10556 /* Structure element reference. */
10557 c_parser_consume_token (parser);
10558 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10559 if (c_parser_next_token_is (parser, CPP_NAME))
10561 c_token *comp_tok = c_parser_peek_token (parser);
10562 ident = comp_tok->value;
10563 comp_loc = comp_tok->location;
10567 c_parser_error (parser, "expected identifier");
10569 expr.original_code = ERROR_MARK;
10570 expr.original_type = NULL;
10573 start = expr.get_start ();
10574 finish = c_parser_peek_token (parser)->get_finish ();
10575 c_parser_consume_token (parser);
10576 expr.value = build_component_ref (op_loc,
10577 build_indirect_ref (op_loc,
10581 set_c_expr_source_range (&expr, start, finish);
10582 expr.original_code = ERROR_MARK;
10583 if (TREE_CODE (expr.value) != COMPONENT_REF)
10584 expr.original_type = NULL;
10587 /* Remember the original type of a bitfield. */
10588 tree field = TREE_OPERAND (expr.value, 1);
10589 if (TREE_CODE (field) != FIELD_DECL)
10590 expr.original_type = NULL;
10592 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10595 case CPP_PLUS_PLUS:
10596 /* Postincrement. */
10597 start = expr.get_start ();
10598 finish = c_parser_peek_token (parser)->get_finish ();
10599 c_parser_consume_token (parser);
10600 expr = default_function_array_read_conversion (expr_loc, expr);
10601 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10602 expr.value, false);
10603 set_c_expr_source_range (&expr, start, finish);
10604 expr.original_code = ERROR_MARK;
10605 expr.original_type = NULL;
10607 case CPP_MINUS_MINUS:
10608 /* Postdecrement. */
10609 start = expr.get_start ();
10610 finish = c_parser_peek_token (parser)->get_finish ();
10611 c_parser_consume_token (parser);
10612 expr = default_function_array_read_conversion (expr_loc, expr);
10613 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10614 expr.value, false);
10615 set_c_expr_source_range (&expr, start, finish);
10616 expr.original_code = ERROR_MARK;
10617 expr.original_type = NULL;
10625 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10628 assignment-expression
10629 expression , assignment-expression
10632 static struct c_expr
10633 c_parser_expression (c_parser *parser)
10635 location_t tloc = c_parser_peek_token (parser)->location;
10636 struct c_expr expr;
10637 expr = c_parser_expr_no_commas (parser, NULL);
10638 if (c_parser_next_token_is (parser, CPP_COMMA))
10639 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10640 while (c_parser_next_token_is (parser, CPP_COMMA))
10642 struct c_expr next;
10644 location_t loc = c_parser_peek_token (parser)->location;
10645 location_t expr_loc;
10646 c_parser_consume_token (parser);
10647 expr_loc = c_parser_peek_token (parser)->location;
10648 lhsval = expr.value;
10649 while (TREE_CODE (lhsval) == COMPOUND_EXPR)
10650 lhsval = TREE_OPERAND (lhsval, 1);
10651 if (DECL_P (lhsval) || handled_component_p (lhsval))
10652 mark_exp_read (lhsval);
10653 next = c_parser_expr_no_commas (parser, NULL);
10654 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10655 expr.value = build_compound_expr (loc, expr.value, next.value);
10656 expr.original_code = COMPOUND_EXPR;
10657 expr.original_type = next.original_type;
10662 /* Parse an expression and convert functions or arrays to pointers and
10663 lvalues to rvalues. */
10665 static struct c_expr
10666 c_parser_expression_conv (c_parser *parser)
10668 struct c_expr expr;
10669 location_t loc = c_parser_peek_token (parser)->location;
10670 expr = c_parser_expression (parser);
10671 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10675 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10676 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10679 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10682 if (idx >= HOST_BITS_PER_INT)
10685 c_token *tok = c_parser_peek_token (parser);
10694 /* If a parameter is literal zero alone, remember it
10695 for -Wmemset-transposed-args warning. */
10696 if (integer_zerop (tok->value)
10697 && !TREE_OVERFLOW (tok->value)
10698 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10699 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10700 *literal_zero_mask |= 1U << idx;
10706 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10707 functions and arrays to pointers and lvalues to rvalues. If
10708 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10709 locations of function arguments into this vector.
10711 nonempty-expr-list:
10712 assignment-expression
10713 nonempty-expr-list , assignment-expression
10716 static vec<tree, va_gc> *
10717 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10718 vec<tree, va_gc> **p_orig_types,
10719 location_t *sizeof_arg_loc, tree *sizeof_arg,
10720 vec<location_t> *locations,
10721 unsigned int *literal_zero_mask)
10723 vec<tree, va_gc> *ret;
10724 vec<tree, va_gc> *orig_types;
10725 struct c_expr expr;
10726 unsigned int idx = 0;
10728 ret = make_tree_vector ();
10729 if (p_orig_types == NULL)
10732 orig_types = make_tree_vector ();
10734 if (literal_zero_mask)
10735 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10736 expr = c_parser_expr_no_commas (parser, NULL);
10738 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10740 expr.value = c_fully_fold (expr.value, false, NULL);
10741 ret->quick_push (expr.value);
10743 orig_types->quick_push (expr.original_type);
10745 locations->safe_push (expr.get_location ());
10746 if (sizeof_arg != NULL
10747 && expr.original_code == SIZEOF_EXPR)
10749 sizeof_arg[0] = c_last_sizeof_arg;
10750 sizeof_arg_loc[0] = c_last_sizeof_loc;
10752 while (c_parser_next_token_is (parser, CPP_COMMA))
10754 c_parser_consume_token (parser);
10755 if (literal_zero_mask)
10756 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10757 expr = c_parser_expr_no_commas (parser, NULL);
10759 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10762 expr.value = c_fully_fold (expr.value, false, NULL);
10763 vec_safe_push (ret, expr.value);
10765 vec_safe_push (orig_types, expr.original_type);
10767 locations->safe_push (expr.get_location ());
10769 && sizeof_arg != NULL
10770 && expr.original_code == SIZEOF_EXPR)
10772 sizeof_arg[idx] = c_last_sizeof_arg;
10773 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10777 *p_orig_types = orig_types;
10781 /* Parse Objective-C-specific constructs. */
10783 /* Parse an objc-class-definition.
10785 objc-class-definition:
10786 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10787 objc-class-instance-variables[opt] objc-methodprotolist @end
10788 @implementation identifier objc-superclass[opt]
10789 objc-class-instance-variables[opt]
10790 @interface identifier ( identifier ) objc-protocol-refs[opt]
10791 objc-methodprotolist @end
10792 @interface identifier ( ) objc-protocol-refs[opt]
10793 objc-methodprotolist @end
10794 @implementation identifier ( identifier )
10799 "@interface identifier (" must start "@interface identifier (
10800 identifier ) ...": objc-methodprotolist in the first production may
10801 not start with a parenthesized identifier as a declarator of a data
10802 definition with no declaration specifiers if the objc-superclass,
10803 objc-protocol-refs and objc-class-instance-variables are omitted. */
10806 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10811 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10813 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10816 gcc_unreachable ();
10818 c_parser_consume_token (parser);
10819 if (c_parser_next_token_is_not (parser, CPP_NAME))
10821 c_parser_error (parser, "expected identifier");
10824 id1 = c_parser_peek_token (parser)->value;
10825 c_parser_consume_token (parser);
10826 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10828 /* We have a category or class extension. */
10830 tree proto = NULL_TREE;
10831 matching_parens parens;
10832 parens.consume_open (parser);
10833 if (c_parser_next_token_is_not (parser, CPP_NAME))
10835 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10837 /* We have a class extension. */
10842 c_parser_error (parser, "expected identifier or %<)%>");
10843 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10849 id2 = c_parser_peek_token (parser)->value;
10850 c_parser_consume_token (parser);
10852 parens.skip_until_found_close (parser);
10855 objc_start_category_implementation (id1, id2);
10858 if (c_parser_next_token_is (parser, CPP_LESS))
10859 proto = c_parser_objc_protocol_refs (parser);
10860 objc_start_category_interface (id1, id2, proto, attributes);
10861 c_parser_objc_methodprotolist (parser);
10862 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10863 objc_finish_interface ();
10866 if (c_parser_next_token_is (parser, CPP_COLON))
10868 c_parser_consume_token (parser);
10869 if (c_parser_next_token_is_not (parser, CPP_NAME))
10871 c_parser_error (parser, "expected identifier");
10874 superclass = c_parser_peek_token (parser)->value;
10875 c_parser_consume_token (parser);
10878 superclass = NULL_TREE;
10881 tree proto = NULL_TREE;
10882 if (c_parser_next_token_is (parser, CPP_LESS))
10883 proto = c_parser_objc_protocol_refs (parser);
10884 objc_start_class_interface (id1, superclass, proto, attributes);
10887 objc_start_class_implementation (id1, superclass);
10888 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10889 c_parser_objc_class_instance_variables (parser);
10892 objc_continue_interface ();
10893 c_parser_objc_methodprotolist (parser);
10894 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10895 objc_finish_interface ();
10899 objc_continue_implementation ();
10904 /* Parse objc-class-instance-variables.
10906 objc-class-instance-variables:
10907 { objc-instance-variable-decl-list[opt] }
10909 objc-instance-variable-decl-list:
10910 objc-visibility-spec
10911 objc-instance-variable-decl ;
10913 objc-instance-variable-decl-list objc-visibility-spec
10914 objc-instance-variable-decl-list objc-instance-variable-decl ;
10915 objc-instance-variable-decl-list ;
10917 objc-visibility-spec:
10922 objc-instance-variable-decl:
10927 c_parser_objc_class_instance_variables (c_parser *parser)
10929 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
10930 c_parser_consume_token (parser);
10931 while (c_parser_next_token_is_not (parser, CPP_EOF))
10934 /* Parse any stray semicolon. */
10935 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10937 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
10938 "extra semicolon");
10939 c_parser_consume_token (parser);
10942 /* Stop if at the end of the instance variables. */
10943 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10945 c_parser_consume_token (parser);
10948 /* Parse any objc-visibility-spec. */
10949 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
10951 c_parser_consume_token (parser);
10952 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
10955 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
10957 c_parser_consume_token (parser);
10958 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
10961 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
10963 c_parser_consume_token (parser);
10964 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
10967 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
10969 c_parser_consume_token (parser);
10970 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
10973 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
10975 c_parser_pragma (parser, pragma_external, NULL);
10979 /* Parse some comma-separated declarations. */
10980 decls = c_parser_struct_declaration (parser);
10983 /* There is a syntax error. We want to skip the offending
10984 tokens up to the next ';' (included) or '}'
10987 /* First, skip manually a ')' or ']'. This is because they
10988 reduce the nesting level, so c_parser_skip_until_found()
10989 wouldn't be able to skip past them. */
10990 c_token *token = c_parser_peek_token (parser);
10991 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
10992 c_parser_consume_token (parser);
10994 /* Then, do the standard skipping. */
10995 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10997 /* We hopefully recovered. Start normal parsing again. */
10998 parser->error = false;
11003 /* Comma-separated instance variables are chained together
11004 in reverse order; add them one by one. */
11005 tree ivar = nreverse (decls);
11006 for (; ivar; ivar = DECL_CHAIN (ivar))
11007 objc_add_instance_variable (copy_node (ivar));
11009 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11013 /* Parse an objc-class-declaration.
11015 objc-class-declaration:
11016 @class identifier-list ;
11020 c_parser_objc_class_declaration (c_parser *parser)
11022 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11023 c_parser_consume_token (parser);
11024 /* Any identifiers, including those declared as type names, are OK
11029 if (c_parser_next_token_is_not (parser, CPP_NAME))
11031 c_parser_error (parser, "expected identifier");
11032 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11033 parser->error = false;
11036 id = c_parser_peek_token (parser)->value;
11037 objc_declare_class (id);
11038 c_parser_consume_token (parser);
11039 if (c_parser_next_token_is (parser, CPP_COMMA))
11040 c_parser_consume_token (parser);
11044 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11047 /* Parse an objc-alias-declaration.
11049 objc-alias-declaration:
11050 @compatibility_alias identifier identifier ;
11054 c_parser_objc_alias_declaration (c_parser *parser)
11057 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11058 c_parser_consume_token (parser);
11059 if (c_parser_next_token_is_not (parser, CPP_NAME))
11061 c_parser_error (parser, "expected identifier");
11062 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11065 id1 = c_parser_peek_token (parser)->value;
11066 c_parser_consume_token (parser);
11067 if (c_parser_next_token_is_not (parser, CPP_NAME))
11069 c_parser_error (parser, "expected identifier");
11070 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11073 id2 = c_parser_peek_token (parser)->value;
11074 c_parser_consume_token (parser);
11075 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11076 objc_declare_alias (id1, id2);
11079 /* Parse an objc-protocol-definition.
11081 objc-protocol-definition:
11082 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11083 @protocol identifier-list ;
11085 "@protocol identifier ;" should be resolved as "@protocol
11086 identifier-list ;": objc-methodprotolist may not start with a
11087 semicolon in the first alternative if objc-protocol-refs are
11091 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11093 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11095 c_parser_consume_token (parser);
11096 if (c_parser_next_token_is_not (parser, CPP_NAME))
11098 c_parser_error (parser, "expected identifier");
11101 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11102 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11104 /* Any identifiers, including those declared as type names, are
11109 if (c_parser_next_token_is_not (parser, CPP_NAME))
11111 c_parser_error (parser, "expected identifier");
11114 id = c_parser_peek_token (parser)->value;
11115 objc_declare_protocol (id, attributes);
11116 c_parser_consume_token (parser);
11117 if (c_parser_next_token_is (parser, CPP_COMMA))
11118 c_parser_consume_token (parser);
11122 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11126 tree id = c_parser_peek_token (parser)->value;
11127 tree proto = NULL_TREE;
11128 c_parser_consume_token (parser);
11129 if (c_parser_next_token_is (parser, CPP_LESS))
11130 proto = c_parser_objc_protocol_refs (parser);
11131 parser->objc_pq_context = true;
11132 objc_start_protocol (id, proto, attributes);
11133 c_parser_objc_methodprotolist (parser);
11134 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11135 parser->objc_pq_context = false;
11136 objc_finish_interface ();
11140 /* Parse an objc-method-type.
11146 Return true if it is a class method (+) and false if it is
11147 an instance method (-).
11150 c_parser_objc_method_type (c_parser *parser)
11152 switch (c_parser_peek_token (parser)->type)
11155 c_parser_consume_token (parser);
11158 c_parser_consume_token (parser);
11161 gcc_unreachable ();
11165 /* Parse an objc-method-definition.
11167 objc-method-definition:
11168 objc-method-type objc-method-decl ;[opt] compound-statement
11172 c_parser_objc_method_definition (c_parser *parser)
11174 bool is_class_method = c_parser_objc_method_type (parser);
11175 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11176 parser->objc_pq_context = true;
11177 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11179 if (decl == error_mark_node)
11180 return; /* Bail here. */
11182 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11184 c_parser_consume_token (parser);
11185 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11186 "extra semicolon in method definition specified");
11189 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11191 c_parser_error (parser, "expected %<{%>");
11195 parser->objc_pq_context = false;
11196 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11198 add_stmt (c_parser_compound_statement (parser));
11199 objc_finish_method_definition (current_function_decl);
11203 /* This code is executed when we find a method definition
11204 outside of an @implementation context (or invalid for other
11205 reasons). Parse the method (to keep going) but do not emit
11208 c_parser_compound_statement (parser);
11212 /* Parse an objc-methodprotolist.
11214 objc-methodprotolist:
11216 objc-methodprotolist objc-methodproto
11217 objc-methodprotolist declaration
11218 objc-methodprotolist ;
11222 The declaration is a data definition, which may be missing
11223 declaration specifiers under the same rules and diagnostics as
11224 other data definitions outside functions, and the stray semicolon
11225 is diagnosed the same way as a stray semicolon outside a
11229 c_parser_objc_methodprotolist (c_parser *parser)
11233 /* The list is terminated by @end. */
11234 switch (c_parser_peek_token (parser)->type)
11236 case CPP_SEMICOLON:
11237 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11238 "ISO C does not allow extra %<;%> outside of a function");
11239 c_parser_consume_token (parser);
11243 c_parser_objc_methodproto (parser);
11246 c_parser_pragma (parser, pragma_external, NULL);
11251 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11253 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11254 c_parser_objc_at_property_declaration (parser);
11255 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11257 objc_set_method_opt (true);
11258 c_parser_consume_token (parser);
11260 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11262 objc_set_method_opt (false);
11263 c_parser_consume_token (parser);
11266 c_parser_declaration_or_fndef (parser, false, false, true,
11267 false, true, NULL, vNULL);
11273 /* Parse an objc-methodproto.
11276 objc-method-type objc-method-decl ;
11280 c_parser_objc_methodproto (c_parser *parser)
11282 bool is_class_method = c_parser_objc_method_type (parser);
11283 tree decl, attributes = NULL_TREE;
11285 /* Remember protocol qualifiers in prototypes. */
11286 parser->objc_pq_context = true;
11287 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11289 /* Forget protocol qualifiers now. */
11290 parser->objc_pq_context = false;
11292 /* Do not allow the presence of attributes to hide an erroneous
11293 method implementation in the interface section. */
11294 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11296 c_parser_error (parser, "expected %<;%>");
11300 if (decl != error_mark_node)
11301 objc_add_method_declaration (is_class_method, decl, attributes);
11303 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11306 /* If we are at a position that method attributes may be present, check that
11307 there are not any parsed already (a syntax error) and then collect any
11308 specified at the current location. Finally, if new attributes were present,
11309 check that the next token is legal ( ';' for decls and '{' for defs). */
11312 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11317 c_parser_error (parser,
11318 "method attributes must be specified at the end only");
11319 *attributes = NULL_TREE;
11323 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11324 *attributes = c_parser_gnu_attributes (parser);
11326 /* If there were no attributes here, just report any earlier error. */
11327 if (*attributes == NULL_TREE || bad)
11330 /* If the attributes are followed by a ; or {, then just report any earlier
11332 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11333 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11336 /* We've got attributes, but not at the end. */
11337 c_parser_error (parser,
11338 "expected %<;%> or %<{%> after method attribute definition");
11342 /* Parse an objc-method-decl.
11345 ( objc-type-name ) objc-selector
11347 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11348 objc-keyword-selector objc-optparmlist
11351 objc-keyword-selector:
11353 objc-keyword-selector objc-keyword-decl
11356 objc-selector : ( objc-type-name ) identifier
11357 objc-selector : identifier
11358 : ( objc-type-name ) identifier
11362 objc-optparms objc-optellipsis
11366 objc-opt-parms , parameter-declaration
11374 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11375 tree *attributes, tree *expr)
11377 tree type = NULL_TREE;
11379 tree parms = NULL_TREE;
11380 bool ellipsis = false;
11381 bool attr_err = false;
11383 *attributes = NULL_TREE;
11384 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11386 matching_parens parens;
11387 parens.consume_open (parser);
11388 type = c_parser_objc_type_name (parser);
11389 parens.skip_until_found_close (parser);
11391 sel = c_parser_objc_selector (parser);
11392 /* If there is no selector, or a colon follows, we have an
11393 objc-keyword-selector. If there is a selector, and a colon does
11394 not follow, that selector ends the objc-method-decl. */
11395 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11398 tree list = NULL_TREE;
11401 tree atype = NULL_TREE, id, keyworddecl;
11402 tree param_attr = NULL_TREE;
11403 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11405 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11407 c_parser_consume_token (parser);
11408 atype = c_parser_objc_type_name (parser);
11409 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11412 /* New ObjC allows attributes on method parameters. */
11413 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11414 param_attr = c_parser_gnu_attributes (parser);
11415 if (c_parser_next_token_is_not (parser, CPP_NAME))
11417 c_parser_error (parser, "expected identifier");
11418 return error_mark_node;
11420 id = c_parser_peek_token (parser)->value;
11421 c_parser_consume_token (parser);
11422 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11423 list = chainon (list, keyworddecl);
11424 tsel = c_parser_objc_selector (parser);
11425 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11429 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11431 /* Parse the optional parameter list. Optional Objective-C
11432 method parameters follow the C syntax, and may include '...'
11433 to denote a variable number of arguments. */
11434 parms = make_node (TREE_LIST);
11435 while (c_parser_next_token_is (parser, CPP_COMMA))
11437 struct c_parm *parm;
11438 c_parser_consume_token (parser);
11439 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11442 c_parser_consume_token (parser);
11443 attr_err |= c_parser_objc_maybe_method_attributes
11444 (parser, attributes) ;
11447 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11450 parms = chainon (parms,
11451 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11456 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11460 c_parser_error (parser, "objective-c method declaration is expected");
11461 return error_mark_node;
11465 return error_mark_node;
11467 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11470 /* Parse an objc-type-name.
11473 objc-type-qualifiers[opt] type-name
11474 objc-type-qualifiers[opt]
11476 objc-type-qualifiers:
11477 objc-type-qualifier
11478 objc-type-qualifiers objc-type-qualifier
11480 objc-type-qualifier: one of
11481 in out inout bycopy byref oneway
11485 c_parser_objc_type_name (c_parser *parser)
11487 tree quals = NULL_TREE;
11488 struct c_type_name *type_name = NULL;
11489 tree type = NULL_TREE;
11492 c_token *token = c_parser_peek_token (parser);
11493 if (token->type == CPP_KEYWORD
11494 && (token->keyword == RID_IN
11495 || token->keyword == RID_OUT
11496 || token->keyword == RID_INOUT
11497 || token->keyword == RID_BYCOPY
11498 || token->keyword == RID_BYREF
11499 || token->keyword == RID_ONEWAY))
11501 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11502 c_parser_consume_token (parser);
11507 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11508 type_name = c_parser_type_name (parser);
11510 type = groktypename (type_name, NULL, NULL);
11512 /* If the type is unknown, and error has already been produced and
11513 we need to recover from the error. In that case, use NULL_TREE
11514 for the type, as if no type had been specified; this will use the
11515 default type ('id') which is good for error recovery. */
11516 if (type == error_mark_node)
11519 return build_tree_list (quals, type);
11522 /* Parse objc-protocol-refs.
11524 objc-protocol-refs:
11525 < identifier-list >
11529 c_parser_objc_protocol_refs (c_parser *parser)
11531 tree list = NULL_TREE;
11532 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11533 c_parser_consume_token (parser);
11534 /* Any identifiers, including those declared as type names, are OK
11539 if (c_parser_next_token_is_not (parser, CPP_NAME))
11541 c_parser_error (parser, "expected identifier");
11544 id = c_parser_peek_token (parser)->value;
11545 list = chainon (list, build_tree_list (NULL_TREE, id));
11546 c_parser_consume_token (parser);
11547 if (c_parser_next_token_is (parser, CPP_COMMA))
11548 c_parser_consume_token (parser);
11552 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11556 /* Parse an objc-try-catch-finally-statement.
11558 objc-try-catch-finally-statement:
11559 @try compound-statement objc-catch-list[opt]
11560 @try compound-statement objc-catch-list[opt] @finally compound-statement
11563 @catch ( objc-catch-parameter-declaration ) compound-statement
11564 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11566 objc-catch-parameter-declaration:
11567 parameter-declaration
11570 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11572 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11573 for C++. Keep them in sync. */
11576 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11578 location_t location;
11581 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11582 c_parser_consume_token (parser);
11583 location = c_parser_peek_token (parser)->location;
11584 objc_maybe_warn_exceptions (location);
11585 stmt = c_parser_compound_statement (parser);
11586 objc_begin_try_stmt (location, stmt);
11588 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11590 struct c_parm *parm;
11591 tree parameter_declaration = error_mark_node;
11592 bool seen_open_paren = false;
11594 c_parser_consume_token (parser);
11595 matching_parens parens;
11596 if (!parens.require_open (parser))
11597 seen_open_paren = true;
11598 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11600 /* We have "@catch (...)" (where the '...' are literally
11601 what is in the code). Skip the '...'.
11602 parameter_declaration is set to NULL_TREE, and
11603 objc_being_catch_clauses() knows that that means
11605 c_parser_consume_token (parser);
11606 parameter_declaration = NULL_TREE;
11610 /* We have "@catch (NSException *exception)" or something
11611 like that. Parse the parameter declaration. */
11612 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11614 parameter_declaration = error_mark_node;
11616 parameter_declaration = grokparm (parm, NULL);
11618 if (seen_open_paren)
11619 parens.require_close (parser);
11622 /* If there was no open parenthesis, we are recovering from
11623 an error, and we are trying to figure out what mistake
11624 the user has made. */
11626 /* If there is an immediate closing parenthesis, the user
11627 probably forgot the opening one (ie, they typed "@catch
11628 NSException *e)". Parse the closing parenthesis and keep
11630 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11631 c_parser_consume_token (parser);
11633 /* If these is no immediate closing parenthesis, the user
11634 probably doesn't know that parenthesis are required at
11635 all (ie, they typed "@catch NSException *e"). So, just
11636 forget about the closing parenthesis and keep going. */
11638 objc_begin_catch_clause (parameter_declaration);
11639 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11640 c_parser_compound_statement_nostart (parser);
11641 objc_finish_catch_clause ();
11643 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11645 c_parser_consume_token (parser);
11646 location = c_parser_peek_token (parser)->location;
11647 stmt = c_parser_compound_statement (parser);
11648 objc_build_finally_clause (location, stmt);
11650 objc_finish_try_stmt ();
11653 /* Parse an objc-synchronized-statement.
11655 objc-synchronized-statement:
11656 @synchronized ( expression ) compound-statement
11660 c_parser_objc_synchronized_statement (c_parser *parser)
11664 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11665 c_parser_consume_token (parser);
11666 loc = c_parser_peek_token (parser)->location;
11667 objc_maybe_warn_exceptions (loc);
11668 matching_parens parens;
11669 if (parens.require_open (parser))
11671 struct c_expr ce = c_parser_expression (parser);
11672 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11674 expr = c_fully_fold (expr, false, NULL);
11675 parens.skip_until_found_close (parser);
11678 expr = error_mark_node;
11679 stmt = c_parser_compound_statement (parser);
11680 objc_build_synchronized (loc, expr, stmt);
11683 /* Parse an objc-selector; return NULL_TREE without an error if the
11684 next token is not an objc-selector.
11689 enum struct union if else while do for switch case default
11690 break continue return goto asm sizeof typeof __alignof
11691 unsigned long const short volatile signed restrict _Complex
11692 in out inout bycopy byref oneway int char float double void _Bool
11695 ??? Why this selection of keywords but not, for example, storage
11696 class specifiers? */
11699 c_parser_objc_selector (c_parser *parser)
11701 c_token *token = c_parser_peek_token (parser);
11702 tree value = token->value;
11703 if (token->type == CPP_NAME)
11705 c_parser_consume_token (parser);
11708 if (token->type != CPP_KEYWORD)
11710 switch (token->keyword)
11749 CASE_RID_FLOATN_NX:
11753 case RID_AUTO_TYPE:
11758 c_parser_consume_token (parser);
11765 /* Parse an objc-selector-arg.
11769 objc-keywordname-list
11771 objc-keywordname-list:
11773 objc-keywordname-list objc-keywordname
11781 c_parser_objc_selector_arg (c_parser *parser)
11783 tree sel = c_parser_objc_selector (parser);
11784 tree list = NULL_TREE;
11785 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11789 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11791 list = chainon (list, build_tree_list (sel, NULL_TREE));
11792 sel = c_parser_objc_selector (parser);
11793 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11799 /* Parse an objc-receiver.
11808 c_parser_objc_receiver (c_parser *parser)
11810 location_t loc = c_parser_peek_token (parser)->location;
11812 if (c_parser_peek_token (parser)->type == CPP_NAME
11813 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11814 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11816 tree id = c_parser_peek_token (parser)->value;
11817 c_parser_consume_token (parser);
11818 return objc_get_class_reference (id);
11820 struct c_expr ce = c_parser_expression (parser);
11821 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11822 return c_fully_fold (ce.value, false, NULL);
11825 /* Parse objc-message-args.
11829 objc-keywordarg-list
11831 objc-keywordarg-list:
11833 objc-keywordarg-list objc-keywordarg
11836 objc-selector : objc-keywordexpr
11841 c_parser_objc_message_args (c_parser *parser)
11843 tree sel = c_parser_objc_selector (parser);
11844 tree list = NULL_TREE;
11845 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11850 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11851 return error_mark_node;
11852 keywordexpr = c_parser_objc_keywordexpr (parser);
11853 list = chainon (list, build_tree_list (sel, keywordexpr));
11854 sel = c_parser_objc_selector (parser);
11855 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11861 /* Parse an objc-keywordexpr.
11868 c_parser_objc_keywordexpr (c_parser *parser)
11871 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11872 NULL, NULL, NULL, NULL);
11873 if (vec_safe_length (expr_list) == 1)
11875 /* Just return the expression, remove a level of
11877 ret = (*expr_list)[0];
11881 /* We have a comma expression, we will collapse later. */
11882 ret = build_tree_list_vec (expr_list);
11884 release_tree_vector (expr_list);
11888 /* A check, needed in several places, that ObjC interface, implementation or
11889 method definitions are not prefixed by incorrect items. */
11891 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11892 struct c_declspecs *specs)
11894 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11895 || specs->typespec_kind != ctsk_none)
11897 c_parser_error (parser,
11898 "no type or storage class may be specified here,");
11899 c_parser_skip_to_end_of_block_or_statement (parser);
11905 /* Parse an Objective-C @property declaration. The syntax is:
11907 objc-property-declaration:
11908 '@property' objc-property-attributes[opt] struct-declaration ;
11910 objc-property-attributes:
11911 '(' objc-property-attribute-list ')'
11913 objc-property-attribute-list:
11914 objc-property-attribute
11915 objc-property-attribute-list, objc-property-attribute
11917 objc-property-attribute
11918 'getter' = identifier
11919 'setter' = identifier
11928 @property NSString *name;
11929 @property (readonly) id object;
11930 @property (retain, nonatomic, getter=getTheName) id name;
11931 @property int a, b, c;
11933 PS: This function is identical to cp_parser_objc_at_propery_declaration
11934 for C++. Keep them in sync. */
11936 c_parser_objc_at_property_declaration (c_parser *parser)
11938 /* The following variables hold the attributes of the properties as
11939 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
11940 seen. When we see an attribute, we set them to 'true' (if they
11941 are boolean properties) or to the identifier (if they have an
11942 argument, ie, for getter and setter). Note that here we only
11943 parse the list of attributes, check the syntax and accumulate the
11944 attributes that we find. objc_add_property_declaration() will
11945 then process the information. */
11946 bool property_assign = false;
11947 bool property_copy = false;
11948 tree property_getter_ident = NULL_TREE;
11949 bool property_nonatomic = false;
11950 bool property_readonly = false;
11951 bool property_readwrite = false;
11952 bool property_retain = false;
11953 tree property_setter_ident = NULL_TREE;
11955 /* 'properties' is the list of properties that we read. Usually a
11956 single one, but maybe more (eg, in "@property int a, b, c;" there
11961 loc = c_parser_peek_token (parser)->location;
11962 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
11964 c_parser_consume_token (parser); /* Eat '@property'. */
11966 /* Parse the optional attribute list... */
11967 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11969 matching_parens parens;
11972 parens.consume_open (parser);
11974 /* Property attribute keywords are valid now. */
11975 parser->objc_property_attr_context = true;
11979 bool syntax_error = false;
11980 c_token *token = c_parser_peek_token (parser);
11983 if (token->type != CPP_KEYWORD)
11985 if (token->type == CPP_CLOSE_PAREN)
11986 c_parser_error (parser, "expected identifier");
11989 c_parser_consume_token (parser);
11990 c_parser_error (parser, "unknown property attribute");
11994 keyword = token->keyword;
11995 c_parser_consume_token (parser);
11998 case RID_ASSIGN: property_assign = true; break;
11999 case RID_COPY: property_copy = true; break;
12000 case RID_NONATOMIC: property_nonatomic = true; break;
12001 case RID_READONLY: property_readonly = true; break;
12002 case RID_READWRITE: property_readwrite = true; break;
12003 case RID_RETAIN: property_retain = true; break;
12007 if (c_parser_next_token_is_not (parser, CPP_EQ))
12009 if (keyword == RID_GETTER)
12010 c_parser_error (parser,
12011 "missing %<=%> (after %<getter%> attribute)");
12013 c_parser_error (parser,
12014 "missing %<=%> (after %<setter%> attribute)");
12015 syntax_error = true;
12018 c_parser_consume_token (parser); /* eat the = */
12019 if (c_parser_next_token_is_not (parser, CPP_NAME))
12021 c_parser_error (parser, "expected identifier");
12022 syntax_error = true;
12025 if (keyword == RID_SETTER)
12027 if (property_setter_ident != NULL_TREE)
12028 c_parser_error (parser, "the %<setter%> attribute may only be specified once");
12030 property_setter_ident = c_parser_peek_token (parser)->value;
12031 c_parser_consume_token (parser);
12032 if (c_parser_next_token_is_not (parser, CPP_COLON))
12033 c_parser_error (parser, "setter name must terminate with %<:%>");
12035 c_parser_consume_token (parser);
12039 if (property_getter_ident != NULL_TREE)
12040 c_parser_error (parser, "the %<getter%> attribute may only be specified once");
12042 property_getter_ident = c_parser_peek_token (parser)->value;
12043 c_parser_consume_token (parser);
12047 c_parser_error (parser, "unknown property attribute");
12048 syntax_error = true;
12055 if (c_parser_next_token_is (parser, CPP_COMMA))
12056 c_parser_consume_token (parser);
12060 parser->objc_property_attr_context = false;
12061 parens.skip_until_found_close (parser);
12063 /* ... and the property declaration(s). */
12064 properties = c_parser_struct_declaration (parser);
12066 if (properties == error_mark_node)
12068 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12069 parser->error = false;
12073 if (properties == NULL_TREE)
12074 c_parser_error (parser, "expected identifier");
12077 /* Comma-separated properties are chained together in
12078 reverse order; add them one by one. */
12079 properties = nreverse (properties);
12081 for (; properties; properties = TREE_CHAIN (properties))
12082 objc_add_property_declaration (loc, copy_node (properties),
12083 property_readonly, property_readwrite,
12084 property_assign, property_retain,
12085 property_copy, property_nonatomic,
12086 property_getter_ident, property_setter_ident);
12089 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12090 parser->error = false;
12093 /* Parse an Objective-C @synthesize declaration. The syntax is:
12095 objc-synthesize-declaration:
12096 @synthesize objc-synthesize-identifier-list ;
12098 objc-synthesize-identifier-list:
12099 objc-synthesize-identifier
12100 objc-synthesize-identifier-list, objc-synthesize-identifier
12102 objc-synthesize-identifier
12104 identifier = identifier
12107 @synthesize MyProperty;
12108 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12110 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12111 for C++. Keep them in sync.
12114 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12116 tree list = NULL_TREE;
12118 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12119 loc = c_parser_peek_token (parser)->location;
12121 c_parser_consume_token (parser);
12124 tree property, ivar;
12125 if (c_parser_next_token_is_not (parser, CPP_NAME))
12127 c_parser_error (parser, "expected identifier");
12128 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12129 /* Once we find the semicolon, we can resume normal parsing.
12130 We have to reset parser->error manually because
12131 c_parser_skip_until_found() won't reset it for us if the
12132 next token is precisely a semicolon. */
12133 parser->error = false;
12136 property = c_parser_peek_token (parser)->value;
12137 c_parser_consume_token (parser);
12138 if (c_parser_next_token_is (parser, CPP_EQ))
12140 c_parser_consume_token (parser);
12141 if (c_parser_next_token_is_not (parser, CPP_NAME))
12143 c_parser_error (parser, "expected identifier");
12144 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12145 parser->error = false;
12148 ivar = c_parser_peek_token (parser)->value;
12149 c_parser_consume_token (parser);
12153 list = chainon (list, build_tree_list (ivar, property));
12154 if (c_parser_next_token_is (parser, CPP_COMMA))
12155 c_parser_consume_token (parser);
12159 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12160 objc_add_synthesize_declaration (loc, list);
12163 /* Parse an Objective-C @dynamic declaration. The syntax is:
12165 objc-dynamic-declaration:
12166 @dynamic identifier-list ;
12169 @dynamic MyProperty;
12170 @dynamic MyProperty, AnotherProperty;
12172 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12173 for C++. Keep them in sync.
12176 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12178 tree list = NULL_TREE;
12180 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12181 loc = c_parser_peek_token (parser)->location;
12183 c_parser_consume_token (parser);
12187 if (c_parser_next_token_is_not (parser, CPP_NAME))
12189 c_parser_error (parser, "expected identifier");
12190 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12191 parser->error = false;
12194 property = c_parser_peek_token (parser)->value;
12195 list = chainon (list, build_tree_list (NULL_TREE, property));
12196 c_parser_consume_token (parser);
12197 if (c_parser_next_token_is (parser, CPP_COMMA))
12198 c_parser_consume_token (parser);
12202 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12203 objc_add_dynamic_declaration (loc, list);
12207 /* Parse a pragma GCC ivdep. */
12210 c_parse_pragma_ivdep (c_parser *parser)
12212 c_parser_consume_pragma (parser);
12213 c_parser_skip_to_pragma_eol (parser);
12217 /* Parse a pragma GCC unroll. */
12219 static unsigned short
12220 c_parser_pragma_unroll (c_parser *parser)
12222 unsigned short unroll;
12223 c_parser_consume_pragma (parser);
12224 location_t location = c_parser_peek_token (parser)->location;
12225 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12226 mark_exp_read (expr);
12227 expr = c_fully_fold (expr, false, NULL);
12228 HOST_WIDE_INT lunroll = 0;
12229 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12230 || TREE_CODE (expr) != INTEGER_CST
12231 || (lunroll = tree_to_shwi (expr)) < 0
12232 || lunroll >= USHRT_MAX)
12234 error_at (location, "%<#pragma GCC unroll%> requires an"
12235 " assignment-expression that evaluates to a non-negative"
12236 " integral constant less than %u", USHRT_MAX);
12241 unroll = (unsigned short)lunroll;
12246 c_parser_skip_to_pragma_eol (parser);
12250 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12251 should be considered, statements. ALLOW_STMT is true if we're within
12252 the context of a function and such pragmas are to be allowed. Returns
12253 true if we actually parsed such a pragma. */
12256 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12259 const char *construct = NULL;
12261 id = c_parser_peek_token (parser)->pragma_kind;
12262 gcc_assert (id != PRAGMA_NONE);
12266 case PRAGMA_OACC_DECLARE:
12267 c_parser_oacc_declare (parser);
12270 case PRAGMA_OACC_ENTER_DATA:
12271 if (context != pragma_compound)
12273 construct = "acc enter data";
12275 if (context == pragma_stmt)
12277 error_at (c_parser_peek_token (parser)->location,
12278 "%<#pragma %s%> may only be used in compound "
12279 "statements", construct);
12280 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12285 c_parser_oacc_enter_exit_data (parser, true);
12288 case PRAGMA_OACC_EXIT_DATA:
12289 if (context != pragma_compound)
12291 construct = "acc exit data";
12294 c_parser_oacc_enter_exit_data (parser, false);
12297 case PRAGMA_OACC_ROUTINE:
12298 if (context != pragma_external)
12300 error_at (c_parser_peek_token (parser)->location,
12301 "%<#pragma acc routine%> must be at file scope");
12302 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12305 c_parser_oacc_routine (parser, context);
12308 case PRAGMA_OACC_UPDATE:
12309 if (context != pragma_compound)
12311 construct = "acc update";
12314 c_parser_oacc_update (parser);
12317 case PRAGMA_OMP_BARRIER:
12318 if (context != pragma_compound)
12320 construct = "omp barrier";
12323 c_parser_omp_barrier (parser);
12326 case PRAGMA_OMP_DEPOBJ:
12327 if (context != pragma_compound)
12329 construct = "omp depobj";
12332 c_parser_omp_depobj (parser);
12335 case PRAGMA_OMP_FLUSH:
12336 if (context != pragma_compound)
12338 construct = "omp flush";
12341 c_parser_omp_flush (parser);
12344 case PRAGMA_OMP_TASKWAIT:
12345 if (context != pragma_compound)
12347 construct = "omp taskwait";
12350 c_parser_omp_taskwait (parser);
12353 case PRAGMA_OMP_TASKYIELD:
12354 if (context != pragma_compound)
12356 construct = "omp taskyield";
12359 c_parser_omp_taskyield (parser);
12362 case PRAGMA_OMP_CANCEL:
12363 if (context != pragma_compound)
12365 construct = "omp cancel";
12368 c_parser_omp_cancel (parser);
12371 case PRAGMA_OMP_CANCELLATION_POINT:
12372 c_parser_omp_cancellation_point (parser, context);
12375 case PRAGMA_OMP_THREADPRIVATE:
12376 c_parser_omp_threadprivate (parser);
12379 case PRAGMA_OMP_TARGET:
12380 return c_parser_omp_target (parser, context, if_p);
12382 case PRAGMA_OMP_END_DECLARE_TARGET:
12383 c_parser_omp_end_declare_target (parser);
12386 case PRAGMA_OMP_SCAN:
12387 error_at (c_parser_peek_token (parser)->location,
12388 "%<#pragma omp scan%> may only be used in "
12389 "a loop construct with %<inscan%> %<reduction%> clause");
12390 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12393 case PRAGMA_OMP_SECTION:
12394 error_at (c_parser_peek_token (parser)->location,
12395 "%<#pragma omp section%> may only be used in "
12396 "%<#pragma omp sections%> construct");
12397 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12400 case PRAGMA_OMP_DECLARE:
12401 c_parser_omp_declare (parser, context);
12404 case PRAGMA_OMP_REQUIRES:
12405 c_parser_omp_requires (parser);
12408 case PRAGMA_OMP_ORDERED:
12409 return c_parser_omp_ordered (parser, context, if_p);
12413 const bool ivdep = c_parse_pragma_ivdep (parser);
12414 unsigned short unroll;
12415 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12416 unroll = c_parser_pragma_unroll (parser);
12419 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12420 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12421 && !c_parser_next_token_is_keyword (parser, RID_DO))
12423 c_parser_error (parser, "for, while or do statement expected");
12426 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12427 c_parser_for_statement (parser, ivdep, unroll, if_p);
12428 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12429 c_parser_while_statement (parser, ivdep, unroll, if_p);
12431 c_parser_do_statement (parser, ivdep, unroll);
12435 case PRAGMA_UNROLL:
12437 unsigned short unroll = c_parser_pragma_unroll (parser);
12439 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12440 ivdep = c_parse_pragma_ivdep (parser);
12443 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12444 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12445 && !c_parser_next_token_is_keyword (parser, RID_DO))
12447 c_parser_error (parser, "for, while or do statement expected");
12450 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12451 c_parser_for_statement (parser, ivdep, unroll, if_p);
12452 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12453 c_parser_while_statement (parser, ivdep, unroll, if_p);
12455 c_parser_do_statement (parser, ivdep, unroll);
12459 case PRAGMA_GCC_PCH_PREPROCESS:
12460 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12461 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12464 case PRAGMA_OACC_WAIT:
12465 if (context != pragma_compound)
12467 construct = "acc wait";
12470 /* FALL THROUGH. */
12473 if (id < PRAGMA_FIRST_EXTERNAL)
12475 if (context != pragma_stmt && context != pragma_compound)
12478 c_parser_error (parser, "expected declaration specifiers");
12479 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12482 c_parser_omp_construct (parser, if_p);
12488 c_parser_consume_pragma (parser);
12489 c_invoke_pragma_handler (id);
12491 /* Skip to EOL, but suppress any error message. Those will have been
12492 generated by the handler routine through calling error, as opposed
12493 to calling c_parser_error. */
12494 parser->error = true;
12495 c_parser_skip_to_pragma_eol (parser);
12500 /* The interface the pragma parsers have to the lexer. */
12503 pragma_lex (tree *value, location_t *loc)
12505 c_token *tok = c_parser_peek_token (the_parser);
12506 enum cpp_ttype ret = tok->type;
12508 *value = tok->value;
12510 *loc = tok->location;
12512 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12514 else if (ret == CPP_STRING)
12515 *value = c_parser_string_literal (the_parser, false, false).value;
12518 if (ret == CPP_KEYWORD)
12520 c_parser_consume_token (the_parser);
12527 c_parser_pragma_pch_preprocess (c_parser *parser)
12531 parser->lex_joined_string = true;
12532 c_parser_consume_pragma (parser);
12533 if (c_parser_next_token_is (parser, CPP_STRING))
12535 name = c_parser_peek_token (parser)->value;
12536 c_parser_consume_token (parser);
12539 c_parser_error (parser, "expected string literal");
12540 c_parser_skip_to_pragma_eol (parser);
12541 parser->lex_joined_string = false;
12544 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12547 /* OpenACC and OpenMP parsing routines. */
12549 /* Returns name of the next clause.
12550 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12551 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12552 returned and the token is consumed. */
12554 static pragma_omp_clause
12555 c_parser_omp_clause_name (c_parser *parser)
12557 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12559 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12560 result = PRAGMA_OACC_CLAUSE_AUTO;
12561 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12562 result = PRAGMA_OMP_CLAUSE_IF;
12563 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12564 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12565 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12566 result = PRAGMA_OMP_CLAUSE_FOR;
12567 else if (c_parser_next_token_is (parser, CPP_NAME))
12569 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12574 if (!strcmp ("aligned", p))
12575 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12576 else if (!strcmp ("async", p))
12577 result = PRAGMA_OACC_CLAUSE_ASYNC;
12578 else if (!strcmp ("attach", p))
12579 result = PRAGMA_OACC_CLAUSE_ATTACH;
12582 if (!strcmp ("bind", p))
12583 result = PRAGMA_OMP_CLAUSE_BIND;
12586 if (!strcmp ("collapse", p))
12587 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12588 else if (!strcmp ("copy", p))
12589 result = PRAGMA_OACC_CLAUSE_COPY;
12590 else if (!strcmp ("copyin", p))
12591 result = PRAGMA_OMP_CLAUSE_COPYIN;
12592 else if (!strcmp ("copyout", p))
12593 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12594 else if (!strcmp ("copyprivate", p))
12595 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12596 else if (!strcmp ("create", p))
12597 result = PRAGMA_OACC_CLAUSE_CREATE;
12600 if (!strcmp ("defaultmap", p))
12601 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12602 else if (!strcmp ("delete", p))
12603 result = PRAGMA_OACC_CLAUSE_DELETE;
12604 else if (!strcmp ("depend", p))
12605 result = PRAGMA_OMP_CLAUSE_DEPEND;
12606 else if (!strcmp ("detach", p))
12607 result = PRAGMA_OACC_CLAUSE_DETACH;
12608 else if (!strcmp ("device", p))
12609 result = PRAGMA_OMP_CLAUSE_DEVICE;
12610 else if (!strcmp ("deviceptr", p))
12611 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12612 else if (!strcmp ("device_resident", p))
12613 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12614 else if (!strcmp ("device_type", p))
12615 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12616 else if (!strcmp ("dist_schedule", p))
12617 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12620 if (!strcmp ("final", p))
12621 result = PRAGMA_OMP_CLAUSE_FINAL;
12622 else if (!strcmp ("finalize", p))
12623 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12624 else if (!strcmp ("firstprivate", p))
12625 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12626 else if (!strcmp ("from", p))
12627 result = PRAGMA_OMP_CLAUSE_FROM;
12630 if (!strcmp ("gang", p))
12631 result = PRAGMA_OACC_CLAUSE_GANG;
12632 else if (!strcmp ("grainsize", p))
12633 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12636 if (!strcmp ("hint", p))
12637 result = PRAGMA_OMP_CLAUSE_HINT;
12638 else if (!strcmp ("host", p))
12639 result = PRAGMA_OACC_CLAUSE_HOST;
12642 if (!strcmp ("if_present", p))
12643 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12644 else if (!strcmp ("in_reduction", p))
12645 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12646 else if (!strcmp ("inbranch", p))
12647 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12648 else if (!strcmp ("independent", p))
12649 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12650 else if (!strcmp ("is_device_ptr", p))
12651 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12654 if (!strcmp ("lastprivate", p))
12655 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12656 else if (!strcmp ("linear", p))
12657 result = PRAGMA_OMP_CLAUSE_LINEAR;
12658 else if (!strcmp ("link", p))
12659 result = PRAGMA_OMP_CLAUSE_LINK;
12662 if (!strcmp ("map", p))
12663 result = PRAGMA_OMP_CLAUSE_MAP;
12664 else if (!strcmp ("mergeable", p))
12665 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12668 if (!strcmp ("no_create", p))
12669 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12670 else if (!strcmp ("nogroup", p))
12671 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12672 else if (!strcmp ("nontemporal", p))
12673 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12674 else if (!strcmp ("notinbranch", p))
12675 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12676 else if (!strcmp ("nowait", p))
12677 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12678 else if (!strcmp ("num_gangs", p))
12679 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12680 else if (!strcmp ("num_tasks", p))
12681 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12682 else if (!strcmp ("num_teams", p))
12683 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12684 else if (!strcmp ("num_threads", p))
12685 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12686 else if (!strcmp ("num_workers", p))
12687 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12690 if (!strcmp ("ordered", p))
12691 result = PRAGMA_OMP_CLAUSE_ORDERED;
12692 else if (!strcmp ("order", p))
12693 result = PRAGMA_OMP_CLAUSE_ORDER;
12696 if (!strcmp ("parallel", p))
12697 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12698 else if (!strcmp ("present", p))
12699 result = PRAGMA_OACC_CLAUSE_PRESENT;
12700 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12702 else if (!strcmp ("present_or_copy", p)
12703 || !strcmp ("pcopy", p))
12704 result = PRAGMA_OACC_CLAUSE_COPY;
12705 else if (!strcmp ("present_or_copyin", p)
12706 || !strcmp ("pcopyin", p))
12707 result = PRAGMA_OACC_CLAUSE_COPYIN;
12708 else if (!strcmp ("present_or_copyout", p)
12709 || !strcmp ("pcopyout", p))
12710 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12711 else if (!strcmp ("present_or_create", p)
12712 || !strcmp ("pcreate", p))
12713 result = PRAGMA_OACC_CLAUSE_CREATE;
12714 else if (!strcmp ("priority", p))
12715 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12716 else if (!strcmp ("private", p))
12717 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12718 else if (!strcmp ("proc_bind", p))
12719 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12722 if (!strcmp ("reduction", p))
12723 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12726 if (!strcmp ("safelen", p))
12727 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12728 else if (!strcmp ("schedule", p))
12729 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12730 else if (!strcmp ("sections", p))
12731 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12732 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12733 result = PRAGMA_OACC_CLAUSE_HOST;
12734 else if (!strcmp ("seq", p))
12735 result = PRAGMA_OACC_CLAUSE_SEQ;
12736 else if (!strcmp ("shared", p))
12737 result = PRAGMA_OMP_CLAUSE_SHARED;
12738 else if (!strcmp ("simd", p))
12739 result = PRAGMA_OMP_CLAUSE_SIMD;
12740 else if (!strcmp ("simdlen", p))
12741 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12744 if (!strcmp ("task_reduction", p))
12745 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12746 else if (!strcmp ("taskgroup", p))
12747 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12748 else if (!strcmp ("thread_limit", p))
12749 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12750 else if (!strcmp ("threads", p))
12751 result = PRAGMA_OMP_CLAUSE_THREADS;
12752 else if (!strcmp ("tile", p))
12753 result = PRAGMA_OACC_CLAUSE_TILE;
12754 else if (!strcmp ("to", p))
12755 result = PRAGMA_OMP_CLAUSE_TO;
12758 if (!strcmp ("uniform", p))
12759 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12760 else if (!strcmp ("untied", p))
12761 result = PRAGMA_OMP_CLAUSE_UNTIED;
12762 else if (!strcmp ("use_device", p))
12763 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12764 else if (!strcmp ("use_device_addr", p))
12765 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12766 else if (!strcmp ("use_device_ptr", p))
12767 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12770 if (!strcmp ("vector", p))
12771 result = PRAGMA_OACC_CLAUSE_VECTOR;
12772 else if (!strcmp ("vector_length", p))
12773 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12776 if (!strcmp ("wait", p))
12777 result = PRAGMA_OACC_CLAUSE_WAIT;
12778 else if (!strcmp ("worker", p))
12779 result = PRAGMA_OACC_CLAUSE_WORKER;
12784 if (result != PRAGMA_OMP_CLAUSE_NONE)
12785 c_parser_consume_token (parser);
12790 /* Validate that a clause of the given type does not already exist. */
12793 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12796 if (tree c = omp_find_clause (clauses, code))
12797 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12801 Parse wait clause or wait directive parameters. */
12804 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12806 vec<tree, va_gc> *args;
12809 matching_parens parens;
12810 if (!parens.require_open (parser))
12813 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12814 args_tree = build_tree_list_vec (args);
12816 for (t = args_tree; t; t = TREE_CHAIN (t))
12818 tree targ = TREE_VALUE (t);
12820 if (targ != error_mark_node)
12822 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12824 c_parser_error (parser, "expression must be integral");
12825 targ = error_mark_node;
12829 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12831 OMP_CLAUSE_DECL (c) = targ;
12832 OMP_CLAUSE_CHAIN (c) = list;
12838 release_tree_vector (args);
12839 parens.require_close (parser);
12843 /* OpenACC 2.0, OpenMP 2.5:
12846 variable-list , identifier
12848 If KIND is nonzero, create the appropriate node and install the
12849 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12850 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12852 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12853 return the list created.
12855 The optional ALLOW_DEREF argument is true if list items can use the deref
12859 c_parser_omp_variable_list (c_parser *parser,
12860 location_t clause_loc,
12861 enum omp_clause_code kind, tree list,
12862 bool allow_deref = false)
12864 auto_vec<c_token> tokens;
12865 unsigned int tokens_avail = 0;
12870 bool array_section_p = false;
12871 if (kind == OMP_CLAUSE_DEPEND)
12873 if (c_parser_next_token_is_not (parser, CPP_NAME)
12874 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
12876 struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
12877 if (expr.value != error_mark_node)
12879 tree u = build_omp_clause (clause_loc, kind);
12880 OMP_CLAUSE_DECL (u) = expr.value;
12881 OMP_CLAUSE_CHAIN (u) = list;
12885 if (c_parser_next_token_is_not (parser, CPP_COMMA))
12888 c_parser_consume_token (parser);
12893 tokens.truncate (0);
12894 unsigned int nesting_depth = 0;
12897 c_token *token = c_parser_peek_token (parser);
12898 switch (token->type)
12901 case CPP_PRAGMA_EOL:
12903 case CPP_OPEN_BRACE:
12904 case CPP_OPEN_PAREN:
12905 case CPP_OPEN_SQUARE:
12908 case CPP_CLOSE_BRACE:
12909 case CPP_CLOSE_PAREN:
12910 case CPP_CLOSE_SQUARE:
12911 if (nesting_depth-- == 0)
12915 if (nesting_depth == 0)
12920 tokens.safe_push (*token);
12921 c_parser_consume_token (parser);
12927 /* Make sure nothing tries to read past the end of the tokens. */
12929 memset (&eof_token, 0, sizeof (eof_token));
12930 eof_token.type = CPP_EOF;
12931 tokens.safe_push (eof_token);
12932 tokens.safe_push (eof_token);
12934 tokens_avail = parser->tokens_avail;
12935 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
12936 parser->tokens = tokens.address ();
12937 parser->tokens_avail = tokens.length ();
12940 tree t = NULL_TREE;
12942 if (c_parser_next_token_is (parser, CPP_NAME)
12943 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
12945 t = lookup_name (c_parser_peek_token (parser)->value);
12947 if (t == NULL_TREE)
12949 undeclared_variable (c_parser_peek_token (parser)->location,
12950 c_parser_peek_token (parser)->value);
12951 t = error_mark_node;
12954 c_parser_consume_token (parser);
12956 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
12957 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
12958 || (c_parser_peek_token (parser)->keyword
12959 == RID_PRETTY_FUNCTION_NAME)
12960 || (c_parser_peek_token (parser)->keyword
12961 == RID_C99_FUNCTION_NAME)))
12962 t = c_parser_predefined_identifier (parser).value;
12966 c_parser_error (parser, "expected identifier");
12970 if (t == error_mark_node)
12972 else if (kind != 0)
12976 case OMP_CLAUSE__CACHE_:
12977 /* The OpenACC cache directive explicitly only allows "array
12978 elements or subarrays". */
12979 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
12981 c_parser_error (parser, "expected %<[%>");
12982 t = error_mark_node;
12986 case OMP_CLAUSE_MAP:
12987 case OMP_CLAUSE_FROM:
12988 case OMP_CLAUSE_TO:
12989 while (c_parser_next_token_is (parser, CPP_DOT)
12991 && c_parser_next_token_is (parser, CPP_DEREF)))
12993 location_t op_loc = c_parser_peek_token (parser)->location;
12994 if (c_parser_next_token_is (parser, CPP_DEREF))
12995 t = build_simple_mem_ref (t);
12996 c_parser_consume_token (parser);
12997 if (!c_parser_next_token_is (parser, CPP_NAME))
12999 c_parser_error (parser, "expected identifier");
13000 t = error_mark_node;
13004 c_token *comp_tok = c_parser_peek_token (parser);
13005 tree ident = comp_tok->value;
13006 location_t comp_loc = comp_tok->location;
13007 c_parser_consume_token (parser);
13008 t = build_component_ref (op_loc, t, ident, comp_loc);
13011 case OMP_CLAUSE_DEPEND:
13012 case OMP_CLAUSE_REDUCTION:
13013 case OMP_CLAUSE_IN_REDUCTION:
13014 case OMP_CLAUSE_TASK_REDUCTION:
13015 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13017 tree low_bound = NULL_TREE, length = NULL_TREE;
13019 c_parser_consume_token (parser);
13020 if (!c_parser_next_token_is (parser, CPP_COLON))
13022 location_t expr_loc
13023 = c_parser_peek_token (parser)->location;
13024 c_expr expr = c_parser_expression (parser);
13025 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13027 low_bound = expr.value;
13029 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13030 length = integer_one_node;
13033 /* Look for `:'. */
13034 if (!c_parser_require (parser, CPP_COLON,
13037 t = error_mark_node;
13040 array_section_p = true;
13041 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13043 location_t expr_loc
13044 = c_parser_peek_token (parser)->location;
13045 c_expr expr = c_parser_expression (parser);
13046 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13048 length = expr.value;
13051 /* Look for the closing `]'. */
13052 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13055 t = error_mark_node;
13059 t = tree_cons (low_bound, length, t);
13061 if (kind == OMP_CLAUSE_DEPEND
13062 && t != error_mark_node
13063 && parser->tokens_avail != 2)
13065 if (array_section_p)
13067 error_at (c_parser_peek_token (parser)->location,
13068 "expected %<)%> or %<,%>");
13069 t = error_mark_node;
13073 parser->tokens = tokens.address ();
13074 parser->tokens_avail = tokens.length ();
13076 t = c_parser_expr_no_commas (parser, NULL).value;
13077 if (t != error_mark_node && parser->tokens_avail != 2)
13079 error_at (c_parser_peek_token (parser)->location,
13080 "expected %<)%> or %<,%>");
13081 t = error_mark_node;
13090 if (t != error_mark_node)
13092 tree u = build_omp_clause (clause_loc, kind);
13093 OMP_CLAUSE_DECL (u) = t;
13094 OMP_CLAUSE_CHAIN (u) = list;
13099 list = tree_cons (t, NULL_TREE, list);
13101 if (kind == OMP_CLAUSE_DEPEND)
13103 parser->tokens = &parser->tokens_buf[0];
13104 parser->tokens_avail = tokens_avail;
13106 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13109 c_parser_consume_token (parser);
13116 /* Similarly, but expect leading and trailing parenthesis. This is a very
13117 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13118 argument is true if list items can use the deref (->) operator. */
13121 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13122 tree list, bool allow_deref = false)
13124 /* The clauses location. */
13125 location_t loc = c_parser_peek_token (parser)->location;
13127 matching_parens parens;
13128 if (parens.require_open (parser))
13130 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13131 parens.skip_until_found_close (parser);
13137 copy ( variable-list )
13138 copyin ( variable-list )
13139 copyout ( variable-list )
13140 create ( variable-list )
13141 delete ( variable-list )
13142 present ( variable-list )
13145 no_create ( variable-list )
13146 attach ( variable-list )
13147 detach ( variable-list ) */
13150 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13153 enum gomp_map_kind kind;
13156 case PRAGMA_OACC_CLAUSE_ATTACH:
13157 kind = GOMP_MAP_ATTACH;
13159 case PRAGMA_OACC_CLAUSE_COPY:
13160 kind = GOMP_MAP_TOFROM;
13162 case PRAGMA_OACC_CLAUSE_COPYIN:
13163 kind = GOMP_MAP_TO;
13165 case PRAGMA_OACC_CLAUSE_COPYOUT:
13166 kind = GOMP_MAP_FROM;
13168 case PRAGMA_OACC_CLAUSE_CREATE:
13169 kind = GOMP_MAP_ALLOC;
13171 case PRAGMA_OACC_CLAUSE_DELETE:
13172 kind = GOMP_MAP_RELEASE;
13174 case PRAGMA_OACC_CLAUSE_DETACH:
13175 kind = GOMP_MAP_DETACH;
13177 case PRAGMA_OACC_CLAUSE_DEVICE:
13178 kind = GOMP_MAP_FORCE_TO;
13180 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13181 kind = GOMP_MAP_DEVICE_RESIDENT;
13183 case PRAGMA_OACC_CLAUSE_HOST:
13184 kind = GOMP_MAP_FORCE_FROM;
13186 case PRAGMA_OACC_CLAUSE_LINK:
13187 kind = GOMP_MAP_LINK;
13189 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13190 kind = GOMP_MAP_IF_PRESENT;
13192 case PRAGMA_OACC_CLAUSE_PRESENT:
13193 kind = GOMP_MAP_FORCE_PRESENT;
13196 gcc_unreachable ();
13199 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13201 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13202 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13208 deviceptr ( variable-list ) */
13211 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13213 location_t loc = c_parser_peek_token (parser)->location;
13216 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13217 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13218 variable-list must only allow for pointer variables. */
13219 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13220 for (t = vars; t && t; t = TREE_CHAIN (t))
13222 tree v = TREE_PURPOSE (t);
13224 /* FIXME diagnostics: Ideally we should keep individual
13225 locations for all the variables in the var list to make the
13226 following errors more precise. Perhaps
13227 c_parser_omp_var_list_parens() should construct a list of
13228 locations to go along with the var list. */
13230 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13231 error_at (loc, "%qD is not a variable", v);
13232 else if (TREE_TYPE (v) == error_mark_node)
13234 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13235 error_at (loc, "%qD is not a pointer variable", v);
13237 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13238 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13239 OMP_CLAUSE_DECL (u) = v;
13240 OMP_CLAUSE_CHAIN (u) = list;
13247 /* OpenACC 2.0, OpenMP 3.0:
13248 collapse ( constant-expression ) */
13251 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13253 tree c, num = error_mark_node;
13257 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13258 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13260 loc = c_parser_peek_token (parser)->location;
13261 matching_parens parens;
13262 if (parens.require_open (parser))
13264 num = c_parser_expr_no_commas (parser, NULL).value;
13265 parens.skip_until_found_close (parser);
13267 if (num == error_mark_node)
13269 mark_exp_read (num);
13270 num = c_fully_fold (num, false, NULL);
13271 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13272 || !tree_fits_shwi_p (num)
13273 || (n = tree_to_shwi (num)) <= 0
13277 "collapse argument needs positive constant integer expression");
13280 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13281 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13282 OMP_CLAUSE_CHAIN (c) = list;
13287 copyin ( variable-list ) */
13290 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13292 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13296 copyprivate ( variable-list ) */
13299 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13301 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13305 default ( none | shared )
13308 default ( none | present ) */
13311 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13313 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13314 location_t loc = c_parser_peek_token (parser)->location;
13317 matching_parens parens;
13318 if (!parens.require_open (parser))
13320 if (c_parser_next_token_is (parser, CPP_NAME))
13322 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13327 if (strcmp ("none", p) != 0)
13329 kind = OMP_CLAUSE_DEFAULT_NONE;
13333 if (strcmp ("present", p) != 0 || !is_oacc)
13335 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13339 if (strcmp ("shared", p) != 0 || is_oacc)
13341 kind = OMP_CLAUSE_DEFAULT_SHARED;
13348 c_parser_consume_token (parser);
13354 c_parser_error (parser, "expected %<none%> or %<present%>");
13356 c_parser_error (parser, "expected %<none%> or %<shared%>");
13358 parens.skip_until_found_close (parser);
13360 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13363 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13364 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13365 OMP_CLAUSE_CHAIN (c) = list;
13366 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13372 firstprivate ( variable-list ) */
13375 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13377 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13381 final ( expression ) */
13384 c_parser_omp_clause_final (c_parser *parser, tree list)
13386 location_t loc = c_parser_peek_token (parser)->location;
13387 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13389 matching_parens parens;
13391 if (!parens.require_open (parser))
13392 t = error_mark_node;
13395 location_t eloc = c_parser_peek_token (parser)->location;
13396 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13397 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13398 t = c_objc_common_truthvalue_conversion (eloc, t);
13399 t = c_fully_fold (t, false, NULL);
13400 parens.skip_until_found_close (parser);
13403 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13405 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13406 OMP_CLAUSE_FINAL_EXPR (c) = t;
13407 OMP_CLAUSE_CHAIN (c) = list;
13411 c_parser_error (parser, "expected %<(%>");
13416 /* OpenACC, OpenMP 2.5:
13420 if ( directive-name-modifier : expression )
13422 directive-name-modifier:
13423 parallel | task | taskloop | target data | target | target update
13424 | target enter data | target exit data
13427 directive-name-modifier:
13428 ... | simd | cancel */
13431 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13433 location_t location = c_parser_peek_token (parser)->location;
13434 enum tree_code if_modifier = ERROR_MARK;
13436 matching_parens parens;
13437 if (!parens.require_open (parser))
13440 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13442 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13444 if (strcmp (p, "cancel") == 0)
13445 if_modifier = VOID_CST;
13446 else if (strcmp (p, "parallel") == 0)
13447 if_modifier = OMP_PARALLEL;
13448 else if (strcmp (p, "simd") == 0)
13449 if_modifier = OMP_SIMD;
13450 else if (strcmp (p, "task") == 0)
13451 if_modifier = OMP_TASK;
13452 else if (strcmp (p, "taskloop") == 0)
13453 if_modifier = OMP_TASKLOOP;
13454 else if (strcmp (p, "target") == 0)
13456 if_modifier = OMP_TARGET;
13457 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13459 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13460 if (strcmp ("data", p) == 0)
13461 if_modifier = OMP_TARGET_DATA;
13462 else if (strcmp ("update", p) == 0)
13463 if_modifier = OMP_TARGET_UPDATE;
13464 else if (strcmp ("enter", p) == 0)
13465 if_modifier = OMP_TARGET_ENTER_DATA;
13466 else if (strcmp ("exit", p) == 0)
13467 if_modifier = OMP_TARGET_EXIT_DATA;
13468 if (if_modifier != OMP_TARGET)
13471 c_parser_consume_token (parser);
13475 location_t loc = c_parser_peek_2nd_token (parser)->location;
13476 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13478 if_modifier = ERROR_MARK;
13480 if (if_modifier == OMP_TARGET_ENTER_DATA
13481 || if_modifier == OMP_TARGET_EXIT_DATA)
13483 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13485 p = IDENTIFIER_POINTER
13486 (c_parser_peek_2nd_token (parser)->value);
13487 if (strcmp ("data", p) == 0)
13491 c_parser_consume_token (parser);
13495 = c_parser_peek_2nd_token (parser)->location;
13496 error_at (loc, "expected %<data%>");
13497 if_modifier = ERROR_MARK;
13502 if (if_modifier != ERROR_MARK)
13504 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13506 c_parser_consume_token (parser);
13507 c_parser_consume_token (parser);
13513 location_t loc = c_parser_peek_2nd_token (parser)->location;
13514 error_at (loc, "expected %<:%>");
13516 if_modifier = ERROR_MARK;
13521 location_t loc = c_parser_peek_token (parser)->location;
13522 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13523 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13524 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13525 t = c_fully_fold (t, false, NULL);
13526 parens.skip_until_found_close (parser);
13528 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13529 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13531 if (if_modifier != ERROR_MARK
13532 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13534 const char *p = NULL;
13535 switch (if_modifier)
13537 case VOID_CST: p = "cancel"; break;
13538 case OMP_PARALLEL: p = "parallel"; break;
13539 case OMP_SIMD: p = "simd"; break;
13540 case OMP_TASK: p = "task"; break;
13541 case OMP_TASKLOOP: p = "taskloop"; break;
13542 case OMP_TARGET_DATA: p = "target data"; break;
13543 case OMP_TARGET: p = "target"; break;
13544 case OMP_TARGET_UPDATE: p = "target update"; break;
13545 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13546 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13547 default: gcc_unreachable ();
13549 error_at (location, "too many %<if%> clauses with %qs modifier",
13553 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13556 error_at (location, "too many %<if%> clauses");
13558 error_at (location, "too many %<if%> clauses without modifier");
13561 else if (if_modifier == ERROR_MARK
13562 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13564 error_at (location, "if any %<if%> clause has modifier, then all "
13565 "%<if%> clauses have to use modifier");
13570 c = build_omp_clause (location, OMP_CLAUSE_IF);
13571 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13572 OMP_CLAUSE_IF_EXPR (c) = t;
13573 OMP_CLAUSE_CHAIN (c) = list;
13578 lastprivate ( variable-list )
13581 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13584 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13586 /* The clauses location. */
13587 location_t loc = c_parser_peek_token (parser)->location;
13589 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13591 bool conditional = false;
13592 if (c_parser_next_token_is (parser, CPP_NAME)
13593 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13596 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13597 if (strcmp (p, "conditional") == 0)
13599 conditional = true;
13600 c_parser_consume_token (parser);
13601 c_parser_consume_token (parser);
13604 tree nlist = c_parser_omp_variable_list (parser, loc,
13605 OMP_CLAUSE_LASTPRIVATE, list);
13606 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13608 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13609 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13619 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13623 /* FIXME: Should we allow duplicates? */
13624 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13626 c = build_omp_clause (c_parser_peek_token (parser)->location,
13627 OMP_CLAUSE_MERGEABLE);
13628 OMP_CLAUSE_CHAIN (c) = list;
13637 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13640 location_t loc = c_parser_peek_token (parser)->location;
13642 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13644 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13645 OMP_CLAUSE_CHAIN (c) = list;
13650 num_threads ( expression ) */
13653 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13655 location_t num_threads_loc = c_parser_peek_token (parser)->location;
13656 matching_parens parens;
13657 if (parens.require_open (parser))
13659 location_t expr_loc = c_parser_peek_token (parser)->location;
13660 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13661 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13662 tree c, t = expr.value;
13663 t = c_fully_fold (t, false, NULL);
13665 parens.skip_until_found_close (parser);
13667 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13669 c_parser_error (parser, "expected integer expression");
13673 /* Attempt to statically determine when the number isn't positive. */
13674 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13675 build_int_cst (TREE_TYPE (t), 0));
13676 protected_set_expr_location (c, expr_loc);
13677 if (c == boolean_true_node)
13679 warning_at (expr_loc, 0,
13680 "%<num_threads%> value must be positive");
13681 t = integer_one_node;
13684 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13686 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13687 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13688 OMP_CLAUSE_CHAIN (c) = list;
13696 num_tasks ( expression ) */
13699 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13701 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13702 matching_parens parens;
13703 if (parens.require_open (parser))
13705 location_t expr_loc = c_parser_peek_token (parser)->location;
13706 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13707 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13708 tree c, t = expr.value;
13709 t = c_fully_fold (t, false, NULL);
13711 parens.skip_until_found_close (parser);
13713 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13715 c_parser_error (parser, "expected integer expression");
13719 /* Attempt to statically determine when the number isn't positive. */
13720 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13721 build_int_cst (TREE_TYPE (t), 0));
13722 if (CAN_HAVE_LOCATION_P (c))
13723 SET_EXPR_LOCATION (c, expr_loc);
13724 if (c == boolean_true_node)
13726 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13727 t = integer_one_node;
13730 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13732 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13733 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13734 OMP_CLAUSE_CHAIN (c) = list;
13742 grainsize ( expression ) */
13745 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13747 location_t grainsize_loc = c_parser_peek_token (parser)->location;
13748 matching_parens parens;
13749 if (parens.require_open (parser))
13751 location_t expr_loc = c_parser_peek_token (parser)->location;
13752 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13753 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13754 tree c, t = expr.value;
13755 t = c_fully_fold (t, false, NULL);
13757 parens.skip_until_found_close (parser);
13759 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13761 c_parser_error (parser, "expected integer expression");
13765 /* Attempt to statically determine when the number isn't positive. */
13766 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13767 build_int_cst (TREE_TYPE (t), 0));
13768 if (CAN_HAVE_LOCATION_P (c))
13769 SET_EXPR_LOCATION (c, expr_loc);
13770 if (c == boolean_true_node)
13772 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
13773 t = integer_one_node;
13776 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
13778 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
13779 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
13780 OMP_CLAUSE_CHAIN (c) = list;
13788 priority ( expression ) */
13791 c_parser_omp_clause_priority (c_parser *parser, tree list)
13793 location_t priority_loc = c_parser_peek_token (parser)->location;
13794 matching_parens parens;
13795 if (parens.require_open (parser))
13797 location_t expr_loc = c_parser_peek_token (parser)->location;
13798 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13799 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13800 tree c, t = expr.value;
13801 t = c_fully_fold (t, false, NULL);
13803 parens.skip_until_found_close (parser);
13805 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13807 c_parser_error (parser, "expected integer expression");
13811 /* Attempt to statically determine when the number isn't
13813 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
13814 build_int_cst (TREE_TYPE (t), 0));
13815 if (CAN_HAVE_LOCATION_P (c))
13816 SET_EXPR_LOCATION (c, expr_loc);
13817 if (c == boolean_true_node)
13819 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
13820 t = integer_one_node;
13823 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
13825 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
13826 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
13827 OMP_CLAUSE_CHAIN (c) = list;
13835 hint ( expression ) */
13838 c_parser_omp_clause_hint (c_parser *parser, tree list)
13840 location_t hint_loc = c_parser_peek_token (parser)->location;
13841 matching_parens parens;
13842 if (parens.require_open (parser))
13844 location_t expr_loc = c_parser_peek_token (parser)->location;
13845 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13846 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13847 tree c, t = expr.value;
13848 t = c_fully_fold (t, false, NULL);
13850 parens.skip_until_found_close (parser);
13852 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
13853 || TREE_CODE (t) != INTEGER_CST)
13855 c_parser_error (parser, "expected constant integer expression");
13859 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
13861 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
13862 OMP_CLAUSE_HINT_EXPR (c) = t;
13863 OMP_CLAUSE_CHAIN (c) = list;
13871 defaultmap ( tofrom : scalar )
13874 defaultmap ( implicit-behavior [ : variable-category ] ) */
13877 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
13879 location_t loc = c_parser_peek_token (parser)->location;
13882 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13883 enum omp_clause_defaultmap_kind category
13884 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
13886 matching_parens parens;
13887 if (!parens.require_open (parser))
13889 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
13891 else if (!c_parser_next_token_is (parser, CPP_NAME))
13894 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
13895 "%<tofrom%>, %<firstprivate%>, %<none%> "
13900 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13905 if (strcmp ("alloc", p) == 0)
13906 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
13908 goto invalid_behavior;
13912 if (strcmp ("default", p) == 0)
13913 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13915 goto invalid_behavior;
13919 if (strcmp ("firstprivate", p) == 0)
13920 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
13921 else if (strcmp ("from", p) == 0)
13922 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
13924 goto invalid_behavior;
13928 if (strcmp ("none", p) == 0)
13929 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
13931 goto invalid_behavior;
13935 if (strcmp ("tofrom", p) == 0)
13936 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
13937 else if (strcmp ("to", p) == 0)
13938 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
13940 goto invalid_behavior;
13944 goto invalid_behavior;
13946 c_parser_consume_token (parser);
13948 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
13950 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13952 if (!c_parser_next_token_is (parser, CPP_NAME))
13955 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
13959 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13963 if (strcmp ("aggregate", p) == 0)
13964 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
13966 goto invalid_category;
13970 if (strcmp ("pointer", p) == 0)
13971 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
13973 goto invalid_category;
13977 if (strcmp ("scalar", p) == 0)
13978 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
13980 goto invalid_category;
13984 goto invalid_category;
13987 c_parser_consume_token (parser);
13989 parens.skip_until_found_close (parser);
13991 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13992 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
13993 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
13994 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
13995 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
13996 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
13998 enum omp_clause_defaultmap_kind cat = category;
13999 location_t loc = OMP_CLAUSE_LOCATION (c);
14000 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14001 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14005 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14008 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14011 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14014 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14018 gcc_unreachable ();
14021 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14024 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14029 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14030 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14031 OMP_CLAUSE_CHAIN (c) = list;
14035 parens.skip_until_found_close (parser);
14040 use_device ( variable-list )
14043 use_device_ptr ( variable-list ) */
14046 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14048 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14053 use_device_addr ( variable-list ) */
14056 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14058 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14063 is_device_ptr ( variable-list ) */
14066 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14068 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14072 num_gangs ( expression )
14073 num_workers ( expression )
14074 vector_length ( expression ) */
14077 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14080 location_t loc = c_parser_peek_token (parser)->location;
14082 matching_parens parens;
14083 if (!parens.require_open (parser))
14086 location_t expr_loc = c_parser_peek_token (parser)->location;
14087 c_expr expr = c_parser_expression (parser);
14088 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14089 tree c, t = expr.value;
14090 t = c_fully_fold (t, false, NULL);
14092 parens.skip_until_found_close (parser);
14094 if (t == error_mark_node)
14096 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14098 error_at (expr_loc, "%qs expression must be integral",
14099 omp_clause_code_name[code]);
14103 /* Attempt to statically determine when the number isn't positive. */
14104 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14105 build_int_cst (TREE_TYPE (t), 0));
14106 protected_set_expr_location (c, expr_loc);
14107 if (c == boolean_true_node)
14109 warning_at (expr_loc, 0,
14110 "%qs value must be positive",
14111 omp_clause_code_name[code]);
14112 t = integer_one_node;
14115 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14117 c = build_omp_clause (loc, code);
14118 OMP_CLAUSE_OPERAND (c, 0) = t;
14119 OMP_CLAUSE_CHAIN (c) = list;
14125 gang [( gang-arg-list )]
14126 worker [( [num:] int-expr )]
14127 vector [( [length:] int-expr )]
14129 where gang-arg is one of:
14134 and size-expr may be:
14141 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14142 omp_clause_code kind,
14143 const char *str, tree list)
14145 const char *id = "num";
14146 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14148 if (kind == OMP_CLAUSE_VECTOR)
14151 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14153 c_parser_consume_token (parser);
14157 c_token *next = c_parser_peek_token (parser);
14160 /* Gang static argument. */
14161 if (kind == OMP_CLAUSE_GANG
14162 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14164 c_parser_consume_token (parser);
14166 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14167 goto cleanup_error;
14170 if (ops[idx] != NULL_TREE)
14172 c_parser_error (parser, "too many %<static%> arguments");
14173 goto cleanup_error;
14176 /* Check for the '*' argument. */
14177 if (c_parser_next_token_is (parser, CPP_MULT)
14178 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14179 || c_parser_peek_2nd_token (parser)->type
14180 == CPP_CLOSE_PAREN))
14182 c_parser_consume_token (parser);
14183 ops[idx] = integer_minus_one_node;
14185 if (c_parser_next_token_is (parser, CPP_COMMA))
14187 c_parser_consume_token (parser);
14194 /* Worker num: argument and vector length: arguments. */
14195 else if (c_parser_next_token_is (parser, CPP_NAME)
14196 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14197 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14199 c_parser_consume_token (parser); /* id */
14200 c_parser_consume_token (parser); /* ':' */
14203 /* Now collect the actual argument. */
14204 if (ops[idx] != NULL_TREE)
14206 c_parser_error (parser, "unexpected argument");
14207 goto cleanup_error;
14210 location_t expr_loc = c_parser_peek_token (parser)->location;
14211 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14212 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14213 tree expr = cexpr.value;
14214 if (expr == error_mark_node)
14215 goto cleanup_error;
14217 expr = c_fully_fold (expr, false, NULL);
14219 /* Attempt to statically determine when the number isn't a
14220 positive integer. */
14222 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14224 c_parser_error (parser, "expected integer expression");
14228 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14229 build_int_cst (TREE_TYPE (expr), 0));
14230 if (c == boolean_true_node)
14232 warning_at (loc, 0,
14233 "%qs value must be positive", str);
14234 expr = integer_one_node;
14239 if (kind == OMP_CLAUSE_GANG
14240 && c_parser_next_token_is (parser, CPP_COMMA))
14242 c_parser_consume_token (parser);
14249 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14250 goto cleanup_error;
14253 check_no_duplicate_clause (list, kind, str);
14255 c = build_omp_clause (loc, kind);
14258 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14260 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14261 OMP_CLAUSE_CHAIN (c) = list;
14266 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14278 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14281 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14283 tree c = build_omp_clause (loc, code);
14284 OMP_CLAUSE_CHAIN (c) = list;
14290 async [( int-expr )] */
14293 c_parser_oacc_clause_async (c_parser *parser, tree list)
14296 location_t loc = c_parser_peek_token (parser)->location;
14298 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14300 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14302 c_parser_consume_token (parser);
14304 t = c_parser_expression (parser).value;
14305 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14306 c_parser_error (parser, "expected integer expression");
14307 else if (t == error_mark_node
14308 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14312 t = c_fully_fold (t, false, NULL);
14314 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14316 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14317 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14318 OMP_CLAUSE_CHAIN (c) = list;
14325 tile ( size-expr-list ) */
14328 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14330 tree c, expr = error_mark_node;
14332 tree tile = NULL_TREE;
14334 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14335 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14337 loc = c_parser_peek_token (parser)->location;
14338 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14343 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14346 if (c_parser_next_token_is (parser, CPP_MULT)
14347 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14348 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14350 c_parser_consume_token (parser);
14351 expr = integer_zero_node;
14355 location_t expr_loc = c_parser_peek_token (parser)->location;
14356 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14357 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14358 expr = cexpr.value;
14360 if (expr == error_mark_node)
14362 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14367 expr = c_fully_fold (expr, false, NULL);
14369 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14370 || !tree_fits_shwi_p (expr)
14371 || tree_to_shwi (expr) <= 0)
14373 error_at (expr_loc, "%<tile%> argument needs positive"
14374 " integral constant");
14375 expr = integer_zero_node;
14379 tile = tree_cons (NULL_TREE, expr, tile);
14381 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14383 /* Consume the trailing ')'. */
14384 c_parser_consume_token (parser);
14386 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14387 tile = nreverse (tile);
14388 OMP_CLAUSE_TILE_LIST (c) = tile;
14389 OMP_CLAUSE_CHAIN (c) = list;
14394 wait [( int-expr-list )] */
14397 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14399 location_t clause_loc = c_parser_peek_token (parser)->location;
14401 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14402 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14405 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14407 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14408 OMP_CLAUSE_CHAIN (c) = list;
14417 order ( concurrent ) */
14420 c_parser_omp_clause_order (c_parser *parser, tree list)
14422 location_t loc = c_parser_peek_token (parser)->location;
14426 matching_parens parens;
14427 if (!parens.require_open (parser))
14429 if (!c_parser_next_token_is (parser, CPP_NAME))
14431 c_parser_error (parser, "expected %<concurrent%>");
14434 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14435 if (strcmp (p, "concurrent") != 0)
14437 c_parser_error (parser, "expected %<concurrent%>");
14440 c_parser_consume_token (parser);
14441 parens.skip_until_found_close (parser);
14442 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14443 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14444 OMP_CLAUSE_CHAIN (c) = list;
14448 parens.skip_until_found_close (parser);
14454 bind ( teams | parallel | thread ) */
14457 c_parser_omp_clause_bind (c_parser *parser, tree list)
14459 location_t loc = c_parser_peek_token (parser)->location;
14462 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14464 matching_parens parens;
14465 if (!parens.require_open (parser))
14467 if (!c_parser_next_token_is (parser, CPP_NAME))
14470 c_parser_error (parser,
14471 "expected %<teams%>, %<parallel%> or %<thread%>");
14472 parens.skip_until_found_close (parser);
14475 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14476 if (strcmp (p, "teams") == 0)
14477 kind = OMP_CLAUSE_BIND_TEAMS;
14478 else if (strcmp (p, "parallel") == 0)
14479 kind = OMP_CLAUSE_BIND_PARALLEL;
14480 else if (strcmp (p, "thread") != 0)
14482 c_parser_consume_token (parser);
14483 parens.skip_until_found_close (parser);
14484 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14485 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14486 OMP_CLAUSE_BIND_KIND (c) = kind;
14487 OMP_CLAUSE_CHAIN (c) = list;
14496 ordered ( constant-expression ) */
14499 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14501 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14503 tree c, num = NULL_TREE;
14505 location_t loc = c_parser_peek_token (parser)->location;
14506 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14508 matching_parens parens;
14509 parens.consume_open (parser);
14510 num = c_parser_expr_no_commas (parser, NULL).value;
14511 parens.skip_until_found_close (parser);
14513 if (num == error_mark_node)
14517 mark_exp_read (num);
14518 num = c_fully_fold (num, false, NULL);
14519 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14520 || !tree_fits_shwi_p (num)
14521 || (n = tree_to_shwi (num)) <= 0
14524 error_at (loc, "ordered argument needs positive "
14525 "constant integer expression");
14529 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14530 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14531 OMP_CLAUSE_CHAIN (c) = list;
14536 private ( variable-list ) */
14539 c_parser_omp_clause_private (c_parser *parser, tree list)
14541 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14545 reduction ( reduction-operator : variable-list )
14547 reduction-operator:
14548 One of: + * - & ^ | && ||
14552 reduction-operator:
14553 One of: + * - & ^ | && || max min
14557 reduction-operator:
14558 One of: + * - & ^ | && ||
14562 reduction ( reduction-modifier, reduction-operator : variable-list )
14563 in_reduction ( reduction-operator : variable-list )
14564 task_reduction ( reduction-operator : variable-list ) */
14567 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14568 bool is_omp, tree list)
14570 location_t clause_loc = c_parser_peek_token (parser)->location;
14571 matching_parens parens;
14572 if (parens.require_open (parser))
14575 bool inscan = false;
14576 enum tree_code code = ERROR_MARK;
14577 tree reduc_id = NULL_TREE;
14579 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14581 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14582 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14584 c_parser_consume_token (parser);
14585 c_parser_consume_token (parser);
14587 else if (c_parser_next_token_is (parser, CPP_NAME)
14588 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14591 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14592 if (strcmp (p, "task") == 0)
14594 else if (strcmp (p, "inscan") == 0)
14596 if (task || inscan)
14598 c_parser_consume_token (parser);
14599 c_parser_consume_token (parser);
14604 switch (c_parser_peek_token (parser)->type)
14616 code = BIT_AND_EXPR;
14619 code = BIT_XOR_EXPR;
14622 code = BIT_IOR_EXPR;
14625 code = TRUTH_ANDIF_EXPR;
14628 code = TRUTH_ORIF_EXPR;
14633 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14634 if (strcmp (p, "min") == 0)
14639 if (strcmp (p, "max") == 0)
14644 reduc_id = c_parser_peek_token (parser)->value;
14648 c_parser_error (parser,
14649 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14650 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14651 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14654 c_parser_consume_token (parser);
14655 reduc_id = c_omp_reduction_id (code, reduc_id);
14656 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14660 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
14661 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14663 tree d = OMP_CLAUSE_DECL (c), type;
14664 if (TREE_CODE (d) != TREE_LIST)
14665 type = TREE_TYPE (d);
14670 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
14672 type = TREE_TYPE (t);
14675 if (TREE_CODE (type) != POINTER_TYPE
14676 && TREE_CODE (type) != ARRAY_TYPE)
14678 type = TREE_TYPE (type);
14682 while (TREE_CODE (type) == ARRAY_TYPE)
14683 type = TREE_TYPE (type);
14684 OMP_CLAUSE_REDUCTION_CODE (c) = code;
14686 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
14688 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
14689 if (code == ERROR_MARK
14690 || !(INTEGRAL_TYPE_P (type)
14691 || TREE_CODE (type) == REAL_TYPE
14692 || TREE_CODE (type) == COMPLEX_TYPE))
14693 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
14694 = c_omp_reduction_lookup (reduc_id,
14695 TYPE_MAIN_VARIANT (type));
14700 parens.skip_until_found_close (parser);
14706 schedule ( schedule-kind )
14707 schedule ( schedule-kind , expression )
14710 static | dynamic | guided | runtime | auto
14713 schedule ( schedule-modifier : schedule-kind )
14714 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14722 c_parser_omp_clause_schedule (c_parser *parser, tree list)
14725 location_t loc = c_parser_peek_token (parser)->location;
14726 int modifiers = 0, nmodifiers = 0;
14728 matching_parens parens;
14729 if (!parens.require_open (parser))
14732 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
14734 while (c_parser_next_token_is (parser, CPP_NAME))
14736 tree kind = c_parser_peek_token (parser)->value;
14737 const char *p = IDENTIFIER_POINTER (kind);
14738 if (strcmp ("simd", p) == 0)
14739 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
14740 else if (strcmp ("monotonic", p) == 0)
14741 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
14742 else if (strcmp ("nonmonotonic", p) == 0)
14743 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
14746 c_parser_consume_token (parser);
14747 if (nmodifiers++ == 0
14748 && c_parser_next_token_is (parser, CPP_COMMA))
14749 c_parser_consume_token (parser);
14752 c_parser_require (parser, CPP_COLON, "expected %<:%>");
14757 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
14758 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14759 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14760 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14762 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14767 if (c_parser_next_token_is (parser, CPP_NAME))
14769 tree kind = c_parser_peek_token (parser)->value;
14770 const char *p = IDENTIFIER_POINTER (kind);
14775 if (strcmp ("dynamic", p) != 0)
14777 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
14781 if (strcmp ("guided", p) != 0)
14783 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
14787 if (strcmp ("runtime", p) != 0)
14789 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
14796 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
14797 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
14798 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14799 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
14803 c_parser_consume_token (parser);
14804 if (c_parser_next_token_is (parser, CPP_COMMA))
14807 c_parser_consume_token (parser);
14809 here = c_parser_peek_token (parser)->location;
14810 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14811 expr = convert_lvalue_to_rvalue (here, expr, false, true);
14813 t = c_fully_fold (t, false, NULL);
14815 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
14816 error_at (here, "schedule %<runtime%> does not take "
14817 "a %<chunk_size%> parameter");
14818 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
14820 "schedule %<auto%> does not take "
14821 "a %<chunk_size%> parameter");
14822 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
14824 /* Attempt to statically determine when the number isn't
14826 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
14827 build_int_cst (TREE_TYPE (t), 0));
14828 protected_set_expr_location (s, loc);
14829 if (s == boolean_true_node)
14831 warning_at (loc, 0,
14832 "chunk size value must be positive");
14833 t = integer_one_node;
14835 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
14838 c_parser_error (parser, "expected integer expression");
14840 parens.skip_until_found_close (parser);
14843 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14844 "expected %<,%> or %<)%>");
14846 OMP_CLAUSE_SCHEDULE_KIND (c)
14847 = (enum omp_clause_schedule_kind)
14848 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
14850 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
14851 OMP_CLAUSE_CHAIN (c) = list;
14855 c_parser_error (parser, "invalid schedule kind");
14856 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14861 shared ( variable-list ) */
14864 c_parser_omp_clause_shared (c_parser *parser, tree list)
14866 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
14873 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14877 /* FIXME: Should we allow duplicates? */
14878 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
14880 c = build_omp_clause (c_parser_peek_token (parser)->location,
14881 OMP_CLAUSE_UNTIED);
14882 OMP_CLAUSE_CHAIN (c) = list;
14892 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
14893 enum omp_clause_code code, tree list)
14895 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14897 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14898 OMP_CLAUSE_CHAIN (c) = list;
14910 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
14911 enum omp_clause_code code, tree list)
14913 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14914 OMP_CLAUSE_CHAIN (c) = list;
14923 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14925 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
14926 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
14927 OMP_CLAUSE_NOGROUP);
14928 OMP_CLAUSE_CHAIN (c) = list;
14937 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
14938 enum omp_clause_code code, tree list)
14940 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14941 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14942 OMP_CLAUSE_CHAIN (c) = list;
14947 num_teams ( expression ) */
14950 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
14952 location_t num_teams_loc = c_parser_peek_token (parser)->location;
14953 matching_parens parens;
14954 if (parens.require_open (parser))
14956 location_t expr_loc = c_parser_peek_token (parser)->location;
14957 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14958 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14959 tree c, t = expr.value;
14960 t = c_fully_fold (t, false, NULL);
14962 parens.skip_until_found_close (parser);
14964 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14966 c_parser_error (parser, "expected integer expression");
14970 /* Attempt to statically determine when the number isn't positive. */
14971 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14972 build_int_cst (TREE_TYPE (t), 0));
14973 protected_set_expr_location (c, expr_loc);
14974 if (c == boolean_true_node)
14976 warning_at (expr_loc, 0, "%<num_teams%> value must be positive");
14977 t = integer_one_node;
14980 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
14982 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
14983 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
14984 OMP_CLAUSE_CHAIN (c) = list;
14992 thread_limit ( expression ) */
14995 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
14997 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
14998 matching_parens parens;
14999 if (parens.require_open (parser))
15001 location_t expr_loc = c_parser_peek_token (parser)->location;
15002 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15003 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15004 tree c, t = expr.value;
15005 t = c_fully_fold (t, false, NULL);
15007 parens.skip_until_found_close (parser);
15009 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15011 c_parser_error (parser, "expected integer expression");
15015 /* Attempt to statically determine when the number isn't positive. */
15016 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15017 build_int_cst (TREE_TYPE (t), 0));
15018 protected_set_expr_location (c, expr_loc);
15019 if (c == boolean_true_node)
15021 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15022 t = integer_one_node;
15025 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15028 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15029 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15030 OMP_CLAUSE_CHAIN (c) = list;
15038 aligned ( variable-list )
15039 aligned ( variable-list : constant-expression ) */
15042 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15044 location_t clause_loc = c_parser_peek_token (parser)->location;
15047 matching_parens parens;
15048 if (!parens.require_open (parser))
15051 nl = c_parser_omp_variable_list (parser, clause_loc,
15052 OMP_CLAUSE_ALIGNED, list);
15054 if (c_parser_next_token_is (parser, CPP_COLON))
15056 c_parser_consume_token (parser);
15057 location_t expr_loc = c_parser_peek_token (parser)->location;
15058 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15059 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15060 tree alignment = expr.value;
15061 alignment = c_fully_fold (alignment, false, NULL);
15062 if (TREE_CODE (alignment) != INTEGER_CST
15063 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15064 || tree_int_cst_sgn (alignment) != 1)
15066 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15067 "be positive constant integer expression");
15068 alignment = NULL_TREE;
15071 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15072 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15075 parens.skip_until_found_close (parser);
15080 linear ( variable-list )
15081 linear ( variable-list : expression )
15084 linear ( modifier ( variable-list ) )
15085 linear ( modifier ( variable-list ) : expression ) */
15088 c_parser_omp_clause_linear (c_parser *parser, tree list)
15090 location_t clause_loc = c_parser_peek_token (parser)->location;
15092 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15094 matching_parens parens;
15095 if (!parens.require_open (parser))
15098 if (c_parser_next_token_is (parser, CPP_NAME))
15100 c_token *tok = c_parser_peek_token (parser);
15101 const char *p = IDENTIFIER_POINTER (tok->value);
15102 if (strcmp ("val", p) == 0)
15103 kind = OMP_CLAUSE_LINEAR_VAL;
15104 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15105 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15106 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15108 c_parser_consume_token (parser);
15109 c_parser_consume_token (parser);
15113 nl = c_parser_omp_variable_list (parser, clause_loc,
15114 OMP_CLAUSE_LINEAR, list);
15116 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15117 parens.skip_until_found_close (parser);
15119 if (c_parser_next_token_is (parser, CPP_COLON))
15121 c_parser_consume_token (parser);
15122 location_t expr_loc = c_parser_peek_token (parser)->location;
15123 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15124 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15126 step = c_fully_fold (step, false, NULL);
15127 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15129 error_at (clause_loc, "%<linear%> clause step expression must "
15131 step = integer_one_node;
15136 step = integer_one_node;
15138 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15140 OMP_CLAUSE_LINEAR_STEP (c) = step;
15141 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15144 parens.skip_until_found_close (parser);
15149 nontemporal ( variable-list ) */
15152 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15154 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15158 safelen ( constant-expression ) */
15161 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15163 location_t clause_loc = c_parser_peek_token (parser)->location;
15166 matching_parens parens;
15167 if (!parens.require_open (parser))
15170 location_t expr_loc = c_parser_peek_token (parser)->location;
15171 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15172 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15174 t = c_fully_fold (t, false, NULL);
15175 if (TREE_CODE (t) != INTEGER_CST
15176 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15177 || tree_int_cst_sgn (t) != 1)
15179 error_at (clause_loc, "%<safelen%> clause expression must "
15180 "be positive constant integer expression");
15184 parens.skip_until_found_close (parser);
15185 if (t == NULL_TREE || t == error_mark_node)
15188 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15190 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15191 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15192 OMP_CLAUSE_CHAIN (c) = list;
15197 simdlen ( constant-expression ) */
15200 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15202 location_t clause_loc = c_parser_peek_token (parser)->location;
15205 matching_parens parens;
15206 if (!parens.require_open (parser))
15209 location_t expr_loc = c_parser_peek_token (parser)->location;
15210 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15211 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15213 t = c_fully_fold (t, false, NULL);
15214 if (TREE_CODE (t) != INTEGER_CST
15215 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15216 || tree_int_cst_sgn (t) != 1)
15218 error_at (clause_loc, "%<simdlen%> clause expression must "
15219 "be positive constant integer expression");
15223 parens.skip_until_found_close (parser);
15224 if (t == NULL_TREE || t == error_mark_node)
15227 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15229 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15230 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15231 OMP_CLAUSE_CHAIN (c) = list;
15237 identifier [+/- integer]
15238 vec , identifier [+/- integer]
15242 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15246 if (c_parser_next_token_is_not (parser, CPP_NAME)
15247 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15249 c_parser_error (parser, "expected identifier");
15253 while (c_parser_next_token_is (parser, CPP_NAME)
15254 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15256 tree t = lookup_name (c_parser_peek_token (parser)->value);
15257 tree addend = NULL;
15259 if (t == NULL_TREE)
15261 undeclared_variable (c_parser_peek_token (parser)->location,
15262 c_parser_peek_token (parser)->value);
15263 t = error_mark_node;
15266 c_parser_consume_token (parser);
15269 if (c_parser_next_token_is (parser, CPP_MINUS))
15271 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15273 addend = integer_zero_node;
15275 goto add_to_vector;
15277 c_parser_consume_token (parser);
15279 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15281 c_parser_error (parser, "expected integer");
15285 addend = c_parser_peek_token (parser)->value;
15286 if (TREE_CODE (addend) != INTEGER_CST)
15288 c_parser_error (parser, "expected integer");
15291 c_parser_consume_token (parser);
15294 if (t != error_mark_node)
15296 vec = tree_cons (addend, t, vec);
15298 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15301 if (c_parser_next_token_is_not (parser, CPP_COMMA))
15304 c_parser_consume_token (parser);
15307 if (vec == NULL_TREE)
15310 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15311 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15312 OMP_CLAUSE_DECL (u) = nreverse (vec);
15313 OMP_CLAUSE_CHAIN (u) = list;
15318 iterators ( iterators-definition )
15320 iterators-definition:
15322 iterator-specifier , iterators-definition
15324 iterator-specifier:
15325 identifier = range-specification
15326 iterator-type identifier = range-specification
15328 range-specification:
15330 begin : end : step */
15333 c_parser_omp_iterators (c_parser *parser)
15335 tree ret = NULL_TREE, *last = &ret;
15336 c_parser_consume_token (parser);
15340 matching_parens parens;
15341 if (!parens.require_open (parser))
15342 return error_mark_node;
15346 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
15347 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
15349 struct c_type_name *type = c_parser_type_name (parser);
15351 iter_type = groktypename (type, &type_expr, NULL);
15353 if (iter_type == NULL_TREE)
15354 iter_type = integer_type_node;
15356 location_t loc = c_parser_peek_token (parser)->location;
15357 if (!c_parser_next_token_is (parser, CPP_NAME))
15359 c_parser_error (parser, "expected identifier");
15363 tree id = c_parser_peek_token (parser)->value;
15364 c_parser_consume_token (parser);
15366 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15369 location_t eloc = c_parser_peek_token (parser)->location;
15370 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15371 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15372 tree begin = expr.value;
15374 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15377 eloc = c_parser_peek_token (parser)->location;
15378 expr = c_parser_expr_no_commas (parser, NULL);
15379 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15380 tree end = expr.value;
15382 tree step = integer_one_node;
15383 if (c_parser_next_token_is (parser, CPP_COLON))
15385 c_parser_consume_token (parser);
15386 eloc = c_parser_peek_token (parser)->location;
15387 expr = c_parser_expr_no_commas (parser, NULL);
15388 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15392 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
15393 DECL_ARTIFICIAL (iter_var) = 1;
15394 DECL_CONTEXT (iter_var) = current_function_decl;
15395 pushdecl (iter_var);
15397 *last = make_tree_vec (6);
15398 TREE_VEC_ELT (*last, 0) = iter_var;
15399 TREE_VEC_ELT (*last, 1) = begin;
15400 TREE_VEC_ELT (*last, 2) = end;
15401 TREE_VEC_ELT (*last, 3) = step;
15402 last = &TREE_CHAIN (*last);
15404 if (c_parser_next_token_is (parser, CPP_COMMA))
15406 c_parser_consume_token (parser);
15413 parens.skip_until_found_close (parser);
15414 return ret ? ret : error_mark_node;
15418 depend ( depend-kind: variable-list )
15426 depend ( sink : vec )
15429 depend ( depend-modifier , depend-kind: variable-list )
15432 in | out | inout | mutexinoutset | depobj
15435 iterator ( iterators-definition ) */
15438 c_parser_omp_clause_depend (c_parser *parser, tree list)
15440 location_t clause_loc = c_parser_peek_token (parser)->location;
15441 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
15442 tree nl, c, iterators = NULL_TREE;
15444 matching_parens parens;
15445 if (!parens.require_open (parser))
15450 if (c_parser_next_token_is_not (parser, CPP_NAME))
15453 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15454 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
15456 iterators = c_parser_omp_iterators (parser);
15457 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
15460 if (strcmp ("in", p) == 0)
15461 kind = OMP_CLAUSE_DEPEND_IN;
15462 else if (strcmp ("inout", p) == 0)
15463 kind = OMP_CLAUSE_DEPEND_INOUT;
15464 else if (strcmp ("mutexinoutset", p) == 0)
15465 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
15466 else if (strcmp ("out", p) == 0)
15467 kind = OMP_CLAUSE_DEPEND_OUT;
15468 else if (strcmp ("depobj", p) == 0)
15469 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
15470 else if (strcmp ("sink", p) == 0)
15471 kind = OMP_CLAUSE_DEPEND_SINK;
15472 else if (strcmp ("source", p) == 0)
15473 kind = OMP_CLAUSE_DEPEND_SOURCE;
15480 c_parser_consume_token (parser);
15483 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
15486 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
15487 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
15488 iterators = NULL_TREE;
15491 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
15493 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15494 OMP_CLAUSE_DEPEND_KIND (c) = kind;
15495 OMP_CLAUSE_DECL (c) = NULL_TREE;
15496 OMP_CLAUSE_CHAIN (c) = list;
15497 parens.skip_until_found_close (parser);
15501 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15504 if (kind == OMP_CLAUSE_DEPEND_SINK)
15505 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
15508 nl = c_parser_omp_variable_list (parser, clause_loc,
15509 OMP_CLAUSE_DEPEND, list);
15513 tree block = pop_scope ();
15514 if (iterators == error_mark_node)
15515 iterators = NULL_TREE;
15517 TREE_VEC_ELT (iterators, 5) = block;
15520 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15522 OMP_CLAUSE_DEPEND_KIND (c) = kind;
15524 OMP_CLAUSE_DECL (c)
15525 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
15529 parens.skip_until_found_close (parser);
15533 c_parser_error (parser, "invalid depend kind");
15535 parens.skip_until_found_close (parser);
15542 map ( map-kind: variable-list )
15543 map ( variable-list )
15546 alloc | to | from | tofrom
15550 alloc | to | from | tofrom | release | delete
15552 map ( always [,] map-kind: variable-list ) */
15555 c_parser_omp_clause_map (c_parser *parser, tree list)
15557 location_t clause_loc = c_parser_peek_token (parser)->location;
15558 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
15560 enum c_id_kind always_id_kind = C_ID_NONE;
15561 location_t always_loc = UNKNOWN_LOCATION;
15562 tree always_id = NULL_TREE;
15565 matching_parens parens;
15566 if (!parens.require_open (parser))
15569 if (c_parser_next_token_is (parser, CPP_NAME))
15571 c_token *tok = c_parser_peek_token (parser);
15572 const char *p = IDENTIFIER_POINTER (tok->value);
15573 always_id_kind = tok->id_kind;
15574 always_loc = tok->location;
15575 always_id = tok->value;
15576 if (strcmp ("always", p) == 0)
15578 c_token *sectok = c_parser_peek_2nd_token (parser);
15579 if (sectok->type == CPP_COMMA)
15581 c_parser_consume_token (parser);
15582 c_parser_consume_token (parser);
15585 else if (sectok->type == CPP_NAME)
15587 p = IDENTIFIER_POINTER (sectok->value);
15588 if (strcmp ("alloc", p) == 0
15589 || strcmp ("to", p) == 0
15590 || strcmp ("from", p) == 0
15591 || strcmp ("tofrom", p) == 0
15592 || strcmp ("release", p) == 0
15593 || strcmp ("delete", p) == 0)
15595 c_parser_consume_token (parser);
15602 if (c_parser_next_token_is (parser, CPP_NAME)
15603 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15605 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15606 if (strcmp ("alloc", p) == 0)
15607 kind = GOMP_MAP_ALLOC;
15608 else if (strcmp ("to", p) == 0)
15609 kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
15610 else if (strcmp ("from", p) == 0)
15611 kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
15612 else if (strcmp ("tofrom", p) == 0)
15613 kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
15614 else if (strcmp ("release", p) == 0)
15615 kind = GOMP_MAP_RELEASE;
15616 else if (strcmp ("delete", p) == 0)
15617 kind = GOMP_MAP_DELETE;
15620 c_parser_error (parser, "invalid map kind");
15621 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15625 c_parser_consume_token (parser);
15626 c_parser_consume_token (parser);
15630 if (always_id_kind != C_ID_ID)
15632 c_parser_error (parser, "expected identifier");
15633 parens.skip_until_found_close (parser);
15637 tree t = lookup_name (always_id);
15638 if (t == NULL_TREE)
15640 undeclared_variable (always_loc, always_id);
15641 t = error_mark_node;
15643 if (t != error_mark_node)
15645 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP);
15646 OMP_CLAUSE_DECL (u) = t;
15647 OMP_CLAUSE_CHAIN (u) = list;
15648 OMP_CLAUSE_SET_MAP_KIND (u, kind);
15653 parens.skip_until_found_close (parser);
15658 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
15660 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15661 OMP_CLAUSE_SET_MAP_KIND (c, kind);
15663 parens.skip_until_found_close (parser);
15668 device ( expression ) */
15671 c_parser_omp_clause_device (c_parser *parser, tree list)
15673 location_t clause_loc = c_parser_peek_token (parser)->location;
15674 matching_parens parens;
15675 if (parens.require_open (parser))
15677 location_t expr_loc = c_parser_peek_token (parser)->location;
15678 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15679 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15680 tree c, t = expr.value;
15681 t = c_fully_fold (t, false, NULL);
15683 parens.skip_until_found_close (parser);
15685 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15687 c_parser_error (parser, "expected integer expression");
15691 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
15693 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
15694 OMP_CLAUSE_DEVICE_ID (c) = t;
15695 OMP_CLAUSE_CHAIN (c) = list;
15703 dist_schedule ( static )
15704 dist_schedule ( static , expression ) */
15707 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
15709 tree c, t = NULL_TREE;
15710 location_t loc = c_parser_peek_token (parser)->location;
15712 matching_parens parens;
15713 if (!parens.require_open (parser))
15716 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
15718 c_parser_error (parser, "invalid dist_schedule kind");
15719 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15724 c_parser_consume_token (parser);
15725 if (c_parser_next_token_is (parser, CPP_COMMA))
15727 c_parser_consume_token (parser);
15729 location_t expr_loc = c_parser_peek_token (parser)->location;
15730 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15731 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15733 t = c_fully_fold (t, false, NULL);
15734 parens.skip_until_found_close (parser);
15737 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15738 "expected %<,%> or %<)%>");
15740 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15741 "dist_schedule"); */
15742 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
15743 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
15744 if (t == error_mark_node)
15747 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
15748 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
15749 OMP_CLAUSE_CHAIN (c) = list;
15754 proc_bind ( proc-bind-kind )
15757 master | close | spread */
15760 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
15762 location_t clause_loc = c_parser_peek_token (parser)->location;
15763 enum omp_clause_proc_bind_kind kind;
15766 matching_parens parens;
15767 if (!parens.require_open (parser))
15770 if (c_parser_next_token_is (parser, CPP_NAME))
15772 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15773 if (strcmp ("master", p) == 0)
15774 kind = OMP_CLAUSE_PROC_BIND_MASTER;
15775 else if (strcmp ("close", p) == 0)
15776 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
15777 else if (strcmp ("spread", p) == 0)
15778 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
15785 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
15786 c_parser_consume_token (parser);
15787 parens.skip_until_found_close (parser);
15788 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
15789 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
15790 OMP_CLAUSE_CHAIN (c) = list;
15794 c_parser_error (parser, "invalid proc_bind kind");
15795 parens.skip_until_found_close (parser);
15800 device_type ( host | nohost | any ) */
15803 c_parser_omp_clause_device_type (c_parser *parser, tree list)
15805 location_t clause_loc = c_parser_peek_token (parser)->location;
15806 enum omp_clause_device_type_kind kind;
15809 matching_parens parens;
15810 if (!parens.require_open (parser))
15813 if (c_parser_next_token_is (parser, CPP_NAME))
15815 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15816 if (strcmp ("host", p) == 0)
15817 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
15818 else if (strcmp ("nohost", p) == 0)
15819 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
15820 else if (strcmp ("any", p) == 0)
15821 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
15828 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15830 c_parser_consume_token (parser);
15831 parens.skip_until_found_close (parser);
15832 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
15833 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
15834 OMP_CLAUSE_CHAIN (c) = list;
15838 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
15839 parens.skip_until_found_close (parser);
15844 to ( variable-list ) */
15847 c_parser_omp_clause_to (c_parser *parser, tree list)
15849 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list);
15853 from ( variable-list ) */
15856 c_parser_omp_clause_from (c_parser *parser, tree list)
15858 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list);
15862 uniform ( variable-list ) */
15865 c_parser_omp_clause_uniform (c_parser *parser, tree list)
15867 /* The clauses location. */
15868 location_t loc = c_parser_peek_token (parser)->location;
15870 matching_parens parens;
15871 if (parens.require_open (parser))
15873 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
15875 parens.skip_until_found_close (parser);
15880 /* Parse all OpenACC clauses. The set clauses allowed by the directive
15881 is a bitmask in MASK. Return the list of clauses found. */
15884 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
15885 const char *where, bool finish_p = true)
15887 tree clauses = NULL;
15890 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
15893 pragma_omp_clause c_kind;
15894 const char *c_name;
15895 tree prev = clauses;
15897 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
15898 c_parser_consume_token (parser);
15900 here = c_parser_peek_token (parser)->location;
15901 c_kind = c_parser_omp_clause_name (parser);
15905 case PRAGMA_OACC_CLAUSE_ASYNC:
15906 clauses = c_parser_oacc_clause_async (parser, clauses);
15909 case PRAGMA_OACC_CLAUSE_AUTO:
15910 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
15914 case PRAGMA_OACC_CLAUSE_ATTACH:
15915 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15918 case PRAGMA_OACC_CLAUSE_COLLAPSE:
15919 clauses = c_parser_omp_clause_collapse (parser, clauses);
15920 c_name = "collapse";
15922 case PRAGMA_OACC_CLAUSE_COPY:
15923 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15926 case PRAGMA_OACC_CLAUSE_COPYIN:
15927 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15930 case PRAGMA_OACC_CLAUSE_COPYOUT:
15931 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15932 c_name = "copyout";
15934 case PRAGMA_OACC_CLAUSE_CREATE:
15935 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15938 case PRAGMA_OACC_CLAUSE_DELETE:
15939 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15942 case PRAGMA_OMP_CLAUSE_DEFAULT:
15943 clauses = c_parser_omp_clause_default (parser, clauses, true);
15944 c_name = "default";
15946 case PRAGMA_OACC_CLAUSE_DETACH:
15947 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15950 case PRAGMA_OACC_CLAUSE_DEVICE:
15951 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15954 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
15955 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
15956 c_name = "deviceptr";
15958 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
15959 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15960 c_name = "device_resident";
15962 case PRAGMA_OACC_CLAUSE_FINALIZE:
15963 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
15965 c_name = "finalize";
15967 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
15968 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
15969 c_name = "firstprivate";
15971 case PRAGMA_OACC_CLAUSE_GANG:
15973 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
15976 case PRAGMA_OACC_CLAUSE_HOST:
15977 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15980 case PRAGMA_OACC_CLAUSE_IF:
15981 clauses = c_parser_omp_clause_if (parser, clauses, false);
15984 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
15985 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
15987 c_name = "if_present";
15989 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
15990 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
15992 c_name = "independent";
15994 case PRAGMA_OACC_CLAUSE_LINK:
15995 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15998 case PRAGMA_OACC_CLAUSE_NO_CREATE:
15999 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16000 c_name = "no_create";
16002 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16003 clauses = c_parser_oacc_single_int_clause (parser,
16004 OMP_CLAUSE_NUM_GANGS,
16006 c_name = "num_gangs";
16008 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16009 clauses = c_parser_oacc_single_int_clause (parser,
16010 OMP_CLAUSE_NUM_WORKERS,
16012 c_name = "num_workers";
16014 case PRAGMA_OACC_CLAUSE_PRESENT:
16015 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16016 c_name = "present";
16018 case PRAGMA_OACC_CLAUSE_PRIVATE:
16019 clauses = c_parser_omp_clause_private (parser, clauses);
16020 c_name = "private";
16022 case PRAGMA_OACC_CLAUSE_REDUCTION:
16024 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16026 c_name = "reduction";
16028 case PRAGMA_OACC_CLAUSE_SEQ:
16029 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16033 case PRAGMA_OACC_CLAUSE_TILE:
16034 clauses = c_parser_oacc_clause_tile (parser, clauses);
16037 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16038 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16039 c_name = "use_device";
16041 case PRAGMA_OACC_CLAUSE_VECTOR:
16043 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16046 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16047 clauses = c_parser_oacc_single_int_clause (parser,
16048 OMP_CLAUSE_VECTOR_LENGTH,
16050 c_name = "vector_length";
16052 case PRAGMA_OACC_CLAUSE_WAIT:
16053 clauses = c_parser_oacc_clause_wait (parser, clauses);
16056 case PRAGMA_OACC_CLAUSE_WORKER:
16058 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16062 c_parser_error (parser, "expected %<#pragma acc%> clause");
16068 if (((mask >> c_kind) & 1) == 0)
16070 /* Remove the invalid clause(s) from the list to avoid
16071 confusing the rest of the compiler. */
16073 error_at (here, "%qs is not valid for %qs", c_name, where);
16078 c_parser_skip_to_pragma_eol (parser);
16081 return c_finish_omp_clauses (clauses, C_ORT_ACC);
16086 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16087 is a bitmask in MASK. Return the list of clauses found.
16088 FINISH_P set if c_finish_omp_clauses should be called.
16089 NESTED non-zero if clauses should be terminated by closing paren instead
16090 of end of pragma. If it is 2, additionally commas are required in between
16094 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16095 const char *where, bool finish_p = true,
16098 tree clauses = NULL;
16101 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16104 pragma_omp_clause c_kind;
16105 const char *c_name;
16106 tree prev = clauses;
16108 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16113 if (c_parser_next_token_is (parser, CPP_COMMA))
16114 c_parser_consume_token (parser);
16115 else if (nested == 2)
16116 error_at (c_parser_peek_token (parser)->location,
16117 "clauses in %<simd%> trait should be separated "
16121 here = c_parser_peek_token (parser)->location;
16122 c_kind = c_parser_omp_clause_name (parser);
16126 case PRAGMA_OMP_CLAUSE_BIND:
16127 clauses = c_parser_omp_clause_bind (parser, clauses);
16130 case PRAGMA_OMP_CLAUSE_COLLAPSE:
16131 clauses = c_parser_omp_clause_collapse (parser, clauses);
16132 c_name = "collapse";
16134 case PRAGMA_OMP_CLAUSE_COPYIN:
16135 clauses = c_parser_omp_clause_copyin (parser, clauses);
16138 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16139 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16140 c_name = "copyprivate";
16142 case PRAGMA_OMP_CLAUSE_DEFAULT:
16143 clauses = c_parser_omp_clause_default (parser, clauses, false);
16144 c_name = "default";
16146 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
16147 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16148 c_name = "firstprivate";
16150 case PRAGMA_OMP_CLAUSE_FINAL:
16151 clauses = c_parser_omp_clause_final (parser, clauses);
16154 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
16155 clauses = c_parser_omp_clause_grainsize (parser, clauses);
16156 c_name = "grainsize";
16158 case PRAGMA_OMP_CLAUSE_HINT:
16159 clauses = c_parser_omp_clause_hint (parser, clauses);
16162 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
16163 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
16164 c_name = "defaultmap";
16166 case PRAGMA_OMP_CLAUSE_IF:
16167 clauses = c_parser_omp_clause_if (parser, clauses, true);
16170 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
16172 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
16174 c_name = "in_reduction";
16176 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
16177 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
16178 c_name = "lastprivate";
16180 case PRAGMA_OMP_CLAUSE_MERGEABLE:
16181 clauses = c_parser_omp_clause_mergeable (parser, clauses);
16182 c_name = "mergeable";
16184 case PRAGMA_OMP_CLAUSE_NOWAIT:
16185 clauses = c_parser_omp_clause_nowait (parser, clauses);
16188 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
16189 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
16190 c_name = "num_tasks";
16192 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
16193 clauses = c_parser_omp_clause_num_threads (parser, clauses);
16194 c_name = "num_threads";
16196 case PRAGMA_OMP_CLAUSE_ORDER:
16197 clauses = c_parser_omp_clause_order (parser, clauses);
16200 case PRAGMA_OMP_CLAUSE_ORDERED:
16201 clauses = c_parser_omp_clause_ordered (parser, clauses);
16202 c_name = "ordered";
16204 case PRAGMA_OMP_CLAUSE_PRIORITY:
16205 clauses = c_parser_omp_clause_priority (parser, clauses);
16206 c_name = "priority";
16208 case PRAGMA_OMP_CLAUSE_PRIVATE:
16209 clauses = c_parser_omp_clause_private (parser, clauses);
16210 c_name = "private";
16212 case PRAGMA_OMP_CLAUSE_REDUCTION:
16214 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16216 c_name = "reduction";
16218 case PRAGMA_OMP_CLAUSE_SCHEDULE:
16219 clauses = c_parser_omp_clause_schedule (parser, clauses);
16220 c_name = "schedule";
16222 case PRAGMA_OMP_CLAUSE_SHARED:
16223 clauses = c_parser_omp_clause_shared (parser, clauses);
16226 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
16228 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
16230 c_name = "task_reduction";
16232 case PRAGMA_OMP_CLAUSE_UNTIED:
16233 clauses = c_parser_omp_clause_untied (parser, clauses);
16236 case PRAGMA_OMP_CLAUSE_INBRANCH:
16237 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
16239 c_name = "inbranch";
16241 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
16242 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
16243 c_name = "nontemporal";
16245 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
16246 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
16248 c_name = "notinbranch";
16250 case PRAGMA_OMP_CLAUSE_PARALLEL:
16252 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
16254 c_name = "parallel";
16258 error_at (here, "%qs must be the first clause of %qs",
16263 case PRAGMA_OMP_CLAUSE_FOR:
16265 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
16269 goto clause_not_first;
16271 case PRAGMA_OMP_CLAUSE_SECTIONS:
16273 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
16275 c_name = "sections";
16277 goto clause_not_first;
16279 case PRAGMA_OMP_CLAUSE_TASKGROUP:
16281 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
16283 c_name = "taskgroup";
16285 goto clause_not_first;
16287 case PRAGMA_OMP_CLAUSE_LINK:
16289 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
16292 case PRAGMA_OMP_CLAUSE_TO:
16293 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
16295 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
16298 clauses = c_parser_omp_clause_to (parser, clauses);
16301 case PRAGMA_OMP_CLAUSE_FROM:
16302 clauses = c_parser_omp_clause_from (parser, clauses);
16305 case PRAGMA_OMP_CLAUSE_UNIFORM:
16306 clauses = c_parser_omp_clause_uniform (parser, clauses);
16307 c_name = "uniform";
16309 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
16310 clauses = c_parser_omp_clause_num_teams (parser, clauses);
16311 c_name = "num_teams";
16313 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
16314 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
16315 c_name = "thread_limit";
16317 case PRAGMA_OMP_CLAUSE_ALIGNED:
16318 clauses = c_parser_omp_clause_aligned (parser, clauses);
16319 c_name = "aligned";
16321 case PRAGMA_OMP_CLAUSE_LINEAR:
16322 clauses = c_parser_omp_clause_linear (parser, clauses);
16325 case PRAGMA_OMP_CLAUSE_DEPEND:
16326 clauses = c_parser_omp_clause_depend (parser, clauses);
16329 case PRAGMA_OMP_CLAUSE_MAP:
16330 clauses = c_parser_omp_clause_map (parser, clauses);
16333 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
16334 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16335 c_name = "use_device_ptr";
16337 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
16338 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
16339 c_name = "use_device_addr";
16341 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
16342 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
16343 c_name = "is_device_ptr";
16345 case PRAGMA_OMP_CLAUSE_DEVICE:
16346 clauses = c_parser_omp_clause_device (parser, clauses);
16349 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
16350 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
16351 c_name = "dist_schedule";
16353 case PRAGMA_OMP_CLAUSE_PROC_BIND:
16354 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
16355 c_name = "proc_bind";
16357 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
16358 clauses = c_parser_omp_clause_device_type (parser, clauses);
16359 c_name = "device_type";
16361 case PRAGMA_OMP_CLAUSE_SAFELEN:
16362 clauses = c_parser_omp_clause_safelen (parser, clauses);
16363 c_name = "safelen";
16365 case PRAGMA_OMP_CLAUSE_SIMDLEN:
16366 clauses = c_parser_omp_clause_simdlen (parser, clauses);
16367 c_name = "simdlen";
16369 case PRAGMA_OMP_CLAUSE_NOGROUP:
16370 clauses = c_parser_omp_clause_nogroup (parser, clauses);
16371 c_name = "nogroup";
16373 case PRAGMA_OMP_CLAUSE_THREADS:
16375 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
16377 c_name = "threads";
16379 case PRAGMA_OMP_CLAUSE_SIMD:
16381 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
16386 c_parser_error (parser, "expected %<#pragma omp%> clause");
16392 if (((mask >> c_kind) & 1) == 0)
16394 /* Remove the invalid clause(s) from the list to avoid
16395 confusing the rest of the compiler. */
16397 error_at (here, "%qs is not valid for %qs", c_name, where);
16403 c_parser_skip_to_pragma_eol (parser);
16407 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
16408 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
16409 return c_finish_omp_clauses (clauses, C_ORT_OMP);
16415 /* OpenACC 2.0, OpenMP 2.5:
16419 In practice, we're also interested in adding the statement to an
16420 outer node. So it is convenient if we work around the fact that
16421 c_parser_statement calls add_stmt. */
16424 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
16426 tree stmt = push_stmt_list ();
16427 c_parser_statement (parser, if_p);
16428 return pop_stmt_list (stmt);
16432 # pragma acc cache (variable-list) new-line
16434 LOC is the location of the #pragma token.
16438 c_parser_oacc_cache (location_t loc, c_parser *parser)
16440 tree stmt, clauses;
16442 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
16443 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16445 c_parser_skip_to_pragma_eol (parser);
16447 stmt = make_node (OACC_CACHE);
16448 TREE_TYPE (stmt) = void_type_node;
16449 OACC_CACHE_CLAUSES (stmt) = clauses;
16450 SET_EXPR_LOCATION (stmt, loc);
16457 # pragma acc data oacc-data-clause[optseq] new-line
16460 LOC is the location of the #pragma token.
16463 #define OACC_DATA_CLAUSE_MASK \
16464 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16465 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16475 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
16477 tree stmt, clauses, block;
16479 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
16480 "#pragma acc data");
16482 block = c_begin_omp_parallel ();
16483 add_stmt (c_parser_omp_structured_block (parser, if_p));
16485 stmt = c_finish_oacc_data (loc, clauses, block);
16491 # pragma acc declare oacc-data-clause[optseq] new-line
16494 #define OACC_DECLARE_CLAUSE_MASK \
16495 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
16501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
16502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16505 c_parser_oacc_declare (c_parser *parser)
16507 location_t pragma_loc = c_parser_peek_token (parser)->location;
16508 tree clauses, stmt, t, decl;
16510 bool error = false;
16512 c_parser_consume_pragma (parser);
16514 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
16515 "#pragma acc declare");
16518 error_at (pragma_loc,
16519 "no valid clauses specified in %<#pragma acc declare%>");
16523 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
16525 location_t loc = OMP_CLAUSE_LOCATION (t);
16526 decl = OMP_CLAUSE_DECL (t);
16527 if (!DECL_P (decl))
16529 error_at (loc, "array section in %<#pragma acc declare%>");
16534 switch (OMP_CLAUSE_MAP_KIND (t))
16536 case GOMP_MAP_FIRSTPRIVATE_POINTER:
16537 case GOMP_MAP_ALLOC:
16539 case GOMP_MAP_FORCE_DEVICEPTR:
16540 case GOMP_MAP_DEVICE_RESIDENT:
16543 case GOMP_MAP_LINK:
16544 if (!global_bindings_p ()
16545 && (TREE_STATIC (decl)
16546 || !DECL_EXTERNAL (decl)))
16549 "%qD must be a global variable in "
16550 "%<#pragma acc declare link%>",
16558 if (global_bindings_p ())
16560 error_at (loc, "invalid OpenACC clause at file scope");
16564 if (DECL_EXTERNAL (decl))
16567 "invalid use of %<extern%> variable %qD "
16568 "in %<#pragma acc declare%>", decl);
16572 else if (TREE_PUBLIC (decl))
16575 "invalid use of %<global%> variable %qD "
16576 "in %<#pragma acc declare%>", decl);
16583 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
16584 || lookup_attribute ("omp declare target link",
16585 DECL_ATTRIBUTES (decl)))
16587 error_at (loc, "variable %qD used more than once with "
16588 "%<#pragma acc declare%>", decl);
16597 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
16598 id = get_identifier ("omp declare target link");
16600 id = get_identifier ("omp declare target");
16602 DECL_ATTRIBUTES (decl)
16603 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
16605 if (global_bindings_p ())
16607 symtab_node *node = symtab_node::get (decl);
16610 node->offloadable = 1;
16611 if (ENABLE_OFFLOADING)
16613 g->have_offload = true;
16614 if (is_a <varpool_node *> (node))
16615 vec_safe_push (offload_vars, decl);
16622 if (error || global_bindings_p ())
16625 stmt = make_node (OACC_DECLARE);
16626 TREE_TYPE (stmt) = void_type_node;
16627 OACC_DECLARE_CLAUSES (stmt) = clauses;
16628 SET_EXPR_LOCATION (stmt, pragma_loc);
16636 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16640 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16643 LOC is the location of the #pragma token.
16646 #define OACC_ENTER_DATA_CLAUSE_MASK \
16647 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16654 #define OACC_EXIT_DATA_CLAUSE_MASK \
16655 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16656 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16657 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16658 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
16659 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
16660 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
16661 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16664 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
16666 location_t loc = c_parser_peek_token (parser)->location;
16667 tree clauses, stmt;
16668 const char *p = "";
16670 c_parser_consume_pragma (parser);
16672 if (c_parser_next_token_is (parser, CPP_NAME))
16674 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16675 c_parser_consume_token (parser);
16678 if (strcmp (p, "data") != 0)
16680 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
16681 enter ? "enter" : "exit");
16682 parser->error = true;
16683 c_parser_skip_to_pragma_eol (parser);
16688 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
16689 "#pragma acc enter data");
16691 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
16692 "#pragma acc exit data");
16694 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
16696 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
16697 enter ? "enter" : "exit");
16701 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
16702 TREE_TYPE (stmt) = void_type_node;
16703 OMP_STANDALONE_CLAUSES (stmt) = clauses;
16704 SET_EXPR_LOCATION (stmt, loc);
16710 # pragma acc host_data oacc-data-clause[optseq] new-line
16714 #define OACC_HOST_DATA_CLAUSE_MASK \
16715 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
16716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
16720 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
16722 tree stmt, clauses, block;
16724 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
16725 "#pragma acc host_data");
16727 block = c_begin_omp_parallel ();
16728 add_stmt (c_parser_omp_structured_block (parser, if_p));
16729 stmt = c_finish_oacc_host_data (loc, clauses, block);
16736 # pragma acc loop oacc-loop-clause[optseq] new-line
16739 LOC is the location of the #pragma token.
16742 #define OACC_LOOP_CLAUSE_MASK \
16743 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
16744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
16750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
16751 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
16752 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
16754 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
16755 omp_clause_mask mask, tree *cclauses, bool *if_p)
16757 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
16759 strcat (p_name, " loop");
16760 mask |= OACC_LOOP_CLAUSE_MASK;
16762 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
16766 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
16768 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
16770 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16773 tree block = c_begin_compound_stmt (true);
16774 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
16776 block = c_end_compound_stmt (loc, block, true);
16783 # pragma acc kernels oacc-kernels-clause[optseq] new-line
16788 # pragma acc parallel oacc-parallel-clause[optseq] new-line
16793 # pragma acc serial oacc-serial-clause[optseq] new-line
16796 LOC is the location of the #pragma token.
16799 #define OACC_KERNELS_CLAUSE_MASK \
16800 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16816 #define OACC_PARALLEL_CLAUSE_MASK \
16817 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16818 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16819 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16820 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16830 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16831 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16836 #define OACC_SERIAL_CLAUSE_MASK \
16837 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16842 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16844 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16845 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16848 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16849 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16850 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16851 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16854 c_parser_oacc_compute (location_t loc, c_parser *parser,
16855 enum pragma_kind p_kind, char *p_name, bool *if_p)
16857 omp_clause_mask mask;
16858 enum tree_code code;
16861 case PRAGMA_OACC_KERNELS:
16862 strcat (p_name, " kernels");
16863 mask = OACC_KERNELS_CLAUSE_MASK;
16864 code = OACC_KERNELS;
16866 case PRAGMA_OACC_PARALLEL:
16867 strcat (p_name, " parallel");
16868 mask = OACC_PARALLEL_CLAUSE_MASK;
16869 code = OACC_PARALLEL;
16871 case PRAGMA_OACC_SERIAL:
16872 strcat (p_name, " serial");
16873 mask = OACC_SERIAL_CLAUSE_MASK;
16874 code = OACC_SERIAL;
16877 gcc_unreachable ();
16880 if (c_parser_next_token_is (parser, CPP_NAME))
16882 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16883 if (strcmp (p, "loop") == 0)
16885 c_parser_consume_token (parser);
16886 tree block = c_begin_omp_parallel ();
16888 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
16889 return c_finish_omp_construct (loc, code, block, clauses);
16893 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
16895 tree block = c_begin_omp_parallel ();
16896 add_stmt (c_parser_omp_structured_block (parser, if_p));
16898 return c_finish_omp_construct (loc, code, block, clauses);
16902 # pragma acc routine oacc-routine-clause[optseq] new-line
16903 function-definition
16905 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
16908 #define OACC_ROUTINE_CLAUSE_MASK \
16909 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
16914 /* Parse an OpenACC routine directive. For named directives, we apply
16915 immediately to the named function. For unnamed ones we then parse
16916 a declaration or definition, which must be for a function. */
16919 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
16921 gcc_checking_assert (context == pragma_external);
16923 oacc_routine_data data;
16924 data.error_seen = false;
16925 data.fndecl_seen = false;
16926 data.clauses = NULL_TREE;
16927 data.loc = c_parser_peek_token (parser)->location;
16929 c_parser_consume_pragma (parser);
16931 /* Look for optional '( name )'. */
16932 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
16934 c_parser_consume_token (parser); /* '(' */
16936 tree decl = NULL_TREE;
16937 c_token *name_token = c_parser_peek_token (parser);
16938 location_t name_loc = name_token->location;
16939 if (name_token->type == CPP_NAME
16940 && (name_token->id_kind == C_ID_ID
16941 || name_token->id_kind == C_ID_TYPENAME))
16943 decl = lookup_name (name_token->value);
16945 error_at (name_loc,
16946 "%qE has not been declared", name_token->value);
16947 c_parser_consume_token (parser);
16950 c_parser_error (parser, "expected function name");
16953 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
16955 c_parser_skip_to_pragma_eol (parser, false);
16960 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
16961 "#pragma acc routine");
16962 /* The clauses are in reverse order; fix that to make later diagnostic
16963 emission easier. */
16964 data.clauses = nreverse (data.clauses);
16966 if (TREE_CODE (decl) != FUNCTION_DECL)
16968 error_at (name_loc, "%qD does not refer to a function", decl);
16972 c_finish_oacc_routine (&data, decl, false);
16974 else /* No optional '( name )'. */
16977 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
16978 "#pragma acc routine");
16979 /* The clauses are in reverse order; fix that to make later diagnostic
16980 emission easier. */
16981 data.clauses = nreverse (data.clauses);
16983 /* Emit a helpful diagnostic if there's another pragma following this
16984 one. Also don't allow a static assertion declaration, as in the
16985 following we'll just parse a *single* "declaration or function
16986 definition", and the static assertion counts an one. */
16987 if (c_parser_next_token_is (parser, CPP_PRAGMA)
16988 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
16990 error_at (data.loc,
16991 "%<#pragma acc routine%> not immediately followed by"
16992 " function declaration or definition");
16993 /* ..., and then just keep going. */
16997 /* We only have to consider the pragma_external case here. */
16998 if (c_parser_next_token_is (parser, CPP_KEYWORD)
16999 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17001 int ext = disable_extension_diagnostics ();
17003 c_parser_consume_token (parser);
17004 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17005 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17006 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17007 NULL, vNULL, false, NULL, &data);
17008 restore_extension_diagnostics (ext);
17011 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17012 NULL, vNULL, false, NULL, &data);
17016 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17017 IS_DEFN is true if we're applying it to the definition. */
17020 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17023 /* Keep going if we're in error reporting mode. */
17024 if (data->error_seen
17025 || fndecl == error_mark_node)
17028 if (data->fndecl_seen)
17030 error_at (data->loc,
17031 "%<#pragma acc routine%> not immediately followed by"
17032 " a single function declaration or definition");
17033 data->error_seen = true;
17036 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17038 error_at (data->loc,
17039 "%<#pragma acc routine%> not immediately followed by"
17040 " function declaration or definition");
17041 data->error_seen = true;
17046 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17047 "#pragma acc routine");
17048 if (compatible < 0)
17050 data->error_seen = true;
17053 if (compatible > 0)
17058 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17060 error_at (data->loc,
17062 ? G_("%<#pragma acc routine%> must be applied before use")
17063 : G_("%<#pragma acc routine%> must be applied before"
17065 data->error_seen = true;
17069 /* Set the routine's level of parallelism. */
17070 tree dims = oacc_build_routine_dims (data->clauses);
17071 oacc_replace_fn_attrib (fndecl, dims);
17073 /* Add an "omp declare target" attribute. */
17074 DECL_ATTRIBUTES (fndecl)
17075 = tree_cons (get_identifier ("omp declare target"),
17076 data->clauses, DECL_ATTRIBUTES (fndecl));
17079 /* Remember that we've used this "#pragma acc routine". */
17080 data->fndecl_seen = true;
17084 # pragma acc update oacc-update-clause[optseq] new-line
17087 #define OACC_UPDATE_CLAUSE_MASK \
17088 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17089 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17090 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17096 c_parser_oacc_update (c_parser *parser)
17098 location_t loc = c_parser_peek_token (parser)->location;
17100 c_parser_consume_pragma (parser);
17102 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17103 "#pragma acc update");
17104 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17107 "%<#pragma acc update%> must contain at least one "
17108 "%<device%> or %<host%> or %<self%> clause");
17115 tree stmt = make_node (OACC_UPDATE);
17116 TREE_TYPE (stmt) = void_type_node;
17117 OACC_UPDATE_CLAUSES (stmt) = clauses;
17118 SET_EXPR_LOCATION (stmt, loc);
17123 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17125 LOC is the location of the #pragma token.
17128 #define OACC_WAIT_CLAUSE_MASK \
17129 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17132 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
17134 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
17136 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17137 list = c_parser_oacc_wait_list (parser, loc, list);
17139 strcpy (p_name, " wait");
17140 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
17141 stmt = c_finish_oacc_wait (loc, list, clauses);
17148 # pragma omp atomic new-line
17152 x binop= expr | x++ | ++x | x-- | --x
17154 +, *, -, /, &, ^, |, <<, >>
17156 where x is an lvalue expression with scalar type.
17159 # pragma omp atomic new-line
17162 # pragma omp atomic read new-line
17165 # pragma omp atomic write new-line
17168 # pragma omp atomic update new-line
17171 # pragma omp atomic capture new-line
17174 # pragma omp atomic capture new-line
17182 expression-stmt | x = x binop expr
17184 v = expression-stmt
17186 { v = x; update-stmt; } | { update-stmt; v = x; }
17190 expression-stmt | x = x binop expr | x = expr binop x
17194 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17196 where x and v are lvalue expressions with scalar type.
17198 LOC is the location of the #pragma token. */
17201 c_parser_omp_atomic (location_t loc, c_parser *parser)
17203 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
17204 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
17205 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
17206 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
17207 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
17208 struct c_expr expr;
17210 bool structured_block = false;
17211 bool swapped = false;
17214 tree clauses = NULL_TREE;
17216 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17218 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
17219 c_parser_consume_token (parser);
17223 if (c_parser_next_token_is (parser, CPP_NAME))
17226 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17227 location_t cloc = c_parser_peek_token (parser)->location;
17228 enum tree_code new_code = ERROR_MARK;
17229 enum omp_memory_order new_memory_order
17230 = OMP_MEMORY_ORDER_UNSPECIFIED;
17232 if (!strcmp (p, "read"))
17233 new_code = OMP_ATOMIC_READ;
17234 else if (!strcmp (p, "write"))
17235 new_code = NOP_EXPR;
17236 else if (!strcmp (p, "update"))
17237 new_code = OMP_ATOMIC;
17238 else if (!strcmp (p, "capture"))
17239 new_code = OMP_ATOMIC_CAPTURE_NEW;
17240 else if (!strcmp (p, "seq_cst"))
17241 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17242 else if (!strcmp (p, "acq_rel"))
17243 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17244 else if (!strcmp (p, "release"))
17245 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
17246 else if (!strcmp (p, "acquire"))
17247 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17248 else if (!strcmp (p, "relaxed"))
17249 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
17250 else if (!strcmp (p, "hint"))
17252 c_parser_consume_token (parser);
17253 clauses = c_parser_omp_clause_hint (parser, clauses);
17259 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
17260 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17261 "%<release%>, %<relaxed%> or %<hint%> clause");
17265 if (new_code != ERROR_MARK)
17267 if (code != ERROR_MARK)
17268 error_at (cloc, "too many atomic clauses");
17272 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17274 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17275 error_at (cloc, "too many memory order clauses");
17277 memory_order = new_memory_order;
17279 c_parser_consume_token (parser);
17285 c_parser_skip_to_pragma_eol (parser);
17287 if (code == ERROR_MARK)
17289 if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
17292 = (enum omp_requires) (omp_requires_mask
17293 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
17294 switch ((enum omp_memory_order)
17295 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
17297 case OMP_MEMORY_ORDER_UNSPECIFIED:
17298 case OMP_MEMORY_ORDER_RELAXED:
17299 memory_order = OMP_MEMORY_ORDER_RELAXED;
17301 case OMP_MEMORY_ORDER_SEQ_CST:
17302 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17304 case OMP_MEMORY_ORDER_ACQ_REL:
17307 case OMP_ATOMIC_READ:
17308 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17310 case NOP_EXPR: /* atomic write */
17312 memory_order = OMP_MEMORY_ORDER_RELEASE;
17315 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17320 gcc_unreachable ();
17326 case OMP_ATOMIC_READ:
17327 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17328 || memory_order == OMP_MEMORY_ORDER_RELEASE)
17330 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
17331 "%<acq_rel%> or %<release%> clauses");
17332 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17335 case NOP_EXPR: /* atomic write */
17336 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17337 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17339 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
17340 "%<acq_rel%> or %<acquire%> clauses");
17341 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17345 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17346 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17348 error_at (loc, "%<#pragma omp atomic update%> incompatible with "
17349 "%<acq_rel%> or %<acquire%> clauses");
17350 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17359 case OMP_ATOMIC_READ:
17360 case NOP_EXPR: /* atomic write */
17361 v = c_parser_cast_expression (parser, NULL).value;
17362 non_lvalue_p = !lvalue_p (v);
17363 v = c_fully_fold (v, false, NULL, true);
17364 if (v == error_mark_node)
17367 v = non_lvalue (v);
17368 loc = c_parser_peek_token (parser)->location;
17369 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17371 if (code == NOP_EXPR)
17373 lhs = c_parser_expression (parser).value;
17374 lhs = c_fully_fold (lhs, false, NULL);
17375 if (lhs == error_mark_node)
17380 lhs = c_parser_cast_expression (parser, NULL).value;
17381 non_lvalue_p = !lvalue_p (lhs);
17382 lhs = c_fully_fold (lhs, false, NULL, true);
17383 if (lhs == error_mark_node)
17386 lhs = non_lvalue (lhs);
17388 if (code == NOP_EXPR)
17390 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17398 case OMP_ATOMIC_CAPTURE_NEW:
17399 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
17401 c_parser_consume_token (parser);
17402 structured_block = true;
17406 v = c_parser_cast_expression (parser, NULL).value;
17407 non_lvalue_p = !lvalue_p (v);
17408 v = c_fully_fold (v, false, NULL, true);
17409 if (v == error_mark_node)
17412 v = non_lvalue (v);
17413 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17421 /* For structured_block case we don't know yet whether
17422 old or new x should be captured. */
17424 eloc = c_parser_peek_token (parser)->location;
17425 expr = c_parser_cast_expression (parser, NULL);
17427 expr = default_function_array_conversion (eloc, expr);
17428 unfolded_lhs = expr.value;
17429 lhs = c_fully_fold (lhs, false, NULL, true);
17431 switch (TREE_CODE (lhs))
17435 c_parser_skip_to_end_of_block_or_statement (parser);
17436 if (structured_block)
17438 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17439 c_parser_consume_token (parser);
17440 else if (code == OMP_ATOMIC_CAPTURE_NEW)
17442 c_parser_skip_to_end_of_block_or_statement (parser);
17443 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17444 c_parser_consume_token (parser);
17449 case POSTINCREMENT_EXPR:
17450 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17451 code = OMP_ATOMIC_CAPTURE_OLD;
17453 case PREINCREMENT_EXPR:
17454 lhs = TREE_OPERAND (lhs, 0);
17455 unfolded_lhs = NULL_TREE;
17456 opcode = PLUS_EXPR;
17457 rhs = integer_one_node;
17460 case POSTDECREMENT_EXPR:
17461 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17462 code = OMP_ATOMIC_CAPTURE_OLD;
17464 case PREDECREMENT_EXPR:
17465 lhs = TREE_OPERAND (lhs, 0);
17466 unfolded_lhs = NULL_TREE;
17467 opcode = MINUS_EXPR;
17468 rhs = integer_one_node;
17471 case COMPOUND_EXPR:
17472 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
17473 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
17474 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
17475 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
17476 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17477 (TREE_OPERAND (lhs, 1), 0), 0)))
17479 /* Undo effects of boolean_increment for post {in,de}crement. */
17480 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
17483 if (TREE_CODE (lhs) == MODIFY_EXPR
17484 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
17486 /* Undo effects of boolean_increment. */
17487 if (integer_onep (TREE_OPERAND (lhs, 1)))
17489 /* This is pre or post increment. */
17490 rhs = TREE_OPERAND (lhs, 1);
17491 lhs = TREE_OPERAND (lhs, 0);
17492 unfolded_lhs = NULL_TREE;
17494 if (code == OMP_ATOMIC_CAPTURE_NEW
17495 && !structured_block
17496 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17497 code = OMP_ATOMIC_CAPTURE_OLD;
17500 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
17501 && TREE_OPERAND (lhs, 0)
17502 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
17504 /* This is pre or post decrement. */
17505 rhs = TREE_OPERAND (lhs, 1);
17506 lhs = TREE_OPERAND (lhs, 0);
17507 unfolded_lhs = NULL_TREE;
17509 if (code == OMP_ATOMIC_CAPTURE_NEW
17510 && !structured_block
17511 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17512 code = OMP_ATOMIC_CAPTURE_OLD;
17518 if (!lvalue_p (unfolded_lhs))
17519 lhs = non_lvalue (lhs);
17520 switch (c_parser_peek_token (parser)->type)
17523 opcode = MULT_EXPR;
17526 opcode = TRUNC_DIV_EXPR;
17529 opcode = PLUS_EXPR;
17532 opcode = MINUS_EXPR;
17534 case CPP_LSHIFT_EQ:
17535 opcode = LSHIFT_EXPR;
17537 case CPP_RSHIFT_EQ:
17538 opcode = RSHIFT_EXPR;
17541 opcode = BIT_AND_EXPR;
17544 opcode = BIT_IOR_EXPR;
17547 opcode = BIT_XOR_EXPR;
17550 c_parser_consume_token (parser);
17551 eloc = c_parser_peek_token (parser)->location;
17552 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
17554 switch (TREE_CODE (rhs1))
17557 case TRUNC_DIV_EXPR:
17566 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
17568 opcode = TREE_CODE (rhs1);
17569 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17571 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17575 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
17577 opcode = TREE_CODE (rhs1);
17578 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17580 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17582 swapped = !commutative_tree_code (opcode);
17591 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
17593 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17595 code = OMP_ATOMIC_CAPTURE_OLD;
17598 expr = default_function_array_read_conversion (eloc, expr);
17599 unfolded_lhs1 = expr.value;
17600 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
17602 c_parser_consume_token (parser);
17605 if (structured_block)
17608 expr = default_function_array_read_conversion (eloc, expr);
17609 rhs = c_fully_fold (expr.value, false, NULL, true);
17614 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
17617 c_parser_error (parser,
17618 "invalid operator for %<#pragma omp atomic%>");
17622 /* Arrange to pass the location of the assignment operator to
17623 c_finish_omp_atomic. */
17624 loc = c_parser_peek_token (parser)->location;
17625 c_parser_consume_token (parser);
17626 eloc = c_parser_peek_token (parser)->location;
17627 expr = c_parser_expression (parser);
17628 expr = default_function_array_read_conversion (eloc, expr);
17630 rhs = c_fully_fold (rhs, false, NULL, true);
17634 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17636 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
17638 v = c_parser_cast_expression (parser, NULL).value;
17639 non_lvalue_p = !lvalue_p (v);
17640 v = c_fully_fold (v, false, NULL, true);
17641 if (v == error_mark_node)
17644 v = non_lvalue (v);
17645 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17647 eloc = c_parser_peek_token (parser)->location;
17648 expr = c_parser_cast_expression (parser, NULL);
17650 expr = default_function_array_read_conversion (eloc, expr);
17651 unfolded_lhs1 = expr.value;
17652 lhs1 = c_fully_fold (lhs1, false, NULL, true);
17653 if (lhs1 == error_mark_node)
17655 if (!lvalue_p (unfolded_lhs1))
17656 lhs1 = non_lvalue (lhs1);
17658 if (structured_block)
17660 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17661 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
17664 if (unfolded_lhs && unfolded_lhs1
17665 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
17667 error ("%<#pragma omp atomic capture%> uses two different "
17668 "expressions for memory");
17669 stmt = error_mark_node;
17672 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1,
17673 swapped, memory_order);
17674 if (stmt != error_mark_node)
17677 if (!structured_block)
17678 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17683 # pragma omp barrier new-line
17687 c_parser_omp_barrier (c_parser *parser)
17689 location_t loc = c_parser_peek_token (parser)->location;
17690 c_parser_consume_pragma (parser);
17691 c_parser_skip_to_pragma_eol (parser);
17693 c_finish_omp_barrier (loc);
17697 # pragma omp critical [(name)] new-line
17701 # pragma omp critical [(name) [hint(expression)]] new-line
17703 LOC is the location of the #pragma itself. */
17705 #define OMP_CRITICAL_CLAUSE_MASK \
17706 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
17709 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
17711 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
17713 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17715 c_parser_consume_token (parser);
17716 if (c_parser_next_token_is (parser, CPP_NAME))
17718 name = c_parser_peek_token (parser)->value;
17719 c_parser_consume_token (parser);
17720 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
17723 c_parser_error (parser, "expected identifier");
17725 if (c_parser_next_token_is (parser, CPP_COMMA)
17726 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
17727 c_parser_consume_token (parser);
17729 clauses = c_parser_omp_all_clauses (parser,
17730 OMP_CRITICAL_CLAUSE_MASK,
17731 "#pragma omp critical");
17735 if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17736 c_parser_error (parser, "expected %<(%> or end of line");
17737 c_parser_skip_to_pragma_eol (parser);
17740 stmt = c_parser_omp_structured_block (parser, if_p);
17741 return c_finish_omp_critical (loc, stmt, name, clauses);
17745 # pragma omp depobj ( depobj ) depobj-clause new-line
17748 depend (dependence-type : locator)
17750 update (dependence-type)
17759 c_parser_omp_depobj (c_parser *parser)
17761 location_t loc = c_parser_peek_token (parser)->location;
17762 c_parser_consume_pragma (parser);
17763 matching_parens parens;
17764 if (!parens.require_open (parser))
17766 c_parser_skip_to_pragma_eol (parser);
17770 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
17771 if (depobj != error_mark_node)
17773 if (!lvalue_p (depobj))
17775 error_at (EXPR_LOC_OR_LOC (depobj, loc),
17776 "%<depobj%> expression is not lvalue expression");
17777 depobj = error_mark_node;
17781 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
17783 if (addr == error_mark_node)
17784 depobj = error_mark_node;
17786 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
17787 addr, RO_UNARY_STAR);
17791 parens.skip_until_found_close (parser);
17792 tree clause = NULL_TREE;
17793 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
17794 location_t c_loc = c_parser_peek_token (parser)->location;
17795 if (c_parser_next_token_is (parser, CPP_NAME))
17797 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17799 c_parser_consume_token (parser);
17800 if (!strcmp ("depend", p))
17802 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
17803 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
17805 clause = error_mark_node;
17807 else if (!strcmp ("destroy", p))
17808 kind = OMP_CLAUSE_DEPEND_LAST;
17809 else if (!strcmp ("update", p))
17811 matching_parens c_parens;
17812 if (c_parens.require_open (parser))
17814 location_t c2_loc = c_parser_peek_token (parser)->location;
17815 if (c_parser_next_token_is (parser, CPP_NAME))
17818 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17820 c_parser_consume_token (parser);
17821 if (!strcmp ("in", p2))
17822 kind = OMP_CLAUSE_DEPEND_IN;
17823 else if (!strcmp ("out", p2))
17824 kind = OMP_CLAUSE_DEPEND_OUT;
17825 else if (!strcmp ("inout", p2))
17826 kind = OMP_CLAUSE_DEPEND_INOUT;
17827 else if (!strcmp ("mutexinoutset", p2))
17828 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
17830 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
17832 clause = error_mark_node;
17833 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
17834 "%<mutexinoutset%>");
17836 c_parens.skip_until_found_close (parser);
17839 clause = error_mark_node;
17842 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
17844 clause = error_mark_node;
17845 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
17847 c_parser_skip_to_pragma_eol (parser);
17849 c_finish_omp_depobj (loc, depobj, kind, clause);
17854 # pragma omp flush flush-vars[opt] new-line
17860 # pragma omp flush memory-order-clause new-line */
17863 c_parser_omp_flush (c_parser *parser)
17865 location_t loc = c_parser_peek_token (parser)->location;
17866 c_parser_consume_pragma (parser);
17867 enum memmodel mo = MEMMODEL_LAST;
17868 if (c_parser_next_token_is (parser, CPP_NAME))
17871 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17873 if (!strcmp (p, "acq_rel"))
17874 mo = MEMMODEL_ACQ_REL;
17875 else if (!strcmp (p, "release"))
17876 mo = MEMMODEL_RELEASE;
17877 else if (!strcmp (p, "acquire"))
17878 mo = MEMMODEL_ACQUIRE;
17880 error_at (c_parser_peek_token (parser)->location,
17881 "expected %<acq_rel%>, %<release%> or %<acquire%>");
17882 c_parser_consume_token (parser);
17884 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17886 if (mo != MEMMODEL_LAST)
17887 error_at (c_parser_peek_token (parser)->location,
17888 "%<flush%> list specified together with memory order "
17890 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
17892 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17893 c_parser_error (parser, "expected %<(%> or end of line");
17894 c_parser_skip_to_pragma_eol (parser);
17896 c_finish_omp_flush (loc, mo);
17902 { structured-block scan-directive structured-block } */
17905 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
17909 tree clauses = NULL_TREE;
17911 loc = c_parser_peek_token (parser)->location;
17912 if (!open_brace_parsed
17913 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
17915 /* Avoid skipping until the end of the block. */
17916 parser->error = false;
17920 substmt = c_parser_omp_structured_block (parser, NULL);
17921 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
17922 SET_EXPR_LOCATION (substmt, loc);
17923 add_stmt (substmt);
17925 loc = c_parser_peek_token (parser)->location;
17926 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
17928 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
17930 c_parser_consume_pragma (parser);
17932 if (c_parser_next_token_is (parser, CPP_NAME))
17935 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17936 if (strcmp (p, "inclusive") == 0)
17937 clause = OMP_CLAUSE_INCLUSIVE;
17938 else if (strcmp (p, "exclusive") == 0)
17939 clause = OMP_CLAUSE_EXCLUSIVE;
17941 if (clause != OMP_CLAUSE_ERROR)
17943 c_parser_consume_token (parser);
17944 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
17947 c_parser_error (parser, "expected %<inclusive%> or "
17948 "%<exclusive%> clause");
17949 c_parser_skip_to_pragma_eol (parser);
17952 error ("expected %<#pragma omp scan%>");
17954 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
17955 substmt = c_parser_omp_structured_block (parser, NULL);
17956 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
17957 SET_EXPR_LOCATION (substmt, loc);
17958 add_stmt (substmt);
17960 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
17964 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
17965 The real trick here is to determine the loop control variable early
17966 so that we can push a new decl if necessary to make it private.
17967 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
17971 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
17972 tree clauses, tree *cclauses, bool *if_p)
17974 tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
17975 tree declv, condv, incrv, initv, ret = NULL_TREE;
17976 tree pre_body = NULL_TREE, this_pre_body;
17977 tree ordered_cl = NULL_TREE;
17978 bool fail = false, open_brace_parsed = false;
17979 int i, collapse = 1, ordered = 0, count, nbraces = 0;
17980 location_t for_loc;
17981 bool tiling = false;
17982 bool inscan = false;
17983 vec<tree, va_gc> *for_block = make_tree_vector ();
17985 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
17986 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
17987 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
17988 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
17991 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
17993 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
17994 && OMP_CLAUSE_ORDERED_EXPR (cl))
17997 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
17999 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
18000 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
18001 && (code == OMP_SIMD || code == OMP_FOR))
18004 if (ordered && ordered < collapse)
18006 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
18007 "%<ordered%> clause parameter is less than %<collapse%>");
18008 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
18009 = build_int_cst (NULL_TREE, collapse);
18010 ordered = collapse;
18014 for (tree *pc = &clauses; *pc; )
18015 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
18017 error_at (OMP_CLAUSE_LOCATION (*pc),
18018 "%<linear%> clause may not be specified together "
18019 "with %<ordered%> clause with a parameter");
18020 *pc = OMP_CLAUSE_CHAIN (*pc);
18023 pc = &OMP_CLAUSE_CHAIN (*pc);
18026 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
18027 count = ordered ? ordered : collapse;
18029 declv = make_tree_vec (count);
18030 initv = make_tree_vec (count);
18031 condv = make_tree_vec (count);
18032 incrv = make_tree_vec (count);
18034 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
18036 c_parser_error (parser, "for statement expected");
18039 for_loc = c_parser_peek_token (parser)->location;
18040 c_parser_consume_token (parser);
18042 for (i = 0; i < count; i++)
18044 int bracecount = 0;
18046 matching_parens parens;
18047 if (!parens.require_open (parser))
18050 /* Parse the initialization declaration or expression. */
18051 if (c_parser_next_tokens_start_declaration (parser))
18054 vec_safe_push (for_block, c_begin_compound_stmt (true));
18055 this_pre_body = push_stmt_list ();
18056 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
18060 this_pre_body = pop_stmt_list (this_pre_body);
18064 pre_body = push_stmt_list ();
18066 add_stmt (this_pre_body);
18067 pre_body = pop_stmt_list (pre_body);
18070 pre_body = this_pre_body;
18072 decl = check_for_loop_decls (for_loc, flag_isoc99);
18075 if (DECL_INITIAL (decl) == error_mark_node)
18076 decl = error_mark_node;
18079 else if (c_parser_next_token_is (parser, CPP_NAME)
18080 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
18082 struct c_expr decl_exp;
18083 struct c_expr init_exp;
18084 location_t init_loc;
18086 decl_exp = c_parser_postfix_expression (parser);
18087 decl = decl_exp.value;
18089 c_parser_require (parser, CPP_EQ, "expected %<=%>");
18091 init_loc = c_parser_peek_token (parser)->location;
18092 init_exp = c_parser_expr_no_commas (parser, NULL);
18093 init_exp = default_function_array_read_conversion (init_loc,
18095 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
18096 NOP_EXPR, init_loc, init_exp.value,
18097 init_exp.original_type);
18098 init = c_process_expr_stmt (init_loc, init);
18100 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18105 c_parser_error (parser,
18106 "expected iteration declaration or initialization");
18107 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18113 /* Parse the loop condition. */
18115 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
18117 location_t cond_loc = c_parser_peek_token (parser)->location;
18118 struct c_expr cond_expr
18119 = c_parser_binary_expression (parser, NULL, NULL_TREE);
18121 cond = cond_expr.value;
18122 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
18123 if (COMPARISON_CLASS_P (cond))
18125 tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1);
18126 op0 = c_fully_fold (op0, false, NULL);
18127 op1 = c_fully_fold (op1, false, NULL);
18128 TREE_OPERAND (cond, 0) = op0;
18129 TREE_OPERAND (cond, 1) = op1;
18131 switch (cond_expr.original_code)
18139 if (code != OACC_LOOP)
18143 /* Can't be cond = error_mark_node, because we want to preserve
18144 the location until c_finish_omp_for. */
18145 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
18148 protected_set_expr_location (cond, cond_loc);
18150 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18152 /* Parse the increment expression. */
18154 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
18156 location_t incr_loc = c_parser_peek_token (parser)->location;
18158 incr = c_process_expr_stmt (incr_loc,
18159 c_parser_expression (parser).value);
18161 parens.skip_until_found_close (parser);
18163 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
18167 TREE_VEC_ELT (declv, i) = decl;
18168 TREE_VEC_ELT (initv, i) = init;
18169 TREE_VEC_ELT (condv, i) = cond;
18170 TREE_VEC_ELT (incrv, i) = incr;
18174 if (i == count - 1)
18177 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18178 in between the collapsed for loops to be still considered perfectly
18179 nested. Hopefully the final version clarifies this.
18180 For now handle (multiple) {'s and empty statements. */
18183 if (c_parser_next_token_is_keyword (parser, RID_FOR))
18185 c_parser_consume_token (parser);
18188 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18190 c_parser_consume_token (parser);
18193 else if (bracecount
18194 && c_parser_next_token_is (parser, CPP_SEMICOLON))
18195 c_parser_consume_token (parser);
18198 c_parser_error (parser, "not enough perfectly nested loops");
18201 open_brace_parsed = true;
18211 nbraces += bracecount;
18217 save_break = c_break_label;
18218 c_break_label = size_one_node;
18219 save_cont = c_cont_label;
18220 c_cont_label = NULL_TREE;
18221 body = push_stmt_list ();
18224 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
18225 else if (open_brace_parsed)
18227 location_t here = c_parser_peek_token (parser)->location;
18228 stmt = c_begin_compound_stmt (true);
18229 c_parser_compound_statement_nostart (parser);
18230 add_stmt (c_end_compound_stmt (here, stmt, true));
18233 add_stmt (c_parser_c99_block_statement (parser, if_p));
18236 tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
18237 SET_EXPR_LOCATION (t, loc);
18241 body = pop_stmt_list (body);
18242 c_break_label = save_break;
18243 c_cont_label = save_cont;
18247 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18249 c_parser_consume_token (parser);
18252 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
18253 c_parser_consume_token (parser);
18256 c_parser_error (parser, "collapsed loops not perfectly nested");
18259 location_t here = c_parser_peek_token (parser)->location;
18260 stmt = c_begin_compound_stmt (true);
18262 c_parser_compound_statement_nostart (parser);
18263 body = c_end_compound_stmt (here, stmt, true);
18270 /* Only bother calling c_finish_omp_for if we haven't already generated
18271 an error from the initialization parsing. */
18274 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
18275 incrv, body, pre_body, true);
18277 /* Check for iterators appearing in lb, b or incr expressions. */
18278 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
18285 if (cclauses != NULL
18286 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
18289 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
18290 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
18291 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
18292 c = &OMP_CLAUSE_CHAIN (*c);
18295 for (i = 0; i < count; i++)
18296 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
18299 c = &OMP_CLAUSE_CHAIN (*c);
18300 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
18303 "iteration variable %qD should not be firstprivate",
18304 OMP_CLAUSE_DECL (*c));
18305 *c = OMP_CLAUSE_CHAIN (*c);
18309 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
18311 *c = OMP_CLAUSE_CHAIN (*c);
18312 if (code == OMP_SIMD)
18314 OMP_CLAUSE_CHAIN (l)
18315 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18316 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
18320 OMP_CLAUSE_CHAIN (l) = clauses;
18326 OMP_FOR_CLAUSES (stmt) = clauses;
18331 while (!for_block->is_empty ())
18333 /* FIXME diagnostics: LOC below should be the actual location of
18334 this particular for block. We need to build a list of
18335 locations to go along with FOR_BLOCK. */
18336 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
18339 release_tree_vector (for_block);
18343 /* Helper function for OpenMP parsing, split clauses and call
18344 finish_omp_clauses on each of the set of clauses afterwards. */
18347 omp_split_clauses (location_t loc, enum tree_code code,
18348 omp_clause_mask mask, tree clauses, tree *cclauses)
18351 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
18352 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
18354 cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP);
18358 #pragma omp loop loop-clause[optseq] new-line
18361 LOC is the location of the #pragma token.
18364 #define OMP_LOOP_CLAUSE_MASK \
18365 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18366 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18367 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18368 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18369 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
18370 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18373 c_parser_omp_loop (location_t loc, c_parser *parser,
18374 char *p_name, omp_clause_mask mask, tree *cclauses,
18377 tree block, clauses, ret;
18379 strcat (p_name, " loop");
18380 mask |= OMP_LOOP_CLAUSE_MASK;
18382 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18385 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
18386 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
18389 block = c_begin_compound_stmt (true);
18390 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
18391 block = c_end_compound_stmt (loc, block, true);
18398 #pragma omp simd simd-clause[optseq] new-line
18401 LOC is the location of the #pragma token.
18404 #define OMP_SIMD_CLAUSE_MASK \
18405 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
18406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
18407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
18409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18410 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18411 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18412 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18413 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18414 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
18415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18418 c_parser_omp_simd (location_t loc, c_parser *parser,
18419 char *p_name, omp_clause_mask mask, tree *cclauses,
18422 tree block, clauses, ret;
18424 strcat (p_name, " simd");
18425 mask |= OMP_SIMD_CLAUSE_MASK;
18427 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18430 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
18431 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
18432 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
18433 OMP_CLAUSE_ORDERED);
18434 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
18436 error_at (OMP_CLAUSE_LOCATION (c),
18437 "%<ordered%> clause with parameter may not be specified "
18438 "on %qs construct", p_name);
18439 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
18443 block = c_begin_compound_stmt (true);
18444 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
18445 block = c_end_compound_stmt (loc, block, true);
18452 #pragma omp for for-clause[optseq] new-line
18456 #pragma omp for simd for-simd-clause[optseq] new-line
18459 LOC is the location of the #pragma token.
18462 #define OMP_FOR_CLAUSE_MASK \
18463 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18464 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18465 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
18469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
18470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18475 c_parser_omp_for (location_t loc, c_parser *parser,
18476 char *p_name, omp_clause_mask mask, tree *cclauses,
18479 tree block, clauses, ret;
18481 strcat (p_name, " for");
18482 mask |= OMP_FOR_CLAUSE_MASK;
18483 /* parallel for{, simd} disallows nowait clause, but for
18484 target {teams distribute ,}parallel for{, simd} it should be accepted. */
18485 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
18486 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18487 /* Composite distribute parallel for{, simd} disallows ordered clause. */
18488 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18489 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
18491 if (c_parser_next_token_is (parser, CPP_NAME))
18493 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18495 if (strcmp (p, "simd") == 0)
18497 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18498 if (cclauses == NULL)
18499 cclauses = cclauses_buf;
18501 c_parser_consume_token (parser);
18502 if (!flag_openmp) /* flag_openmp_simd */
18503 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
18505 block = c_begin_compound_stmt (true);
18506 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
18507 block = c_end_compound_stmt (loc, block, true);
18508 if (ret == NULL_TREE)
18510 ret = make_node (OMP_FOR);
18511 TREE_TYPE (ret) = void_type_node;
18512 OMP_FOR_BODY (ret) = block;
18513 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18514 SET_EXPR_LOCATION (ret, loc);
18519 if (!flag_openmp) /* flag_openmp_simd */
18521 c_parser_skip_to_pragma_eol (parser, false);
18525 /* Composite distribute parallel for disallows linear clause. */
18526 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18527 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
18529 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18532 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
18533 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18536 block = c_begin_compound_stmt (true);
18537 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
18538 block = c_end_compound_stmt (loc, block, true);
18544 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
18545 omp_clause_mask, tree *, bool *);
18548 # pragma omp master new-line
18551 LOC is the location of the #pragma token.
18555 c_parser_omp_master (location_t loc, c_parser *parser,
18556 char *p_name, omp_clause_mask mask, tree *cclauses,
18559 tree block, clauses, ret;
18561 strcat (p_name, " master");
18563 if (c_parser_next_token_is (parser, CPP_NAME))
18565 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18567 if (strcmp (p, "taskloop") == 0)
18569 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18570 if (cclauses == NULL)
18571 cclauses = cclauses_buf;
18573 c_parser_consume_token (parser);
18574 if (!flag_openmp) /* flag_openmp_simd */
18575 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18577 block = c_begin_compound_stmt (true);
18578 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18580 block = c_end_compound_stmt (loc, block, true);
18581 if (ret == NULL_TREE)
18583 ret = c_finish_omp_master (loc, block);
18587 if (!flag_openmp) /* flag_openmp_simd */
18589 c_parser_skip_to_pragma_eol (parser, false);
18595 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
18596 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
18599 c_parser_skip_to_pragma_eol (parser);
18601 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
18606 # pragma omp ordered new-line
18610 # pragma omp ordered ordered-clauses new-line
18613 # pragma omp ordered depend-clauses new-line */
18615 #define OMP_ORDERED_CLAUSE_MASK \
18616 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
18617 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
18619 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
18620 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18623 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
18626 location_t loc = c_parser_peek_token (parser)->location;
18627 c_parser_consume_pragma (parser);
18629 if (context != pragma_stmt && context != pragma_compound)
18631 c_parser_error (parser, "expected declaration specifiers");
18632 c_parser_skip_to_pragma_eol (parser, false);
18636 if (c_parser_next_token_is (parser, CPP_NAME))
18638 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18640 if (!strcmp ("depend", p))
18642 if (!flag_openmp) /* flag_openmp_simd */
18644 c_parser_skip_to_pragma_eol (parser, false);
18647 if (context == pragma_stmt)
18650 "%<#pragma omp ordered%> with %<depend%> clause may "
18651 "only be used in compound statements");
18652 c_parser_skip_to_pragma_eol (parser, false);
18657 = c_parser_omp_all_clauses (parser,
18658 OMP_ORDERED_DEPEND_CLAUSE_MASK,
18659 "#pragma omp ordered");
18660 c_finish_omp_ordered (loc, clauses, NULL_TREE);
18665 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
18666 "#pragma omp ordered");
18668 if (!flag_openmp /* flag_openmp_simd */
18669 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
18672 c_finish_omp_ordered (loc, clauses,
18673 c_parser_omp_structured_block (parser, if_p));
18680 { section-sequence }
18683 section-directive[opt] structured-block
18684 section-sequence section-directive structured-block
18686 SECTIONS_LOC is the location of the #pragma omp sections. */
18689 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
18691 tree stmt, substmt;
18692 bool error_suppress = false;
18695 loc = c_parser_peek_token (parser)->location;
18696 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18698 /* Avoid skipping until the end of the block. */
18699 parser->error = false;
18703 stmt = push_stmt_list ();
18705 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
18707 substmt = c_parser_omp_structured_block (parser, NULL);
18708 substmt = build1 (OMP_SECTION, void_type_node, substmt);
18709 SET_EXPR_LOCATION (substmt, loc);
18710 add_stmt (substmt);
18715 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18717 if (c_parser_next_token_is (parser, CPP_EOF))
18720 loc = c_parser_peek_token (parser)->location;
18721 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
18723 c_parser_consume_pragma (parser);
18724 c_parser_skip_to_pragma_eol (parser);
18725 error_suppress = false;
18727 else if (!error_suppress)
18729 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
18730 error_suppress = true;
18733 substmt = c_parser_omp_structured_block (parser, NULL);
18734 substmt = build1 (OMP_SECTION, void_type_node, substmt);
18735 SET_EXPR_LOCATION (substmt, loc);
18736 add_stmt (substmt);
18738 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
18739 "expected %<#pragma omp section%> or %<}%>");
18741 substmt = pop_stmt_list (stmt);
18743 stmt = make_node (OMP_SECTIONS);
18744 SET_EXPR_LOCATION (stmt, sections_loc);
18745 TREE_TYPE (stmt) = void_type_node;
18746 OMP_SECTIONS_BODY (stmt) = substmt;
18748 return add_stmt (stmt);
18752 # pragma omp sections sections-clause[optseq] newline
18755 LOC is the location of the #pragma token.
18758 #define OMP_SECTIONS_CLAUSE_MASK \
18759 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18760 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18761 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18762 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18763 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18766 c_parser_omp_sections (location_t loc, c_parser *parser,
18767 char *p_name, omp_clause_mask mask, tree *cclauses)
18769 tree block, clauses, ret;
18771 strcat (p_name, " sections");
18772 mask |= OMP_SECTIONS_CLAUSE_MASK;
18774 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18776 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18779 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
18780 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
18783 block = c_begin_compound_stmt (true);
18784 ret = c_parser_omp_sections_scope (loc, parser);
18786 OMP_SECTIONS_CLAUSES (ret) = clauses;
18787 block = c_end_compound_stmt (loc, block, true);
18794 # pragma omp parallel parallel-clause[optseq] new-line
18796 # pragma omp parallel for parallel-for-clause[optseq] new-line
18798 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
18802 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
18805 LOC is the location of the #pragma token.
18808 #define OMP_PARALLEL_CLAUSE_MASK \
18809 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
18815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
18817 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
18820 c_parser_omp_parallel (location_t loc, c_parser *parser,
18821 char *p_name, omp_clause_mask mask, tree *cclauses,
18824 tree stmt, clauses, block;
18826 strcat (p_name, " parallel");
18827 mask |= OMP_PARALLEL_CLAUSE_MASK;
18828 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
18829 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
18830 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
18831 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
18833 if (c_parser_next_token_is_keyword (parser, RID_FOR))
18835 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18836 if (cclauses == NULL)
18837 cclauses = cclauses_buf;
18839 c_parser_consume_token (parser);
18840 if (!flag_openmp) /* flag_openmp_simd */
18841 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
18842 block = c_begin_omp_parallel ();
18843 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
18845 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18847 if (ret == NULL_TREE)
18849 OMP_PARALLEL_COMBINED (stmt) = 1;
18852 /* When combined with distribute, parallel has to be followed by for.
18853 #pragma omp target parallel is allowed though. */
18855 && (mask & (OMP_CLAUSE_MASK_1
18856 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18858 error_at (loc, "expected %<for%> after %qs", p_name);
18859 c_parser_skip_to_pragma_eol (parser);
18862 else if (c_parser_next_token_is (parser, CPP_NAME))
18864 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18865 if (cclauses == NULL && strcmp (p, "master") == 0)
18867 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18868 cclauses = cclauses_buf;
18870 c_parser_consume_token (parser);
18871 if (!flag_openmp) /* flag_openmp_simd */
18872 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18874 block = c_begin_omp_parallel ();
18875 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18877 stmt = c_finish_omp_parallel (loc,
18878 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18880 OMP_PARALLEL_COMBINED (stmt) = 1;
18885 else if (strcmp (p, "loop") == 0)
18887 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18888 if (cclauses == NULL)
18889 cclauses = cclauses_buf;
18891 c_parser_consume_token (parser);
18892 if (!flag_openmp) /* flag_openmp_simd */
18893 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18895 block = c_begin_omp_parallel ();
18896 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18899 = c_finish_omp_parallel (loc,
18900 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18902 if (ret == NULL_TREE)
18904 OMP_PARALLEL_COMBINED (stmt) = 1;
18907 else if (!flag_openmp) /* flag_openmp_simd */
18909 c_parser_skip_to_pragma_eol (parser, false);
18912 else if (cclauses == NULL && strcmp (p, "sections") == 0)
18914 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18915 cclauses = cclauses_buf;
18917 c_parser_consume_token (parser);
18918 block = c_begin_omp_parallel ();
18919 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
18920 stmt = c_finish_omp_parallel (loc,
18921 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18923 OMP_PARALLEL_COMBINED (stmt) = 1;
18927 else if (!flag_openmp) /* flag_openmp_simd */
18929 c_parser_skip_to_pragma_eol (parser, false);
18933 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18936 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
18937 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
18940 block = c_begin_omp_parallel ();
18941 c_parser_statement (parser, if_p);
18942 stmt = c_finish_omp_parallel (loc, clauses, block);
18948 # pragma omp single single-clause[optseq] new-line
18951 LOC is the location of the #pragma.
18954 #define OMP_SINGLE_CLAUSE_MASK \
18955 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18956 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18957 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
18958 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18961 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
18963 tree stmt = make_node (OMP_SINGLE);
18964 SET_EXPR_LOCATION (stmt, loc);
18965 TREE_TYPE (stmt) = void_type_node;
18967 OMP_SINGLE_CLAUSES (stmt)
18968 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
18969 "#pragma omp single");
18970 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
18972 return add_stmt (stmt);
18976 # pragma omp task task-clause[optseq] new-line
18978 LOC is the location of the #pragma.
18981 #define OMP_TASK_CLAUSE_MASK \
18982 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
18984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18986 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18987 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
18989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
18990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
18992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
18995 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
18997 tree clauses, block;
18999 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
19000 "#pragma omp task");
19002 block = c_begin_omp_task ();
19003 c_parser_statement (parser, if_p);
19004 return c_finish_omp_task (loc, clauses, block);
19008 # pragma omp taskwait new-line
19011 # pragma omp taskwait taskwait-clause[optseq] new-line
19014 #define OMP_TASKWAIT_CLAUSE_MASK \
19015 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19018 c_parser_omp_taskwait (c_parser *parser)
19020 location_t loc = c_parser_peek_token (parser)->location;
19021 c_parser_consume_pragma (parser);
19024 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
19025 "#pragma omp taskwait");
19029 tree stmt = make_node (OMP_TASK);
19030 TREE_TYPE (stmt) = void_node;
19031 OMP_TASK_CLAUSES (stmt) = clauses;
19032 OMP_TASK_BODY (stmt) = NULL_TREE;
19033 SET_EXPR_LOCATION (stmt, loc);
19037 c_finish_omp_taskwait (loc);
19041 # pragma omp taskyield new-line
19045 c_parser_omp_taskyield (c_parser *parser)
19047 location_t loc = c_parser_peek_token (parser)->location;
19048 c_parser_consume_pragma (parser);
19049 c_parser_skip_to_pragma_eol (parser);
19051 c_finish_omp_taskyield (loc);
19055 # pragma omp taskgroup new-line
19058 # pragma omp taskgroup taskgroup-clause[optseq] new-line
19061 #define OMP_TASKGROUP_CLAUSE_MASK \
19062 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19065 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
19067 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
19068 "#pragma omp taskgroup");
19070 tree body = c_parser_omp_structured_block (parser, if_p);
19071 return c_finish_omp_taskgroup (loc, body, clauses);
19075 # pragma omp cancel cancel-clause[optseq] new-line
19077 LOC is the location of the #pragma.
19080 #define OMP_CANCEL_CLAUSE_MASK \
19081 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19082 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19083 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
19085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
19088 c_parser_omp_cancel (c_parser *parser)
19090 location_t loc = c_parser_peek_token (parser)->location;
19092 c_parser_consume_pragma (parser);
19093 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
19094 "#pragma omp cancel");
19096 c_finish_omp_cancel (loc, clauses);
19100 # pragma omp cancellation point cancelpt-clause[optseq] new-line
19102 LOC is the location of the #pragma.
19105 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
19106 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19107 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19108 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19109 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
19112 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
19114 location_t loc = c_parser_peek_token (parser)->location;
19116 bool point_seen = false;
19118 c_parser_consume_pragma (parser);
19119 if (c_parser_next_token_is (parser, CPP_NAME))
19121 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19122 if (strcmp (p, "point") == 0)
19124 c_parser_consume_token (parser);
19130 c_parser_error (parser, "expected %<point%>");
19131 c_parser_skip_to_pragma_eol (parser);
19135 if (context != pragma_compound)
19137 if (context == pragma_stmt)
19139 "%<#pragma %s%> may only be used in compound statements",
19140 "omp cancellation point");
19142 c_parser_error (parser, "expected declaration specifiers");
19143 c_parser_skip_to_pragma_eol (parser, false);
19148 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
19149 "#pragma omp cancellation point");
19151 c_finish_omp_cancellation_point (loc, clauses);
19155 #pragma omp distribute distribute-clause[optseq] new-line
19158 #define OMP_DISTRIBUTE_CLAUSE_MASK \
19159 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19162 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19163 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
19166 c_parser_omp_distribute (location_t loc, c_parser *parser,
19167 char *p_name, omp_clause_mask mask, tree *cclauses,
19170 tree clauses, block, ret;
19172 strcat (p_name, " distribute");
19173 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
19175 if (c_parser_next_token_is (parser, CPP_NAME))
19177 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19179 bool parallel = false;
19181 if (strcmp (p, "simd") == 0)
19184 parallel = strcmp (p, "parallel") == 0;
19185 if (parallel || simd)
19187 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19188 if (cclauses == NULL)
19189 cclauses = cclauses_buf;
19190 c_parser_consume_token (parser);
19191 if (!flag_openmp) /* flag_openmp_simd */
19194 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19197 return c_parser_omp_parallel (loc, parser, p_name, mask,
19200 block = c_begin_compound_stmt (true);
19202 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19205 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
19207 block = c_end_compound_stmt (loc, block, true);
19210 ret = make_node (OMP_DISTRIBUTE);
19211 TREE_TYPE (ret) = void_type_node;
19212 OMP_FOR_BODY (ret) = block;
19213 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19214 SET_EXPR_LOCATION (ret, loc);
19219 if (!flag_openmp) /* flag_openmp_simd */
19221 c_parser_skip_to_pragma_eol (parser, false);
19225 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19228 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
19229 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19232 block = c_begin_compound_stmt (true);
19233 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
19235 block = c_end_compound_stmt (loc, block, true);
19242 # pragma omp teams teams-clause[optseq] new-line
19243 structured-block */
19245 #define OMP_TEAMS_CLAUSE_MASK \
19246 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19250 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
19251 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
19252 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
19255 c_parser_omp_teams (location_t loc, c_parser *parser,
19256 char *p_name, omp_clause_mask mask, tree *cclauses,
19259 tree clauses, block, ret;
19261 strcat (p_name, " teams");
19262 mask |= OMP_TEAMS_CLAUSE_MASK;
19264 if (c_parser_next_token_is (parser, CPP_NAME))
19266 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19267 if (strcmp (p, "distribute") == 0)
19269 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19270 if (cclauses == NULL)
19271 cclauses = cclauses_buf;
19273 c_parser_consume_token (parser);
19274 if (!flag_openmp) /* flag_openmp_simd */
19275 return c_parser_omp_distribute (loc, parser, p_name, mask,
19277 block = c_begin_omp_parallel ();
19278 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
19280 block = c_end_compound_stmt (loc, block, true);
19283 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19284 ret = make_node (OMP_TEAMS);
19285 TREE_TYPE (ret) = void_type_node;
19286 OMP_TEAMS_CLAUSES (ret) = clauses;
19287 OMP_TEAMS_BODY (ret) = block;
19288 OMP_TEAMS_COMBINED (ret) = 1;
19289 SET_EXPR_LOCATION (ret, loc);
19290 return add_stmt (ret);
19292 else if (strcmp (p, "loop") == 0)
19294 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19295 if (cclauses == NULL)
19296 cclauses = cclauses_buf;
19298 c_parser_consume_token (parser);
19299 if (!flag_openmp) /* flag_openmp_simd */
19300 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19302 block = c_begin_omp_parallel ();
19303 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
19304 block = c_end_compound_stmt (loc, block, true);
19307 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19308 ret = make_node (OMP_TEAMS);
19309 TREE_TYPE (ret) = void_type_node;
19310 OMP_TEAMS_CLAUSES (ret) = clauses;
19311 OMP_TEAMS_BODY (ret) = block;
19312 OMP_TEAMS_COMBINED (ret) = 1;
19313 SET_EXPR_LOCATION (ret, loc);
19314 return add_stmt (ret);
19317 if (!flag_openmp) /* flag_openmp_simd */
19319 c_parser_skip_to_pragma_eol (parser, false);
19323 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19326 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
19327 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19330 tree stmt = make_node (OMP_TEAMS);
19331 TREE_TYPE (stmt) = void_type_node;
19332 OMP_TEAMS_CLAUSES (stmt) = clauses;
19333 block = c_begin_omp_parallel ();
19334 add_stmt (c_parser_omp_structured_block (parser, if_p));
19335 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19336 SET_EXPR_LOCATION (stmt, loc);
19338 return add_stmt (stmt);
19342 # pragma omp target data target-data-clause[optseq] new-line
19343 structured-block */
19345 #define OMP_TARGET_DATA_CLAUSE_MASK \
19346 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19347 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19348 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
19353 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
19356 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
19357 "#pragma omp target data");
19359 for (tree *pc = &clauses; *pc;)
19361 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19362 switch (OMP_CLAUSE_MAP_KIND (*pc))
19365 case GOMP_MAP_ALWAYS_TO:
19366 case GOMP_MAP_FROM:
19367 case GOMP_MAP_ALWAYS_FROM:
19368 case GOMP_MAP_TOFROM:
19369 case GOMP_MAP_ALWAYS_TOFROM:
19370 case GOMP_MAP_ALLOC:
19373 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19374 case GOMP_MAP_ALWAYS_POINTER:
19378 error_at (OMP_CLAUSE_LOCATION (*pc),
19379 "%<#pragma omp target data%> with map-type other "
19380 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19381 "on %<map%> clause");
19382 *pc = OMP_CLAUSE_CHAIN (*pc);
19385 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
19386 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
19388 pc = &OMP_CLAUSE_CHAIN (*pc);
19395 "%<#pragma omp target data%> must contain at least "
19396 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19401 tree stmt = make_node (OMP_TARGET_DATA);
19402 TREE_TYPE (stmt) = void_type_node;
19403 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
19404 keep_next_level ();
19405 tree block = c_begin_compound_stmt (true);
19406 add_stmt (c_parser_omp_structured_block (parser, if_p));
19407 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19409 SET_EXPR_LOCATION (stmt, loc);
19410 return add_stmt (stmt);
19414 # pragma omp target update target-update-clause[optseq] new-line */
19416 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
19417 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
19418 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19419 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19425 c_parser_omp_target_update (location_t loc, c_parser *parser,
19426 enum pragma_context context)
19428 if (context == pragma_stmt)
19430 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19431 "omp target update");
19432 c_parser_skip_to_pragma_eol (parser, false);
19437 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
19438 "#pragma omp target update");
19439 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
19440 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
19443 "%<#pragma omp target update%> must contain at least one "
19444 "%<from%> or %<to%> clauses");
19448 tree stmt = make_node (OMP_TARGET_UPDATE);
19449 TREE_TYPE (stmt) = void_type_node;
19450 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
19451 SET_EXPR_LOCATION (stmt, loc);
19457 # pragma omp target enter data target-data-clause[optseq] new-line */
19459 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
19460 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19461 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19462 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19463 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19464 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19467 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
19468 enum pragma_context context)
19470 bool data_seen = false;
19471 if (c_parser_next_token_is (parser, CPP_NAME))
19473 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19474 if (strcmp (p, "data") == 0)
19476 c_parser_consume_token (parser);
19482 c_parser_error (parser, "expected %<data%>");
19483 c_parser_skip_to_pragma_eol (parser);
19487 if (context == pragma_stmt)
19489 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19490 "omp target enter data");
19491 c_parser_skip_to_pragma_eol (parser, false);
19496 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
19497 "#pragma omp target enter data");
19499 for (tree *pc = &clauses; *pc;)
19501 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19502 switch (OMP_CLAUSE_MAP_KIND (*pc))
19505 case GOMP_MAP_ALWAYS_TO:
19506 case GOMP_MAP_ALLOC:
19509 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19510 case GOMP_MAP_ALWAYS_POINTER:
19514 error_at (OMP_CLAUSE_LOCATION (*pc),
19515 "%<#pragma omp target enter data%> with map-type other "
19516 "than %<to%> or %<alloc%> on %<map%> clause");
19517 *pc = OMP_CLAUSE_CHAIN (*pc);
19520 pc = &OMP_CLAUSE_CHAIN (*pc);
19527 "%<#pragma omp target enter data%> must contain at least "
19528 "one %<map%> clause");
19532 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
19533 TREE_TYPE (stmt) = void_type_node;
19534 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
19535 SET_EXPR_LOCATION (stmt, loc);
19541 # pragma omp target exit data target-data-clause[optseq] new-line */
19543 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
19544 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19551 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
19552 enum pragma_context context)
19554 bool data_seen = false;
19555 if (c_parser_next_token_is (parser, CPP_NAME))
19557 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19558 if (strcmp (p, "data") == 0)
19560 c_parser_consume_token (parser);
19566 c_parser_error (parser, "expected %<data%>");
19567 c_parser_skip_to_pragma_eol (parser);
19571 if (context == pragma_stmt)
19573 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19574 "omp target exit data");
19575 c_parser_skip_to_pragma_eol (parser, false);
19580 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
19581 "#pragma omp target exit data");
19584 for (tree *pc = &clauses; *pc;)
19586 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19587 switch (OMP_CLAUSE_MAP_KIND (*pc))
19589 case GOMP_MAP_FROM:
19590 case GOMP_MAP_ALWAYS_FROM:
19591 case GOMP_MAP_RELEASE:
19592 case GOMP_MAP_DELETE:
19595 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19596 case GOMP_MAP_ALWAYS_POINTER:
19600 error_at (OMP_CLAUSE_LOCATION (*pc),
19601 "%<#pragma omp target exit data%> with map-type other "
19602 "than %<from%>, %<release%> or %<delete%> on %<map%>"
19604 *pc = OMP_CLAUSE_CHAIN (*pc);
19607 pc = &OMP_CLAUSE_CHAIN (*pc);
19614 "%<#pragma omp target exit data%> must contain at least one "
19619 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
19620 TREE_TYPE (stmt) = void_type_node;
19621 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
19622 SET_EXPR_LOCATION (stmt, loc);
19628 # pragma omp target target-clause[optseq] new-line
19629 structured-block */
19631 #define OMP_TARGET_CLAUSE_MASK \
19632 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19634 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19635 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
19640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
19643 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
19645 location_t loc = c_parser_peek_token (parser)->location;
19646 c_parser_consume_pragma (parser);
19647 tree *pc = NULL, stmt, block;
19649 if (context != pragma_stmt && context != pragma_compound)
19651 c_parser_error (parser, "expected declaration specifiers");
19652 c_parser_skip_to_pragma_eol (parser);
19658 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
19660 if (c_parser_next_token_is (parser, CPP_NAME))
19662 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19663 enum tree_code ccode = ERROR_MARK;
19665 if (strcmp (p, "teams") == 0)
19667 else if (strcmp (p, "parallel") == 0)
19668 ccode = OMP_PARALLEL;
19669 else if (strcmp (p, "simd") == 0)
19671 if (ccode != ERROR_MARK)
19673 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
19674 char p_name[sizeof ("#pragma omp target teams distribute "
19675 "parallel for simd")];
19677 c_parser_consume_token (parser);
19678 strcpy (p_name, "#pragma omp target");
19679 if (!flag_openmp) /* flag_openmp_simd */
19685 stmt = c_parser_omp_teams (loc, parser, p_name,
19686 OMP_TARGET_CLAUSE_MASK,
19690 stmt = c_parser_omp_parallel (loc, parser, p_name,
19691 OMP_TARGET_CLAUSE_MASK,
19695 stmt = c_parser_omp_simd (loc, parser, p_name,
19696 OMP_TARGET_CLAUSE_MASK,
19700 gcc_unreachable ();
19702 return stmt != NULL_TREE;
19704 keep_next_level ();
19705 tree block = c_begin_compound_stmt (true), ret;
19709 ret = c_parser_omp_teams (loc, parser, p_name,
19710 OMP_TARGET_CLAUSE_MASK, cclauses,
19714 ret = c_parser_omp_parallel (loc, parser, p_name,
19715 OMP_TARGET_CLAUSE_MASK, cclauses,
19719 ret = c_parser_omp_simd (loc, parser, p_name,
19720 OMP_TARGET_CLAUSE_MASK, cclauses,
19724 gcc_unreachable ();
19726 block = c_end_compound_stmt (loc, block, true);
19727 if (ret == NULL_TREE)
19729 if (ccode == OMP_TEAMS)
19731 /* For combined target teams, ensure the num_teams and
19732 thread_limit clause expressions are evaluated on the host,
19733 before entering the target construct. */
19735 for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19736 c; c = OMP_CLAUSE_CHAIN (c))
19737 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
19738 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
19739 && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
19741 tree expr = OMP_CLAUSE_OPERAND (c, 0);
19742 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
19743 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
19744 expr, NULL_TREE, NULL_TREE);
19746 OMP_CLAUSE_OPERAND (c, 0) = expr;
19747 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
19748 OMP_CLAUSE_FIRSTPRIVATE);
19749 OMP_CLAUSE_DECL (tc) = tmp;
19750 OMP_CLAUSE_CHAIN (tc)
19751 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
19752 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
19755 tree stmt = make_node (OMP_TARGET);
19756 TREE_TYPE (stmt) = void_type_node;
19757 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
19758 OMP_TARGET_BODY (stmt) = block;
19759 OMP_TARGET_COMBINED (stmt) = 1;
19760 SET_EXPR_LOCATION (stmt, loc);
19762 pc = &OMP_TARGET_CLAUSES (stmt);
19763 goto check_clauses;
19765 else if (!flag_openmp) /* flag_openmp_simd */
19767 c_parser_skip_to_pragma_eol (parser, false);
19770 else if (strcmp (p, "data") == 0)
19772 c_parser_consume_token (parser);
19773 c_parser_omp_target_data (loc, parser, if_p);
19776 else if (strcmp (p, "enter") == 0)
19778 c_parser_consume_token (parser);
19779 c_parser_omp_target_enter_data (loc, parser, context);
19782 else if (strcmp (p, "exit") == 0)
19784 c_parser_consume_token (parser);
19785 c_parser_omp_target_exit_data (loc, parser, context);
19788 else if (strcmp (p, "update") == 0)
19790 c_parser_consume_token (parser);
19791 return c_parser_omp_target_update (loc, parser, context);
19794 if (!flag_openmp) /* flag_openmp_simd */
19796 c_parser_skip_to_pragma_eol (parser, false);
19800 stmt = make_node (OMP_TARGET);
19801 TREE_TYPE (stmt) = void_type_node;
19803 OMP_TARGET_CLAUSES (stmt)
19804 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
19805 "#pragma omp target");
19806 pc = &OMP_TARGET_CLAUSES (stmt);
19807 keep_next_level ();
19808 block = c_begin_compound_stmt (true);
19809 add_stmt (c_parser_omp_structured_block (parser, if_p));
19810 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19812 SET_EXPR_LOCATION (stmt, loc);
19818 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19819 switch (OMP_CLAUSE_MAP_KIND (*pc))
19822 case GOMP_MAP_ALWAYS_TO:
19823 case GOMP_MAP_FROM:
19824 case GOMP_MAP_ALWAYS_FROM:
19825 case GOMP_MAP_TOFROM:
19826 case GOMP_MAP_ALWAYS_TOFROM:
19827 case GOMP_MAP_ALLOC:
19828 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19829 case GOMP_MAP_ALWAYS_POINTER:
19832 error_at (OMP_CLAUSE_LOCATION (*pc),
19833 "%<#pragma omp target%> with map-type other "
19834 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19835 "on %<map%> clause");
19836 *pc = OMP_CLAUSE_CHAIN (*pc);
19839 pc = &OMP_CLAUSE_CHAIN (*pc);
19845 # pragma omp declare simd declare-simd-clauses[optseq] new-line
19848 # pragma omp declare variant (identifier) match(context-selector) new-line
19851 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
19852 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19853 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19854 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
19856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
19857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
19860 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
19862 c_token *token = c_parser_peek_token (parser);
19863 gcc_assert (token->type == CPP_NAME);
19864 tree kind = token->value;
19865 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
19866 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
19868 auto_vec<c_token> clauses;
19869 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19871 c_token *token = c_parser_peek_token (parser);
19872 if (token->type == CPP_EOF)
19874 c_parser_skip_to_pragma_eol (parser);
19877 clauses.safe_push (*token);
19878 c_parser_consume_token (parser);
19880 clauses.safe_push (*c_parser_peek_token (parser));
19881 c_parser_skip_to_pragma_eol (parser);
19883 while (c_parser_next_token_is (parser, CPP_PRAGMA))
19885 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
19886 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
19887 || c_parser_peek_2nd_token (parser)->value != kind)
19889 error ("%<#pragma omp declare %s%> must be followed by "
19890 "function declaration or definition or another "
19891 "%<#pragma omp declare %s%>",
19892 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
19895 c_parser_consume_pragma (parser);
19896 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19898 c_token *token = c_parser_peek_token (parser);
19899 if (token->type == CPP_EOF)
19901 c_parser_skip_to_pragma_eol (parser);
19904 clauses.safe_push (*token);
19905 c_parser_consume_token (parser);
19907 clauses.safe_push (*c_parser_peek_token (parser));
19908 c_parser_skip_to_pragma_eol (parser);
19911 /* Make sure nothing tries to read past the end of the tokens. */
19913 memset (&eof_token, 0, sizeof (eof_token));
19914 eof_token.type = CPP_EOF;
19915 clauses.safe_push (eof_token);
19916 clauses.safe_push (eof_token);
19920 case pragma_external:
19921 if (c_parser_next_token_is (parser, CPP_KEYWORD)
19922 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
19924 int ext = disable_extension_diagnostics ();
19926 c_parser_consume_token (parser);
19927 while (c_parser_next_token_is (parser, CPP_KEYWORD)
19928 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
19929 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
19931 restore_extension_diagnostics (ext);
19934 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
19937 case pragma_struct:
19940 error ("%<#pragma omp declare %s%> must be followed by "
19941 "function declaration or definition",
19942 IDENTIFIER_POINTER (kind));
19944 case pragma_compound:
19945 if (c_parser_next_token_is (parser, CPP_KEYWORD)
19946 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
19948 int ext = disable_extension_diagnostics ();
19950 c_parser_consume_token (parser);
19951 while (c_parser_next_token_is (parser, CPP_KEYWORD)
19952 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
19953 if (c_parser_next_tokens_start_declaration (parser))
19955 c_parser_declaration_or_fndef (parser, true, true, true, true,
19956 true, NULL, clauses);
19957 restore_extension_diagnostics (ext);
19960 restore_extension_diagnostics (ext);
19962 else if (c_parser_next_tokens_start_declaration (parser))
19964 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
19968 error ("%<#pragma omp declare %s%> must be followed by "
19969 "function declaration or definition",
19970 IDENTIFIER_POINTER (kind));
19973 gcc_unreachable ();
19977 static const char *const omp_construct_selectors[] = {
19978 "simd", "target", "teams", "parallel", "for", NULL };
19979 static const char *const omp_device_selectors[] = {
19980 "kind", "isa", "arch", NULL };
19981 static const char *const omp_implementation_selectors[] = {
19982 "vendor", "extension", "atomic_default_mem_order", "unified_address",
19983 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
19984 static const char *const omp_user_selectors[] = {
19985 "condition", NULL };
19990 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
19993 score(score-expression) */
19996 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
19998 tree ret = NULL_TREE;
20002 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20003 || c_parser_next_token_is (parser, CPP_NAME))
20004 selector = c_parser_peek_token (parser)->value;
20007 c_parser_error (parser, "expected trait selector name");
20008 return error_mark_node;
20011 tree properties = NULL_TREE;
20012 const char *const *selectors = NULL;
20013 bool allow_score = true;
20014 bool allow_user = false;
20015 int property_limit = 0;
20016 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
20017 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
20018 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
20019 switch (IDENTIFIER_POINTER (set)[0])
20021 case 'c': /* construct */
20022 selectors = omp_construct_selectors;
20023 allow_score = false;
20024 property_limit = 1;
20025 property_kind = CTX_PROPERTY_SIMD;
20027 case 'd': /* device */
20028 selectors = omp_device_selectors;
20029 allow_score = false;
20031 property_limit = 3;
20032 property_kind = CTX_PROPERTY_NAME_LIST;
20034 case 'i': /* implementation */
20035 selectors = omp_implementation_selectors;
20037 property_limit = 3;
20038 property_kind = CTX_PROPERTY_NAME_LIST;
20040 case 'u': /* user */
20041 selectors = omp_user_selectors;
20042 property_limit = 1;
20043 property_kind = CTX_PROPERTY_EXPR;
20046 gcc_unreachable ();
20048 for (int i = 0; ; i++)
20050 if (selectors[i] == NULL)
20054 property_kind = CTX_PROPERTY_USER;
20059 error_at (c_parser_peek_token (parser)->location,
20060 "selector %qs not allowed for context selector "
20061 "set %qs", IDENTIFIER_POINTER (selector),
20062 IDENTIFIER_POINTER (set));
20063 c_parser_consume_token (parser);
20064 return error_mark_node;
20067 if (i == property_limit)
20068 property_kind = CTX_PROPERTY_NONE;
20069 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
20072 if (property_kind == CTX_PROPERTY_NAME_LIST
20073 && IDENTIFIER_POINTER (set)[0] == 'i'
20074 && strcmp (IDENTIFIER_POINTER (selector),
20075 "atomic_default_mem_order") == 0)
20076 property_kind = CTX_PROPERTY_ID;
20078 c_parser_consume_token (parser);
20080 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20082 if (property_kind == CTX_PROPERTY_NONE)
20084 error_at (c_parser_peek_token (parser)->location,
20085 "selector %qs does not accept any properties",
20086 IDENTIFIER_POINTER (selector));
20087 return error_mark_node;
20090 matching_parens parens;
20091 parens.require_open (parser);
20093 c_token *token = c_parser_peek_token (parser);
20095 && c_parser_next_token_is (parser, CPP_NAME)
20096 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
20097 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
20099 c_parser_consume_token (parser);
20101 matching_parens parens2;
20102 parens2.require_open (parser);
20103 tree score = c_parser_expr_no_commas (parser, NULL).value;
20104 parens2.skip_until_found_close (parser);
20105 c_parser_require (parser, CPP_COLON, "expected %<:%>");
20106 if (score != error_mark_node)
20108 mark_exp_read (score);
20109 score = c_fully_fold (score, false, NULL);
20110 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
20111 || TREE_CODE (score) != INTEGER_CST)
20112 error_at (token->location, "score argument must be "
20113 "constant integer expression");
20114 else if (tree_int_cst_sgn (score) < 0)
20115 error_at (token->location, "score argument must be "
20118 properties = tree_cons (get_identifier (" score"),
20119 score, properties);
20121 token = c_parser_peek_token (parser);
20124 switch (property_kind)
20127 case CTX_PROPERTY_USER:
20130 t = c_parser_expr_no_commas (parser, NULL).value;
20131 if (TREE_CODE (t) == STRING_CST)
20132 properties = tree_cons (NULL_TREE, t, properties);
20133 else if (t != error_mark_node)
20136 t = c_fully_fold (t, false, NULL);
20137 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20138 || !tree_fits_shwi_p (t))
20139 error_at (token->location, "property must be "
20140 "constant integer expression or string "
20143 properties = tree_cons (NULL_TREE, t, properties);
20146 return error_mark_node;
20148 if (c_parser_next_token_is (parser, CPP_COMMA))
20149 c_parser_consume_token (parser);
20155 case CTX_PROPERTY_ID:
20156 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20157 || c_parser_next_token_is (parser, CPP_NAME))
20159 tree prop = c_parser_peek_token (parser)->value;
20160 c_parser_consume_token (parser);
20161 properties = tree_cons (prop, NULL_TREE, properties);
20165 c_parser_error (parser, "expected identifier");
20166 return error_mark_node;
20169 case CTX_PROPERTY_NAME_LIST:
20172 tree prop = NULL_TREE, value = NULL_TREE;
20173 if (c_parser_next_token_is (parser, CPP_KEYWORD)
20174 || c_parser_next_token_is (parser, CPP_NAME))
20176 prop = c_parser_peek_token (parser)->value;
20177 c_parser_consume_token (parser);
20179 else if (c_parser_next_token_is (parser, CPP_STRING))
20180 value = c_parser_string_literal (parser, false,
20184 c_parser_error (parser, "expected identifier or "
20186 return error_mark_node;
20189 properties = tree_cons (prop, value, properties);
20191 if (c_parser_next_token_is (parser, CPP_COMMA))
20192 c_parser_consume_token (parser);
20198 case CTX_PROPERTY_EXPR:
20199 t = c_parser_expr_no_commas (parser, NULL).value;
20200 if (t != error_mark_node)
20203 t = c_fully_fold (t, false, NULL);
20204 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20205 || !tree_fits_shwi_p (t))
20206 error_at (token->location, "property must be "
20207 "constant integer expression");
20209 properties = tree_cons (NULL_TREE, t, properties);
20212 return error_mark_node;
20214 case CTX_PROPERTY_SIMD:
20215 if (parms == NULL_TREE)
20217 error_at (token->location, "properties for %<simd%> "
20218 "selector may not be specified in "
20219 "%<metadirective%>");
20220 return error_mark_node;
20223 c = c_parser_omp_all_clauses (parser,
20224 OMP_DECLARE_SIMD_CLAUSE_MASK,
20226 c = c_omp_declare_simd_clauses_to_numbers (parms
20228 ? NULL_TREE : parms,
20233 gcc_unreachable ();
20236 parens.skip_until_found_close (parser);
20237 properties = nreverse (properties);
20239 else if (property_kind == CTX_PROPERTY_NAME_LIST
20240 || property_kind == CTX_PROPERTY_ID
20241 || property_kind == CTX_PROPERTY_EXPR)
20243 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
20244 return error_mark_node;
20247 ret = tree_cons (selector, properties, ret);
20249 if (c_parser_next_token_is (parser, CPP_COMMA))
20250 c_parser_consume_token (parser);
20256 return nreverse (ret);
20261 trait-set-selector[,trait-set-selector[,...]]
20263 trait-set-selector:
20264 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20266 trait-set-selector-name:
20273 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
20275 tree ret = NULL_TREE;
20278 const char *setp = "";
20279 if (c_parser_next_token_is (parser, CPP_NAME))
20280 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20284 if (strcmp (setp, "construct") == 0)
20288 if (strcmp (setp, "device") == 0)
20292 if (strcmp (setp, "implementation") == 0)
20296 if (strcmp (setp, "user") == 0)
20304 c_parser_error (parser, "expected %<construct%>, %<device%>, "
20305 "%<implementation%> or %<user%>");
20306 return error_mark_node;
20309 tree set = c_parser_peek_token (parser)->value;
20310 c_parser_consume_token (parser);
20312 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
20313 return error_mark_node;
20315 matching_braces braces;
20316 if (!braces.require_open (parser))
20317 return error_mark_node;
20319 tree selectors = c_parser_omp_context_selector (parser, set, parms);
20320 if (selectors == error_mark_node)
20321 ret = error_mark_node;
20322 else if (ret != error_mark_node)
20323 ret = tree_cons (set, selectors, ret);
20325 braces.skip_until_found_close (parser);
20327 if (c_parser_next_token_is (parser, CPP_COMMA))
20328 c_parser_consume_token (parser);
20334 if (ret == error_mark_node)
20336 return nreverse (ret);
20339 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20340 that into "omp declare variant base" attribute. */
20343 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
20345 matching_parens parens;
20346 if (!parens.require_open (parser))
20349 c_parser_skip_to_pragma_eol (parser, false);
20353 if (c_parser_next_token_is_not (parser, CPP_NAME)
20354 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20356 c_parser_error (parser, "expected identifier");
20360 c_token *token = c_parser_peek_token (parser);
20361 tree variant = lookup_name (token->value);
20363 if (variant == NULL_TREE)
20365 undeclared_variable (token->location, token->value);
20366 variant = error_mark_node;
20369 c_parser_consume_token (parser);
20371 parens.require_close (parser);
20373 const char *clause = "";
20374 location_t match_loc = c_parser_peek_token (parser)->location;
20375 if (c_parser_next_token_is (parser, CPP_NAME))
20376 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20377 if (strcmp (clause, "match"))
20379 c_parser_error (parser, "expected %<match%>");
20383 c_parser_consume_token (parser);
20385 if (!parens.require_open (parser))
20388 if (parms == NULL_TREE)
20389 parms = error_mark_node;
20391 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
20392 if (ctx == error_mark_node)
20394 ctx = c_omp_check_context_selector (match_loc, ctx);
20395 if (ctx != error_mark_node && variant != error_mark_node)
20397 if (TREE_CODE (variant) != FUNCTION_DECL)
20399 error_at (token->location, "variant %qD is not a function", variant);
20400 variant = error_mark_node;
20402 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
20403 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
20405 error_at (token->location, "variant %qD and base %qD have "
20406 "incompatible types", variant, fndecl);
20407 variant = error_mark_node;
20409 else if (fndecl_built_in_p (variant)
20410 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20411 "__builtin_", strlen ("__builtin_")) == 0
20412 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20413 "__sync_", strlen ("__sync_")) == 0
20414 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20415 "__atomic_", strlen ("__atomic_")) == 0))
20417 error_at (token->location, "variant %qD is a built-in", variant);
20418 variant = error_mark_node;
20420 if (variant != error_mark_node)
20422 C_DECL_USED (variant) = 1;
20423 tree construct = omp_get_context_selector (ctx, "construct", NULL);
20424 c_omp_mark_declare_variant (match_loc, variant, construct);
20425 if (omp_context_selector_matches (ctx))
20428 = tree_cons (get_identifier ("omp declare variant base"),
20429 build_tree_list (variant, ctx),
20430 DECL_ATTRIBUTES (fndecl));
20431 DECL_ATTRIBUTES (fndecl) = attr;
20436 parens.require_close (parser);
20437 c_parser_skip_to_pragma_eol (parser);
20440 /* Finalize #pragma omp declare simd or #pragma omp declare variant
20441 clauses after FNDECL has been parsed, and put that into "omp declare simd"
20442 or "omp declare variant base" attribute. */
20445 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
20446 vec<c_token> clauses)
20448 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
20449 indicates error has been reported and CPP_PRAGMA that
20450 c_finish_omp_declare_simd has already processed the tokens. */
20451 if (clauses.exists () && clauses[0].type == CPP_EOF)
20453 const char *kind = "simd";
20454 if (clauses.exists ()
20455 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
20456 kind = IDENTIFIER_POINTER (clauses[0].value);
20457 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
20458 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
20460 error ("%<#pragma omp declare %s%> not immediately followed by "
20461 "a function declaration or definition", kind);
20462 clauses[0].type = CPP_EOF;
20465 if (clauses.exists () && clauses[0].type != CPP_NAME)
20467 error_at (DECL_SOURCE_LOCATION (fndecl),
20468 "%<#pragma omp declare %s%> not immediately followed by "
20469 "a single function declaration or definition", kind);
20470 clauses[0].type = CPP_EOF;
20474 if (parms == NULL_TREE)
20475 parms = DECL_ARGUMENTS (fndecl);
20477 unsigned int tokens_avail = parser->tokens_avail;
20478 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
20480 parser->tokens = clauses.address ();
20481 parser->tokens_avail = clauses.length ();
20483 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
20484 while (parser->tokens_avail > 3)
20486 c_token *token = c_parser_peek_token (parser);
20487 gcc_assert (token->type == CPP_NAME
20488 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
20489 c_parser_consume_token (parser);
20490 parser->in_pragma = true;
20492 if (strcmp (kind, "simd") == 0)
20495 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
20496 "#pragma omp declare simd");
20497 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
20498 if (c != NULL_TREE)
20499 c = tree_cons (NULL_TREE, c, NULL_TREE);
20500 c = build_tree_list (get_identifier ("omp declare simd"), c);
20501 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
20502 DECL_ATTRIBUTES (fndecl) = c;
20506 gcc_assert (strcmp (kind, "variant") == 0);
20507 c_finish_omp_declare_variant (parser, fndecl, parms);
20511 parser->tokens = &parser->tokens_buf[0];
20512 parser->tokens_avail = tokens_avail;
20513 if (clauses.exists ())
20514 clauses[0].type = CPP_PRAGMA;
20519 # pragma omp declare target new-line
20520 declarations and definitions
20521 # pragma omp end declare target new-line
20524 # pragma omp declare target ( extended-list ) new-line
20526 # pragma omp declare target declare-target-clauses[seq] new-line */
20528 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
20529 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20530 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
20531 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
20534 c_parser_omp_declare_target (c_parser *parser)
20536 tree clauses = NULL_TREE;
20537 int device_type = 0;
20538 bool only_device_type = true;
20539 if (c_parser_next_token_is (parser, CPP_NAME))
20540 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
20541 "#pragma omp declare target");
20542 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20544 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
20546 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
20547 c_parser_skip_to_pragma_eol (parser);
20551 c_parser_skip_to_pragma_eol (parser);
20552 current_omp_declare_target_attribute++;
20555 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20556 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20557 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
20558 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20560 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20562 tree t = OMP_CLAUSE_DECL (c), id;
20563 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
20564 tree at2 = lookup_attribute ("omp declare target link",
20565 DECL_ATTRIBUTES (t));
20566 only_device_type = false;
20567 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
20569 id = get_identifier ("omp declare target link");
20570 std::swap (at1, at2);
20573 id = get_identifier ("omp declare target");
20576 error_at (OMP_CLAUSE_LOCATION (c),
20577 "%qD specified both in declare target %<link%> and %<to%>"
20583 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20584 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
20587 symtab_node *node = symtab_node::get (t);
20590 node->offloadable = 1;
20591 if (ENABLE_OFFLOADING)
20593 g->have_offload = true;
20594 if (is_a <varpool_node *> (node))
20595 vec_safe_push (offload_vars, t);
20599 if (TREE_CODE (t) != FUNCTION_DECL)
20601 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
20603 tree at3 = lookup_attribute ("omp declare target host",
20604 DECL_ATTRIBUTES (t));
20605 if (at3 == NULL_TREE)
20607 id = get_identifier ("omp declare target host");
20608 DECL_ATTRIBUTES (t)
20609 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20612 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
20614 tree at3 = lookup_attribute ("omp declare target nohost",
20615 DECL_ATTRIBUTES (t));
20616 if (at3 == NULL_TREE)
20618 id = get_identifier ("omp declare target nohost");
20619 DECL_ATTRIBUTES (t)
20620 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20624 if (device_type && only_device_type)
20625 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
20626 "directive with only %<device_type%> clauses ignored");
20630 c_parser_omp_end_declare_target (c_parser *parser)
20632 location_t loc = c_parser_peek_token (parser)->location;
20633 c_parser_consume_pragma (parser);
20634 if (c_parser_next_token_is (parser, CPP_NAME)
20635 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20638 c_parser_consume_token (parser);
20639 if (c_parser_next_token_is (parser, CPP_NAME)
20640 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20642 c_parser_consume_token (parser);
20645 c_parser_error (parser, "expected %<target%>");
20646 c_parser_skip_to_pragma_eol (parser);
20652 c_parser_error (parser, "expected %<declare%>");
20653 c_parser_skip_to_pragma_eol (parser);
20656 c_parser_skip_to_pragma_eol (parser);
20657 if (!current_omp_declare_target_attribute)
20658 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
20659 "%<#pragma omp declare target%>");
20661 current_omp_declare_target_attribute--;
20666 #pragma omp declare reduction (reduction-id : typename-list : expression) \
20667 initializer-clause[opt] new-line
20669 initializer-clause:
20670 initializer (omp_priv = initializer)
20671 initializer (function-name (argument-list)) */
20674 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
20676 unsigned int tokens_avail = 0, i;
20677 vec<tree> types = vNULL;
20678 vec<c_token> clauses = vNULL;
20679 enum tree_code reduc_code = ERROR_MARK;
20680 tree reduc_id = NULL_TREE;
20682 location_t rloc = c_parser_peek_token (parser)->location;
20684 if (context == pragma_struct || context == pragma_param)
20686 error ("%<#pragma omp declare reduction%> not at file or block scope");
20690 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
20693 switch (c_parser_peek_token (parser)->type)
20696 reduc_code = PLUS_EXPR;
20699 reduc_code = MULT_EXPR;
20702 reduc_code = MINUS_EXPR;
20705 reduc_code = BIT_AND_EXPR;
20708 reduc_code = BIT_XOR_EXPR;
20711 reduc_code = BIT_IOR_EXPR;
20714 reduc_code = TRUTH_ANDIF_EXPR;
20717 reduc_code = TRUTH_ORIF_EXPR;
20721 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20722 if (strcmp (p, "min") == 0)
20724 reduc_code = MIN_EXPR;
20727 if (strcmp (p, "max") == 0)
20729 reduc_code = MAX_EXPR;
20732 reduc_id = c_parser_peek_token (parser)->value;
20735 c_parser_error (parser,
20736 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
20737 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
20741 tree orig_reduc_id, reduc_decl;
20742 orig_reduc_id = reduc_id;
20743 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
20744 reduc_decl = c_omp_reduction_decl (reduc_id);
20745 c_parser_consume_token (parser);
20747 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
20752 location_t loc = c_parser_peek_token (parser)->location;
20753 struct c_type_name *ctype = c_parser_type_name (parser);
20756 type = groktypename (ctype, NULL, NULL);
20757 if (type == error_mark_node)
20759 else if ((INTEGRAL_TYPE_P (type)
20760 || TREE_CODE (type) == REAL_TYPE
20761 || TREE_CODE (type) == COMPLEX_TYPE)
20762 && orig_reduc_id == NULL_TREE)
20763 error_at (loc, "predeclared arithmetic type in "
20764 "%<#pragma omp declare reduction%>");
20765 else if (TREE_CODE (type) == FUNCTION_TYPE
20766 || TREE_CODE (type) == ARRAY_TYPE)
20767 error_at (loc, "function or array type in "
20768 "%<#pragma omp declare reduction%>");
20769 else if (TYPE_ATOMIC (type))
20770 error_at (loc, "%<_Atomic%> qualified type in "
20771 "%<#pragma omp declare reduction%>");
20772 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
20773 error_at (loc, "const, volatile or restrict qualified type in "
20774 "%<#pragma omp declare reduction%>");
20778 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
20779 if (comptypes (TREE_PURPOSE (t), type))
20781 error_at (loc, "redeclaration of %qs "
20782 "%<#pragma omp declare reduction%> for "
20784 IDENTIFIER_POINTER (reduc_id)
20785 + sizeof ("omp declare reduction ") - 1,
20788 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
20790 error_at (ploc, "previous %<#pragma omp declare "
20794 if (t == NULL_TREE)
20795 types.safe_push (type);
20797 if (c_parser_next_token_is (parser, CPP_COMMA))
20798 c_parser_consume_token (parser);
20806 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
20807 || types.is_empty ())
20810 clauses.release ();
20814 c_token *token = c_parser_peek_token (parser);
20815 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
20817 c_parser_consume_token (parser);
20819 c_parser_skip_to_pragma_eol (parser);
20823 if (types.length () > 1)
20825 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20827 c_token *token = c_parser_peek_token (parser);
20828 if (token->type == CPP_EOF)
20830 clauses.safe_push (*token);
20831 c_parser_consume_token (parser);
20833 clauses.safe_push (*c_parser_peek_token (parser));
20834 c_parser_skip_to_pragma_eol (parser);
20836 /* Make sure nothing tries to read past the end of the tokens. */
20838 memset (&eof_token, 0, sizeof (eof_token));
20839 eof_token.type = CPP_EOF;
20840 clauses.safe_push (eof_token);
20841 clauses.safe_push (eof_token);
20844 int errs = errorcount;
20845 FOR_EACH_VEC_ELT (types, i, type)
20847 tokens_avail = parser->tokens_avail;
20848 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
20849 if (!clauses.is_empty ())
20851 parser->tokens = clauses.address ();
20852 parser->tokens_avail = clauses.length ();
20853 parser->in_pragma = true;
20856 bool nested = current_function_decl != NULL_TREE;
20858 c_push_function_context ();
20859 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
20860 reduc_id, default_function_type);
20861 current_function_decl = fndecl;
20862 allocate_struct_function (fndecl, true);
20864 tree stmt = push_stmt_list ();
20865 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
20866 warn about these. */
20867 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
20868 get_identifier ("omp_out"), type);
20869 DECL_ARTIFICIAL (omp_out) = 1;
20870 DECL_CONTEXT (omp_out) = fndecl;
20871 pushdecl (omp_out);
20872 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
20873 get_identifier ("omp_in"), type);
20874 DECL_ARTIFICIAL (omp_in) = 1;
20875 DECL_CONTEXT (omp_in) = fndecl;
20877 struct c_expr combiner = c_parser_expression (parser);
20878 struct c_expr initializer;
20879 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
20881 initializer.set_error ();
20882 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20884 else if (c_parser_next_token_is (parser, CPP_NAME)
20885 && strcmp (IDENTIFIER_POINTER
20886 (c_parser_peek_token (parser)->value),
20887 "initializer") == 0)
20889 c_parser_consume_token (parser);
20892 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
20893 get_identifier ("omp_priv"), type);
20894 DECL_ARTIFICIAL (omp_priv) = 1;
20895 DECL_INITIAL (omp_priv) = error_mark_node;
20896 DECL_CONTEXT (omp_priv) = fndecl;
20897 pushdecl (omp_priv);
20898 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
20899 get_identifier ("omp_orig"), type);
20900 DECL_ARTIFICIAL (omp_orig) = 1;
20901 DECL_CONTEXT (omp_orig) = fndecl;
20902 pushdecl (omp_orig);
20903 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
20905 else if (!c_parser_next_token_is (parser, CPP_NAME))
20907 c_parser_error (parser, "expected %<omp_priv%> or "
20911 else if (strcmp (IDENTIFIER_POINTER
20912 (c_parser_peek_token (parser)->value),
20915 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
20916 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20918 c_parser_error (parser, "expected function-name %<(%>");
20922 initializer = c_parser_postfix_expression (parser);
20923 if (initializer.value
20924 && TREE_CODE (initializer.value) == CALL_EXPR)
20927 tree c = initializer.value;
20928 for (j = 0; j < call_expr_nargs (c); j++)
20930 tree a = CALL_EXPR_ARG (c, j);
20932 if (TREE_CODE (a) == ADDR_EXPR
20933 && TREE_OPERAND (a, 0) == omp_priv)
20936 if (j == call_expr_nargs (c))
20937 error ("one of the initializer call arguments should be "
20943 c_parser_consume_token (parser);
20944 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
20948 tree st = push_stmt_list ();
20949 location_t loc = c_parser_peek_token (parser)->location;
20950 rich_location richloc (line_table, loc);
20951 start_init (omp_priv, NULL_TREE, 0, &richloc);
20952 struct c_expr init = c_parser_initializer (parser);
20954 finish_decl (omp_priv, loc, init.value,
20955 init.original_type, NULL_TREE);
20956 pop_stmt_list (st);
20960 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20966 c_parser_skip_to_pragma_eol (parser);
20968 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
20969 DECL_INITIAL (reduc_decl));
20970 DECL_INITIAL (reduc_decl) = t;
20971 DECL_SOURCE_LOCATION (omp_out) = rloc;
20972 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
20973 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
20974 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
20975 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
20976 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
20979 DECL_SOURCE_LOCATION (omp_priv) = rloc;
20980 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
20981 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
20982 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
20983 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
20984 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
20985 walk_tree (&DECL_INITIAL (omp_priv),
20986 c_check_omp_declare_reduction_r,
20987 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
20991 pop_stmt_list (stmt);
20993 if (cfun->language != NULL)
20995 ggc_free (cfun->language);
20996 cfun->language = NULL;
20999 current_function_decl = NULL_TREE;
21001 c_pop_function_context ();
21003 if (!clauses.is_empty ())
21005 parser->tokens = &parser->tokens_buf[0];
21006 parser->tokens_avail = tokens_avail;
21010 if (errs != errorcount)
21014 clauses.release ();
21020 #pragma omp declare simd declare-simd-clauses[optseq] new-line
21021 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21022 initializer-clause[opt] new-line
21023 #pragma omp declare target new-line
21026 #pragma omp declare variant (identifier) match (context-selector) */
21029 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
21031 c_parser_consume_pragma (parser);
21032 if (c_parser_next_token_is (parser, CPP_NAME))
21034 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21035 if (strcmp (p, "simd") == 0)
21037 /* c_parser_consume_token (parser); done in
21038 c_parser_omp_declare_simd. */
21039 c_parser_omp_declare_simd (parser, context);
21042 if (strcmp (p, "reduction") == 0)
21044 c_parser_consume_token (parser);
21045 c_parser_omp_declare_reduction (parser, context);
21048 if (!flag_openmp) /* flag_openmp_simd */
21050 c_parser_skip_to_pragma_eol (parser, false);
21053 if (strcmp (p, "target") == 0)
21055 c_parser_consume_token (parser);
21056 c_parser_omp_declare_target (parser);
21059 if (strcmp (p, "variant") == 0)
21061 /* c_parser_consume_token (parser); done in
21062 c_parser_omp_declare_simd. */
21063 c_parser_omp_declare_simd (parser, context);
21068 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
21069 "%<target%> or %<variant%>");
21070 c_parser_skip_to_pragma_eol (parser);
21074 #pragma omp requires clauses[optseq] new-line */
21077 c_parser_omp_requires (c_parser *parser)
21080 enum omp_requires new_req = (enum omp_requires) 0;
21082 c_parser_consume_pragma (parser);
21084 location_t loc = c_parser_peek_token (parser)->location;
21085 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21087 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
21088 c_parser_consume_token (parser);
21092 if (c_parser_next_token_is (parser, CPP_NAME))
21095 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21096 location_t cloc = c_parser_peek_token (parser)->location;
21097 enum omp_requires this_req = (enum omp_requires) 0;
21099 if (!strcmp (p, "unified_address"))
21100 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
21101 else if (!strcmp (p, "unified_shared_memory"))
21102 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
21103 else if (!strcmp (p, "dynamic_allocators"))
21104 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
21105 else if (!strcmp (p, "reverse_offload"))
21106 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
21107 else if (!strcmp (p, "atomic_default_mem_order"))
21109 c_parser_consume_token (parser);
21111 matching_parens parens;
21112 if (parens.require_open (parser))
21114 if (c_parser_next_token_is (parser, CPP_NAME))
21116 tree v = c_parser_peek_token (parser)->value;
21117 p = IDENTIFIER_POINTER (v);
21119 if (!strcmp (p, "seq_cst"))
21121 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
21122 else if (!strcmp (p, "relaxed"))
21124 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
21125 else if (!strcmp (p, "acq_rel"))
21127 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
21131 error_at (c_parser_peek_token (parser)->location,
21132 "expected %<seq_cst%>, %<relaxed%> or "
21134 if (c_parser_peek_2nd_token (parser)->type
21135 == CPP_CLOSE_PAREN)
21136 c_parser_consume_token (parser);
21139 c_parser_consume_token (parser);
21141 parens.skip_until_found_close (parser);
21144 c_parser_skip_to_pragma_eol (parser, false);
21152 error_at (cloc, "expected %<unified_address%>, "
21153 "%<unified_shared_memory%>, "
21154 "%<dynamic_allocators%>, "
21155 "%<reverse_offload%> "
21156 "or %<atomic_default_mem_order%> clause");
21157 c_parser_skip_to_pragma_eol (parser, false);
21161 sorry_at (cloc, "%qs clause on %<requires%> directive not "
21162 "supported yet", p);
21164 c_parser_consume_token (parser);
21167 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21169 if ((this_req & new_req) != 0)
21170 error_at (cloc, "too many %qs clauses", p);
21171 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
21172 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
21173 error_at (cloc, "%qs clause used lexically after first "
21174 "target construct or offloading API", p);
21176 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21178 error_at (cloc, "too many %qs clauses",
21179 "atomic_default_mem_order");
21180 this_req = (enum omp_requires) 0;
21182 else if ((omp_requires_mask
21183 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21185 error_at (cloc, "more than one %<atomic_default_mem_order%>"
21186 " clause in a single compilation unit");
21188 = (enum omp_requires)
21190 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
21192 else if ((omp_requires_mask
21193 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
21194 error_at (cloc, "%<atomic_default_mem_order%> clause used "
21195 "lexically after first %<atomic%> construct "
21196 "without memory order clause");
21197 new_req = (enum omp_requires) (new_req | this_req);
21199 = (enum omp_requires) (omp_requires_mask | this_req);
21205 c_parser_skip_to_pragma_eol (parser);
21208 error_at (loc, "%<pragma omp requires%> requires at least one clause");
21211 /* Helper function for c_parser_omp_taskloop.
21212 Disallow zero sized or potentially zero sized task reductions. */
21215 c_finish_taskloop_clauses (tree clauses)
21217 tree *pc = &clauses;
21218 for (tree c = clauses; c; c = *pc)
21220 bool remove = false;
21221 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
21223 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
21224 if (integer_zerop (TYPE_SIZE_UNIT (type)))
21226 error_at (OMP_CLAUSE_LOCATION (c),
21227 "zero sized type %qT in %<reduction%> clause", type);
21230 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
21232 error_at (OMP_CLAUSE_LOCATION (c),
21233 "variable sized type %qT in %<reduction%> clause",
21239 *pc = OMP_CLAUSE_CHAIN (c);
21241 pc = &OMP_CLAUSE_CHAIN (c);
21247 #pragma omp taskloop taskloop-clause[optseq] new-line
21250 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21253 #define OMP_TASKLOOP_CLAUSE_MASK \
21254 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21255 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21256 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21257 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21258 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21259 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
21260 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
21261 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21262 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21263 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21264 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21265 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21266 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
21267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21268 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21269 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
21272 c_parser_omp_taskloop (location_t loc, c_parser *parser,
21273 char *p_name, omp_clause_mask mask, tree *cclauses,
21276 tree clauses, block, ret;
21278 strcat (p_name, " taskloop");
21279 mask |= OMP_TASKLOOP_CLAUSE_MASK;
21280 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21282 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
21283 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
21285 if (c_parser_next_token_is (parser, CPP_NAME))
21287 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21289 if (strcmp (p, "simd") == 0)
21291 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21292 if (cclauses == NULL)
21293 cclauses = cclauses_buf;
21294 c_parser_consume_token (parser);
21295 if (!flag_openmp) /* flag_openmp_simd */
21296 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21298 block = c_begin_compound_stmt (true);
21299 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
21300 block = c_end_compound_stmt (loc, block, true);
21303 ret = make_node (OMP_TASKLOOP);
21304 TREE_TYPE (ret) = void_type_node;
21305 OMP_FOR_BODY (ret) = block;
21306 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21307 OMP_FOR_CLAUSES (ret)
21308 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
21309 SET_EXPR_LOCATION (ret, loc);
21314 if (!flag_openmp) /* flag_openmp_simd */
21316 c_parser_skip_to_pragma_eol (parser, false);
21320 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21323 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
21324 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21327 clauses = c_finish_taskloop_clauses (clauses);
21328 block = c_begin_compound_stmt (true);
21329 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
21330 block = c_end_compound_stmt (loc, block, true);
21336 /* Main entry point to parsing most OpenMP pragmas. */
21339 c_parser_omp_construct (c_parser *parser, bool *if_p)
21341 enum pragma_kind p_kind;
21344 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
21345 omp_clause_mask mask (0);
21347 loc = c_parser_peek_token (parser)->location;
21348 p_kind = c_parser_peek_token (parser)->pragma_kind;
21349 c_parser_consume_pragma (parser);
21353 case PRAGMA_OACC_ATOMIC:
21354 c_parser_omp_atomic (loc, parser);
21356 case PRAGMA_OACC_CACHE:
21357 strcpy (p_name, "#pragma acc");
21358 stmt = c_parser_oacc_cache (loc, parser);
21360 case PRAGMA_OACC_DATA:
21361 stmt = c_parser_oacc_data (loc, parser, if_p);
21363 case PRAGMA_OACC_HOST_DATA:
21364 stmt = c_parser_oacc_host_data (loc, parser, if_p);
21366 case PRAGMA_OACC_KERNELS:
21367 case PRAGMA_OACC_PARALLEL:
21368 case PRAGMA_OACC_SERIAL:
21369 strcpy (p_name, "#pragma acc");
21370 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
21372 case PRAGMA_OACC_LOOP:
21373 strcpy (p_name, "#pragma acc");
21374 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
21376 case PRAGMA_OACC_WAIT:
21377 strcpy (p_name, "#pragma wait");
21378 stmt = c_parser_oacc_wait (loc, parser, p_name);
21380 case PRAGMA_OMP_ATOMIC:
21381 c_parser_omp_atomic (loc, parser);
21383 case PRAGMA_OMP_CRITICAL:
21384 stmt = c_parser_omp_critical (loc, parser, if_p);
21386 case PRAGMA_OMP_DISTRIBUTE:
21387 strcpy (p_name, "#pragma omp");
21388 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
21390 case PRAGMA_OMP_FOR:
21391 strcpy (p_name, "#pragma omp");
21392 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
21394 case PRAGMA_OMP_LOOP:
21395 strcpy (p_name, "#pragma omp");
21396 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
21398 case PRAGMA_OMP_MASTER:
21399 strcpy (p_name, "#pragma omp");
21400 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
21402 case PRAGMA_OMP_PARALLEL:
21403 strcpy (p_name, "#pragma omp");
21404 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
21406 case PRAGMA_OMP_SECTIONS:
21407 strcpy (p_name, "#pragma omp");
21408 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
21410 case PRAGMA_OMP_SIMD:
21411 strcpy (p_name, "#pragma omp");
21412 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
21414 case PRAGMA_OMP_SINGLE:
21415 stmt = c_parser_omp_single (loc, parser, if_p);
21417 case PRAGMA_OMP_TASK:
21418 stmt = c_parser_omp_task (loc, parser, if_p);
21420 case PRAGMA_OMP_TASKGROUP:
21421 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
21423 case PRAGMA_OMP_TASKLOOP:
21424 strcpy (p_name, "#pragma omp");
21425 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
21427 case PRAGMA_OMP_TEAMS:
21428 strcpy (p_name, "#pragma omp");
21429 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
21432 gcc_unreachable ();
21436 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
21441 # pragma omp threadprivate (variable-list) */
21444 c_parser_omp_threadprivate (c_parser *parser)
21449 c_parser_consume_pragma (parser);
21450 loc = c_parser_peek_token (parser)->location;
21451 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
21453 /* Mark every variable in VARS to be assigned thread local storage. */
21454 for (t = vars; t; t = TREE_CHAIN (t))
21456 tree v = TREE_PURPOSE (t);
21458 /* FIXME diagnostics: Ideally we should keep individual
21459 locations for all the variables in the var list to make the
21460 following errors more precise. Perhaps
21461 c_parser_omp_var_list_parens() should construct a list of
21462 locations to go along with the var list. */
21464 /* If V had already been marked threadprivate, it doesn't matter
21465 whether it had been used prior to this point. */
21467 error_at (loc, "%qD is not a variable", v);
21468 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
21469 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
21470 else if (! is_global_var (v))
21471 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
21472 else if (TREE_TYPE (v) == error_mark_node)
21474 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
21475 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
21478 if (! DECL_THREAD_LOCAL_P (v))
21480 set_decl_tls_model (v, decl_default_tls_model (v));
21481 /* If rtl has been already set for this var, call
21482 make_decl_rtl once again, so that encode_section_info
21483 has a chance to look at the new decl flags. */
21484 if (DECL_RTL_SET_P (v))
21487 C_DECL_THREADPRIVATE_P (v) = 1;
21491 c_parser_skip_to_pragma_eol (parser);
21494 /* Parse a transaction attribute (GCC Extension).
21496 transaction-attribute:
21498 attribute-specifier
21502 c_parser_transaction_attributes (c_parser *parser)
21504 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
21505 return c_parser_gnu_attributes (parser);
21507 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
21509 return c_parser_std_attribute_specifier (parser, true);
21512 /* Parse a __transaction_atomic or __transaction_relaxed statement
21515 transaction-statement:
21516 __transaction_atomic transaction-attribute[opt] compound-statement
21517 __transaction_relaxed compound-statement
21519 Note that the only valid attribute is: "outer".
21523 c_parser_transaction (c_parser *parser, enum rid keyword)
21525 unsigned int old_in = parser->in_transaction;
21526 unsigned int this_in = 1, new_in;
21527 location_t loc = c_parser_peek_token (parser)->location;
21530 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21531 || keyword == RID_TRANSACTION_RELAXED)
21532 && c_parser_next_token_is_keyword (parser, keyword));
21533 c_parser_consume_token (parser);
21535 if (keyword == RID_TRANSACTION_RELAXED)
21536 this_in |= TM_STMT_ATTR_RELAXED;
21539 attrs = c_parser_transaction_attributes (parser);
21541 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
21544 /* Keep track if we're in the lexical scope of an outer transaction. */
21545 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
21547 parser->in_transaction = new_in;
21548 stmt = c_parser_compound_statement (parser);
21549 parser->in_transaction = old_in;
21552 stmt = c_finish_transaction (loc, stmt, this_in);
21554 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21555 "%<__transaction_atomic%> without transactional memory support enabled"
21556 : "%<__transaction_relaxed %> "
21557 "without transactional memory support enabled"));
21562 /* Parse a __transaction_atomic or __transaction_relaxed expression
21565 transaction-expression:
21566 __transaction_atomic ( expression )
21567 __transaction_relaxed ( expression )
21570 static struct c_expr
21571 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
21574 unsigned int old_in = parser->in_transaction;
21575 unsigned int this_in = 1;
21576 location_t loc = c_parser_peek_token (parser)->location;
21579 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21580 || keyword == RID_TRANSACTION_RELAXED)
21581 && c_parser_next_token_is_keyword (parser, keyword));
21582 c_parser_consume_token (parser);
21584 if (keyword == RID_TRANSACTION_RELAXED)
21585 this_in |= TM_STMT_ATTR_RELAXED;
21588 attrs = c_parser_transaction_attributes (parser);
21590 this_in |= parse_tm_stmt_attr (attrs, 0);
21593 parser->in_transaction = this_in;
21594 matching_parens parens;
21595 if (parens.require_open (parser))
21597 tree expr = c_parser_expression (parser).value;
21598 ret.original_type = TREE_TYPE (expr);
21599 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
21600 if (this_in & TM_STMT_ATTR_RELAXED)
21601 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
21602 SET_EXPR_LOCATION (ret.value, loc);
21603 ret.original_code = TRANSACTION_EXPR;
21604 if (!parens.require_close (parser))
21606 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
21614 ret.original_code = ERROR_MARK;
21615 ret.original_type = NULL;
21617 parser->in_transaction = old_in;
21620 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21621 "%<__transaction_atomic%> without transactional memory support enabled"
21622 : "%<__transaction_relaxed %> "
21623 "without transactional memory support enabled"));
21625 set_c_expr_source_range (&ret, loc, loc);
21630 /* Parse a __transaction_cancel statement (GCC Extension).
21632 transaction-cancel-statement:
21633 __transaction_cancel transaction-attribute[opt] ;
21635 Note that the only valid attribute is "outer".
21639 c_parser_transaction_cancel (c_parser *parser)
21641 location_t loc = c_parser_peek_token (parser)->location;
21643 bool is_outer = false;
21645 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
21646 c_parser_consume_token (parser);
21648 attrs = c_parser_transaction_attributes (parser);
21650 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
21654 error_at (loc, "%<__transaction_cancel%> without "
21655 "transactional memory support enabled");
21658 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
21660 error_at (loc, "%<__transaction_cancel%> within a "
21661 "%<__transaction_relaxed%>");
21666 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
21667 && !is_tm_may_cancel_outer (current_function_decl))
21669 error_at (loc, "outer %<__transaction_cancel%> not "
21670 "within outer %<__transaction_atomic%> or "
21671 "a %<transaction_may_cancel_outer%> function");
21675 else if (parser->in_transaction == 0)
21677 error_at (loc, "%<__transaction_cancel%> not within "
21678 "%<__transaction_atomic%>");
21682 return add_stmt (build_tm_abort_call (loc, is_outer));
21685 return build1 (NOP_EXPR, void_type_node, error_mark_node);
21688 /* Parse a single source file. */
21691 c_parse_file (void)
21693 /* Use local storage to begin. If the first token is a pragma, parse it.
21694 If it is #pragma GCC pch_preprocess, then this will load a PCH file
21695 which will cause garbage collection. */
21698 memset (&tparser, 0, sizeof tparser);
21699 tparser.translate_strings_p = true;
21700 tparser.tokens = &tparser.tokens_buf[0];
21701 the_parser = &tparser;
21703 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
21704 c_parser_pragma_pch_preprocess (&tparser);
21706 c_common_no_more_pch ();
21708 the_parser = ggc_alloc<c_parser> ();
21709 *the_parser = tparser;
21710 if (tparser.tokens == &tparser.tokens_buf[0])
21711 the_parser->tokens = &the_parser->tokens_buf[0];
21713 /* Initialize EH, if we've been told to do so. */
21714 if (flag_exceptions)
21715 using_eh_for_cleanups ();
21717 c_parser_translation_unit (the_parser);
21721 /* Parse the body of a function declaration marked with "__RTL".
21723 The RTL parser works on the level of characters read from a
21724 FILE *, whereas c_parser works at the level of tokens.
21725 Square this circle by consuming all of the tokens up to and
21726 including the closing brace, recording the start/end of the RTL
21727 fragment, and reopening the file and re-reading the relevant
21728 lines within the RTL parser.
21730 This requires the opening and closing braces of the C function
21731 to be on separate lines from the RTL they wrap.
21733 Take ownership of START_WITH_PASS, if non-NULL. */
21736 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
21738 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21740 free (start_with_pass);
21741 return c_parser_peek_token (parser)->location;
21744 location_t start_loc = c_parser_peek_token (parser)->location;
21746 /* Consume all tokens, up to the closing brace, handling
21747 matching pairs of braces in the rtl dump. */
21748 int num_open_braces = 1;
21751 switch (c_parser_peek_token (parser)->type)
21753 case CPP_OPEN_BRACE:
21756 case CPP_CLOSE_BRACE:
21757 if (--num_open_braces == 0)
21758 goto found_closing_brace;
21761 error_at (start_loc, "no closing brace");
21762 free (start_with_pass);
21763 return c_parser_peek_token (parser)->location;
21767 c_parser_consume_token (parser);
21770 found_closing_brace:
21771 /* At the closing brace; record its location. */
21772 location_t end_loc = c_parser_peek_token (parser)->location;
21774 /* Consume the closing brace. */
21775 c_parser_consume_token (parser);
21777 /* Invoke the RTL parser. */
21778 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
21780 free (start_with_pass);
21784 /* Run the backend on the cfun created above, transferring ownership of
21785 START_WITH_PASS. */
21786 run_rtl_passes (start_with_pass);
21790 #include "gt-c-c-parser.h"